@open-pioneer/toc 0.8.0 → 0.9.0-dev.20250220091855

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,35 @@
1
1
  # @open-pioneer/toc
2
2
 
3
+ ## 0.9.0-dev.20250220091855
4
+
5
+ ### Minor Changes
6
+
7
+ - bd82a78: Adds the optional functionality to collapse and expand groups in the TOC.
8
+ This option can be activated with the `collapsibleGroups` property (default is `false`).
9
+ If the property `initiallyCollapsed` is `true` all groups are collapsed by default when the TOC is rendered. This is helpful if the app has a large layer tree.
10
+ Additionally, a menu item to collapse all groups can be added to the Tools section by setting `toolsConfig.showCollapseAllGroups` to `true` (default is `true`).
11
+ This is only applicable if `collapsibleGroups` and `showTools` are both `true`.
12
+
13
+ ```jsx
14
+ import { Toc } from "@open-pioneer/toc";
15
+
16
+ <Toc
17
+ mapId={MAP_ID}
18
+ showTools={true}
19
+ collapsibleGroups={true} //groups are collapsible in TOC
20
+ initiallyCollapsed={true} //groups are collapsed initially
21
+ toolsConfig={{ showCollapseAllGroups: true }} //show 'collapse all' menu item in Tools
22
+ />;
23
+ ```
24
+
25
+ ### Patch Changes
26
+
27
+ - Updated dependencies [f327eec]
28
+ - Updated dependencies [f327eec]
29
+ - Updated dependencies [209eb8e]
30
+ - @open-pioneer/map@0.9.0-dev.20250220091855
31
+ - @open-pioneer/basemap-switcher@0.9.0-dev.20250220091855
32
+
3
33
  ## 0.8.0
4
34
 
5
35
  ### Minor Changes
package/README.md CHANGED
@@ -16,12 +16,18 @@ To integrate the TOC (table of contents) in your app, insert the following snipp
16
16
 
17
17
  Additional tools are available for operational layers.
18
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
19
 
21
20
  ```tsx
22
21
  <Toc mapId="map_id" showTools={true} />
23
22
  ```
24
23
 
24
+ The default tools provided by the TOC are:
25
+
26
+ - A button to hide all layers (sets `visibility` to false, enabled by default)
27
+ - A button to collapse all groups (enabled by default if groups are collapsible)
28
+
29
+ These tools can be configured by using the `toolsConfig` property.
30
+
25
31
  ### Basemaps
26
32
 
27
33
  By default, the TOC shows the basemap switcher as an embedded element.
@@ -70,6 +76,20 @@ This can be disabled by configuring `autoShowParents={false}` on the `TOC` compo
70
76
  <Toc autoShowParents={false} />
71
77
  ```
72
78
 
79
+ ### Collapsible groups
80
+
81
+ The TOC renders the hierarchy of layers as a tree structure of nested lists ("groups").
82
+ Groups can be made collapsible through user action by setting the `collapsibleGroups` property to `true`.
83
+ If enabled, a toggle button appears next to parent nodes by which the user can expand or collapse the group.
84
+
85
+ ```tsx
86
+ <Toc
87
+ mapId={MAP_ID}
88
+ collapsibleGroups={true}
89
+ initiallyCollapsed={true} // Whether groups are collapsed by default. Defaults to false.
90
+ />
91
+ ```
92
+
73
93
  ## License
74
94
 
75
95
  Apache-2.0 (see `LICENSE` file)
package/i18n/de.yaml CHANGED
@@ -4,8 +4,12 @@ messages:
4
4
  operationalLayerLabel: "Layer"
5
5
  childgroupLabel: "Layergruppe {title}"
6
6
  missingLayers: "Es sind keine Layer vorhanden."
7
+ group:
8
+ expand: "Gruppe {title} ausklappen"
9
+ collapse: "Gruppe {title} einklappen"
7
10
  error: "Beim Erstellen des Karteninhalts ist ein Fehler aufgetreten."
8
11
  layerNotAvailable: "Layer nicht verfügbar"
9
12
  toolsLabel: "Kartenwerkzeuge"
10
13
  tools:
11
14
  hideAllLayers: "Alle Karteninhalte ausblenden"
15
+ collapseAllGroups: "Alle Gruppen einklappen"
package/i18n/en.yaml CHANGED
@@ -4,8 +4,12 @@ messages:
4
4
  operationalLayerLabel: "Operational layers"
5
5
  childgroupLabel: "Layer group {title}"
6
6
  missingLayers: "There are no layers to display."
7
+ group:
8
+ expand: "Expand group {title}"
9
+ collapse: "Collapse group {title}"
7
10
  error: "Error while creating map content."
8
11
  layerNotAvailable: "Layer not available"
9
12
  toolsLabel: "Map tools"
10
13
  tools:
11
14
  hideAllLayers: "Hide all layers"
15
+ collapseAllGroups: "Collapse all groups"
package/index.d.ts CHANGED
@@ -1 +1 @@
1
- export { Toc, type TocProps, type ToolsConfig } from "./Toc";
1
+ export { Toc, type TocProps, type ToolsConfig } from "./ui/Toc";
package/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { Toc } from './Toc.js';
1
+ export { Toc } from './ui/Toc.js';
2
2
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,76 @@
1
+ import { Provider } from "react";
2
+ /**
3
+ * Provider for the toc's shared model.
4
+ * Used at the root of the component.
5
+ */
6
+ export declare const TocModelProvider: Provider<TocModel>;
7
+ /**
8
+ * Returns the shared model for the current toc component.
9
+ */
10
+ export declare function useTocModel(): TocModel;
11
+ /**
12
+ * Shared model used by the toc and all its sub-components.
13
+ *
14
+ * @internal
15
+ */
16
+ export interface TocModel {
17
+ /**
18
+ * Return the global widget options.
19
+ *
20
+ * NOTE: The object itself is reactive, but individual properties are not (change -> replace).
21
+ */
22
+ readonly options: TocWidgetOptions;
23
+ /**
24
+ * Returns the item that corresponds with the `layerId`.
25
+ */
26
+ getItem(layerId: string): TocItem | undefined;
27
+ /**
28
+ * Returns the list of all items.
29
+ */
30
+ getItems(): TocItem[];
31
+ registerItem(item: TocItem): void;
32
+ unregisterItem(item: TocItem): void;
33
+ }
34
+ /**
35
+ * Global toc widget options.
36
+ *
37
+ * @internal
38
+ */
39
+ export interface TocWidgetOptions {
40
+ /**
41
+ * True: When showing a child, show all parents as well (`setVisible(true)`).
42
+ */
43
+ autoShowParents: boolean;
44
+ /**
45
+ * True: Layer items with children can be collapsed.
46
+ */
47
+ collapsibleGroups: boolean;
48
+ /**
49
+ * True: All groups are initially collapsed.
50
+ */
51
+ initiallyCollapsed: boolean;
52
+ }
53
+ /**
54
+ * Represents an item in the toc.
55
+ *
56
+ * Currently items register themselves in the model when they are mounted
57
+ * and remove themselves when they are unmounted.
58
+ *
59
+ * @internal
60
+ */
61
+ export interface TocItem {
62
+ /**
63
+ * Identifier of the layer that corresponds with the list item.
64
+ */
65
+ readonly layerId: string;
66
+ /**
67
+ * true if list item is expanded.
68
+ */
69
+ readonly isExpanded: boolean;
70
+ /**
71
+ * Expands or collapses the list item.
72
+ *
73
+ * Note: not all list items support this operation.
74
+ */
75
+ setExpanded(expanded: boolean): void;
76
+ }
@@ -0,0 +1,14 @@
1
+ import { createContext, useContext } from 'react';
2
+
3
+ const TocModelContext = createContext(void 0);
4
+ const TocModelProvider = TocModelContext.Provider;
5
+ function useTocModel() {
6
+ const model = useContext(TocModelContext);
7
+ if (!model) {
8
+ throw new Error("Internal error: TocModel not found in context.");
9
+ }
10
+ return model;
11
+ }
12
+
13
+ export { TocModelProvider, useTocModel };
14
+ //# sourceMappingURL=TocModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TocModel.js","sources":["TocModel.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { createContext, Provider, useContext } from \"react\";\n\nconst TocModelContext = createContext<TocModel | undefined>(undefined);\n\n/**\n * Provider for the toc's shared model.\n * Used at the root of the component.\n */\nexport const TocModelProvider: Provider<TocModel> = TocModelContext.Provider as Provider<TocModel>;\n\n/**\n * Returns the shared model for the current toc component.\n */\nexport function useTocModel(): TocModel {\n const model = useContext(TocModelContext);\n if (!model) {\n throw new Error(\"Internal error: TocModel not found in context.\");\n }\n return model;\n}\n\n/**\n * Shared model used by the toc and all its sub-components.\n *\n * @internal\n */\nexport interface TocModel {\n /**\n * Return the global widget options.\n *\n * NOTE: The object itself is reactive, but individual properties are not (change -> replace).\n */\n readonly options: TocWidgetOptions;\n\n /**\n * Returns the item that corresponds with the `layerId`.\n */\n getItem(layerId: string): TocItem | undefined;\n\n /**\n * Returns the list of all items.\n */\n getItems(): TocItem[];\n\n // Used by toc item components to register themselves\n registerItem(item: TocItem): void;\n unregisterItem(item: TocItem): void;\n}\n\n/**\n * Global toc widget options.\n *\n * @internal\n */\nexport interface TocWidgetOptions {\n /**\n * True: When showing a child, show all parents as well (`setVisible(true)`).\n */\n autoShowParents: boolean;\n\n /**\n * True: Layer items with children can be collapsed.\n */\n collapsibleGroups: boolean;\n\n /**\n * True: All groups are initially collapsed.\n */\n initiallyCollapsed: boolean;\n}\n\n/**\n * Represents an item in the toc.\n *\n * Currently items register themselves in the model when they are mounted\n * and remove themselves when they are unmounted.\n *\n * @internal\n */\nexport interface TocItem {\n /**\n * Identifier of the layer that corresponds with the list item.\n */\n readonly layerId: string;\n\n /**\n * true if list item is expanded.\n */\n readonly isExpanded: boolean;\n\n /**\n * Expands or collapses the list item.\n *\n * Note: not all list items support this operation.\n */\n setExpanded(expanded: boolean): void;\n}\n"],"names":[],"mappings":";;AAIA,MAAM,eAAA,GAAkB,cAAoC,KAAS,CAAA,CAAA,CAAA;AAM9D,MAAM,mBAAuC,eAAgB,CAAA,SAAA;AAK7D,SAAS,WAAwB,GAAA;AACpC,EAAM,MAAA,KAAA,GAAQ,WAAW,eAAe,CAAA,CAAA;AACxC,EAAA,IAAI,CAAC,KAAO,EAAA;AACR,IAAM,MAAA,IAAI,MAAM,gDAAgD,CAAA,CAAA;AAAA,GACpE;AACA,EAAO,OAAA,KAAA,CAAA;AACX;;;;"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@open-pioneer/toc",
4
- "version": "0.8.0",
4
+ "version": "0.9.0-dev.20250220091855",
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"
@@ -18,13 +18,14 @@
18
18
  "@open-pioneer/react-utils": "^2.4.0",
19
19
  "@open-pioneer/runtime": "^2.4.0",
20
20
  "classnames": "^2.3.2",
21
- "ol": "^10.2.1",
21
+ "ol": "^10.3.0",
22
22
  "react": "^18.3.1",
23
23
  "react-icons": "^5.3.0",
24
+ "@chakra-ui/icons": "^2.2.4",
24
25
  "@open-pioneer/reactivity": "^2.4.0",
25
26
  "@conterra/reactivity-core": "^0.4.3",
26
- "@open-pioneer/basemap-switcher": "^0.8.0",
27
- "@open-pioneer/map": "^0.8.0"
27
+ "@open-pioneer/basemap-switcher": "^0.9.0-dev.20250220091855",
28
+ "@open-pioneer/map": "^0.9.0-dev.20250220091855"
28
29
  },
29
30
  "exports": {
30
31
  "./package.json": "./package.json",
@@ -0,0 +1,9 @@
1
+ import { AnyLayer } from "@open-pioneer/map";
2
+ /**
3
+ * Renders a single layer as a list item.
4
+ *
5
+ * The item may have further nested list items if there are sublayers present.
6
+ */
7
+ export declare const LayerItem: import("react").NamedExoticComponent<{
8
+ layer: AnyLayer;
9
+ }>;
@@ -0,0 +1,153 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { ChevronDownIcon, ChevronRightIcon } from '@chakra-ui/icons';
3
+ import { reactive } from '@conterra/reactivity-core';
4
+ import { Box, Flex, Checkbox, Tooltip, Spacer, Collapse, IconButton } from '@open-pioneer/chakra-integration';
5
+ import { useReactiveSnapshot } from '@open-pioneer/reactivity';
6
+ import classNames from 'classnames';
7
+ import { useIntl } from '../../_virtual/_virtual-pioneer-module_react-hooks.js';
8
+ import { memo, useId, useMemo, useEffect } from 'react';
9
+ import { FiAlertTriangle } from 'react-icons/fi';
10
+ import { useTocModel } from '../../model/TocModel.js';
11
+ import { slug } from '../../utils/slug.js';
12
+ import { useChildLayers, useLoadState } from './hooks.js';
13
+ import { LayerItemMenu } from './LayerItemMenu.js';
14
+ import { LayerList } from './LayerList.js';
15
+
16
+ const LayerItem = memo(function LayerItem2(props) {
17
+ const { layer } = props;
18
+ const intl = useIntl();
19
+ const [tocItem, _tocModel, tocOptions] = useTocItem(layer);
20
+ const expanded = useReactiveSnapshot(() => tocItem.isExpanded, [tocItem]);
21
+ const isCollapsible = tocOptions ? tocOptions.collapsibleGroups : false;
22
+ const layerGroupId = useId();
23
+ const childLayers = useChildLayers(layer);
24
+ const isAvailable = useLoadState(layer) !== "error";
25
+ const notAvailableLabel = intl.formatMessage({ id: "layerNotAvailable" });
26
+ const { title, description, isVisible } = useReactiveSnapshot(() => {
27
+ return {
28
+ title: layer.title,
29
+ description: layer.description,
30
+ isVisible: layer.visible
31
+ };
32
+ }, [layer]);
33
+ let nestedChildren;
34
+ if (childLayers?.length) {
35
+ nestedChildren = /* @__PURE__ */ jsx(
36
+ LayerList,
37
+ {
38
+ layers: childLayers,
39
+ ml: 4,
40
+ "aria-label": intl.formatMessage({ id: "childgroupLabel" }, { title })
41
+ }
42
+ );
43
+ }
44
+ return /* @__PURE__ */ jsxs(Box, { as: "li", className: classNames("toc-layer-item", `layer-${slug(layer.id)}`), children: [
45
+ /* @__PURE__ */ jsxs(
46
+ Flex,
47
+ {
48
+ className: "toc-layer-item-content",
49
+ width: "100%",
50
+ flexDirection: "row",
51
+ align: "center",
52
+ justifyContent: "space-between",
53
+ gap: 2,
54
+ minHeight: 10,
55
+ children: [
56
+ isCollapsible && /* @__PURE__ */ jsx(
57
+ CollapseButton,
58
+ {
59
+ layerTitle: title,
60
+ layerGroupId,
61
+ expanded,
62
+ onClick: () => tocItem.setExpanded(!expanded),
63
+ hasNestedChildren: !!nestedChildren
64
+ }
65
+ ),
66
+ /* @__PURE__ */ jsx(
67
+ Checkbox,
68
+ {
69
+ "aria-label": title + (!isAvailable ? " " + notAvailableLabel : ""),
70
+ isChecked: isVisible,
71
+ isDisabled: !isAvailable,
72
+ onChange: (event) => updateLayerVisibility(
73
+ layer,
74
+ event.target.checked,
75
+ tocOptions.autoShowParents
76
+ ),
77
+ children: title
78
+ }
79
+ ),
80
+ !isAvailable && /* @__PURE__ */ jsx(
81
+ Tooltip,
82
+ {
83
+ className: "toc-layer-item-content-tooltip",
84
+ label: notAvailableLabel,
85
+ placement: "right",
86
+ openDelay: 500,
87
+ children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(
88
+ FiAlertTriangle,
89
+ {
90
+ className: "toc-layer-item-content-icon",
91
+ color: "red",
92
+ "aria-label": notAvailableLabel
93
+ }
94
+ ) })
95
+ }
96
+ ),
97
+ /* @__PURE__ */ jsx(Spacer, {}),
98
+ /* @__PURE__ */ jsx(LayerItemMenu, { layer, title, description, intl })
99
+ ]
100
+ }
101
+ ),
102
+ nestedChildren && /* @__PURE__ */ jsx(Collapse, { in: expanded, id: layerGroupId, className: "toc-collapsible-item", children: nestedChildren })
103
+ ] });
104
+ });
105
+ function CollapseButton(props) {
106
+ const { layerTitle, layerGroupId, expanded, onClick, hasNestedChildren } = props;
107
+ const intl = useIntl();
108
+ return /* @__PURE__ */ jsx(
109
+ IconButton,
110
+ {
111
+ variant: "ghost",
112
+ borderRadius: "full",
113
+ padding: 0,
114
+ className: "toc-layer-item-collapse-button",
115
+ onClick,
116
+ icon: expanded ? /* @__PURE__ */ jsx(ChevronDownIcon, {}) : /* @__PURE__ */ jsx(ChevronRightIcon, {}),
117
+ "aria-label": expanded ? intl.formatMessage({ id: "group.collapse" }, { title: layerTitle }) : intl.formatMessage({ id: "group.expand" }, { title: layerTitle }),
118
+ "aria-expanded": expanded,
119
+ "aria-controls": layerGroupId,
120
+ visibility: hasNestedChildren ? "visible" : "hidden"
121
+ }
122
+ );
123
+ }
124
+ function useTocItem(layer) {
125
+ const tocModel = useTocModel();
126
+ const options = useReactiveSnapshot(() => tocModel.options, [tocModel]);
127
+ const tocItem = useMemo(() => {
128
+ const expanded = reactive(!options.initiallyCollapsed);
129
+ return {
130
+ layerId: layer.id,
131
+ get isExpanded() {
132
+ return expanded.value;
133
+ },
134
+ setExpanded(expand) {
135
+ expanded.value = expand;
136
+ }
137
+ };
138
+ }, [layer, options.initiallyCollapsed]);
139
+ useEffect(() => {
140
+ tocModel.registerItem(tocItem);
141
+ return () => tocModel.unregisterItem(tocItem);
142
+ }, [tocModel, tocItem]);
143
+ return [tocItem, tocModel, options];
144
+ }
145
+ function updateLayerVisibility(layer, visible, autoShowParents) {
146
+ layer.setVisible(visible);
147
+ if (visible && autoShowParents && layer.parent) {
148
+ updateLayerVisibility(layer.parent, true, true);
149
+ }
150
+ }
151
+
152
+ export { LayerItem };
153
+ //# sourceMappingURL=LayerItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LayerItem.js","sources":["LayerItem.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { ChevronDownIcon, ChevronRightIcon } from \"@chakra-ui/icons\";\nimport { reactive } from \"@conterra/reactivity-core\";\nimport {\n Box,\n Checkbox,\n Collapse,\n Flex,\n IconButton,\n Spacer,\n Tooltip\n} from \"@open-pioneer/chakra-integration\";\nimport { AnyLayer } from \"@open-pioneer/map\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport classNames from \"classnames\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { memo, useEffect, useId, useMemo } from \"react\";\nimport { FiAlertTriangle } 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 }): JSX.Element {\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 childLayers = useChildLayers(layer);\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 let nestedChildren;\n if (childLayers?.length) {\n nestedChildren = (\n <LayerList\n layers={childLayers}\n ml={4}\n aria-label={intl.formatMessage({ id: \"childgroupLabel\" }, { title: title })}\n />\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={!!nestedChildren}\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 screenreader 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 isChecked={isVisible}\n isDisabled={!isAvailable}\n onChange={(event) =>\n updateLayerVisibility(\n layer,\n event.target.checked,\n tocOptions.autoShowParents\n )\n }\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 />\n <LayerItemMenu layer={layer} title={title} description={description} intl={intl} />\n </Flex>\n {nestedChildren && (\n <Collapse in={expanded} id={layerGroupId} className=\"toc-collapsible-item\">\n {nestedChildren}\n </Collapse>\n )}\n </Box>\n );\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 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 icon={expanded ? <ChevronDownIcon /> : <ChevronRightIcon />}\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 visibility={hasNestedChildren ? \"visible\" : \"hidden\"} //use visible:hidden for layers without children for correct indent\n />\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 // TODO: isCollapsed -> recreate model is ok?\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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"}
@@ -0,0 +1,8 @@
1
+ import { AnyLayer } from "@open-pioneer/map";
2
+ import { PackageIntl } from "@open-pioneer/runtime";
3
+ export declare function LayerItemMenu(props: {
4
+ layer: AnyLayer;
5
+ title: string;
6
+ description: string;
7
+ intl: PackageIntl;
8
+ }): false | import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,43 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { Popover, PopoverTrigger, Button, Portal, PopoverContent, PopoverArrow, PopoverCloseButton, PopoverHeader, PopoverBody } from '@open-pioneer/chakra-integration';
3
+ import { FiMoreVertical } from 'react-icons/fi';
4
+ import { useLoadState } from './hooks.js';
5
+
6
+ function LayerItemMenu(props) {
7
+ const { layer, title, description, intl } = props;
8
+ const isPresent = !!description;
9
+ const buttonLabel = intl.formatMessage({ id: "descriptionLabel" });
10
+ const isAvailable = useLoadState(layer) !== "error";
11
+ return isPresent && /* @__PURE__ */ jsxs(Popover, { placement: "bottom-start", children: [
12
+ /* @__PURE__ */ jsx(PopoverTrigger, { children: /* @__PURE__ */ jsx(
13
+ Button,
14
+ {
15
+ isDisabled: !isAvailable,
16
+ className: "toc-layer-item-details-button",
17
+ "aria-label": buttonLabel,
18
+ borderRadius: "full",
19
+ iconSpacing: 0,
20
+ padding: 0,
21
+ variant: "ghost",
22
+ leftIcon: /* @__PURE__ */ jsx(FiMoreVertical, {})
23
+ }
24
+ ) }),
25
+ /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsxs(
26
+ PopoverContent,
27
+ {
28
+ className: "toc-layer-item-details",
29
+ overflowY: "auto",
30
+ maxHeight: "400",
31
+ children: [
32
+ /* @__PURE__ */ jsx(PopoverArrow, {}),
33
+ /* @__PURE__ */ jsx(PopoverCloseButton, { mt: 1 }),
34
+ /* @__PURE__ */ jsx(PopoverHeader, { children: title }),
35
+ /* @__PURE__ */ jsx(PopoverBody, { children: description })
36
+ ]
37
+ }
38
+ ) })
39
+ ] });
40
+ }
41
+
42
+ export { LayerItemMenu };
43
+ //# sourceMappingURL=LayerItemMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LayerItemMenu.js","sources":["LayerItemMenu.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n Button,\n Popover,\n PopoverArrow,\n PopoverBody,\n PopoverCloseButton,\n PopoverContent,\n PopoverHeader,\n PopoverTrigger,\n Portal\n} from \"@open-pioneer/chakra-integration\";\nimport { AnyLayer } from \"@open-pioneer/map\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\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, intl } = props;\n const isPresent = !!description;\n const buttonLabel = intl.formatMessage({ id: \"descriptionLabel\" });\n const isAvailable = useLoadState(layer) !== \"error\";\n\n return (\n isPresent && (\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\n className=\"toc-layer-item-details\"\n overflowY=\"auto\"\n maxHeight=\"400\"\n >\n <PopoverArrow />\n <PopoverCloseButton mt={1} />\n <PopoverHeader>{title}</PopoverHeader>\n <PopoverBody>{description}</PopoverBody>\n </PopoverContent>\n </Portal>\n </Popover>\n )\n );\n}\n"],"names":[],"mappings":";;;;;AAkBO,SAAS,cAAc,KAK3B,EAAA;AACC,EAAA,MAAM,EAAE,KAAA,EAAO,KAAO,EAAA,WAAA,EAAa,MAAS,GAAA,KAAA,CAAA;AAC5C,EAAM,MAAA,SAAA,GAAY,CAAC,CAAC,WAAA,CAAA;AACpB,EAAA,MAAM,cAAc,IAAK,CAAA,aAAA,CAAc,EAAE,EAAA,EAAI,oBAAoB,CAAA,CAAA;AACjE,EAAM,MAAA,WAAA,GAAc,YAAa,CAAA,KAAK,CAAM,KAAA,OAAA,CAAA;AAE5C,EAAA,OACI,SACI,oBAAA,IAAA,CAAC,OAAQ,EAAA,EAAA,SAAA,EAAU,cACf,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,cACG,EAAA,EAAA,QAAA,kBAAA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACG,YAAY,CAAC,WAAA;AAAA,QACb,SAAU,EAAA,+BAAA;AAAA,QACV,YAAY,EAAA,WAAA;AAAA,QACZ,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,KAElC,EAAA,CAAA;AAAA,wBACC,MACG,EAAA,EAAA,QAAA,kBAAA,IAAA;AAAA,MAAC,cAAA;AAAA,MAAA;AAAA,QACG,SAAU,EAAA,wBAAA;AAAA,QACV,SAAU,EAAA,MAAA;AAAA,QACV,SAAU,EAAA,KAAA;AAAA,QAEV,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,YAAa,EAAA,EAAA,CAAA;AAAA,0BACd,GAAA,CAAC,kBAAmB,EAAA,EAAA,EAAA,EAAI,CAAG,EAAA,CAAA;AAAA,0BAC3B,GAAA,CAAC,iBAAe,QAAM,EAAA,KAAA,EAAA,CAAA;AAAA,0BACtB,GAAA,CAAC,eAAa,QAAY,EAAA,WAAA,EAAA,CAAA;AAAA,SAAA;AAAA,OAAA;AAAA,KAElC,EAAA,CAAA;AAAA,GACJ,EAAA,CAAA,CAAA;AAGZ;;;;"}
@@ -0,0 +1,18 @@
1
+ import { ListProps } from "@open-pioneer/chakra-integration";
2
+ import { AnyLayer, MapModel } from "@open-pioneer/map";
3
+ interface TopLevelLayerListProps {
4
+ map: MapModel;
5
+ /** The label of the list group (<ul>) */
6
+ "aria-label"?: string;
7
+ }
8
+ /**
9
+ * Lists the operational layers in the map.
10
+ */
11
+ export declare const TopLevelLayerList: import("react").NamedExoticComponent<TopLevelLayerListProps>;
12
+ /**
13
+ * Renders the given layers as a list (<ul>).
14
+ */
15
+ export declare const LayerList: import("react").NamedExoticComponent<{
16
+ layers: AnyLayer[];
17
+ } & ListProps>;
18
+ export {};
@@ -0,0 +1,37 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { Text, Box, List } from '@open-pioneer/chakra-integration';
3
+ import { useIntl } from '../../_virtual/_virtual-pioneer-module_react-hooks.js';
4
+ import { memo, useMemo } from 'react';
5
+ import { LayerItem } from './LayerItem.js';
6
+ import { useLayers } from './hooks.js';
7
+
8
+ const TopLevelLayerList = memo(function TopLevelLayerList2(props) {
9
+ const { map, "aria-label": ariaLabel } = props;
10
+ const intl = useIntl();
11
+ const layers = useLayers(map);
12
+ if (!layers.length) {
13
+ return /* @__PURE__ */ jsx(Text, { className: "toc-missing-layers", "aria-label": ariaLabel, children: intl.formatMessage({ id: "missingLayers" }) });
14
+ }
15
+ return /* @__PURE__ */ jsx(LayerList, { layers, "aria-label": ariaLabel });
16
+ });
17
+ const LayerList = memo(function LayerList2(props) {
18
+ const { layers, ...listProps } = props;
19
+ const items = useMemo(
20
+ () => layers.map((layer) => /* @__PURE__ */ jsx(LayerItem, { layer }, layer.id)),
21
+ [layers]
22
+ );
23
+ return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
24
+ List,
25
+ {
26
+ as: "ul",
27
+ className: "toc-layer-list",
28
+ listStyleType: "none",
29
+ role: "group",
30
+ ...listProps,
31
+ children: items
32
+ }
33
+ ) });
34
+ });
35
+
36
+ export { LayerList, TopLevelLayerList };
37
+ //# sourceMappingURL=LayerList.js.map
@@ -0,0 +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 { Box, List, ListProps, Text } from \"@open-pioneer/chakra-integration\";\nimport { AnyLayer, MapModel } from \"@open-pioneer/map\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { memo, useMemo } from \"react\";\nimport { LayerItem } from \"./LayerItem\";\nimport { useLayers } from \"./hooks\";\n\ninterface TopLevelLayerListProps {\n map: MapModel;\n\n /** The label of the list group (<ul>) */\n \"aria-label\"?: string;\n}\n\n/**\n * Lists the operational layers in the map.\n */\nexport const TopLevelLayerList = memo(function TopLevelLayerList(props: TopLevelLayerListProps) {\n const { map, \"aria-label\": ariaLabel } = props;\n const intl = useIntl();\n const layers = useLayers(map);\n\n if (!layers.length) {\n return (\n <Text className=\"toc-missing-layers\" aria-label={ariaLabel}>\n {intl.formatMessage({ id: \"missingLayers\" })}\n </Text>\n );\n }\n\n return <LayerList layers={layers} aria-label={ariaLabel} />;\n});\n\n/**\n * Renders the given layers as a list (<ul>).\n */\nexport const LayerList = memo(function LayerList(props: { layers: AnyLayer[] } & ListProps) {\n const { layers, ...listProps } = props;\n const items = useMemo(\n () => layers.map((layer) => <LayerItem key={layer.id} layer={layer} />),\n [layers]\n );\n\n return (\n <Box>\n <List\n // Note: not using UnorderedList because it adds default margins\n as=\"ul\"\n className=\"toc-layer-list\"\n listStyleType=\"none\"\n role=\"group\"\n {...listProps}\n >\n {items}\n </List>\n </Box>\n );\n});\n"],"names":["TopLevelLayerList","LayerList"],"mappings":";;;;;;;AAmBO,MAAM,iBAAoB,GAAA,IAAA,CAAK,SAASA,kBAAAA,CAAkB,KAA+B,EAAA;AAC5F,EAAA,MAAM,EAAE,GAAA,EAAK,YAAc,EAAA,SAAA,EAAc,GAAA,KAAA,CAAA;AACzC,EAAA,MAAM,OAAO,OAAQ,EAAA,CAAA;AACrB,EAAM,MAAA,MAAA,GAAS,UAAU,GAAG,CAAA,CAAA;AAE5B,EAAI,IAAA,CAAC,OAAO,MAAQ,EAAA;AAChB,IAAA,uBACK,GAAA,CAAA,IAAA,EAAA,EAAK,SAAU,EAAA,oBAAA,EAAqB,YAAY,EAAA,SAAA,EAC5C,QAAK,EAAA,IAAA,CAAA,aAAA,CAAc,EAAE,EAAA,EAAI,eAAgB,EAAC,CAC/C,EAAA,CAAA,CAAA;AAAA,GAER;AAEA,EAAA,uBAAQ,GAAA,CAAA,SAAA,EAAA,EAAU,MAAgB,EAAA,YAAA,EAAY,SAAW,EAAA,CAAA,CAAA;AAC7D,CAAC,EAAA;AAKM,MAAM,SAAY,GAAA,IAAA,CAAK,SAASC,UAAAA,CAAU,KAA2C,EAAA;AACxF,EAAA,MAAM,EAAE,MAAA,EAAQ,GAAG,SAAA,EAAc,GAAA,KAAA,CAAA;AACjC,EAAA,MAAM,KAAQ,GAAA,OAAA;AAAA,IACV,MAAM,MAAO,CAAA,GAAA,CAAI,CAAC,KAAA,yBAAW,SAAyB,EAAA,EAAA,KAAA,EAAA,EAAV,KAAM,CAAA,EAAkB,CAAE,CAAA;AAAA,IACtE,CAAC,MAAM,CAAA;AAAA,GACX,CAAA;AAEA,EAAA,2BACK,GACG,EAAA,EAAA,QAAA,kBAAA,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MAEG,EAAG,EAAA,IAAA;AAAA,MACH,SAAU,EAAA,gBAAA;AAAA,MACV,aAAc,EAAA,MAAA;AAAA,MACd,IAAK,EAAA,OAAA;AAAA,MACJ,GAAG,SAAA;AAAA,MAEH,QAAA,EAAA,KAAA;AAAA,KAAA;AAAA,GAET,EAAA,CAAA,CAAA;AAER,CAAC;;;;"}
@@ -0,0 +1,10 @@
1
+ import { AnyLayer, Layer, MapModel } from "@open-pioneer/map";
2
+ /** Returns the top level operational layers in render order (topmost layer first). */
3
+ export declare function useLayers(map: MapModel): Layer[];
4
+ /**
5
+ * Returns the child layers (sublayers or layers contained in a group layer) of a layer.
6
+ * Layers are returned in render order (topmost sublayer first).
7
+ */
8
+ export declare function useChildLayers(layer: AnyLayer): AnyLayer[] | undefined;
9
+ /** Returns the layers current state. */
10
+ export declare function useLoadState(layer: AnyLayer): string;
@@ -0,0 +1,26 @@
1
+ import { isSublayer } from '@open-pioneer/map';
2
+ import { useReactiveSnapshot } from '@open-pioneer/reactivity';
3
+
4
+ function useLayers(map) {
5
+ return useReactiveSnapshot(() => {
6
+ const layers = map.layers.getOperationalLayers({ sortByDisplayOrder: true }) ?? [];
7
+ layers.reverse();
8
+ return layers;
9
+ }, [map]);
10
+ }
11
+ function useChildLayers(layer) {
12
+ return useReactiveSnapshot(() => {
13
+ const children = layer.children?.getItems({ sortByDisplayOrder: true });
14
+ children?.reverse();
15
+ return children;
16
+ }, [layer]);
17
+ }
18
+ function useLoadState(layer) {
19
+ return useReactiveSnapshot(() => {
20
+ const target = isSublayer(layer) ? layer.parentLayer : layer;
21
+ return target.loadState;
22
+ }, [layer]);
23
+ }
24
+
25
+ export { useChildLayers, useLayers, useLoadState };
26
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sources":["hooks.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { AnyLayer, isSublayer, Layer, MapModel } from \"@open-pioneer/map\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\n\n/** Returns the top level operational layers in render order (topmost layer first). */\nexport function useLayers(map: MapModel): Layer[] {\n return useReactiveSnapshot(() => {\n const layers = map.layers.getOperationalLayers({ sortByDisplayOrder: true }) ?? [];\n layers.reverse(); // render topmost layer first\n return layers;\n }, [map]);\n}\n\n/**\n * Returns the child layers (sublayers or layers contained in a group layer) of a layer.\n * Layers are returned in render order (topmost sublayer first).\n */\nexport function useChildLayers(layer: AnyLayer): AnyLayer[] | undefined {\n return useReactiveSnapshot(() => {\n const children = layer.children?.getItems({ sortByDisplayOrder: true });\n children?.reverse(); // render topmost layer first\n return children;\n }, [layer]);\n}\n\n/** Returns the layers current state. */\nexport function useLoadState(layer: AnyLayer): string {\n return useReactiveSnapshot(() => {\n // for sublayers, use the state of the parent\n const target = isSublayer(layer) ? layer.parentLayer : layer;\n return target.loadState;\n }, [layer]);\n}\n"],"names":[],"mappings":";;;AAMO,SAAS,UAAU,GAAwB,EAAA;AAC9C,EAAA,OAAO,oBAAoB,MAAM;AAC7B,IAAM,MAAA,MAAA,GAAS,IAAI,MAAO,CAAA,oBAAA,CAAqB,EAAE,kBAAoB,EAAA,IAAA,EAAM,CAAA,IAAK,EAAC,CAAA;AACjF,IAAA,MAAA,CAAO,OAAQ,EAAA,CAAA;AACf,IAAO,OAAA,MAAA,CAAA;AAAA,GACX,EAAG,CAAC,GAAG,CAAC,CAAA,CAAA;AACZ,CAAA;AAMO,SAAS,eAAe,KAAyC,EAAA;AACpE,EAAA,OAAO,oBAAoB,MAAM;AAC7B,IAAA,MAAM,WAAW,KAAM,CAAA,QAAA,EAAU,SAAS,EAAE,kBAAA,EAAoB,MAAM,CAAA,CAAA;AACtE,IAAA,QAAA,EAAU,OAAQ,EAAA,CAAA;AAClB,IAAO,OAAA,QAAA,CAAA;AAAA,GACX,EAAG,CAAC,KAAK,CAAC,CAAA,CAAA;AACd,CAAA;AAGO,SAAS,aAAa,KAAyB,EAAA;AAClD,EAAA,OAAO,oBAAoB,MAAM;AAE7B,IAAA,MAAM,MAAS,GAAA,UAAA,CAAW,KAAK,CAAA,GAAI,MAAM,WAAc,GAAA,KAAA,CAAA;AACvD,IAAA,OAAO,MAAO,CAAA,SAAA,CAAA;AAAA,GAClB,EAAG,CAAC,KAAK,CAAC,CAAA,CAAA;AACd;;;;"}