@open-pioneer/toc 0.11.0 → 0.12.0-dev.20250725080856

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,5 +1,59 @@
1
1
  # @open-pioneer/toc
2
2
 
3
+ ## 0.12.0-dev.20250725080856
4
+
5
+ ### Minor Changes
6
+
7
+ - 2702df4: Layers that are marked as `internal` are not considered by the Toc.
8
+
9
+ ```typescript
10
+ //internal layer will not be displayed in the Toc
11
+ const internalLayer = new SimpleLayer({
12
+ id: "layer1",
13
+ title: "layer 1",
14
+ olLayer: myOlLayer,
15
+ internal: true
16
+ });
17
+ ```
18
+
19
+ The layer's `internal` state also affects other UI widgets (e.g. Legend). If the layer should be hidden specifically in the toc (but not in other widgets) the `listMode` attribute can be used to hide the layer item.
20
+
21
+ ```typescript
22
+ //use listMode to hide the layer specifically in Toc
23
+ const hiddenLayer = new SimpleLayer({
24
+ id: "layer1",
25
+ title: "layer 1",
26
+ olLayer: myOlLayer,
27
+ attributes: {
28
+ toc: {
29
+ listMode: "hide"
30
+ }
31
+ }
32
+ });
33
+ ```
34
+
35
+ Valid values for `listMode` are:
36
+ - `"show"` layer item is displayed in Toc
37
+ - `"hide"` layer item is not rendered in Toc
38
+ - `"hide-children"` layer item for the layer itself is displayed in Toc but no layer items for child layers (e.g. sublayers of a group) are rendered
39
+
40
+ The `listMode` does always have precedence over the layer's `internal` property. For example, if the `listMode` is `"show"` the layer item is displayed even if `internal` is `true`.
41
+
42
+ - 2732052: Icons have been changed to unify the appearance of the components. Preferably, Lucide react-icons are used.
43
+
44
+ ### Patch Changes
45
+
46
+ - 10d2fe7: Update dependencies
47
+ - da6a410: Update dependencies
48
+ - Updated dependencies [10d2fe7]
49
+ - Updated dependencies [2702df4]
50
+ - Updated dependencies [8986b3b]
51
+ - Updated dependencies [2732052]
52
+ - Updated dependencies [f1f69f2]
53
+ - Updated dependencies [da6a410]
54
+ - @open-pioneer/basemap-switcher@0.12.0-dev.20250725080856
55
+ - @open-pioneer/map@0.12.0-dev.20250725080856
56
+
3
57
  ## 0.11.0
4
58
 
5
59
  ### Minor Changes
@@ -108,7 +162,6 @@
108
162
  ### Minor Changes
109
163
 
110
164
  - 2fa8020: Update trails core package dependencies.
111
-
112
165
  - Also updates Chakra UI to the latest 2.x version and Chakra React Select to version 5.
113
166
  - Removes any obsolete references to `@chakra-ui/system`.
114
167
  This dependency seems to be no longer required and may lead to duplicate packages in your dependency tree.
package/README.md CHANGED
@@ -92,6 +92,44 @@ If enabled, a toggle button appears next to parent nodes by which the user can e
92
92
  />
93
93
  ```
94
94
 
95
+ ### Hide certain layers in Toc
96
+
97
+ Layers that are marked as `internal` are not considered by the Toc.
98
+
99
+ ```typescript
100
+ //internal layer will not be displayed in the Toc
101
+ const internalLayer = new SimpleLayer({
102
+ id: "layer1",
103
+ title: "layer 1",
104
+ olLayer: myOlLayer,
105
+ internal: true
106
+ });
107
+ ```
108
+
109
+ The layer's `internal` state also affects other UI widgets (e.g. Legend). If the layer should be hidden specifically in the Toc (but not in other widgets) the `listMode` attribute can be used to hide the layer item.
110
+
111
+ ```typescript
112
+ //use listMode to hide the layer specifically in Toc
113
+ const hiddenLayer = new SimpleLayer({
114
+ id: "layer1",
115
+ title: "layer 1",
116
+ olLayer: myOlLayer,
117
+ attributes: {
118
+ toc: {
119
+ listMode: "hide"
120
+ }
121
+ }
122
+ });
123
+ ```
124
+
125
+ Valid values for `listMode` are:
126
+
127
+ - `"show"` layer item is displayed in Toc
128
+ - `"hide"` layer item is not rendered in Toc
129
+ - `"hide-children"` layer item for the layer itself is displayed in Toc but no layer items for child layers (e.g. sublayers of a group) are rendered
130
+
131
+ The `listMode` always has precedence over the layer's `internal` property. For example, if the `listMode` is `"show"` the layer item is displayed even if `internal` is `true`.
132
+
95
133
  ## License
96
134
 
97
135
  Apache-2.0 (see `LICENSE` file)
package/index.d.ts CHANGED
@@ -1 +1 @@
1
- export { Toc, type TocProps, type ToolsConfig } from "./ui/Toc";
1
+ export { Toc, type TocProps, type ToolsConfig, type LayerTocAttributes, type ListMode } from "./ui/Toc";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@open-pioneer/toc",
4
- "version": "0.11.0",
4
+ "version": "0.12.0-dev.20250725080856",
5
5
  "description": "This package provides a UI component that displays the map content to the user and allows them to control it.",
6
6
  "keywords": [
7
7
  "open-pioneer-trails"
@@ -14,18 +14,18 @@
14
14
  "directory": "src/packages/toc"
15
15
  },
16
16
  "dependencies": {
17
- "@chakra-ui/react": "^3.19.2",
17
+ "@chakra-ui/react": "^3.21.1",
18
18
  "@open-pioneer/react-utils": "^4.0.0",
19
19
  "@open-pioneer/runtime": "^4.0.0",
20
20
  "classnames": "^2.5.1",
21
- "ol": "^10.5.0",
21
+ "ol": "^10.6.1",
22
22
  "react": "^19.1.0",
23
23
  "react-icons": "^5.5.0",
24
24
  "@open-pioneer/reactivity": "^4.0.0",
25
25
  "@conterra/reactivity-core": "^0.7.0",
26
26
  "@open-pioneer/chakra-snippets": "^4.0.0",
27
- "@open-pioneer/basemap-switcher": "^0.11.0",
28
- "@open-pioneer/map": "^0.11.0"
27
+ "@open-pioneer/basemap-switcher": "0.12.0-dev.20250725080856",
28
+ "@open-pioneer/map": "0.12.0-dev.20250725080856"
29
29
  },
30
30
  "exports": {
31
31
  "./package.json": "./package.json",
@@ -7,7 +7,7 @@ import { useReactiveSnapshot } from '@open-pioneer/reactivity';
7
7
  import classNames from 'classnames';
8
8
  import { useIntl } from '../../_virtual/_virtual-pioneer-module_react-hooks.js';
9
9
  import { memo, useId, useMemo, useEffect } from 'react';
10
- import { FiAlertTriangle, FiChevronDown, FiChevronRight } from 'react-icons/fi';
10
+ import { LuTriangleAlert, LuChevronDown, LuChevronRight } from 'react-icons/lu';
11
11
  import { useTocModel } from '../../model/TocModel.js';
12
12
  import { slug } from '../../utils/slug.js';
13
13
  import { useLoadState, useChildLayers } from './hooks.js';
@@ -22,16 +22,27 @@ const LayerItem = memo(function LayerItem2(props) {
22
22
  const isCollapsible = tocOptions ? tocOptions.collapsibleGroups : false;
23
23
  const layerGroupId = useId();
24
24
  const isAvailable = useLoadState(layer) !== "error";
25
+ const listMode = useListMode(layer)?.listMode;
25
26
  const notAvailableLabel = intl.formatMessage({ id: "layerNotAvailable" });
26
- const { title, description, isVisible } = useReactiveSnapshot(() => {
27
+ const { title, description, isVisible, allChildrenHidden } = useReactiveSnapshot(() => {
27
28
  return {
28
29
  title: layer.title,
29
30
  description: layer.description,
30
- isVisible: layer.visible
31
+ isVisible: layer.visible,
32
+ isInternal: layer.internal,
33
+ allChildrenHidden: !hasShownChildren(layer)
34
+ //re-evaluates if a child layer's list mode or internal state changes
31
35
  };
32
36
  }, [layer]);
33
37
  const nestedChildren = useNestedChildren(layerGroupId, title, layer, intl);
34
- const hasNestedChildren = !!nestedChildren;
38
+ let hasNestedChildren = !!nestedChildren;
39
+ const display = displayLayerItem(layer);
40
+ if (!display) {
41
+ return null;
42
+ }
43
+ if (allChildrenHidden || listMode === "hide-children") {
44
+ hasNestedChildren = false;
45
+ }
35
46
  return /* @__PURE__ */ jsxs(Box, { as: "li", className: classNames("toc-layer-item", `layer-${slug(layer.id)}`), children: [
36
47
  /* @__PURE__ */ jsxs(
37
48
  Flex,
@@ -76,7 +87,7 @@ const LayerItem = memo(function LayerItem2(props) {
76
87
  openDelay: 500,
77
88
  contentProps: { className: "toc-layer-item-content-tooltip" },
78
89
  children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(
79
- FiAlertTriangle,
90
+ LuTriangleAlert,
80
91
  {
81
92
  className: "toc-layer-item-content-icon",
82
93
  color: "red",
@@ -90,7 +101,7 @@ const LayerItem = memo(function LayerItem2(props) {
90
101
  ]
91
102
  }
92
103
  ),
93
- nestedChildren && /* @__PURE__ */ jsx(Collapsible.Root, { open: expanded, className: "toc-collapsible-item", children: /* @__PURE__ */ jsx(CollapsibleContent, { children: nestedChildren }) })
104
+ hasNestedChildren && /* @__PURE__ */ jsx(Collapsible.Root, { open: expanded, className: "toc-collapsible-item", children: /* @__PURE__ */ jsx(CollapsibleContent, { children: nestedChildren }) })
94
105
  ] });
95
106
  });
96
107
  function useNestedChildren(layerGroupId, title, layer, intl) {
@@ -113,7 +124,7 @@ function useNestedChildren(layerGroupId, title, layer, intl) {
113
124
  }
114
125
  function CollapseButton(props) {
115
126
  const { layerTitle, layerGroupId, expanded, onClick, hasNestedChildren } = props;
116
- const icon = expanded ? /* @__PURE__ */ jsx(FiChevronDown, {}) : /* @__PURE__ */ jsx(FiChevronRight, {});
127
+ const icon = expanded ? /* @__PURE__ */ jsx(LuChevronDown, {}) : /* @__PURE__ */ jsx(LuChevronRight, {});
117
128
  const intl = useIntl();
118
129
  return /* @__PURE__ */ jsx(
119
130
  IconButton,
@@ -160,12 +171,39 @@ function useTocItem(layer) {
160
171
  }, [tocModel, tocItem]);
161
172
  return [tocItem, tocModel, options];
162
173
  }
174
+ function useListMode(layer) {
175
+ return useReactiveSnapshot(
176
+ () => layer.attributes.toc,
177
+ [layer]
178
+ );
179
+ }
163
180
  function updateLayerVisibility(layer, visible, autoShowParents) {
164
181
  layer.setVisible(visible);
165
182
  if (visible && autoShowParents && layer.parent) {
166
183
  updateLayerVisibility(layer.parent, true, true);
167
184
  }
168
185
  }
186
+ function hasShownChildren(layer) {
187
+ if (!layer.children || layer.children.getItems().length === 0) {
188
+ return false;
189
+ } else {
190
+ return layer.children.getItems().some((childLayer) => {
191
+ const isDisplayed = displayLayerItem(childLayer);
192
+ return isDisplayed;
193
+ });
194
+ }
195
+ }
196
+ function displayLayerItem(layer) {
197
+ const isInternal = layer.internal;
198
+ const listMode = layer.attributes.toc?.listMode;
199
+ if (listMode === "show" || listMode === "hide-children") {
200
+ return true;
201
+ } else if (isInternal || listMode === "hide") {
202
+ return false;
203
+ } else {
204
+ return true;
205
+ }
206
+ }
169
207
 
170
208
  export { LayerItem };
171
209
  //# sourceMappingURL=LayerItem.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LayerItem.js","sources":["LayerItem.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n Box,\n Collapsible,\n CollapsibleContent,\n Flex,\n Icon,\n IconButton,\n Spacer\n} from \"@chakra-ui/react\";\nimport { reactive } from \"@conterra/reactivity-core\";\nimport { Checkbox } from \"@open-pioneer/chakra-snippets/checkbox\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { AnyLayer } from \"@open-pioneer/map\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport classNames from \"classnames\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { memo, ReactNode, useEffect, useId, useMemo } from \"react\";\nimport { FiAlertTriangle, FiChevronDown, FiChevronRight } from \"react-icons/fi\";\nimport { TocItem, useTocModel } from \"../../model/TocModel\";\nimport { slug } from \"../../utils/slug\";\nimport { useChildLayers, useLoadState } from \"./hooks\";\nimport { LayerItemMenu } from \"./LayerItemMenu\";\nimport { LayerList } from \"./LayerList\";\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 */\nexport const LayerItem = memo(function LayerItem(props: { layer: AnyLayer }): ReactNode {\n const { layer } = props;\n const intl = useIntl();\n const [tocItem, _tocModel, tocOptions] = useTocItem(layer);\n const expanded = useReactiveSnapshot(() => tocItem.isExpanded, [tocItem]);\n const isCollapsible = tocOptions ? tocOptions.collapsibleGroups : false;\n\n const layerGroupId = useId();\n const isAvailable = useLoadState(layer) !== \"error\";\n const notAvailableLabel = intl.formatMessage({ id: \"layerNotAvailable\" });\n const { title, description, isVisible } = useReactiveSnapshot(() => {\n return {\n title: layer.title,\n description: layer.description,\n isVisible: layer.visible\n };\n }, [layer]);\n\n const nestedChildren = useNestedChildren(layerGroupId, title, layer, intl);\n const hasNestedChildren = !!nestedChildren;\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 {isCollapsible && (\n <CollapseButton\n layerTitle={title}\n layerGroupId={layerGroupId}\n expanded={expanded}\n onClick={() => tocItem.setExpanded(!expanded)}\n hasNestedChildren={hasNestedChildren}\n />\n )}\n <Checkbox\n // Keyboard navigation jumps only to Checkboxes and uses the texts inside this DOM node.\n // The aria-labels of Tooltip and Icon is ignored by screen reader because they are no child element of the checkbox.\n // To consider the notAvailableLabel, an aria-label at the checkbox is necessary.\n aria-label={title + (!isAvailable ? \" \" + notAvailableLabel : \"\")}\n checked={isVisible}\n disabled={!isAvailable}\n onCheckedChange={(event) =>\n updateLayerVisibility(\n layer,\n event.checked === true,\n tocOptions.autoShowParents\n )\n }\n >\n {title}\n </Checkbox>\n {!isAvailable && (\n <Tooltip\n content={notAvailableLabel}\n positioning={{ placement: \"right\" }}\n openDelay={500}\n contentProps={{ className: \"toc-layer-item-content-tooltip\" }}\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 />\n <LayerItemMenu layer={layer} title={title} description={description} intl={intl} />\n </Flex>\n {nestedChildren && (\n <Collapsible.Root open={expanded} className=\"toc-collapsible-item\">\n <CollapsibleContent>{nestedChildren}</CollapsibleContent>\n </Collapsible.Root>\n )}\n </Box>\n );\n});\n\nfunction useNestedChildren(\n layerGroupId: string,\n title: string,\n layer: AnyLayer,\n intl: PackageIntl\n) {\n const childLayers = useChildLayers(layer);\n const children = useMemo(() => {\n if (childLayers?.length) {\n return (\n <LayerList\n id={layerGroupId}\n layers={childLayers}\n ml={4}\n aria-label={intl.formatMessage({ id: \"childgroupLabel\" }, { title: title })}\n />\n );\n }\n return undefined;\n }, [layerGroupId, intl, title, childLayers]);\n return children;\n}\n\nfunction CollapseButton(props: {\n layerTitle: string;\n layerGroupId: string;\n expanded: boolean;\n onClick: () => void;\n hasNestedChildren: boolean;\n}) {\n const { layerTitle, layerGroupId, expanded, onClick, hasNestedChildren } = props;\n const icon = expanded ? <FiChevronDown /> : <FiChevronRight />;\n const intl = useIntl();\n return (\n <IconButton\n variant=\"ghost\"\n borderRadius=\"full\"\n padding={0}\n className=\"toc-layer-item-collapse-button\"\n onClick={onClick}\n size=\"sm\"\n focusRingOffset=\"-2px\"\n aria-label={\n expanded\n ? intl.formatMessage({ id: \"group.collapse\" }, { title: layerTitle })\n : intl.formatMessage({ id: \"group.expand\" }, { title: layerTitle })\n }\n aria-expanded={expanded}\n aria-controls={layerGroupId}\n //use visible:hidden for layers without children for correct indent\n visibility={hasNestedChildren ? \"visible\" : \"hidden\"}\n css={{\n // Chakra theme adds a background to components with \"aria-expanded\" by default.\n \"&:is([aria-expanded='true']):not(:hover)\": {\n background: \"none\"\n }\n }}\n >\n <Icon>{icon}</Icon>\n </IconButton>\n );\n}\n\n// Creates a toc item and registers it with the shared toc model.\nfunction useTocItem(layer: AnyLayer) {\n const tocModel = useTocModel();\n const options = useReactiveSnapshot(() => tocModel.options, [tocModel]);\n const tocItem = useMemo((): TocItem => {\n const expanded = reactive(!options.initiallyCollapsed);\n return {\n layerId: layer.id,\n get isExpanded(): boolean {\n return expanded.value;\n },\n setExpanded(expand: boolean) {\n expanded.value = expand;\n }\n };\n }, [layer, options.initiallyCollapsed]);\n\n // Register the item on the shared toc model\n useEffect(() => {\n tocModel.registerItem(tocItem);\n return () => tocModel.unregisterItem(tocItem);\n }, [tocModel, tocItem]);\n\n return [tocItem, tocModel, options] as const;\n}\n\nfunction updateLayerVisibility(layer: AnyLayer, visible: boolean, autoShowParents: boolean) {\n layer.setVisible(visible);\n if (visible && autoShowParents && layer.parent) {\n updateLayerVisibility(layer.parent, true, true);\n }\n}\n"],"names":["LayerItem"],"mappings":"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"}
1
+ {"version":3,"file":"LayerItem.js","sources":["LayerItem.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n Box,\n Collapsible,\n CollapsibleContent,\n Flex,\n Icon,\n IconButton,\n Spacer\n} from \"@chakra-ui/react\";\nimport { reactive } from \"@conterra/reactivity-core\";\nimport { Checkbox } from \"@open-pioneer/chakra-snippets/checkbox\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { AnyLayer } from \"@open-pioneer/map\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport classNames from \"classnames\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { memo, ReactNode, useEffect, useId, useMemo } from \"react\";\nimport { LuTriangleAlert, LuChevronDown, LuChevronRight } from \"react-icons/lu\";\nimport { TocItem, useTocModel } from \"../../model/TocModel\";\nimport { slug } from \"../../utils/slug\";\nimport { useChildLayers, useLoadState } from \"./hooks\";\nimport { LayerItemMenu } from \"./LayerItemMenu\";\nimport { LayerList } from \"./LayerList\";\nimport { LayerTocAttributes } from \"../Toc\";\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 */\nexport const LayerItem = memo(function LayerItem(props: { layer: AnyLayer }): ReactNode {\n const { layer } = props;\n const intl = useIntl();\n const [tocItem, _tocModel, tocOptions] = useTocItem(layer);\n const expanded = useReactiveSnapshot(() => tocItem.isExpanded, [tocItem]);\n const isCollapsible = tocOptions ? tocOptions.collapsibleGroups : false;\n\n const layerGroupId = useId();\n const isAvailable = useLoadState(layer) !== \"error\";\n const listMode = useListMode(layer)?.listMode;\n const notAvailableLabel = intl.formatMessage({ id: \"layerNotAvailable\" });\n const { title, description, isVisible, allChildrenHidden } = useReactiveSnapshot(() => {\n return {\n title: layer.title,\n description: layer.description,\n isVisible: layer.visible,\n isInternal: layer.internal,\n allChildrenHidden: !hasShownChildren(layer) //re-evaluates if a child layer's list mode or internal state changes\n };\n }, [layer]);\n\n const nestedChildren = useNestedChildren(layerGroupId, title, layer, intl);\n let hasNestedChildren = !!nestedChildren;\n\n const display = displayLayerItem(layer);\n if (!display) {\n return null;\n }\n //all children hidden => do not render collapse button and child entries\n if (allChildrenHidden || listMode === \"hide-children\") {\n hasNestedChildren = false;\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 {isCollapsible && (\n <CollapseButton\n layerTitle={title}\n layerGroupId={layerGroupId}\n expanded={expanded}\n onClick={() => tocItem.setExpanded(!expanded)}\n hasNestedChildren={hasNestedChildren}\n />\n )}\n <Checkbox\n // Keyboard navigation jumps only to Checkboxes and uses the texts inside this DOM node.\n // The aria-labels of Tooltip and Icon is ignored by screen reader because they are no child element of the checkbox.\n // To consider the notAvailableLabel, an aria-label at the checkbox is necessary.\n aria-label={title + (!isAvailable ? \" \" + notAvailableLabel : \"\")}\n checked={isVisible}\n disabled={!isAvailable}\n onCheckedChange={(event) =>\n updateLayerVisibility(\n layer,\n event.checked === true,\n tocOptions.autoShowParents\n )\n }\n >\n {title}\n </Checkbox>\n {!isAvailable && (\n <Tooltip\n content={notAvailableLabel}\n positioning={{ placement: \"right\" }}\n openDelay={500}\n contentProps={{ className: \"toc-layer-item-content-tooltip\" }}\n >\n <span>\n <LuTriangleAlert\n className=\"toc-layer-item-content-icon\"\n color={\"red\"}\n aria-label={notAvailableLabel}\n />\n </span>\n </Tooltip>\n )}\n <Spacer />\n <LayerItemMenu layer={layer} title={title} description={description} intl={intl} />\n </Flex>\n {hasNestedChildren && (\n <Collapsible.Root open={expanded} className=\"toc-collapsible-item\">\n <CollapsibleContent>{nestedChildren}</CollapsibleContent>\n </Collapsible.Root>\n )}\n </Box>\n );\n});\n\nfunction useNestedChildren(\n layerGroupId: string,\n title: string,\n layer: AnyLayer,\n intl: PackageIntl\n) {\n const childLayers = useChildLayers(layer);\n const children = useMemo(() => {\n if (childLayers?.length) {\n return (\n <LayerList\n id={layerGroupId}\n layers={childLayers}\n ml={4}\n aria-label={intl.formatMessage({ id: \"childgroupLabel\" }, { title: title })}\n />\n );\n }\n return undefined;\n }, [layerGroupId, intl, title, childLayers]);\n return children;\n}\n\nfunction CollapseButton(props: {\n layerTitle: string;\n layerGroupId: string;\n expanded: boolean;\n onClick: () => void;\n hasNestedChildren: boolean;\n}) {\n const { layerTitle, layerGroupId, expanded, onClick, hasNestedChildren } = props;\n const icon = expanded ? <LuChevronDown /> : <LuChevronRight />;\n const intl = useIntl();\n return (\n <IconButton\n variant=\"ghost\"\n borderRadius=\"full\"\n padding={0}\n className=\"toc-layer-item-collapse-button\"\n onClick={onClick}\n size=\"sm\"\n focusRingOffset=\"-2px\"\n aria-label={\n expanded\n ? intl.formatMessage({ id: \"group.collapse\" }, { title: layerTitle })\n : intl.formatMessage({ id: \"group.expand\" }, { title: layerTitle })\n }\n aria-expanded={expanded}\n aria-controls={layerGroupId}\n //use visible:hidden for layers without children for correct indent\n visibility={hasNestedChildren ? \"visible\" : \"hidden\"}\n css={{\n // Chakra theme adds a background to components with \"aria-expanded\" by default.\n \"&:is([aria-expanded='true']):not(:hover)\": {\n background: \"none\"\n }\n }}\n >\n <Icon>{icon}</Icon>\n </IconButton>\n );\n}\n\n// Creates a toc item and registers it with the shared toc model.\nfunction useTocItem(layer: AnyLayer) {\n const tocModel = useTocModel();\n const options = useReactiveSnapshot(() => tocModel.options, [tocModel]);\n const tocItem = useMemo((): TocItem => {\n const expanded = reactive(!options.initiallyCollapsed);\n return {\n layerId: layer.id,\n get isExpanded(): boolean {\n return expanded.value;\n },\n setExpanded(expand: boolean) {\n expanded.value = expand;\n }\n };\n }, [layer, options.initiallyCollapsed]);\n\n // Register the item on the shared toc model\n useEffect(() => {\n tocModel.registerItem(tocItem);\n return () => tocModel.unregisterItem(tocItem);\n }, [tocModel, tocItem]);\n\n return [tocItem, tocModel, options] as const;\n}\n\nfunction useListMode(layer: AnyLayer): LayerTocAttributes | undefined {\n return useReactiveSnapshot(\n () => layer.attributes.toc as LayerTocAttributes | undefined,\n [layer]\n );\n}\n\nfunction updateLayerVisibility(layer: AnyLayer, visible: boolean, autoShowParents: boolean) {\n layer.setVisible(visible);\n if (visible && autoShowParents && layer.parent) {\n updateLayerVisibility(layer.parent, true, true);\n }\n}\n\n/**\n * Checks if at least on child layer of the given layer exists and should be displayed.\n * @param layer\n * @returns true if at least one child layer's display mode is not `hide`\n */\nfunction hasShownChildren(layer: AnyLayer): boolean {\n if (!layer.children || layer.children.getItems().length === 0) {\n return false;\n } else {\n return layer.children.getItems().some((childLayer) => {\n const isDisplayed = displayLayerItem(childLayer);\n return isDisplayed;\n });\n }\n}\n\n/**\n * Checks if a layer should be displayed in the Toc.\n */\nfunction displayLayerItem(layer: AnyLayer): boolean {\n const isInternal = layer.internal;\n const listMode = (layer.attributes.toc as LayerTocAttributes | undefined)?.listMode;\n\n if (listMode === \"show\" || listMode === \"hide-children\") {\n return true;\n } else if (isInternal || listMode === \"hide\") {\n return false;\n } else {\n return true;\n }\n}\n"],"names":["LayerItem"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { Popover, Portal, Text, CloseButton, IconButton, Icon } from '@chakra-ui
3
3
  import { Tooltip } from '@open-pioneer/chakra-snippets/tooltip';
4
4
  import { useIntl } from '../../_virtual/_virtual-pioneer-module_react-hooks.js';
5
5
  import { useId } from 'react';
6
- import { FiMoreVertical } from 'react-icons/fi';
6
+ import { LuEllipsisVertical } from 'react-icons/lu';
7
7
  import { useLoadState } from './hooks.js';
8
8
 
9
9
  function LayerItemMenu(props) {
@@ -61,7 +61,7 @@ function TriggerButton(props) {
61
61
  focusRingOffset: "-2px",
62
62
  variant: "ghost",
63
63
  size: "sm",
64
- children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(FiMoreVertical, { spacing: 0 }) })
64
+ children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(LuEllipsisVertical, { spacing: 0 }) })
65
65
  }
66
66
  ) }) });
67
67
  }
@@ -1 +1 @@
1
- {"version":3,"file":"LayerItemMenu.js","sources":["LayerItemMenu.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { CloseButton, Icon, IconButton, Popover, Portal, Text } from \"@chakra-ui/react\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { AnyLayer } from \"@open-pioneer/map\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useId } from \"react\";\nimport { FiMoreVertical } from \"react-icons/fi\";\nimport { useLoadState } from \"./hooks\";\n\nexport function LayerItemMenu(props: {\n layer: AnyLayer;\n title: string;\n description: string;\n intl: PackageIntl;\n}) {\n const { layer, title, description } = props;\n const isPresent = !!description;\n\n const triggerId = useId(); // see https://chakra-ui.com/docs/components/tooltip#with-menutrigger\n\n return (\n isPresent && (\n <Popover.Root\n ids={{ trigger: triggerId }}\n positioning={{ placement: \"bottom-start\" }}\n lazyMount={true}\n unmountOnExit={true}\n >\n <TriggerButton triggerId={triggerId} layer={layer} />\n <Portal>\n <Popover.Positioner>\n <Popover.Content\n className=\"toc-layer-item-details\"\n overflowY=\"auto\"\n maxHeight=\"400\"\n >\n <Popover.Arrow></Popover.Arrow>\n <Popover.Body>\n <Popover.Title className=\"toc-layer-item-details-title\">\n {title}\n </Popover.Title>\n <Text my=\"2\" className=\"toc-layer-item-details-description\">\n {description}\n </Text>\n </Popover.Body>\n <Popover.CloseTrigger position=\"absolute\" top=\"1\" right=\"1\" asChild>\n <CloseButton\n className=\"toc-layer-item-details-button\"\n variant=\"ghost\"\n size=\"sm\"\n />\n </Popover.CloseTrigger>\n </Popover.Content>\n </Popover.Positioner>\n </Portal>\n </Popover.Root>\n )\n );\n}\n\nfunction TriggerButton(props: { triggerId: string; layer: AnyLayer }) {\n const { layer, triggerId } = props;\n const intl = useIntl();\n const buttonLabel = intl.formatMessage({ id: \"descriptionLabel\" });\n const isAvailable = useLoadState(layer) !== \"error\";\n\n return (\n <Tooltip ids={{ trigger: triggerId }} content={buttonLabel}>\n <Popover.Trigger asChild>\n <IconButton\n disabled={!isAvailable}\n className=\"toc-layer-item-details-button\"\n aria-label={buttonLabel}\n borderRadius=\"full\"\n focusRingOffset=\"-2px\"\n variant=\"ghost\"\n size=\"sm\"\n >\n <Icon>\n <FiMoreVertical spacing={0} />\n </Icon>\n </IconButton>\n </Popover.Trigger>\n </Tooltip>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LayerItemMenu.js","sources":["LayerItemMenu.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { CloseButton, Icon, IconButton, Popover, Portal, Text } from \"@chakra-ui/react\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { AnyLayer } from \"@open-pioneer/map\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useId } from \"react\";\nimport { LuEllipsisVertical } from \"react-icons/lu\";\nimport { useLoadState } from \"./hooks\";\n\nexport function LayerItemMenu(props: {\n layer: AnyLayer;\n title: string;\n description: string;\n intl: PackageIntl;\n}) {\n const { layer, title, description } = props;\n const isPresent = !!description;\n\n const triggerId = useId(); // see https://chakra-ui.com/docs/components/tooltip#with-menutrigger\n\n return (\n isPresent && (\n <Popover.Root\n ids={{ trigger: triggerId }}\n positioning={{ placement: \"bottom-start\" }}\n lazyMount={true}\n unmountOnExit={true}\n >\n <TriggerButton triggerId={triggerId} layer={layer} />\n <Portal>\n <Popover.Positioner>\n <Popover.Content\n className=\"toc-layer-item-details\"\n overflowY=\"auto\"\n maxHeight=\"400\"\n >\n <Popover.Arrow></Popover.Arrow>\n <Popover.Body>\n <Popover.Title className=\"toc-layer-item-details-title\">\n {title}\n </Popover.Title>\n <Text my=\"2\" className=\"toc-layer-item-details-description\">\n {description}\n </Text>\n </Popover.Body>\n <Popover.CloseTrigger position=\"absolute\" top=\"1\" right=\"1\" asChild>\n <CloseButton\n className=\"toc-layer-item-details-button\"\n variant=\"ghost\"\n size=\"sm\"\n />\n </Popover.CloseTrigger>\n </Popover.Content>\n </Popover.Positioner>\n </Portal>\n </Popover.Root>\n )\n );\n}\n\nfunction TriggerButton(props: { triggerId: string; layer: AnyLayer }) {\n const { layer, triggerId } = props;\n const intl = useIntl();\n const buttonLabel = intl.formatMessage({ id: \"descriptionLabel\" });\n const isAvailable = useLoadState(layer) !== \"error\";\n\n return (\n <Tooltip ids={{ trigger: triggerId }} content={buttonLabel}>\n <Popover.Trigger asChild>\n <IconButton\n disabled={!isAvailable}\n className=\"toc-layer-item-details-button\"\n aria-label={buttonLabel}\n borderRadius=\"full\"\n focusRingOffset=\"-2px\"\n variant=\"ghost\"\n size=\"sm\"\n >\n <Icon>\n <LuEllipsisVertical spacing={0} />\n </Icon>\n </IconButton>\n </Popover.Trigger>\n </Tooltip>\n );\n}\n"],"names":[],"mappings":"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"}
package/ui/Toc.d.ts CHANGED
@@ -65,6 +65,23 @@ export interface ToolsConfig {
65
65
  */
66
66
  showCollapseAllGroups?: boolean;
67
67
  }
68
+ /**
69
+ * Layer attributes to specifically configure how a layer is displayed in the Toc.
70
+ */
71
+ export interface LayerTocAttributes {
72
+ /**
73
+ * The {@link ListMode} is used to hide the layer (or it's children) in the Toc.
74
+ */
75
+ listMode?: ListMode;
76
+ }
77
+ /**
78
+ * ListMode determines if a layer item is displayed in the Toc for the layer.
79
+ * The option `"hide-children"` provides a shortcut to hide all child layers (e.g. sublayers of group) of the layer in the Toc.
80
+ * It has the same effect as manually setting the `listMode` to `"hide"` on all child layers.
81
+ *
82
+ * ListMode has precedence over the layer's `internal` attribute but specifically configures the layer's display in the Toc.
83
+ */
84
+ export type ListMode = "show" | "hide" | "hide-children";
68
85
  /**
69
86
  * Displays the layers of the configured map.
70
87
  */
package/ui/Toc.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Toc.js","sources":["Toc.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { reactive, reactiveMap } from \"@conterra/reactivity-core\";\nimport { BasemapSwitcher, BasemapSwitcherProps } from \"@open-pioneer/basemap-switcher\";\nimport { Box, Flex, Spacer, Text } from \"@chakra-ui/react\";\nimport { MapModel, MapModelProps, 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, ReactNode, useEffect, useId, useMemo, useRef } from \"react\";\nimport { TocItem, TocModel, TocModelProvider, TocWidgetOptions } from \"../model/TocModel\";\nimport { TopLevelLayerList } from \"./LayerList/LayerList\";\nimport { Tools } from \"./Tools\";\n\n/**\n * Props supported by the {@link Toc} component.\n */\nexport interface TocProps extends CommonComponentProps, MapModelProps {\n /**\n * Defines whether the tool component is shown in the toc.\n *\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 *\n * Defaults to `true`.\n */\n showBasemapSwitcher?: boolean;\n\n /**\n * Properties for the embedded basemap switcher.\n *\n * Property `mapId` is not applied (the basemap switcher uses the same map as the toc).\n */\n basemapSwitcherProps?: Omit<BasemapSwitcherProps, \"mapId\">;\n\n /**\n * If `true`, groups in the toc can be collapsed and expanded.\n * This property should only be `true` if the map actually contains layer groups.\n *\n * Defaults to `false`.\n */\n collapsibleGroups?: boolean;\n\n /**\n * If `true` groups in the toc are collapsed initially.\n *\n * Defaults to `false`. If {@link collapsibleGroups} is `false` this property should also be `false`. Otherwise, only the top level layers will appear in the toc.\n */\n initiallyCollapsed?: boolean;\n\n /**\n * Show the parent layers when a child layer is made visible.\n *\n * Defaults to `true`.\n */\n autoShowParents?: boolean;\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 *\n * Defaults to `true`.\n */\n showHideAllLayers?: boolean;\n\n /**\n * Optional property to show the `collapse all groups` entry.\n *\n * Defaults to `true`. Only applicable if {@link TocProps.collapsibleGroups} is `true`.\n */\n showCollapseAllGroups?: 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 const { containerProps } = useCommonComponentProps(\"toc\", props);\n const state = useMapModel(props);\n\n let content: ReactNode | 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 map = state.map;\n content = <TocContent {...props} map={map} />;\n break;\n }\n }\n\n return (\n <Flex {...containerProps} direction=\"column\" gap={PADDING}>\n {content}\n </Flex>\n );\n};\n\n/** This component is rendered once we have a reference to the loaded map model. */\nfunction TocContent(props: TocProps & { map: MapModel }) {\n const {\n map,\n showTools = false,\n toolsConfig,\n showBasemapSwitcher = true,\n basemapSwitcherProps\n } = props;\n const intl = useIntl();\n const model = useTocModel(props);\n const basemapsHeadingId = useId();\n const basemapSwitcher = showBasemapSwitcher && (\n <Box className=\"toc-basemap-switcher\" mb={PADDING}>\n <TitledSection\n title={\n <SectionHeading id={basemapsHeadingId} size={\"sm\"} mb={PADDING}>\n {intl.formatMessage({ id: \"basemapsLabel\" })}\n </SectionHeading>\n }\n >\n <BasemapSwitcher\n map={map}\n aria-labelledby={basemapsHeadingId}\n {...basemapSwitcherProps}\n />\n </TitledSection>\n </Box>\n );\n\n const layerList = (\n <Box className=\"toc-operational-layers\">\n <TitledSection\n title={\n <SectionHeading size=\"sm\">\n <Flex>\n <Text>\n {intl.formatMessage({\n id: \"operationalLayerLabel\"\n })}\n </Text>\n <Spacer />\n {showTools && <Tools map={map} {...toolsConfig} />}\n </Flex>\n </SectionHeading>\n }\n >\n <TopLevelLayerList\n map={map}\n aria-label={intl.formatMessage({ id: \"operationalLayerLabel\" })}\n />\n </TitledSection>\n </Box>\n );\n\n return (\n <TocModelProvider value={model}>\n {basemapSwitcher}\n {layerList}\n </TocModelProvider>\n );\n}\n\nfunction useTocModel(props: TocProps): TocModel {\n const initialProps = useRef(props);\n const { model, options } = useMemo(() => {\n const options = reactive<TocWidgetOptions>(\n createOptions(\n initialProps.current.autoShowParents,\n initialProps.current.collapsibleGroups,\n initialProps.current.initiallyCollapsed\n )\n );\n\n // Indexed by layerId\n const items = reactiveMap<string, TocItem>();\n const model: TocModel = {\n get options() {\n return options.value;\n },\n getItem(layerId: string): TocItem | undefined {\n return items.get(layerId);\n },\n getItems(): TocItem[] {\n return Array.from(items.values());\n },\n registerItem(item: TocItem): void {\n if (items.has(item.layerId)) {\n throw new Error(`Item with layerId '${item.layerId}' already registered.`);\n }\n items.set(item.layerId, item);\n },\n unregisterItem(item: TocItem): void {\n if (items.get(item.layerId) !== item) {\n throw new Error(`Item with layerId '${item.layerId}' not registered.`);\n }\n items.delete(item.layerId);\n }\n };\n return { model, options };\n }, []);\n\n // Sync props to model\n useEffect(() => {\n options.value = createOptions(\n props.autoShowParents,\n props.collapsibleGroups,\n props.initiallyCollapsed\n );\n }, [options, props.autoShowParents, props.collapsibleGroups, props.initiallyCollapsed]);\n\n return model;\n}\n\nfunction createOptions(\n autoShowParents?: boolean | undefined,\n collapsibleGroups?: boolean | undefined,\n isCollapsed?: boolean | undefined\n): TocWidgetOptions {\n return {\n autoShowParents: autoShowParents ?? true,\n collapsibleGroups: collapsibleGroups ?? false,\n initiallyCollapsed: isCollapsed ?? false\n };\n}\n"],"names":["options","model"],"mappings":"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"}
1
+ {"version":3,"file":"Toc.js","sources":["Toc.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { reactive, reactiveMap } from \"@conterra/reactivity-core\";\nimport { BasemapSwitcher, BasemapSwitcherProps } from \"@open-pioneer/basemap-switcher\";\nimport { Box, Flex, Spacer, Text } from \"@chakra-ui/react\";\nimport { MapModel, MapModelProps, 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, ReactNode, useEffect, useId, useMemo, useRef } from \"react\";\nimport { TocItem, TocModel, TocModelProvider, TocWidgetOptions } from \"../model/TocModel\";\nimport { TopLevelLayerList } from \"./LayerList/LayerList\";\nimport { Tools } from \"./Tools\";\n\n/**\n * Props supported by the {@link Toc} component.\n */\nexport interface TocProps extends CommonComponentProps, MapModelProps {\n /**\n * Defines whether the tool component is shown in the toc.\n *\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 *\n * Defaults to `true`.\n */\n showBasemapSwitcher?: boolean;\n\n /**\n * Properties for the embedded basemap switcher.\n *\n * Property `mapId` is not applied (the basemap switcher uses the same map as the toc).\n */\n basemapSwitcherProps?: Omit<BasemapSwitcherProps, \"mapId\">;\n\n /**\n * If `true`, groups in the toc can be collapsed and expanded.\n * This property should only be `true` if the map actually contains layer groups.\n *\n * Defaults to `false`.\n */\n collapsibleGroups?: boolean;\n\n /**\n * If `true` groups in the toc are collapsed initially.\n *\n * Defaults to `false`. If {@link collapsibleGroups} is `false` this property should also be `false`. Otherwise, only the top level layers will appear in the toc.\n */\n initiallyCollapsed?: boolean;\n\n /**\n * Show the parent layers when a child layer is made visible.\n *\n * Defaults to `true`.\n */\n autoShowParents?: boolean;\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 *\n * Defaults to `true`.\n */\n showHideAllLayers?: boolean;\n\n /**\n * Optional property to show the `collapse all groups` entry.\n *\n * Defaults to `true`. Only applicable if {@link TocProps.collapsibleGroups} is `true`.\n */\n showCollapseAllGroups?: boolean;\n}\n\n/**\n * Layer attributes to specifically configure how a layer is displayed in the Toc.\n */\nexport interface LayerTocAttributes {\n /**\n * The {@link ListMode} is used to hide the layer (or it's children) in the Toc.\n */\n listMode?: ListMode;\n}\n\n/**\n * ListMode determines if a layer item is displayed in the Toc for the layer.\n * The option `\"hide-children\"` provides a shortcut to hide all child layers (e.g. sublayers of group) of the layer in the Toc.\n * It has the same effect as manually setting the `listMode` to `\"hide\"` on all child layers.\n *\n * ListMode has precedence over the layer's `internal` attribute but specifically configures the layer's display in the Toc.\n */\nexport type ListMode = \"show\" | \"hide\" | \"hide-children\";\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 const { containerProps } = useCommonComponentProps(\"toc\", props);\n const state = useMapModel(props);\n\n let content: ReactNode | 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 map = state.map;\n content = <TocContent {...props} map={map} />;\n break;\n }\n }\n\n return (\n <Flex {...containerProps} direction=\"column\" gap={PADDING}>\n {content}\n </Flex>\n );\n};\n\n/** This component is rendered once we have a reference to the loaded map model. */\nfunction TocContent(props: TocProps & { map: MapModel }) {\n const {\n map,\n showTools = false,\n toolsConfig,\n showBasemapSwitcher = true,\n basemapSwitcherProps\n } = props;\n const intl = useIntl();\n const model = useTocModel(props);\n const basemapsHeadingId = useId();\n const basemapSwitcher = showBasemapSwitcher && (\n <Box className=\"toc-basemap-switcher\" mb={PADDING}>\n <TitledSection\n title={\n <SectionHeading id={basemapsHeadingId} size={\"sm\"} mb={PADDING}>\n {intl.formatMessage({ id: \"basemapsLabel\" })}\n </SectionHeading>\n }\n >\n <BasemapSwitcher\n map={map}\n aria-labelledby={basemapsHeadingId}\n {...basemapSwitcherProps}\n />\n </TitledSection>\n </Box>\n );\n\n const layerList = (\n <Box className=\"toc-operational-layers\">\n <TitledSection\n title={\n <SectionHeading size=\"sm\">\n <Flex>\n <Text>\n {intl.formatMessage({\n id: \"operationalLayerLabel\"\n })}\n </Text>\n <Spacer />\n {showTools && <Tools map={map} {...toolsConfig} />}\n </Flex>\n </SectionHeading>\n }\n >\n <TopLevelLayerList\n map={map}\n aria-label={intl.formatMessage({ id: \"operationalLayerLabel\" })}\n />\n </TitledSection>\n </Box>\n );\n\n return (\n <TocModelProvider value={model}>\n {basemapSwitcher}\n {layerList}\n </TocModelProvider>\n );\n}\n\nfunction useTocModel(props: TocProps): TocModel {\n const initialProps = useRef(props);\n const { model, options } = useMemo(() => {\n const options = reactive<TocWidgetOptions>(\n createOptions(\n initialProps.current.autoShowParents,\n initialProps.current.collapsibleGroups,\n initialProps.current.initiallyCollapsed\n )\n );\n\n // Indexed by layerId\n const items = reactiveMap<string, TocItem>();\n const model: TocModel = {\n get options() {\n return options.value;\n },\n getItem(layerId: string): TocItem | undefined {\n return items.get(layerId);\n },\n getItems(): TocItem[] {\n return Array.from(items.values());\n },\n registerItem(item: TocItem): void {\n if (items.has(item.layerId)) {\n throw new Error(`Item with layerId '${item.layerId}' already registered.`);\n }\n items.set(item.layerId, item);\n },\n unregisterItem(item: TocItem): void {\n if (items.get(item.layerId) !== item) {\n throw new Error(`Item with layerId '${item.layerId}' not registered.`);\n }\n items.delete(item.layerId);\n }\n };\n return { model, options };\n }, []);\n\n // Sync props to model\n useEffect(() => {\n options.value = createOptions(\n props.autoShowParents,\n props.collapsibleGroups,\n props.initiallyCollapsed\n );\n }, [options, props.autoShowParents, props.collapsibleGroups, props.initiallyCollapsed]);\n\n return model;\n}\n\nfunction createOptions(\n autoShowParents?: boolean | undefined,\n collapsibleGroups?: boolean | undefined,\n isCollapsed?: boolean | undefined\n): TocWidgetOptions {\n return {\n autoShowParents: autoShowParents ?? true,\n collapsibleGroups: collapsibleGroups ?? false,\n initiallyCollapsed: isCollapsed ?? false\n };\n}\n"],"names":["options","model"],"mappings":"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"}
package/ui/Tools.js CHANGED
@@ -2,7 +2,7 @@ import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import { Box, Menu, Portal, IconButton, Icon } from '@chakra-ui/react';
3
3
  import { useIntl } from '../_virtual/_virtual-pioneer-module_react-hooks.js';
4
4
  import { memo, useId } from 'react';
5
- import { FiMoreVertical } from 'react-icons/fi';
5
+ import { LuEllipsisVertical } from 'react-icons/lu';
6
6
  import { useTocModel } from '../model/TocModel.js';
7
7
  import { useReactiveSnapshot } from '@open-pioneer/reactivity';
8
8
  import { Tooltip } from '@open-pioneer/chakra-snippets/tooltip';
@@ -68,7 +68,7 @@ function TriggerButton(props) {
68
68
  variant: "ghost",
69
69
  padding: 0,
70
70
  size: "sm",
71
- children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(FiMoreVertical, { spacing: 0 }) })
71
+ children: /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(LuEllipsisVertical, { spacing: 0 }) })
72
72
  }
73
73
  ) }) });
74
74
  }
package/ui/Tools.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Tools.js","sources":["Tools.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Box, IconButton, Menu, Portal, Icon } from \"@chakra-ui/react\";\nimport { AnyLayer, MapModel } from \"@open-pioneer/map\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { FC, memo, useId } from \"react\";\nimport { FiMoreVertical } from \"react-icons/fi\";\nimport { TocModel, useTocModel } from \"../model/TocModel\";\nimport { ToolsConfig } from \"./Toc\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\n\nexport interface ToolsProps extends ToolsConfig {\n map: MapModel;\n}\n\nexport const Tools: FC<ToolsProps> = memo(function Tools(props: ToolsProps) {\n const intl = useIntl();\n const tocModel = useTocModel();\n const collapsibleGroups = useReactiveSnapshot(\n () => tocModel.options.collapsibleGroups,\n [tocModel]\n );\n const {\n map,\n showHideAllLayers = true,\n showCollapseAllGroups: showCollapseAllGroupsProp = collapsibleGroups\n } = props;\n\n // Only respected if groups are collapsible\n const showCollapseAllGroups = collapsibleGroups && showCollapseAllGroupsProp;\n const hasContent = showHideAllLayers || showCollapseAllGroups;\n\n const triggerId = useId(); // see https://chakra-ui.com/docs/components/tooltip#with-menutrigger\n\n return (\n hasContent && (\n <Box className=\"toc-tools\">\n <Menu.Root ids={{ trigger: triggerId }} positioning={{ placement: \"bottom-start\" }}>\n <TriggerButton triggerId={triggerId} />\n <Portal>\n <Menu.Positioner>\n <Menu.Content className=\"toc-tools-menu\">\n {showHideAllLayers && (\n <Menu.Item\n aria-label={intl.formatMessage({\n id: \"tools.hideAllLayers\"\n })}\n onClick={() => {\n hideAllLayers(map);\n }}\n value=\"hideAllLayers\"\n >\n {intl.formatMessage({ id: \"tools.hideAllLayers\" })}\n </Menu.Item>\n )}\n {showCollapseAllGroups && (\n <Menu.Item\n aria-label={intl.formatMessage({\n id: \"tools.collapseAllGroups\"\n })}\n onClick={() => {\n collapseAllGroups(tocModel);\n }}\n value=\"collapseAllGroups\"\n >\n {intl.formatMessage({ id: \"tools.collapseAllGroups\" })}\n </Menu.Item>\n )}\n </Menu.Content>\n </Menu.Positioner>\n </Portal>\n </Menu.Root>\n </Box>\n )\n );\n});\n\nfunction TriggerButton(props: { triggerId: string }) {\n const { triggerId } = props;\n const intl = useIntl();\n const label = intl.formatMessage({ id: \"toolsLabel\" });\n return (\n <Tooltip ids={{ trigger: triggerId }} content={label}>\n <Menu.Trigger asChild>\n <IconButton\n className=\"toc-tools-button\"\n aria-label={label}\n borderRadius=\"full\"\n focusRingOffset=\"-2px\"\n variant=\"ghost\"\n padding={0}\n size=\"sm\"\n >\n <Icon>\n <FiMoreVertical spacing={0} />\n </Icon>\n </IconButton>\n </Menu.Trigger>\n </Tooltip>\n );\n}\n\nfunction hideAllLayers(map: MapModel | undefined) {\n const hide = (layer: AnyLayer) => {\n layer.setVisible(false);\n\n const children = layer.children?.getItems();\n if (children) {\n for (const child of children) {\n hide(child);\n }\n }\n };\n\n map?.layers.getOperationalLayers().forEach((layer) => {\n hide(layer);\n });\n}\n\nfunction collapseAllGroups(tocModel: TocModel) {\n tocModel.getItems().forEach((item) => item.setExpanded(false));\n}\n"],"names":["Tools"],"mappings":"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"}
1
+ {"version":3,"file":"Tools.js","sources":["Tools.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Box, IconButton, Menu, Portal, Icon } from \"@chakra-ui/react\";\nimport { AnyLayer, MapModel } from \"@open-pioneer/map\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { FC, memo, useId } from \"react\";\nimport { LuEllipsisVertical } from \"react-icons/lu\";\nimport { TocModel, useTocModel } from \"../model/TocModel\";\nimport { ToolsConfig } from \"./Toc\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\n\nexport interface ToolsProps extends ToolsConfig {\n map: MapModel;\n}\n\nexport const Tools: FC<ToolsProps> = memo(function Tools(props: ToolsProps) {\n const intl = useIntl();\n const tocModel = useTocModel();\n const collapsibleGroups = useReactiveSnapshot(\n () => tocModel.options.collapsibleGroups,\n [tocModel]\n );\n const {\n map,\n showHideAllLayers = true,\n showCollapseAllGroups: showCollapseAllGroupsProp = collapsibleGroups\n } = props;\n\n // Only respected if groups are collapsible\n const showCollapseAllGroups = collapsibleGroups && showCollapseAllGroupsProp;\n const hasContent = showHideAllLayers || showCollapseAllGroups;\n\n const triggerId = useId(); // see https://chakra-ui.com/docs/components/tooltip#with-menutrigger\n\n return (\n hasContent && (\n <Box className=\"toc-tools\">\n <Menu.Root ids={{ trigger: triggerId }} positioning={{ placement: \"bottom-start\" }}>\n <TriggerButton triggerId={triggerId} />\n <Portal>\n <Menu.Positioner>\n <Menu.Content className=\"toc-tools-menu\">\n {showHideAllLayers && (\n <Menu.Item\n aria-label={intl.formatMessage({\n id: \"tools.hideAllLayers\"\n })}\n onClick={() => {\n hideAllLayers(map);\n }}\n value=\"hideAllLayers\"\n >\n {intl.formatMessage({ id: \"tools.hideAllLayers\" })}\n </Menu.Item>\n )}\n {showCollapseAllGroups && (\n <Menu.Item\n aria-label={intl.formatMessage({\n id: \"tools.collapseAllGroups\"\n })}\n onClick={() => {\n collapseAllGroups(tocModel);\n }}\n value=\"collapseAllGroups\"\n >\n {intl.formatMessage({ id: \"tools.collapseAllGroups\" })}\n </Menu.Item>\n )}\n </Menu.Content>\n </Menu.Positioner>\n </Portal>\n </Menu.Root>\n </Box>\n )\n );\n});\n\nfunction TriggerButton(props: { triggerId: string }) {\n const { triggerId } = props;\n const intl = useIntl();\n const label = intl.formatMessage({ id: \"toolsLabel\" });\n return (\n <Tooltip ids={{ trigger: triggerId }} content={label}>\n <Menu.Trigger asChild>\n <IconButton\n className=\"toc-tools-button\"\n aria-label={label}\n borderRadius=\"full\"\n focusRingOffset=\"-2px\"\n variant=\"ghost\"\n padding={0}\n size=\"sm\"\n >\n <Icon>\n <LuEllipsisVertical spacing={0} />\n </Icon>\n </IconButton>\n </Menu.Trigger>\n </Tooltip>\n );\n}\n\nfunction hideAllLayers(map: MapModel | undefined) {\n const hide = (layer: AnyLayer) => {\n layer.setVisible(false);\n\n const children = layer.children?.getItems();\n if (children) {\n for (const child of children) {\n hide(child);\n }\n }\n };\n\n map?.layers.getOperationalLayers().forEach((layer) => {\n hide(layer);\n });\n}\n\nfunction collapseAllGroups(tocModel: TocModel) {\n tocModel.getItems().forEach((item) => item.setExpanded(false));\n}\n"],"names":["Tools"],"mappings":"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"}