@open-pioneer/toc 0.12.0-dev.20250725080856 → 1.0.0-dev.20251020091932

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,6 +1,6 @@
1
1
  # @open-pioneer/toc
2
2
 
3
- ## 0.12.0-dev.20250725080856
3
+ ## 1.0.0-dev.20251020091932
4
4
 
5
5
  ### Minor Changes
6
6
 
@@ -39,20 +39,40 @@
39
39
 
40
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
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).
42
43
  - 2732052: Icons have been changed to unify the appearance of the components. Preferably, Lucide react-icons are used.
44
+ - 2abcaaf: Update to chakra-ui 3.27.1
43
45
 
44
46
  ### Patch Changes
45
47
 
46
48
  - 10d2fe7: Update dependencies
49
+ - 9e9bc6e: Use new option `includeInternalLayers === true` for layer retrieval because internal layers are already handled by the Toc itself.
50
+ - 138d85b: Update core packages to 4.1.0
47
51
  - da6a410: Update dependencies
52
+ - Updated dependencies [c6180c6]
53
+ - Updated dependencies [29a10df]
48
54
  - Updated dependencies [10d2fe7]
49
55
  - Updated dependencies [2702df4]
56
+ - Updated dependencies [12561fe]
57
+ - Updated dependencies [5df900f]
50
58
  - Updated dependencies [8986b3b]
59
+ - Updated dependencies [b3709f1]
60
+ - Updated dependencies [dfd7c7e]
61
+ - Updated dependencies [14c484e]
62
+ - Updated dependencies [138d85b]
63
+ - Updated dependencies [aeb9000]
64
+ - Updated dependencies [9e9bc6e]
65
+ - Updated dependencies [b3709f1]
66
+ - Updated dependencies [2c8b617]
51
67
  - Updated dependencies [2732052]
68
+ - Updated dependencies [b3709f1]
69
+ - Updated dependencies [5df900f]
52
70
  - Updated dependencies [f1f69f2]
71
+ - Updated dependencies [773fa2d]
72
+ - Updated dependencies [2abcaaf]
53
73
  - Updated dependencies [da6a410]
54
- - @open-pioneer/basemap-switcher@0.12.0-dev.20250725080856
55
- - @open-pioneer/map@0.12.0-dev.20250725080856
74
+ - @open-pioneer/map@1.0.0-dev.20251020091932
75
+ - @open-pioneer/basemap-switcher@1.0.0-dev.20251020091932
56
76
 
57
77
  ## 0.11.0
58
78
 
package/README.md CHANGED
@@ -130,6 +130,46 @@ Valid values for `listMode` are:
130
130
 
131
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
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
+
133
173
  ## License
134
174
 
135
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 { type ExpandItemOptions, type TocApi, type TocDisposedEvent, type TocItem, type TocReadyEvent } from "./model";
1
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.12.0-dev.20250725080856",
4
+ "version": "1.0.0-dev.20251020091932",
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.21.1",
18
- "@open-pioneer/react-utils": "^4.0.0",
19
- "@open-pioneer/runtime": "^4.0.0",
17
+ "@chakra-ui/react": "^3.27.1",
18
+ "@open-pioneer/react-utils": "4.2.0-dev.20251017113502",
19
+ "@open-pioneer/runtime": "4.2.0-dev.20251017113502",
20
20
  "classnames": "^2.5.1",
21
21
  "ol": "^10.6.1",
22
- "react": "^19.1.0",
22
+ "react": "^19.2.0",
23
23
  "react-icons": "^5.5.0",
24
- "@open-pioneer/reactivity": "^4.0.0",
25
- "@conterra/reactivity-core": "^0.7.0",
26
- "@open-pioneer/chakra-snippets": "^4.0.0",
27
- "@open-pioneer/basemap-switcher": "0.12.0-dev.20250725080856",
28
- "@open-pioneer/map": "0.12.0-dev.20250725080856"
24
+ "@open-pioneer/reactivity": "4.2.0-dev.20251017113502",
25
+ "@conterra/reactivity-core": "^0.8.0",
26
+ "@open-pioneer/chakra-snippets": "4.2.0-dev.20251017113502",
27
+ "@open-pioneer/map": "1.0.0-dev.20251020091932",
28
+ "@open-pioneer/basemap-switcher": "1.0.0-dev.20251020091932"
29
29
  },
30
30
  "exports": {
31
31
  "./package.json": "./package.json",