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

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,65 @@
1
1
  # @open-pioneer/toc
2
2
 
3
+ ## 0.12.0-dev.20250905090001
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
+ - cb5368f: Introduce Toc API for programmatic control of toc items, see [PR](https://github.com/open-pioneer/trails-openlayers-base-packages/pull/420).
43
+ - 2732052: Icons have been changed to unify the appearance of the components. Preferably, Lucide react-icons are used.
44
+
45
+ ### Patch Changes
46
+
47
+ - 10d2fe7: Update dependencies
48
+ - da6a410: Update dependencies
49
+ - Updated dependencies [29a10df]
50
+ - Updated dependencies [10d2fe7]
51
+ - Updated dependencies [2702df4]
52
+ - Updated dependencies [12561fe]
53
+ - Updated dependencies [5df900f]
54
+ - Updated dependencies [8986b3b]
55
+ - Updated dependencies [aeb9000]
56
+ - Updated dependencies [2732052]
57
+ - Updated dependencies [5df900f]
58
+ - Updated dependencies [f1f69f2]
59
+ - Updated dependencies [da6a410]
60
+ - @open-pioneer/map@0.12.0-dev.20250905090001
61
+ - @open-pioneer/basemap-switcher@0.12.0-dev.20250905090001
62
+
3
63
  ## 0.11.0
4
64
 
5
65
  ### Minor Changes
@@ -108,7 +168,6 @@
108
168
  ### Minor Changes
109
169
 
110
170
  - 2fa8020: Update trails core package dependencies.
111
-
112
171
  - Also updates Chakra UI to the latest 2.x version and Chakra React Select to version 5.
113
172
  - Removes any obsolete references to `@chakra-ui/system`.
114
173
  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,84 @@ 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
+
133
+ ### Using the Toc API to manipulate Toc Items programmatically
134
+
135
+ The Toc API allows programmatic access to the Toc.
136
+
137
+ Currently, the Toc API allows accessing the individual Toc items.
138
+ Toc items can be expanded/collapsed and provide access to the corresponding DOM element.
139
+
140
+ ```tsx
141
+ import { Toc, TocApi, TocReadyEvent } from "@open-pioneer/toc";
142
+ import { Button } from "@chakra-ui/react";
143
+
144
+ const tocApi = useRef<TocApi>(undefined);
145
+
146
+ // Expand or collapse group layer with the Toc API
147
+ function toggleTocItem(layerId: string) {
148
+ if (!tocApi.current) {
149
+ return; // toc not ready yet
150
+ }
151
+
152
+ const layerItem = tocApi.current.getItemByLayerId(layerId);
153
+ if (!layerItem) {
154
+ return; // item not found
155
+ }
156
+
157
+ console.log("Current html element", layerItem.htmlElement); // access DOM element (e.g. for scrolling)
158
+ const newState = !layerItem.isExpanded;
159
+ layerItem.setExpanded(newState);
160
+ }
161
+
162
+ <Toc
163
+ // get API object from ready event and store it somewhere
164
+ onReady={(e) => { tocApi.current = e.api; }}
165
+
166
+ // don't use the API object after the toc has been destroyed
167
+ onDisposed={() => { tocApi.current = undefined; }}
168
+ />
169
+
170
+ <Button onClick={() => toggleTocItem("myGroupLayer")}>Toggle group layer</Button>
171
+ ```
172
+
95
173
  ## License
96
174
 
97
175
  Apache-2.0 (see `LICENSE` file)
package/i18n/de.yaml CHANGED
@@ -9,7 +9,6 @@ messages:
9
9
  expand: "Gruppe {title} ausklappen"
10
10
  collapse: "Gruppe {title} einklappen"
11
11
 
12
- error: "Beim Erstellen des Karteninhalts ist ein Fehler aufgetreten."
13
12
  layerNotAvailable: "Layer nicht verfügbar"
14
13
 
15
14
  toolsLabel: "Kartenwerkzeuge"
package/i18n/en.yaml CHANGED
@@ -9,7 +9,6 @@ messages:
9
9
  expand: "Expand group {title}"
10
10
  collapse: "Collapse group {title}"
11
11
 
12
- error: "Error while creating map content."
13
12
  layerNotAvailable: "Layer not available"
14
13
 
15
14
  toolsLabel: "Map tools"
package/index.d.ts CHANGED
@@ -1 +1,2 @@
1
- export { Toc, type TocProps, type ToolsConfig } from "./ui/Toc";
1
+ export { type ExpandItemOptions, type TocApi, type TocDisposedEvent, type TocItem, type TocReadyEvent } from "./model";
2
+ export { Toc, type TocProps, type ToolsConfig, type LayerTocAttributes, type ListMode } from "./ui/Toc";
@@ -0,0 +1,9 @@
1
+ import { TocModel } from "./TocModel";
2
+ import { TocApi, TocItem } from "./types";
3
+ export declare class TocApiImpl implements TocApi {
4
+ #private;
5
+ constructor(model: TocModel);
6
+ getItemById(id: string): TocItem | undefined;
7
+ getItemByLayerId(layerId: string): TocItem | undefined;
8
+ getItems(): TocItem[];
9
+ }
@@ -0,0 +1,18 @@
1
+ class TocApiImpl {
2
+ #tocModel;
3
+ constructor(model) {
4
+ this.#tocModel = model;
5
+ }
6
+ getItemById(id) {
7
+ return this.#tocModel.getItemById(id);
8
+ }
9
+ getItemByLayerId(layerId) {
10
+ return this.#tocModel.getItemByLayerId(layerId);
11
+ }
12
+ getItems() {
13
+ return this.#tocModel.getItems();
14
+ }
15
+ }
16
+
17
+ export { TocApiImpl };
18
+ //# sourceMappingURL=TocApiImpl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TocApiImpl.js","sources":["TocApiImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { TocModel } from \"./TocModel\";\nimport { TocApi, TocItem } from \"./types\";\n\nexport class TocApiImpl implements TocApi {\n #tocModel: TocModel;\n\n constructor(model: TocModel) {\n this.#tocModel = model;\n }\n\n getItemById(id: string): TocItem | undefined {\n return this.#tocModel.getItemById(id);\n }\n\n getItemByLayerId(layerId: string): TocItem | undefined {\n return this.#tocModel.getItemByLayerId(layerId);\n }\n\n getItems(): TocItem[] {\n return this.#tocModel.getItems();\n }\n}\n"],"names":[],"mappings":"AAKO,MAAM,UAAA,CAA6B;AAAA,EACtC,SAAA;AAAA,EAEA,YAAY,KAAA,EAAiB;AACzB,IAAA,IAAA,CAAK,SAAA,GAAY,KAAA;AAAA,EACrB;AAAA,EAEA,YAAY,EAAA,EAAiC;AACzC,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,WAAA,CAAY,EAAE,CAAA;AAAA,EACxC;AAAA,EAEA,iBAAiB,OAAA,EAAsC;AACnD,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,gBAAA,CAAiB,OAAO,CAAA;AAAA,EAClD;AAAA,EAEA,QAAA,GAAsB;AAClB,IAAA,OAAO,IAAA,CAAK,UAAU,QAAA,EAAS;AAAA,EACnC;AACJ;;;;"}
@@ -0,0 +1,13 @@
1
+ import { AnyLayer } from "@open-pioneer/map";
2
+ import { TocModel } from "./TocModel";
3
+ import { ExpandItemOptions, TocItem } from "./types";
4
+ export declare class TocItemImpl implements TocItem {
5
+ #private;
6
+ constructor(layer: AnyLayer, tocModel: TocModel, expanded: boolean);
7
+ get id(): string;
8
+ get layerId(): string;
9
+ get isExpanded(): boolean;
10
+ get htmlElement(): HTMLElement | undefined;
11
+ setExpanded(expanded: boolean, options?: ExpandItemOptions): void;
12
+ setHtmlElement(element: HTMLElement | undefined): void;
13
+ }
@@ -0,0 +1,45 @@
1
+ import { reactive } from '@conterra/reactivity-core';
2
+
3
+ class TocItemImpl {
4
+ #htmlElement = reactive();
5
+ #expanded;
6
+ #layer;
7
+ #tocModel;
8
+ constructor(layer, tocModel, expanded) {
9
+ this.#expanded = reactive(expanded);
10
+ this.#layer = layer;
11
+ this.#tocModel = tocModel;
12
+ }
13
+ get id() {
14
+ return this.layerId;
15
+ }
16
+ get layerId() {
17
+ return this.#layer.id;
18
+ }
19
+ get isExpanded() {
20
+ return this.#expanded.value;
21
+ }
22
+ get htmlElement() {
23
+ return this.#htmlElement.value;
24
+ }
25
+ setExpanded(expanded, options) {
26
+ this.#expanded.value = expanded;
27
+ let bubble = options?.bubble;
28
+ if (bubble === void 0) {
29
+ bubble = expanded;
30
+ }
31
+ if (bubble) {
32
+ const parentLayer = this.#layer.parent;
33
+ if (parentLayer) {
34
+ this.#tocModel.getItemByLayerId(parentLayer.id)?.setExpanded(expanded, options);
35
+ }
36
+ }
37
+ }
38
+ //private setter, not exposed in TocItem interface
39
+ setHtmlElement(element) {
40
+ this.#htmlElement.value = element;
41
+ }
42
+ }
43
+
44
+ export { TocItemImpl };
45
+ //# sourceMappingURL=TocItemImpl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TocItemImpl.js","sources":["TocItemImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Reactive, reactive } from \"@conterra/reactivity-core\";\nimport { AnyLayer } from \"@open-pioneer/map\";\nimport { TocModel } from \"./TocModel\";\nimport { ExpandItemOptions, TocItem } from \"./types\";\n\nexport class TocItemImpl implements TocItem {\n #htmlElement = reactive<HTMLElement | undefined>();\n #expanded: Reactive<boolean>;\n #layer: AnyLayer;\n #tocModel: TocModel;\n\n constructor(layer: AnyLayer, tocModel: TocModel, expanded: boolean) {\n this.#expanded = reactive(expanded);\n this.#layer = layer;\n this.#tocModel = tocModel;\n }\n\n get id() {\n return this.layerId;\n }\n\n get layerId() {\n return this.#layer.id;\n }\n\n get isExpanded() {\n return this.#expanded.value;\n }\n\n get htmlElement() {\n return this.#htmlElement.value;\n }\n\n setExpanded(expanded: boolean, options?: ExpandItemOptions): void {\n this.#expanded.value = expanded;\n let bubble = options?.bubble;\n //by default bubble if expand is true\n if (bubble === undefined) {\n bubble = expanded;\n }\n\n if (bubble) {\n const parentLayer = this.#layer.parent;\n if (parentLayer) {\n this.#tocModel.getItemByLayerId(parentLayer.id)?.setExpanded(expanded, options);\n }\n }\n }\n\n //private setter, not exposed in TocItem interface\n setHtmlElement(element: HTMLElement | undefined) {\n this.#htmlElement.value = element;\n }\n}\n"],"names":[],"mappings":";;AAOO,MAAM,WAAA,CAA+B;AAAA,EACxC,eAAe,QAAA,EAAkC;AAAA,EACjD,SAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EAEA,WAAA,CAAY,KAAA,EAAiB,QAAA,EAAoB,QAAA,EAAmB;AAChE,IAAA,IAAA,CAAK,SAAA,GAAY,SAAS,QAAQ,CAAA;AAClC,IAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AACd,IAAA,IAAA,CAAK,SAAA,GAAY,QAAA;AAAA,EACrB;AAAA,EAEA,IAAI,EAAA,GAAK;AACL,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,EAChB;AAAA,EAEA,IAAI,OAAA,GAAU;AACV,IAAA,OAAO,KAAK,MAAA,CAAO,EAAA;AAAA,EACvB;AAAA,EAEA,IAAI,UAAA,GAAa;AACb,IAAA,OAAO,KAAK,SAAA,CAAU,KAAA;AAAA,EAC1B;AAAA,EAEA,IAAI,WAAA,GAAc;AACd,IAAA,OAAO,KAAK,YAAA,CAAa,KAAA;AAAA,EAC7B;AAAA,EAEA,WAAA,CAAY,UAAmB,OAAA,EAAmC;AAC9D,IAAA,IAAA,CAAK,UAAU,KAAA,GAAQ,QAAA;AACvB,IAAA,IAAI,SAAS,OAAA,EAAS,MAAA;AAEtB,IAAA,IAAI,WAAW,MAAA,EAAW;AACtB,MAAA,MAAA,GAAS,QAAA;AAAA,IACb;AAEA,IAAA,IAAI,MAAA,EAAQ;AACR,MAAA,MAAM,WAAA,GAAc,KAAK,MAAA,CAAO,MAAA;AAChC,MAAA,IAAI,WAAA,EAAa;AACb,QAAA,IAAA,CAAK,UAAU,gBAAA,CAAiB,WAAA,CAAY,EAAE,CAAA,EAAG,WAAA,CAAY,UAAU,OAAO,CAAA;AAAA,MAClF;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA,EAGA,eAAe,OAAA,EAAkC;AAC7C,IAAA,IAAA,CAAK,aAAa,KAAA,GAAQ,OAAA;AAAA,EAC9B;AACJ;;;;"}
@@ -1,36 +1,4 @@
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
- }
1
+ import { TocItem } from "./types";
34
2
  /**
35
3
  * Global toc widget options.
36
4
  *
@@ -51,26 +19,26 @@ export interface TocWidgetOptions {
51
19
  initiallyCollapsed: boolean;
52
20
  }
53
21
  /**
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.
22
+ * Shared model used by the Toc and all its sub-components.
23
+ * Extends the external TocAPI with private, internal properties.
58
24
  *
59
25
  * @internal
60
26
  */
61
- export interface TocItem {
62
- /**
63
- * Identifier of the layer that corresponds with the list item.
64
- */
65
- readonly layerId: string;
27
+ export declare class TocModel {
28
+ #private;
29
+ constructor(initialOptions: TocWidgetOptions);
66
30
  /**
67
- * true if list item is expanded.
68
- */
69
- readonly isExpanded: boolean;
70
- /**
71
- * Expands or collapses the list item.
31
+ * Return the global widget options.
72
32
  *
73
- * Note: not all list items support this operation.
33
+ * NOTE: The object itself is reactive, but individual properties are not (change -> replace).
34
+ * See {@link updateOptions}.
74
35
  */
75
- setExpanded(expanded: boolean): void;
36
+ get options(): TocWidgetOptions;
37
+ getItemById(id: string): TocItem | undefined;
38
+ getItemByLayerId(layerId: string): TocItem | undefined;
39
+ getItems(): TocItem[];
40
+ registerItem(item: TocItem): void;
41
+ unregisterItem(item: TocItem): void;
42
+ updateOptions(options: TocWidgetOptions): void;
76
43
  }
44
+ export declare function createOptions(autoShowParents?: boolean | undefined, collapsibleGroups?: boolean | undefined, isCollapsed?: boolean | undefined): TocWidgetOptions;
package/model/TocModel.js CHANGED
@@ -1,14 +1,55 @@
1
- import { createContext, useContext } from 'react';
1
+ import { reactiveMap, reactive } from '@conterra/reactivity-core';
2
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;
3
+ class TocModel {
4
+ #options;
5
+ // Indexed by layerId
6
+ #items = reactiveMap();
7
+ constructor(initialOptions) {
8
+ this.#options = reactive(initialOptions);
9
+ }
10
+ /**
11
+ * Return the global widget options.
12
+ *
13
+ * NOTE: The object itself is reactive, but individual properties are not (change -> replace).
14
+ * See {@link updateOptions}.
15
+ */
16
+ get options() {
17
+ return this.#options.value;
18
+ }
19
+ getItemById(id) {
20
+ return this.#items.get(id);
21
+ }
22
+ getItemByLayerId(layerId) {
23
+ return this.getItemById(layerId);
24
+ }
25
+ getItems() {
26
+ return Array.from(this.#items.values());
27
+ }
28
+ // Used by toc item components to register themselves
29
+ registerItem(item) {
30
+ if (this.#items.has(item.id)) {
31
+ throw new Error(`Item with layerId '${item.layerId}' already registered.`);
32
+ }
33
+ this.#items.set(item.id, item);
34
+ }
35
+ // Used by toc item components to register themselves
36
+ unregisterItem(item) {
37
+ if (this.#items.get(item.id) !== item) {
38
+ throw new Error(`Item with layerId '${item.layerId}' not registered.`);
39
+ }
40
+ this.#items.delete(item.id);
41
+ }
42
+ updateOptions(options) {
43
+ this.#options.value = options;
44
+ }
45
+ }
46
+ function createOptions(autoShowParents, collapsibleGroups, isCollapsed) {
47
+ return {
48
+ autoShowParents: autoShowParents ?? true,
49
+ collapsibleGroups: collapsibleGroups ?? false,
50
+ initiallyCollapsed: isCollapsed ?? false
51
+ };
11
52
  }
12
53
 
13
- export { TocModelProvider, useTocModel };
54
+ export { TocModel, createOptions };
14
55
  //# sourceMappingURL=TocModel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TocModel.js","sources":["TocModel.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 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,MAAS,CAAA;AAM9D,MAAM,mBAAuC,eAAgB,CAAA;AAK7D,SAAS,WAAwB,GAAA;AACpC,EAAM,MAAA,KAAA,GAAQ,WAAW,eAAe,CAAA;AACxC,EAAA,IAAI,CAAC,KAAO,EAAA;AACR,IAAM,MAAA,IAAI,MAAM,gDAAgD,CAAA;AAAA;AAEpE,EAAO,OAAA,KAAA;AACX;;;;"}
1
+ {"version":3,"file":"TocModel.js","sources":["TocModel.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { reactive, Reactive, reactiveMap } from \"@conterra/reactivity-core\";\nimport { TocItem } from \"./types\";\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 * Shared model used by the Toc and all its sub-components.\n * Extends the external TocAPI with private, internal properties.\n *\n * @internal\n */\nexport class TocModel {\n #options: Reactive<TocWidgetOptions>;\n\n // Indexed by layerId\n #items = reactiveMap<string, TocItem>();\n\n constructor(initialOptions: TocWidgetOptions) {\n this.#options = reactive(initialOptions);\n }\n\n /**\n * Return the global widget options.\n *\n * NOTE: The object itself is reactive, but individual properties are not (change -> replace).\n * See {@link updateOptions}.\n */\n get options() {\n return this.#options.value;\n }\n\n getItemById(id: string): TocItem | undefined {\n return this.#items.get(id);\n }\n\n getItemByLayerId(layerId: string): TocItem | undefined {\n return this.getItemById(layerId); // happens to be the same at the moment\n }\n\n getItems(): TocItem[] {\n return Array.from(this.#items.values());\n }\n\n // Used by toc item components to register themselves\n registerItem(item: TocItem): void {\n if (this.#items.has(item.id)) {\n throw new Error(`Item with layerId '${item.layerId}' already registered.`);\n }\n this.#items.set(item.id, item);\n }\n\n // Used by toc item components to register themselves\n unregisterItem(item: TocItem): void {\n if (this.#items.get(item.id) !== item) {\n throw new Error(`Item with layerId '${item.layerId}' not registered.`);\n }\n this.#items.delete(item.id);\n }\n\n updateOptions(options: TocWidgetOptions) {\n this.#options.value = options;\n }\n}\n\nexport function 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":[],"mappings":";;AAiCO,MAAM,QAAA,CAAS;AAAA,EAClB,QAAA;AAAA;AAAA,EAGA,SAAS,WAAA,EAA6B;AAAA,EAEtC,YAAY,cAAA,EAAkC;AAC1C,IAAA,IAAA,CAAK,QAAA,GAAW,SAAS,cAAc,CAAA;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,OAAA,GAAU;AACV,IAAA,OAAO,KAAK,QAAA,CAAS,KAAA;AAAA,EACzB;AAAA,EAEA,YAAY,EAAA,EAAiC;AACzC,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,EAAE,CAAA;AAAA,EAC7B;AAAA,EAEA,iBAAiB,OAAA,EAAsC;AACnD,IAAA,OAAO,IAAA,CAAK,YAAY,OAAO,CAAA;AAAA,EACnC;AAAA,EAEA,QAAA,GAAsB;AAClB,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,QAAQ,CAAA;AAAA,EAC1C;AAAA;AAAA,EAGA,aAAa,IAAA,EAAqB;AAC9B,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG;AAC1B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,IAAA,CAAK,OAAO,CAAA,qBAAA,CAAuB,CAAA;AAAA,IAC7E;AACA,IAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,IAAA,CAAK,EAAA,EAAI,IAAI,CAAA;AAAA,EACjC;AAAA;AAAA,EAGA,eAAe,IAAA,EAAqB;AAChC,IAAA,IAAI,KAAK,MAAA,CAAO,GAAA,CAAI,IAAA,CAAK,EAAE,MAAM,IAAA,EAAM;AACnC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,IAAA,CAAK,OAAO,CAAA,iBAAA,CAAmB,CAAA;AAAA,IACzE;AACA,IAAA,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,EAAE,CAAA;AAAA,EAC9B;AAAA,EAEA,cAAc,OAAA,EAA2B;AACrC,IAAA,IAAA,CAAK,SAAS,KAAA,GAAQ,OAAA;AAAA,EAC1B;AACJ;AAEO,SAAS,aAAA,CACZ,eAAA,EACA,iBAAA,EACA,WAAA,EACgB;AAChB,EAAA,OAAO;AAAA,IACH,iBAAiB,eAAA,IAAmB,IAAA;AAAA,IACpC,mBAAmB,iBAAA,IAAqB,KAAA;AAAA,IACxC,oBAAoB,WAAA,IAAe;AAAA,GACvC;AACJ;;;;"}
@@ -0,0 +1,11 @@
1
+ import { Provider } from "react";
2
+ import { TocModel } from "./TocModel";
3
+ /**
4
+ * Provider for the toc's shared model.
5
+ * Used at the root of the component.
6
+ */
7
+ export declare const TocModelProvider: Provider<TocModel>;
8
+ /**
9
+ * Returns the shared model for the current toc component.
10
+ */
11
+ export declare function useTocModel(): TocModel;
@@ -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=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sources":["context.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { createContext, Provider, useContext } from \"react\";\nimport { TocModel } from \"./TocModel\";\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"],"names":[],"mappings":";;AAKA,MAAM,eAAA,GAAkB,cAAoC,MAAS,CAAA;AAM9D,MAAM,mBAAuC,eAAA,CAAgB;AAK7D,SAAS,WAAA,GAAwB;AACpC,EAAA,MAAM,KAAA,GAAQ,WAAW,eAAe,CAAA;AACxC,EAAA,IAAI,CAAC,KAAA,EAAO;AACR,IAAA,MAAM,IAAI,MAAM,gDAAgD,CAAA;AAAA,EACpE;AACA,EAAA,OAAO,KAAA;AACX;;;;"}
@@ -0,0 +1,5 @@
1
+ export { TocModelProvider, useTocModel } from "./context";
2
+ export { TocApiImpl } from "./TocApiImpl";
3
+ export { TocItemImpl } from "./TocItemImpl";
4
+ export { createOptions, TocModel, type TocWidgetOptions } from "./TocModel";
5
+ export { type ExpandItemOptions, type TocApi, type TocDisposedEvent, type TocItem, type TocReadyEvent } from "./types";
@@ -0,0 +1,74 @@
1
+ /**
2
+ * API to control the Toc component imperatively
3
+ */
4
+ export interface TocApi {
5
+ /**
6
+ * Returns the toc item for the given `id`.
7
+ */
8
+ getItemById(id: string): TocItem | undefined;
9
+ /**
10
+ * Returns the item that corresponds with the `layerId`.
11
+ */
12
+ getItemByLayerId(layerId: string): TocItem | undefined;
13
+ /**
14
+ * Returns the list of all registered items in the Toc.
15
+ */
16
+ getItems(): TocItem[];
17
+ }
18
+ /**
19
+ * Represents an item in the toc.
20
+ *
21
+ * Currently items register themselves in the model when they are mounted
22
+ * and remove themselves when they are unmounted.
23
+ */
24
+ export interface TocItem {
25
+ /**
26
+ * Identifier of the Toc item.
27
+ * Currently, this is the same as `layerId`, but that could be changed in the future.
28
+ */
29
+ readonly id: string;
30
+ /**
31
+ * Identifier of the layer that corresponds with the list item.
32
+ * May be undefined if the item does not represent a layer.
33
+ */
34
+ readonly layerId?: string;
35
+ /**
36
+ * `true` if list item is expanded.
37
+ */
38
+ readonly isExpanded: boolean;
39
+ /**
40
+ * DOM element of the underlying {@link LayerItem}, `undefined` if the toc has been disposed
41
+ * or if the item is currently not being rendered.
42
+ */
43
+ readonly htmlElement: HTMLElement | undefined;
44
+ /**
45
+ * Expands or collapses the list item.
46
+ *
47
+ * Note: not all list items support this operation.
48
+ */
49
+ setExpanded(expanded: boolean, options?: ExpandItemOptions): void;
50
+ }
51
+ export interface ExpandItemOptions {
52
+ /**
53
+ * Align `expanded` state of parent items.
54
+ * By default (`undefined`), the status is only passed on to the parents when the Toc item is being expanded but not if it is being collapsed.
55
+ */
56
+ bubble?: boolean;
57
+ }
58
+ /**
59
+ * Event that indicates that the Toc component is initialized.
60
+ * The event carries a reference to the public {@link TocApi}
61
+ */
62
+ export interface TocReadyEvent {
63
+ /**
64
+ * Reference to the Toc API that allows manipulating the Toc.
65
+ */
66
+ api: TocApi;
67
+ }
68
+ /**
69
+ * Event that indicates that the Toc component has been disposed.
70
+ *
71
+ * Empty interface, might be extended in the future
72
+ */
73
+ export interface TocDisposedEvent {
74
+ }
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.20250905090001",
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.24.2",
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",
22
- "react": "^19.1.0",
21
+ "ol": "^10.6.1",
22
+ "react": "^19.1.1",
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.20250905090001",
28
+ "@open-pioneer/map": "0.12.0-dev.20250905090001"
29
29
  },
30
30
  "exports": {
31
31
  "./package.json": "./package.json",