@open-pioneer/toc 1.4.0-dev.20260625074633 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -2
- package/i18n/de.yaml +2 -0
- package/i18n/en.yaml +2 -0
- package/model/TocApiImpl.js.map +1 -1
- package/model/TocItemImpl.js.map +1 -1
- package/model/TocModel.js.map +1 -1
- package/model/context.js.map +1 -1
- package/package.json +12 -11
- package/ui/LayerList/LayerItem.js +48 -27
- package/ui/LayerList/LayerItem.js.map +1 -1
- package/ui/LayerList/LayerItemMenu.js.map +1 -1
- package/ui/LayerList/LayerList.js +3 -3
- package/ui/LayerList/LayerList.js.map +1 -1
- package/ui/LayerList/hooks.d.ts +7 -3
- package/ui/LayerList/hooks.js +67 -6
- package/ui/LayerList/hooks.js.map +1 -1
- package/ui/Toc.js.map +1 -1
- package/ui/Tools.js +2 -2
- package/ui/Tools.js.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
# @open-pioneer/toc
|
|
2
2
|
|
|
3
|
-
## 1.4.0
|
|
3
|
+
## 1.4.0
|
|
4
4
|
|
|
5
5
|
### Minor Changes
|
|
6
6
|
|
|
7
|
-
- c30396d: Update Chakra to 3.36.
|
|
7
|
+
- c30396d: Update Chakra to 3.36.1
|
|
8
|
+
- d862003: Update to trails core-packages 4.7.0
|
|
9
|
+
- 690a892: Add new problem indicators when there are problems in a layer's children (e.g. sublayers, children of a group layer).
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- c16a401: Migrated from eslint to oxlint and from prettier to oxfmt.
|
|
8
14
|
|
|
9
15
|
## 1.3.0
|
|
10
16
|
|
|
@@ -73,6 +79,7 @@
|
|
|
73
79
|
```
|
|
74
80
|
|
|
75
81
|
Valid values for `listMode` are:
|
|
82
|
+
|
|
76
83
|
- `"show"` layer item is displayed in Toc
|
|
77
84
|
- `"hide"` layer item is not rendered in Toc
|
|
78
85
|
- `"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
|
|
@@ -170,6 +177,7 @@
|
|
|
170
177
|
### Minor Changes
|
|
171
178
|
|
|
172
179
|
- 2fa8020: Update trails core package dependencies.
|
|
180
|
+
|
|
173
181
|
- Also updates Chakra UI to the latest 2.x version and Chakra React Select to version 5.
|
|
174
182
|
- Removes any obsolete references to `@chakra-ui/system`.
|
|
175
183
|
This dependency seems to be no longer required and may lead to duplicate packages in your dependency tree.
|
package/i18n/de.yaml
CHANGED
|
@@ -10,6 +10,8 @@ messages:
|
|
|
10
10
|
collapse: "Gruppe {title} einklappen"
|
|
11
11
|
|
|
12
12
|
layerNotAvailable: "Layer nicht verfügbar"
|
|
13
|
+
childLayerNotAvailable: "Ein untergeordneter Layer ist nicht verfügbar"
|
|
14
|
+
childLayerNotAvailableDetails: "Die folgenden untergeordneten Layer sind nicht verfügbar:"
|
|
13
15
|
layerNotVisible: "Layer in diesem Maßstab nicht sichtbar"
|
|
14
16
|
|
|
15
17
|
toolsLabel: "Kartenwerkzeuge"
|
package/i18n/en.yaml
CHANGED
|
@@ -10,6 +10,8 @@ messages:
|
|
|
10
10
|
collapse: "Collapse group {title}"
|
|
11
11
|
|
|
12
12
|
layerNotAvailable: "Layer not available"
|
|
13
|
+
childLayerNotAvailable: "A child layer is not available"
|
|
14
|
+
childLayerNotAvailableDetails: "The following child layers are not available:"
|
|
13
15
|
layerNotVisible: "Layer not visible in this scale"
|
|
14
16
|
|
|
15
17
|
toolsLabel: "Map tools"
|
package/model/TocApiImpl.js.map
CHANGED
|
@@ -1 +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":"
|
|
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\n\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":"AAMO,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;;;;"}
|
package/model/TocItemImpl.js.map
CHANGED
|
@@ -1 +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":";;
|
|
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\n\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":";;AAQO,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;;;;"}
|
package/model/TocModel.js.map
CHANGED
|
@@ -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 { 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":";;
|
|
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\n\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":";;AAkCO,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;;;;"}
|
package/model/context.js.map
CHANGED
|
@@ -1 +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":";;
|
|
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\n\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":";;AAMA,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;;;;"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@open-pioneer/toc",
|
|
4
|
-
"version": "1.4.0
|
|
4
|
+
"version": "1.4.0",
|
|
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,17 +14,18 @@
|
|
|
14
14
|
"directory": "src/packages/toc"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@chakra-ui/react": "^3.36.
|
|
18
|
-
"@open-pioneer/react-utils": "4.7.0-dev.20260624141040",
|
|
19
|
-
"@open-pioneer/runtime": "4.7.0-dev.20260624141040",
|
|
20
|
-
"ol": "^10.9.0",
|
|
21
|
-
"react": "^19.2.7",
|
|
22
|
-
"react-icons": "^5.6.0",
|
|
23
|
-
"@open-pioneer/reactivity": "4.7.0-dev.20260624141040",
|
|
17
|
+
"@chakra-ui/react": "^3.36.1",
|
|
24
18
|
"@conterra/reactivity-core": "^0.8.6",
|
|
25
|
-
"@open-pioneer/chakra-snippets": "4.7.0
|
|
26
|
-
"@open-pioneer/
|
|
27
|
-
"@open-pioneer/
|
|
19
|
+
"@open-pioneer/chakra-snippets": "^4.7.0",
|
|
20
|
+
"@open-pioneer/core": "^4.7.0",
|
|
21
|
+
"@open-pioneer/react-utils": "^4.7.0",
|
|
22
|
+
"@open-pioneer/reactivity": "^4.7.0",
|
|
23
|
+
"@open-pioneer/runtime": "^4.7.0",
|
|
24
|
+
"ol": "^10.9.0",
|
|
25
|
+
"react": "^19.2.8",
|
|
26
|
+
"react-icons": "^5.7.0",
|
|
27
|
+
"@open-pioneer/basemap-switcher": "1.4.0",
|
|
28
|
+
"@open-pioneer/map": "1.4.0"
|
|
28
29
|
},
|
|
29
30
|
"exports": {
|
|
30
31
|
"./package.json": "./package.json",
|
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { Box, Flex, Text, Spacer, Collapsible, CollapsibleContent, IconButton, Icon } from '@chakra-ui/react';
|
|
3
|
-
import { Checkbox } from '@open-pioneer/chakra-snippets/checkbox';
|
|
1
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { Box, Flex, Checkbox, Text, VisuallyHidden, Spacer, Collapsible, CollapsibleContent, IconButton, Icon, List } from '@chakra-ui/react';
|
|
4
3
|
import { Tooltip } from '@open-pioneer/chakra-snippets/tooltip';
|
|
5
|
-
import { useReactiveSnapshot } from '@open-pioneer/reactivity';
|
|
6
4
|
import { classNames } from '@open-pioneer/react-utils';
|
|
5
|
+
import { useReactiveSnapshot } from '@open-pioneer/reactivity';
|
|
7
6
|
import { useIntl } from '../../_virtual/hooks.js';
|
|
8
|
-
import { memo, useId,
|
|
7
|
+
import { memo, useId, useRef, useMemo, useEffect } from 'react';
|
|
9
8
|
import { LuTriangleAlert, LuInfo, LuChevronDown, LuChevronRight } from 'react-icons/lu';
|
|
10
9
|
import { useTocModel } from '../../model/context.js';
|
|
11
10
|
import { TocItemImpl } from '../../model/TocItemImpl.js';
|
|
12
11
|
import '@conterra/reactivity-core';
|
|
12
|
+
import { displayItemForLayer } from '../../utils/displayLayer.js';
|
|
13
13
|
import { slug } from '../../utils/slug.js';
|
|
14
|
-
import { useLoadState, useVisibleInScale, useChildLayers } from './hooks.js';
|
|
14
|
+
import { useLoadState, useSublayerError, useVisibleInScale, useChildLayers } from './hooks.js';
|
|
15
15
|
import { LayerItemMenu } from './LayerItemMenu.js';
|
|
16
16
|
import { LayerList } from './LayerList.js';
|
|
17
|
-
import { displayItemForLayer } from '../../utils/displayLayer.js';
|
|
18
17
|
|
|
19
18
|
const LayerItem = memo(function LayerItem2(props) {
|
|
20
19
|
const { layer } = props;
|
|
@@ -34,14 +33,11 @@ const LayerItem = memo(function LayerItem2(props) {
|
|
|
34
33
|
//re-evaluates if a child layer's list mode or internal state changes
|
|
35
34
|
};
|
|
36
35
|
}, [layer]);
|
|
37
|
-
const { problemIndicator, problemLabel, disabled, opacity } = useItemProblem(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
return label;
|
|
44
|
-
}, [title, problemLabel]);
|
|
36
|
+
const { problemIndicator, problemLabel, disabled, opacity } = useItemProblem(
|
|
37
|
+
layer,
|
|
38
|
+
intl,
|
|
39
|
+
listMode
|
|
40
|
+
);
|
|
45
41
|
const nestedChildren = useNestedChildren(layerGroupId, title, layer, intl);
|
|
46
42
|
let hasNestedChildren = !!nestedChildren;
|
|
47
43
|
if (allChildrenHidden || listMode === "hide-children") {
|
|
@@ -78,10 +74,9 @@ const LayerItem = memo(function LayerItem2(props) {
|
|
|
78
74
|
hasNestedChildren
|
|
79
75
|
}
|
|
80
76
|
),
|
|
81
|
-
/* @__PURE__ */
|
|
82
|
-
Checkbox,
|
|
77
|
+
/* @__PURE__ */ jsxs(
|
|
78
|
+
Checkbox.Root,
|
|
83
79
|
{
|
|
84
|
-
"aria-label": ariaLabel,
|
|
85
80
|
checked: isVisible,
|
|
86
81
|
disabled,
|
|
87
82
|
onCheckedChange: (event) => updateLayerVisibility(
|
|
@@ -89,7 +84,14 @@ const LayerItem = memo(function LayerItem2(props) {
|
|
|
89
84
|
event.checked === true,
|
|
90
85
|
tocOptions.autoShowParents
|
|
91
86
|
),
|
|
92
|
-
children:
|
|
87
|
+
children: [
|
|
88
|
+
/* @__PURE__ */ jsx(Checkbox.HiddenInput, {}),
|
|
89
|
+
/* @__PURE__ */ jsx(Checkbox.Control, { children: /* @__PURE__ */ jsx(Checkbox.Indicator, {}) }),
|
|
90
|
+
/* @__PURE__ */ jsxs(Checkbox.Label, { children: [
|
|
91
|
+
/* @__PURE__ */ jsx(Text, { as: "span", opacity, children: title }),
|
|
92
|
+
/* @__PURE__ */ jsx(VisuallyHidden, { as: "div", children: problemLabel })
|
|
93
|
+
] })
|
|
94
|
+
]
|
|
93
95
|
}
|
|
94
96
|
),
|
|
95
97
|
problemIndicator,
|
|
@@ -139,7 +141,7 @@ function ProblemIndicator(props) {
|
|
|
139
141
|
content: message,
|
|
140
142
|
positioning: { placement: "right" },
|
|
141
143
|
contentProps: { className: "toc-layer-item-problem-indicator-tooltip" },
|
|
142
|
-
children: /* @__PURE__ */ jsx("span", { className: "toc-layer-item-problem-indicator", children: /* @__PURE__ */ jsx(Icon2, { "aria-
|
|
144
|
+
children: /* @__PURE__ */ jsx("span", { className: "toc-layer-item-problem-indicator", children: /* @__PURE__ */ jsx(Icon2, { "aria-hidden": true, color }) })
|
|
143
145
|
}
|
|
144
146
|
);
|
|
145
147
|
}
|
|
@@ -163,19 +165,23 @@ function useTocItem(layer, display) {
|
|
|
163
165
|
}, [tocModel, tocItem, display]);
|
|
164
166
|
return [tocItem, tocModel, options, tocItemElemRef];
|
|
165
167
|
}
|
|
166
|
-
function useItemProblem(layer, intl) {
|
|
167
|
-
const
|
|
168
|
+
function useItemProblem(layer, intl, listMode) {
|
|
169
|
+
const loadState = useLoadState(layer);
|
|
170
|
+
const sublayerError = useSublayerError(layer);
|
|
168
171
|
const visibleInScale = useVisibleInScale(layer);
|
|
172
|
+
const isOwnError = loadState === "error";
|
|
173
|
+
const hasChildError = !!sublayerError;
|
|
169
174
|
return useMemo(() => {
|
|
170
175
|
let problemIndicator;
|
|
171
176
|
let problemLabel;
|
|
172
177
|
let opacity;
|
|
173
178
|
let disabled;
|
|
174
|
-
if (
|
|
175
|
-
const label = intl
|
|
176
|
-
|
|
179
|
+
if (isOwnError || hasChildError) {
|
|
180
|
+
const label = getProblemLabel(intl, isOwnError, listMode, sublayerError);
|
|
181
|
+
const color = isOwnError ? "red" : "orange";
|
|
182
|
+
problemIndicator = /* @__PURE__ */ jsx(ProblemIndicator, { message: label, Icon: LuTriangleAlert, color });
|
|
177
183
|
problemLabel = label;
|
|
178
|
-
disabled =
|
|
184
|
+
disabled = isOwnError;
|
|
179
185
|
} else if (!visibleInScale) {
|
|
180
186
|
const label = intl.formatMessage({ id: "layerNotVisible" });
|
|
181
187
|
problemIndicator = /* @__PURE__ */ jsx(ProblemIndicator, { message: label, Icon: LuInfo });
|
|
@@ -183,7 +189,22 @@ function useItemProblem(layer, intl) {
|
|
|
183
189
|
opacity = 0.5;
|
|
184
190
|
}
|
|
185
191
|
return { problemIndicator, problemLabel, opacity, disabled };
|
|
186
|
-
}, [
|
|
192
|
+
}, [isOwnError, hasChildError, visibleInScale, intl, listMode, sublayerError]);
|
|
193
|
+
}
|
|
194
|
+
function getProblemLabel(intl, isOwnError, listMode, sublayerError) {
|
|
195
|
+
if (isOwnError) {
|
|
196
|
+
return intl.formatMessage({ id: "layerNotAvailable" });
|
|
197
|
+
}
|
|
198
|
+
if (listMode === "hide-children" && sublayerError) {
|
|
199
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
200
|
+
/* @__PURE__ */ jsx(Text, { children: intl.formatMessage({ id: "childLayerNotAvailableDetails" }) }),
|
|
201
|
+
/* @__PURE__ */ jsx(List.Root, { ml: 2, children: sublayerError.errors.map((error, index) => (
|
|
202
|
+
// oxlint-disable-next-line react/no-array-index-key
|
|
203
|
+
/* @__PURE__ */ jsx(List.Item, { children: error.message }, index)
|
|
204
|
+
)) })
|
|
205
|
+
] });
|
|
206
|
+
}
|
|
207
|
+
return intl.formatMessage({ id: "childLayerNotAvailable" });
|
|
187
208
|
}
|
|
188
209
|
function useListMode(layer) {
|
|
189
210
|
return useReactiveSnapshot(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LayerItem.js","sources":["LayerItem.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n Box,\n Collapsible,\n CollapsibleContent,\n Flex,\n Icon,\n IconButton,\n Spacer,\n Text\n} from \"@chakra-ui/react\";\nimport { Checkbox } from \"@open-pioneer/chakra-snippets/checkbox\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { AnyLayer } from \"@open-pioneer/map\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport { classNames } from \"@open-pioneer/react-utils\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { memo, ReactNode, useEffect, useId, useMemo, useRef } from \"react\";\nimport { LuTriangleAlert, LuChevronDown, LuChevronRight, LuInfo } from \"react-icons/lu\";\nimport { TocItemImpl, useTocModel } from \"../../model/\";\nimport { slug } from \"../../utils/slug\";\nimport { useChildLayers, useLoadState, useVisibleInScale } from \"./hooks\";\nimport { LayerItemMenu } from \"./LayerItemMenu\";\nimport { LayerList } from \"./LayerList\";\nimport { LayerTocAttributes } from \"../Toc\";\nimport { displayItemForLayer } from \"../../utils/displayLayer\";\nimport type { IconType } from \"react-icons/lib\";\n\n/**\n * Renders a single layer as a list item.\n *\n * The item may have further nested list items if there are sublayers present.\n */\nexport const LayerItem = memo(function LayerItem(props: { layer: AnyLayer }): ReactNode {\n const { layer } = props;\n\n const intl = useIntl();\n const display = useReactiveSnapshot(() => displayItemForLayer(layer), [layer]);\n const [tocItem, _tocModel, tocOptions, tocItemElemRef] = useTocItem(layer, display);\n const expanded = useReactiveSnapshot(() => tocItem.isExpanded, [tocItem]);\n const isCollapsible = tocOptions ? tocOptions.collapsibleGroups : false;\n\n const layerGroupId = useId();\n const listMode = useListMode(layer)?.listMode;\n const { title, description, isVisible, allChildrenHidden } = useReactiveSnapshot(() => {\n return {\n title: layer.title,\n description: layer.description,\n isVisible: layer.visible,\n allChildrenHidden: !hasShownChildren(layer) //re-evaluates if a child layer's list mode or internal state changes\n };\n }, [layer]);\n\n const { problemIndicator, problemLabel, disabled, opacity } = useItemProblem(layer, intl);\n const ariaLabel = useMemo(() => {\n let label = title;\n if (problemLabel) {\n label += \" \" + problemLabel;\n }\n return label;\n }, [title, problemLabel]);\n\n const nestedChildren = useNestedChildren(layerGroupId, title, layer, intl);\n //all children hidden => do not render collapse button and child entries\n let hasNestedChildren = !!nestedChildren;\n if (allChildrenHidden || listMode === \"hide-children\") {\n hasNestedChildren = false;\n }\n\n if (!display) {\n return null;\n }\n\n return (\n <Box\n as=\"li\"\n className={classNames(\"toc-layer-item\", getClassNameForLayer(layer))}\n ref={tocItemElemRef}\n >\n <Flex\n className=\"toc-layer-item-content\"\n width=\"100%\"\n flexDirection=\"row\"\n align=\"center\"\n justifyContent=\"space-between\"\n /** Gap to prevent bleeding of the buttons hover style into the layer title */\n gap={2}\n /** Aligned to the size of the (potential) menu button in LayerItemDescriptor */\n minHeight={10}\n >\n {isCollapsible && (\n <CollapseButton\n layerTitle={title}\n layerGroupId={layerGroupId}\n expanded={expanded}\n onClick={() => tocItem.setExpanded(!expanded)}\n hasNestedChildren={hasNestedChildren}\n />\n )}\n <Checkbox\n // Keyboard navigation jumps only to Checkboxes and uses the texts inside this DOM node.\n // The aria-labels of Tooltip and Icon is ignored by screen reader because they are no child element of the checkbox.\n // To consider the notAvailableLabel, an aria-label at the checkbox is necessary.\n aria-label={ariaLabel}\n checked={isVisible}\n disabled={disabled}\n onCheckedChange={(event) =>\n updateLayerVisibility(\n layer,\n event.checked === true,\n tocOptions.autoShowParents\n )\n }\n >\n <Text as=\"span\" opacity={opacity}>\n {title}\n </Text>\n </Checkbox>\n {problemIndicator}\n <Spacer />\n <LayerItemMenu layer={layer} title={title} description={description} intl={intl} />\n </Flex>\n {hasNestedChildren && (\n <Collapsible.Root open={expanded} className=\"toc-collapsible-item\">\n <CollapsibleContent>{nestedChildren}</CollapsibleContent>\n </Collapsible.Root>\n )}\n </Box>\n );\n});\n\nfunction CollapseButton(props: {\n layerTitle: string;\n layerGroupId: string;\n expanded: boolean;\n onClick: () => void;\n hasNestedChildren: boolean;\n}) {\n const { layerTitle, layerGroupId, expanded, onClick, hasNestedChildren } = props;\n const icon = expanded ? <LuChevronDown /> : <LuChevronRight />;\n const intl = useIntl();\n return (\n <IconButton\n variant=\"ghost\"\n borderRadius=\"full\"\n padding={0}\n className=\"toc-layer-item-collapse-button\"\n onClick={onClick}\n size=\"sm\"\n focusRingOffset=\"-2px\"\n aria-label={\n expanded\n ? intl.formatMessage({ id: \"group.collapse\" }, { title: layerTitle })\n : intl.formatMessage({ id: \"group.expand\" }, { title: layerTitle })\n }\n aria-expanded={expanded}\n aria-controls={layerGroupId}\n //use visible:hidden for layers without children for correct indent\n visibility={hasNestedChildren ? \"visible\" : \"hidden\"}\n css={{\n // Chakra theme adds a background to components with \"aria-expanded\" by default.\n \"&:is([aria-expanded='true']):not(:hover)\": {\n background: \"none\"\n }\n }}\n >\n <Icon>{icon}</Icon>\n </IconButton>\n );\n}\n\nfunction ProblemIndicator(props: { message: string; Icon: IconType; color?: string }) {\n const { message, Icon, color } = props;\n return (\n <Tooltip\n content={message}\n positioning={{ placement: \"right\" }}\n contentProps={{ className: \"toc-layer-item-problem-indicator-tooltip\" }}\n >\n <span className=\"toc-layer-item-problem-indicator\">\n <Icon aria-label={message} color={color} />\n </span>\n </Tooltip>\n );\n}\n\n// Creates a toc item and registers it with the shared toc model.\nfunction useTocItem(layer: AnyLayer, display: boolean) {\n const tocModel = useTocModel();\n const options = useReactiveSnapshot(() => tocModel.options, [tocModel]);\n const tocItemElemRef = useRef<HTMLDivElement>(null);\n const tocItem = useMemo((): TocItemImpl => {\n return new TocItemImpl(layer, tocModel, !options.initiallyCollapsed);\n }, [layer, options.initiallyCollapsed, tocModel]);\n\n // Register the item on the shared toc model\n useEffect(() => {\n if (!display) {\n return; //prevent registering if item is not displayed\n }\n tocItem.setHtmlElement(tocItemElemRef.current ?? undefined);\n tocModel.registerItem(tocItem);\n return () => {\n tocItem.setHtmlElement(undefined);\n tocModel.unregisterItem(tocItem);\n };\n }, [tocModel, tocItem, display]);\n\n return [tocItem, tocModel, options, tocItemElemRef] as const;\n}\n\nfunction useItemProblem(layer: AnyLayer, intl: PackageIntl) {\n const isAvailable = useLoadState(layer) !== \"error\";\n const visibleInScale = useVisibleInScale(layer);\n\n return useMemo(() => {\n let problemIndicator;\n let problemLabel;\n let opacity;\n let disabled;\n if (!isAvailable) {\n const label = intl.formatMessage({ id: \"layerNotAvailable\" });\n problemIndicator = (\n <ProblemIndicator message={label} Icon={LuTriangleAlert} color=\"red\" />\n );\n problemLabel = label;\n disabled = true;\n } else if (!visibleInScale) {\n const label = intl.formatMessage({ id: \"layerNotVisible\" });\n problemIndicator = <ProblemIndicator message={label} Icon={LuInfo} />;\n problemLabel = label;\n opacity = 0.5;\n }\n return { problemIndicator, problemLabel, opacity, disabled };\n }, [isAvailable, visibleInScale, intl]);\n}\n\nfunction useListMode(layer: AnyLayer): LayerTocAttributes | undefined {\n return useReactiveSnapshot(\n () => layer.attributes.toc as LayerTocAttributes | undefined,\n [layer]\n );\n}\n\nfunction useNestedChildren(\n layerGroupId: string,\n title: string,\n layer: AnyLayer,\n intl: PackageIntl\n) {\n const childLayers = useChildLayers(layer);\n const children = useMemo(() => {\n if (childLayers?.length) {\n return (\n <LayerList\n id={layerGroupId}\n layers={childLayers}\n ml={4}\n aria-label={intl.formatMessage({ id: \"childgroupLabel\" }, { title: title })}\n />\n );\n }\n return undefined;\n }, [layerGroupId, intl, title, childLayers]);\n return children;\n}\n\nfunction 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\nfunction getClassNameForLayer(layer: AnyLayer) {\n return `layer-${slug(layer.id)}`;\n}\n\n/**\n * Checks if at least on child layer of the given layer exists and should be displayed.\n * @returns true if at least one child layer's display mode is not `hide`\n */\nfunction hasShownChildren(layer: AnyLayer): boolean {\n if (!layer.children || layer.children.getItems().length === 0) {\n return false;\n } else {\n return layer.children.getItems().some((childLayer) => {\n const isDisplayed = displayItemForLayer(childLayer);\n return isDisplayed;\n });\n }\n}\n"],"names":["LayerItem","Icon"],"mappings":";;;;;;;;;;;;;;;;;;AAmCO,MAAM,SAAA,GAAY,IAAA,CAAK,SAASA,UAAAA,CAAU,KAAA,EAAuC;AACpF,EAAA,MAAM,EAAE,OAAM,GAAI,KAAA;AAElB,EAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,EAAA,MAAM,OAAA,GAAU,oBAAoB,MAAM,mBAAA,CAAoB,KAAK,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAC7E,EAAA,MAAM,CAAC,SAAS,SAAA,EAAW,UAAA,EAAY,cAAc,CAAA,GAAI,UAAA,CAAW,OAAO,OAAO,CAAA;AAClF,EAAA,MAAM,WAAW,mBAAA,CAAoB,MAAM,QAAQ,UAAA,EAAY,CAAC,OAAO,CAAC,CAAA;AACxE,EAAA,MAAM,aAAA,GAAgB,UAAA,GAAa,UAAA,CAAW,iBAAA,GAAoB,KAAA;AAElE,EAAA,MAAM,eAAe,KAAA,EAAM;AAC3B,EAAA,MAAM,QAAA,GAAW,WAAA,CAAY,KAAK,CAAA,EAAG,QAAA;AACrC,EAAA,MAAM,EAAE,KAAA,EAAO,WAAA,EAAa,WAAW,iBAAA,EAAkB,GAAI,oBAAoB,MAAM;AACnF,IAAA,OAAO;AAAA,MACH,OAAO,KAAA,CAAM,KAAA;AAAA,MACb,aAAa,KAAA,CAAM,WAAA;AAAA,MACnB,WAAW,KAAA,CAAM,OAAA;AAAA,MACjB,iBAAA,EAAmB,CAAC,gBAAA,CAAiB,KAAK;AAAA;AAAA,KAC9C;AAAA,EACJ,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEV,EAAA,MAAM,EAAE,kBAAkB,YAAA,EAAc,QAAA,EAAU,SAAQ,GAAI,cAAA,CAAe,OAAO,IAAI,CAAA;AACxF,EAAA,MAAM,SAAA,GAAY,QAAQ,MAAM;AAC5B,IAAA,IAAI,KAAA,GAAQ,KAAA;AACZ,IAAA,IAAI,YAAA,EAAc;AACd,MAAA,KAAA,IAAS,GAAA,GAAM,YAAA;AAAA,IACnB;AACA,IAAA,OAAO,KAAA;AAAA,EACX,CAAA,EAAG,CAAC,KAAA,EAAO,YAAY,CAAC,CAAA;AAExB,EAAA,MAAM,cAAA,GAAiB,iBAAA,CAAkB,YAAA,EAAc,KAAA,EAAO,OAAO,IAAI,CAAA;AAEzE,EAAA,IAAI,iBAAA,GAAoB,CAAC,CAAC,cAAA;AAC1B,EAAA,IAAI,iBAAA,IAAqB,aAAa,eAAA,EAAiB;AACnD,IAAA,iBAAA,GAAoB,KAAA;AAAA,EACxB;AAEA,EAAA,IAAI,CAAC,OAAA,EAAS;AACV,IAAA,OAAO,IAAA;AAAA,EACX;AAEA,EAAA,uBACI,IAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACG,EAAA,EAAG,IAAA;AAAA,MACH,SAAA,EAAW,UAAA,CAAW,gBAAA,EAAkB,oBAAA,CAAqB,KAAK,CAAC,CAAA;AAAA,MACnE,GAAA,EAAK,cAAA;AAAA,MAEL,QAAA,EAAA;AAAA,wBAAA,IAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACG,SAAA,EAAU,wBAAA;AAAA,YACV,KAAA,EAAM,MAAA;AAAA,YACN,aAAA,EAAc,KAAA;AAAA,YACd,KAAA,EAAM,QAAA;AAAA,YACN,cAAA,EAAe,eAAA;AAAA,YAEf,GAAA,EAAK,CAAA;AAAA,YAEL,SAAA,EAAW,EAAA;AAAA,YAEV,QAAA,EAAA;AAAA,cAAA,aAAA,oBACG,GAAA;AAAA,gBAAC,cAAA;AAAA,gBAAA;AAAA,kBACG,UAAA,EAAY,KAAA;AAAA,kBACZ,YAAA;AAAA,kBACA,QAAA;AAAA,kBACA,OAAA,EAAS,MAAM,OAAA,CAAQ,WAAA,CAAY,CAAC,QAAQ,CAAA;AAAA,kBAC5C;AAAA;AAAA,eACJ;AAAA,8BAEJ,GAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBAIG,YAAA,EAAY,SAAA;AAAA,kBACZ,OAAA,EAAS,SAAA;AAAA,kBACT,QAAA;AAAA,kBACA,eAAA,EAAiB,CAAC,KAAA,KACd,qBAAA;AAAA,oBACI,KAAA;AAAA,oBACA,MAAM,OAAA,KAAY,IAAA;AAAA,oBAClB,UAAA,CAAW;AAAA,mBACf;AAAA,kBAGJ,QAAA,kBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,EAAA,EAAG,MAAA,EAAO,SACX,QAAA,EAAA,KAAA,EACL;AAAA;AAAA,eACJ;AAAA,cACC,gBAAA;AAAA,kCACA,MAAA,EAAA,EAAO,CAAA;AAAA,8BACR,GAAA,CAAC,aAAA,EAAA,EAAc,KAAA,EAAc,KAAA,EAAc,aAA0B,IAAA,EAAY;AAAA;AAAA;AAAA,SACrF;AAAA,QACC,iBAAA,oBACG,GAAA,CAAC,WAAA,CAAY,IAAA,EAAZ,EAAiB,IAAA,EAAM,QAAA,EAAU,SAAA,EAAU,sBAAA,EACxC,QAAA,kBAAA,GAAA,CAAC,kBAAA,EAAA,EAAoB,QAAA,EAAA,cAAA,EAAe,CAAA,EACxC;AAAA;AAAA;AAAA,GAER;AAER,CAAC;AAED,SAAS,eAAe,KAAA,EAMrB;AACC,EAAA,MAAM,EAAE,UAAA,EAAY,YAAA,EAAc,QAAA,EAAU,OAAA,EAAS,mBAAkB,GAAI,KAAA;AAC3E,EAAA,MAAM,OAAO,QAAA,mBAAW,GAAA,CAAC,aAAA,EAAA,EAAc,CAAA,uBAAM,cAAA,EAAA,EAAe,CAAA;AAC5D,EAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,EAAA,uBACI,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACG,OAAA,EAAQ,OAAA;AAAA,MACR,YAAA,EAAa,MAAA;AAAA,MACb,OAAA,EAAS,CAAA;AAAA,MACT,SAAA,EAAU,gCAAA;AAAA,MACV,OAAA;AAAA,MACA,IAAA,EAAK,IAAA;AAAA,MACL,eAAA,EAAgB,MAAA;AAAA,MAChB,YAAA,EACI,WACM,IAAA,CAAK,aAAA,CAAc,EAAE,EAAA,EAAI,gBAAA,EAAiB,EAAG,EAAE,KAAA,EAAO,UAAA,EAAY,CAAA,GAClE,IAAA,CAAK,cAAc,EAAE,EAAA,EAAI,gBAAe,EAAG,EAAE,KAAA,EAAO,UAAA,EAAY,CAAA;AAAA,MAE1E,eAAA,EAAe,QAAA;AAAA,MACf,eAAA,EAAe,YAAA;AAAA,MAEf,UAAA,EAAY,oBAAoB,SAAA,GAAY,QAAA;AAAA,MAC5C,GAAA,EAAK;AAAA;AAAA,QAED,0CAAA,EAA4C;AAAA,UACxC,UAAA,EAAY;AAAA;AAChB,OACJ;AAAA,MAEA,QAAA,kBAAA,GAAA,CAAC,QAAM,QAAA,EAAA,IAAA,EAAK;AAAA;AAAA,GAChB;AAER;AAEA,SAAS,iBAAiB,KAAA,EAA4D;AAClF,EAAA,MAAM,EAAE,OAAA,EAAS,IAAA,EAAAC,KAAAA,EAAM,OAAM,GAAI,KAAA;AACjC,EAAA,uBACI,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACG,OAAA,EAAS,OAAA;AAAA,MACT,WAAA,EAAa,EAAE,SAAA,EAAW,OAAA,EAAQ;AAAA,MAClC,YAAA,EAAc,EAAE,SAAA,EAAW,0CAAA,EAA2C;AAAA,MAEtE,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kCAAA,EACZ,QAAA,kBAAA,GAAA,CAACA,OAAA,EAAK,YAAA,EAAY,OAAA,EAAS,KAAA,EAAc,CAAA,EAC7C;AAAA;AAAA,GACJ;AAER;AAGA,SAAS,UAAA,CAAW,OAAiB,OAAA,EAAkB;AACnD,EAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,EAAA,MAAM,UAAU,mBAAA,CAAoB,MAAM,SAAS,OAAA,EAAS,CAAC,QAAQ,CAAC,CAAA;AACtE,EAAA,MAAM,cAAA,GAAiB,OAAuB,IAAI,CAAA;AAClD,EAAA,MAAM,OAAA,GAAU,QAAQ,MAAmB;AACvC,IAAA,OAAO,IAAI,WAAA,CAAY,KAAA,EAAO,QAAA,EAAU,CAAC,QAAQ,kBAAkB,CAAA;AAAA,EACvE,GAAG,CAAC,KAAA,EAAO,OAAA,CAAQ,kBAAA,EAAoB,QAAQ,CAAC,CAAA;AAGhD,EAAA,SAAA,CAAU,MAAM;AACZ,IAAA,IAAI,CAAC,OAAA,EAAS;AACV,MAAA;AAAA,IACJ;AACA,IAAA,OAAA,CAAQ,cAAA,CAAe,cAAA,CAAe,OAAA,IAAW,MAAS,CAAA;AAC1D,IAAA,QAAA,CAAS,aAAa,OAAO,CAAA;AAC7B,IAAA,OAAO,MAAM;AACT,MAAA,OAAA,CAAQ,eAAe,MAAS,CAAA;AAChC,MAAA,QAAA,CAAS,eAAe,OAAO,CAAA;AAAA,IACnC,CAAA;AAAA,EACJ,CAAA,EAAG,CAAC,QAAA,EAAU,OAAA,EAAS,OAAO,CAAC,CAAA;AAE/B,EAAA,OAAO,CAAC,OAAA,EAAS,QAAA,EAAU,OAAA,EAAS,cAAc,CAAA;AACtD;AAEA,SAAS,cAAA,CAAe,OAAiB,IAAA,EAAmB;AACxD,EAAA,MAAM,WAAA,GAAc,YAAA,CAAa,KAAK,CAAA,KAAM,OAAA;AAC5C,EAAA,MAAM,cAAA,GAAiB,kBAAkB,KAAK,CAAA;AAE9C,EAAA,OAAO,QAAQ,MAAM;AACjB,IAAA,IAAI,gBAAA;AACJ,IAAA,IAAI,YAAA;AACJ,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI,CAAC,WAAA,EAAa;AACd,MAAA,MAAM,QAAQ,IAAA,CAAK,aAAA,CAAc,EAAE,EAAA,EAAI,qBAAqB,CAAA;AAC5D,MAAA,gBAAA,uBACK,gBAAA,EAAA,EAAiB,OAAA,EAAS,OAAO,IAAA,EAAM,eAAA,EAAiB,OAAM,KAAA,EAAM,CAAA;AAEzE,MAAA,YAAA,GAAe,KAAA;AACf,MAAA,QAAA,GAAW,IAAA;AAAA,IACf,CAAA,MAAA,IAAW,CAAC,cAAA,EAAgB;AACxB,MAAA,MAAM,QAAQ,IAAA,CAAK,aAAA,CAAc,EAAE,EAAA,EAAI,mBAAmB,CAAA;AAC1D,MAAA,gBAAA,mBAAmB,GAAA,CAAC,gBAAA,EAAA,EAAiB,OAAA,EAAS,KAAA,EAAO,MAAM,MAAA,EAAQ,CAAA;AACnE,MAAA,YAAA,GAAe,KAAA;AACf,MAAA,OAAA,GAAU,GAAA;AAAA,IACd;AACA,IAAA,OAAO,EAAE,gBAAA,EAAkB,YAAA,EAAc,OAAA,EAAS,QAAA,EAAS;AAAA,EAC/D,CAAA,EAAG,CAAC,WAAA,EAAa,cAAA,EAAgB,IAAI,CAAC,CAAA;AAC1C;AAEA,SAAS,YAAY,KAAA,EAAiD;AAClE,EAAA,OAAO,mBAAA;AAAA,IACH,MAAM,MAAM,UAAA,CAAW,GAAA;AAAA,IACvB,CAAC,KAAK;AAAA,GACV;AACJ;AAEA,SAAS,iBAAA,CACL,YAAA,EACA,KAAA,EACA,KAAA,EACA,IAAA,EACF;AACE,EAAA,MAAM,WAAA,GAAc,eAAe,KAAK,CAAA;AACxC,EAAA,MAAM,QAAA,GAAW,QAAQ,MAAM;AAC3B,IAAA,IAAI,aAAa,MAAA,EAAQ;AACrB,MAAA,uBACI,GAAA;AAAA,QAAC,SAAA;AAAA,QAAA;AAAA,UACG,EAAA,EAAI,YAAA;AAAA,UACJ,MAAA,EAAQ,WAAA;AAAA,UACR,EAAA,EAAI,CAAA;AAAA,UACJ,YAAA,EAAY,KAAK,aAAA,CAAc,EAAE,IAAI,iBAAA,EAAkB,EAAG,EAAE,KAAA,EAAc;AAAA;AAAA,OAC9E;AAAA,IAER;AACA,IAAA,OAAO,MAAA;AAAA,EACX,GAAG,CAAC,YAAA,EAAc,IAAA,EAAM,KAAA,EAAO,WAAW,CAAC,CAAA;AAC3C,EAAA,OAAO,QAAA;AACX;AAEA,SAAS,qBAAA,CAAsB,KAAA,EAAiB,OAAA,EAAkB,eAAA,EAA0B;AACxF,EAAA,KAAA,CAAM,WAAW,OAAO,CAAA;AACxB,EAAA,IAAI,OAAA,IAAW,eAAA,IAAmB,KAAA,CAAM,MAAA,EAAQ;AAC5C,IAAA,qBAAA,CAAsB,KAAA,CAAM,MAAA,EAAQ,IAAA,EAAM,IAAI,CAAA;AAAA,EAClD;AACJ;AAEA,SAAS,qBAAqB,KAAA,EAAiB;AAC3C,EAAA,OAAO,CAAA,MAAA,EAAS,IAAA,CAAK,KAAA,CAAM,EAAE,CAAC,CAAA,CAAA;AAClC;AAMA,SAAS,iBAAiB,KAAA,EAA0B;AAChD,EAAA,IAAI,CAAC,MAAM,QAAA,IAAY,KAAA,CAAM,SAAS,QAAA,EAAS,CAAE,WAAW,CAAA,EAAG;AAC3D,IAAA,OAAO,KAAA;AAAA,EACX,CAAA,MAAO;AACH,IAAA,OAAO,MAAM,QAAA,CAAS,QAAA,EAAS,CAAE,IAAA,CAAK,CAAC,UAAA,KAAe;AAClD,MAAA,MAAM,WAAA,GAAc,oBAAoB,UAAU,CAAA;AAClD,MAAA,OAAO,WAAA;AAAA,IACX,CAAC,CAAA;AAAA,EACL;AACJ;;;;"}
|
|
1
|
+
{"version":3,"file":"LayerItem.js","sources":["LayerItem.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n Box,\n Checkbox,\n Collapsible,\n CollapsibleContent,\n Flex,\n Icon,\n IconButton,\n List,\n Spacer,\n Text,\n VisuallyHidden,\n} from \"@chakra-ui/react\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { AnyLayer } from \"@open-pioneer/map\";\nimport { classNames } from \"@open-pioneer/react-utils\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { memo, ReactNode, useEffect, useId, useMemo, useRef } from \"react\";\nimport type { IconType } from \"react-icons/lib\";\nimport { LuChevronDown, LuChevronRight, LuInfo, LuTriangleAlert } from \"react-icons/lu\";\nimport { TocItemImpl, useTocModel } from \"../../model/\";\nimport { displayItemForLayer } from \"../../utils/displayLayer\";\nimport { slug } from \"../../utils/slug\";\nimport { LayerTocAttributes, ListMode } from \"../Toc\";\nimport { useChildLayers, useLoadState, useSublayerError, useVisibleInScale } from \"./hooks\";\nimport { LayerItemMenu } from \"./LayerItemMenu\";\nimport { LayerList } from \"./LayerList\";\n\n/**\n * Renders a single layer as a list item.\n *\n * The item may have further nested list items if there are sublayers present.\n */\nexport const LayerItem = memo(function LayerItem(props: { layer: AnyLayer }): ReactNode {\n const { layer } = props;\n\n const intl = useIntl();\n const display = useReactiveSnapshot(() => displayItemForLayer(layer), [layer]);\n const [tocItem, _tocModel, tocOptions, tocItemElemRef] = useTocItem(layer, display);\n const expanded = useReactiveSnapshot(() => tocItem.isExpanded, [tocItem]);\n const isCollapsible = tocOptions ? tocOptions.collapsibleGroups : false;\n\n const layerGroupId = useId();\n const listMode = useListMode(layer)?.listMode;\n const { title, description, isVisible, allChildrenHidden } = useReactiveSnapshot(() => {\n return {\n title: layer.title,\n description: layer.description,\n isVisible: layer.visible,\n allChildrenHidden: !hasShownChildren(layer), //re-evaluates if a child layer's list mode or internal state changes\n };\n }, [layer]);\n\n const { problemIndicator, problemLabel, disabled, opacity } = useItemProblem(\n layer,\n intl,\n listMode,\n );\n\n const nestedChildren = useNestedChildren(layerGroupId, title, layer, intl);\n //all children hidden => do not render collapse button and child entries\n let hasNestedChildren = !!nestedChildren;\n if (allChildrenHidden || listMode === \"hide-children\") {\n hasNestedChildren = false;\n }\n\n if (!display) {\n return null;\n }\n\n return (\n <Box\n as=\"li\"\n className={classNames(\"toc-layer-item\", getClassNameForLayer(layer))}\n ref={tocItemElemRef}\n >\n <Flex\n className=\"toc-layer-item-content\"\n width=\"100%\"\n flexDirection=\"row\"\n align=\"center\"\n justifyContent=\"space-between\"\n /** Gap to prevent bleeding of the buttons hover style into the layer title */\n gap={2}\n /** Aligned to the size of the (potential) menu button in LayerItemDescriptor */\n minHeight={10}\n >\n {isCollapsible && (\n <CollapseButton\n layerTitle={title}\n layerGroupId={layerGroupId}\n expanded={expanded}\n onClick={() => tocItem.setExpanded(!expanded)}\n hasNestedChildren={hasNestedChildren}\n />\n )}\n\n <Checkbox.Root\n checked={isVisible}\n disabled={disabled}\n onCheckedChange={(event) =>\n updateLayerVisibility(\n layer,\n event.checked === true,\n tocOptions.autoShowParents,\n )\n }\n >\n <Checkbox.HiddenInput />\n <Checkbox.Control>\n <Checkbox.Indicator />\n </Checkbox.Control>\n <Checkbox.Label>\n <Text as=\"span\" opacity={opacity}>\n {title}\n </Text>\n {/* Same content as tooltip */}\n <VisuallyHidden as=\"div\">{problemLabel}</VisuallyHidden>\n </Checkbox.Label>\n </Checkbox.Root>\n {problemIndicator}\n <Spacer />\n <LayerItemMenu layer={layer} title={title} description={description} intl={intl} />\n </Flex>\n {hasNestedChildren && (\n <Collapsible.Root open={expanded} className=\"toc-collapsible-item\">\n <CollapsibleContent>{nestedChildren}</CollapsibleContent>\n </Collapsible.Root>\n )}\n </Box>\n );\n});\n\nfunction CollapseButton(props: {\n layerTitle: string;\n layerGroupId: string;\n expanded: boolean;\n onClick: () => void;\n hasNestedChildren: boolean;\n}) {\n const { layerTitle, layerGroupId, expanded, onClick, hasNestedChildren } = props;\n const icon = expanded ? <LuChevronDown /> : <LuChevronRight />;\n const intl = useIntl();\n return (\n <IconButton\n variant=\"ghost\"\n borderRadius=\"full\"\n padding={0}\n className=\"toc-layer-item-collapse-button\"\n onClick={onClick}\n size=\"sm\"\n focusRingOffset=\"-2px\"\n aria-label={\n expanded\n ? intl.formatMessage({ id: \"group.collapse\" }, { title: layerTitle })\n : intl.formatMessage({ id: \"group.expand\" }, { title: layerTitle })\n }\n aria-expanded={expanded}\n aria-controls={layerGroupId}\n //use visible:hidden for layers without children for correct indent\n visibility={hasNestedChildren ? \"visible\" : \"hidden\"}\n css={{\n // Chakra theme adds a background to components with \"aria-expanded\" by default.\n \"&:is([aria-expanded='true']):not(:hover)\": {\n background: \"none\",\n },\n }}\n >\n <Icon>{icon}</Icon>\n </IconButton>\n );\n}\n\nfunction ProblemIndicator(props: { message: ReactNode; Icon: IconType; color?: string }) {\n const { message, Icon, color } = props;\n return (\n <Tooltip\n content={message}\n positioning={{ placement: \"right\" }}\n contentProps={{ className: \"toc-layer-item-problem-indicator-tooltip\" }}\n >\n <span className=\"toc-layer-item-problem-indicator\">\n {/* aria-hidden: layer item has an aria label that includes the problem as well */}\n <Icon aria-hidden={true} color={color} />\n </span>\n </Tooltip>\n );\n}\n\n// Creates a toc item and registers it with the shared toc model.\nfunction useTocItem(layer: AnyLayer, display: boolean) {\n const tocModel = useTocModel();\n const options = useReactiveSnapshot(() => tocModel.options, [tocModel]);\n const tocItemElemRef = useRef<HTMLDivElement>(null);\n const tocItem = useMemo((): TocItemImpl => {\n return new TocItemImpl(layer, tocModel, !options.initiallyCollapsed);\n }, [layer, options.initiallyCollapsed, tocModel]);\n\n // Register the item on the shared toc model\n useEffect(() => {\n if (!display) {\n return; //prevent registering if item is not displayed\n }\n tocItem.setHtmlElement(tocItemElemRef.current ?? undefined);\n tocModel.registerItem(tocItem);\n return () => {\n tocItem.setHtmlElement(undefined);\n tocModel.unregisterItem(tocItem);\n };\n }, [tocModel, tocItem, display]);\n\n return [tocItem, tocModel, options, tocItemElemRef] as const;\n}\n\nfunction useItemProblem(layer: AnyLayer, intl: PackageIntl, listMode: ListMode | undefined) {\n const loadState = useLoadState(layer);\n const sublayerError = useSublayerError(layer);\n const visibleInScale = useVisibleInScale(layer);\n const isOwnError = loadState === \"error\";\n const hasChildError = !!sublayerError;\n\n return useMemo(() => {\n let problemIndicator;\n let problemLabel;\n let opacity;\n let disabled;\n if (isOwnError || hasChildError) {\n const label = getProblemLabel(intl, isOwnError, listMode, sublayerError);\n const color = isOwnError ? \"red\" : \"orange\";\n problemIndicator = (\n <ProblemIndicator message={label} Icon={LuTriangleAlert} color={color} />\n );\n problemLabel = label;\n // Only disable the checkbox for the layer that is the actual source\n // of the error, so a group with a broken child can still be toggled.\n disabled = isOwnError;\n } else if (!visibleInScale) {\n const label = intl.formatMessage({ id: \"layerNotVisible\" });\n problemIndicator = <ProblemIndicator message={label} Icon={LuInfo} />;\n problemLabel = label;\n opacity = 0.5;\n }\n return { problemIndicator, problemLabel, opacity, disabled };\n }, [isOwnError, hasChildError, visibleInScale, intl, listMode, sublayerError]);\n}\n\n/**\n * Builds the message shown in the problem indicator.\n *\n * When the layer's own load state is in error, a generic message is used.\n * If the list mode is \"hide-children\" the aggregated sublayer errors are listed so the user can\n * still see which children failed, since their own indicators are not rendered.\n */\nfunction getProblemLabel(\n intl: PackageIntl,\n isOwnError: boolean,\n listMode: ListMode | undefined,\n sublayerError: AggregateError | undefined,\n): ReactNode {\n if (isOwnError) {\n return intl.formatMessage({ id: \"layerNotAvailable\" });\n }\n if (listMode === \"hide-children\" && sublayerError) {\n return (\n <>\n <Text>{intl.formatMessage({ id: \"childLayerNotAvailableDetails\" })}</Text>\n <List.Root ml={2}>\n {sublayerError.errors.map((error: Error, index) => (\n // oxlint-disable-next-line react/no-array-index-key\n <List.Item key={index}>{error.message}</List.Item>\n ))}\n </List.Root>\n </>\n );\n }\n return intl.formatMessage({ id: \"childLayerNotAvailable\" });\n}\n\nfunction useListMode(layer: AnyLayer): LayerTocAttributes | undefined {\n return useReactiveSnapshot(\n () => layer.attributes.toc as LayerTocAttributes | undefined,\n [layer],\n );\n}\n\nfunction useNestedChildren(\n layerGroupId: string,\n title: string,\n layer: AnyLayer,\n intl: PackageIntl,\n) {\n const childLayers = useChildLayers(layer);\n const children = useMemo(() => {\n if (childLayers?.length) {\n return (\n <LayerList\n id={layerGroupId}\n layers={childLayers}\n ml={4}\n aria-label={intl.formatMessage({ id: \"childgroupLabel\" }, { title: title })}\n />\n );\n }\n return undefined;\n }, [layerGroupId, intl, title, childLayers]);\n return children;\n}\n\nfunction 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\nfunction getClassNameForLayer(layer: AnyLayer) {\n return `layer-${slug(layer.id)}`;\n}\n\n/**\n * Checks if at least on child layer of the given layer exists and should be displayed.\n * @returns true if at least one child layer's display mode is not `hide`\n */\nfunction hasShownChildren(layer: AnyLayer): boolean {\n if (!layer.children || layer.children.getItems().length === 0) {\n return false;\n } else {\n return layer.children.getItems().some((childLayer) => {\n const isDisplayed = displayItemForLayer(childLayer);\n return isDisplayed;\n });\n }\n}\n"],"names":["LayerItem","Icon"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LayerItemMenu.js","sources":["LayerItemMenu.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { CloseButton, Icon, IconButton, Popover, Portal, Text } from \"@chakra-ui/react\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { AnyLayer } from \"@open-pioneer/map\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useId } from \"react\";\nimport { LuEllipsisVertical } from \"react-icons/lu\";\nimport { useLoadState } from \"./hooks\";\n\nexport function LayerItemMenu(props: {\n layer: AnyLayer;\n title: string;\n description: string;\n intl: PackageIntl;\n}) {\n const { layer, title, description } = props;\n const isPresent = !!description;\n\n const triggerId = useId(); // see https://chakra-ui.com/docs/components/tooltip#with-menutrigger\n\n return (\n isPresent && (\n <Popover.Root\n ids={{ trigger: triggerId }}\n positioning={{ placement: \"bottom-start\" }}\n lazyMount={true}\n unmountOnExit={true}\n >\n <TriggerButton triggerId={triggerId} layer={layer} />\n <Portal>\n <Popover.Positioner>\n <Popover.Content\n className=\"toc-layer-item-details\"\n overflowY=\"auto\"\n maxHeight=\"400\"\n >\n <Popover.Arrow
|
|
1
|
+
{"version":3,"file":"LayerItemMenu.js","sources":["LayerItemMenu.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { CloseButton, Icon, IconButton, Popover, Portal, Text } from \"@chakra-ui/react\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { AnyLayer } from \"@open-pioneer/map\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useId } from \"react\";\nimport { LuEllipsisVertical } from \"react-icons/lu\";\nimport { useLoadState } from \"./hooks\";\n\nexport function LayerItemMenu(props: {\n layer: AnyLayer;\n title: string;\n description: string;\n intl: PackageIntl;\n}) {\n const { layer, title, description } = props;\n const isPresent = !!description;\n\n const triggerId = useId(); // see https://chakra-ui.com/docs/components/tooltip#with-menutrigger\n\n return (\n isPresent && (\n <Popover.Root\n ids={{ trigger: triggerId }}\n positioning={{ placement: \"bottom-start\" }}\n lazyMount={true}\n unmountOnExit={true}\n >\n <TriggerButton triggerId={triggerId} layer={layer} />\n <Portal>\n <Popover.Positioner>\n <Popover.Content\n className=\"toc-layer-item-details\"\n overflowY=\"auto\"\n maxHeight=\"400\"\n >\n <Popover.Arrow />\n <Popover.Body>\n <Popover.Title className=\"toc-layer-item-details-title\">\n {title}\n </Popover.Title>\n <Text my=\"2\" className=\"toc-layer-item-details-description\">\n {description}\n </Text>\n </Popover.Body>\n <Popover.CloseTrigger position=\"absolute\" top=\"1\" right=\"1\" asChild>\n <CloseButton\n className=\"toc-layer-item-details-button\"\n variant=\"ghost\"\n size=\"sm\"\n />\n </Popover.CloseTrigger>\n </Popover.Content>\n </Popover.Positioner>\n </Portal>\n </Popover.Root>\n )\n );\n}\n\nfunction TriggerButton(props: { triggerId: string; layer: AnyLayer }) {\n const { layer, triggerId } = props;\n const intl = useIntl();\n const buttonLabel = intl.formatMessage({ id: \"descriptionLabel\" });\n const isAvailable = useLoadState(layer) !== \"error\";\n\n return (\n <Tooltip ids={{ trigger: triggerId }} content={buttonLabel}>\n <Popover.Trigger asChild>\n <IconButton\n disabled={!isAvailable}\n className=\"toc-layer-item-details-button\"\n aria-label={buttonLabel}\n borderRadius=\"full\"\n focusRingOffset=\"-2px\"\n variant=\"ghost\"\n size=\"sm\"\n >\n <Icon>\n <LuEllipsisVertical spacing={0} />\n </Icon>\n </IconButton>\n </Popover.Trigger>\n </Tooltip>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { List, Text } from '@chakra-ui/react';
|
|
3
|
+
import { useReactiveSnapshot } from '@open-pioneer/reactivity';
|
|
3
4
|
import { useIntl } from '../../_virtual/hooks.js';
|
|
4
5
|
import { memo, useMemo } from 'react';
|
|
5
|
-
import { LayerItem } from './LayerItem.js';
|
|
6
|
-
import { useLayers } from './hooks.js';
|
|
7
6
|
import { displayItemForLayer } from '../../utils/displayLayer.js';
|
|
8
|
-
import {
|
|
7
|
+
import { useLayers } from './hooks.js';
|
|
8
|
+
import { LayerItem } from './LayerItem.js';
|
|
9
9
|
|
|
10
10
|
const TopLevelLayerList = memo(function TopLevelLayerList2(props) {
|
|
11
11
|
const { map, "aria-label": ariaLabel } = props;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LayerList.js","sources":["LayerList.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { List, ListRootProps, Text } from \"@chakra-ui/react\";\nimport { AnyLayer, MapModel, Layer } from \"@open-pioneer/map\";\nimport {
|
|
1
|
+
{"version":3,"file":"LayerList.js","sources":["LayerList.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { List, ListRootProps, Text } from \"@chakra-ui/react\";\nimport { AnyLayer, MapModel, Layer } from \"@open-pioneer/map\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { memo, useMemo } from \"react\";\nimport { displayItemForLayer } from \"../../utils/displayLayer\";\nimport { useLayers } from \"./hooks\";\nimport { LayerItem } from \"./LayerItem\";\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 const empty = useReactiveSnapshot(() => isEmpty(layers), [layers]);\n if (empty) {\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[] } & ListRootProps) {\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 <List.Root\n // Note: not using UnorderedList because it adds default margins\n as=\"ul\"\n className=\"toc-layer-list\"\n listStyleType=\"none\"\n {...listProps}\n >\n {items}\n </List.Root>\n );\n});\n\n/**\n * Checks if there is any layer that should be displayed in the Toc\n */\nfunction isEmpty(layers: Layer[]): boolean {\n const isEmpty = !layers.length || layers.every((l) => !displayItemForLayer(l));\n\n return isEmpty;\n}\n"],"names":["TopLevelLayerList","LayerList","isEmpty"],"mappings":";;;;;;;;;AAsBO,MAAM,iBAAA,GAAoB,IAAA,CAAK,SAASA,kBAAAA,CAAkB,KAAA,EAA+B;AAC5F,EAAA,MAAM,EAAE,GAAA,EAAK,YAAA,EAAc,SAAA,EAAU,GAAI,KAAA;AACzC,EAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,EAAA,MAAM,MAAA,GAAS,UAAU,GAAG,CAAA;AAC5B,EAAA,MAAM,KAAA,GAAQ,oBAAoB,MAAM,OAAA,CAAQ,MAAM,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AACjE,EAAA,IAAI,KAAA,EAAO;AACP,IAAA,uBACI,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,oBAAA,EAAqB,YAAA,EAAY,SAAA,EAC5C,QAAA,EAAA,IAAA,CAAK,aAAA,CAAc,EAAE,EAAA,EAAI,eAAA,EAAiB,CAAA,EAC/C,CAAA;AAAA,EAER;AAEA,EAAA,uBAAO,GAAA,CAAC,SAAA,EAAA,EAAU,MAAA,EAAgB,YAAA,EAAY,SAAA,EAAW,CAAA;AAC7D,CAAC;AAKM,MAAM,SAAA,GAAY,IAAA,CAAK,SAASC,UAAAA,CAAU,KAAA,EAA+C;AAC5F,EAAA,MAAM,EAAE,MAAA,EAAQ,GAAG,SAAA,EAAU,GAAI,KAAA;AACjC,EAAA,MAAM,KAAA,GAAQ,OAAA;AAAA,IACV,MAAM,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,yBAAW,SAAA,EAAA,EAAyB,KAAA,EAAA,EAAV,KAAA,CAAM,EAAkB,CAAE,CAAA;AAAA,IACtE,CAAC,MAAM;AAAA,GACX;AAEA,EAAA,uBACI,GAAA;AAAA,IAAC,IAAA,CAAK,IAAA;AAAA,IAAL;AAAA,MAEG,EAAA,EAAG,IAAA;AAAA,MACH,SAAA,EAAU,gBAAA;AAAA,MACV,aAAA,EAAc,MAAA;AAAA,MACb,GAAG,SAAA;AAAA,MAEH,QAAA,EAAA;AAAA;AAAA,GACL;AAER,CAAC;AAKD,SAAS,QAAQ,MAAA,EAA0B;AACvC,EAAA,MAAMC,QAAAA,GAAU,CAAC,MAAA,CAAO,MAAA,IAAU,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA,KAAM,CAAC,mBAAA,CAAoB,CAAC,CAAC,CAAA;AAE7E,EAAA,OAAOA,QAAAA;AACX;;;;"}
|
package/ui/LayerList/hooks.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AnyLayer, Layer, MapModel } from "@open-pioneer/map";
|
|
1
|
+
import { AnyLayer, Layer, LayerLoadState, MapModel } from "@open-pioneer/map";
|
|
2
2
|
/** Returns the top level operational layers in render order (topmost layer first). */
|
|
3
3
|
export declare function useLayers(map: MapModel): Layer[];
|
|
4
4
|
/**
|
|
@@ -6,7 +6,11 @@ export declare function useLayers(map: MapModel): Layer[];
|
|
|
6
6
|
* Layers are returned in render order (topmost sublayer first).
|
|
7
7
|
*/
|
|
8
8
|
export declare function useChildLayers(layer: AnyLayer): AnyLayer[] | undefined;
|
|
9
|
-
|
|
10
|
-
export declare function useLoadState(layer: AnyLayer): string;
|
|
9
|
+
export declare function useLoadState(layer: AnyLayer): LayerLoadState;
|
|
11
10
|
/** Returns the layers current visibility. */
|
|
12
11
|
export declare function useVisibleInScale(layer: AnyLayer): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Returns the combined errors of all descendants
|
|
14
|
+
* or `undefined` if no descendant is in an error state.
|
|
15
|
+
*/
|
|
16
|
+
export declare function useSublayerError(layer: AnyLayer): AggregateError | undefined;
|
package/ui/LayerList/hooks.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { computed } from '@conterra/reactivity-core';
|
|
2
|
+
import { shallowEqual } from '@open-pioneer/core';
|
|
3
|
+
import { isLayer, isSublayer } from '@open-pioneer/map';
|
|
2
4
|
import { useReactiveSnapshot } from '@open-pioneer/reactivity';
|
|
5
|
+
import { useMemo } from 'react';
|
|
3
6
|
|
|
4
7
|
function useLayers(map) {
|
|
5
8
|
return useReactiveSnapshot(() => {
|
|
@@ -24,10 +27,7 @@ function useChildLayers(layer) {
|
|
|
24
27
|
}, [layer]);
|
|
25
28
|
}
|
|
26
29
|
function useLoadState(layer) {
|
|
27
|
-
return useReactiveSnapshot(() =>
|
|
28
|
-
const target = isSublayer(layer) ? layer.parentLayer : layer;
|
|
29
|
-
return target.loadState;
|
|
30
|
-
}, [layer]);
|
|
30
|
+
return useReactiveSnapshot(() => ownLoadState(layer), [layer]);
|
|
31
31
|
}
|
|
32
32
|
function useVisibleInScale(layer) {
|
|
33
33
|
return useReactiveSnapshot(() => {
|
|
@@ -35,6 +35,67 @@ function useVisibleInScale(layer) {
|
|
|
35
35
|
return target.visibleInScale;
|
|
36
36
|
}, [layer]);
|
|
37
37
|
}
|
|
38
|
+
function useSublayerError(layer) {
|
|
39
|
+
const sublayerError = useMemo(
|
|
40
|
+
() => computed(() => isLayer(layer) ? collectSublayerError(layer) : void 0, {
|
|
41
|
+
equal: sublayerErrorsEqual
|
|
42
|
+
}),
|
|
43
|
+
[layer]
|
|
44
|
+
);
|
|
45
|
+
return useReactiveSnapshot(() => sublayerError.value, [sublayerError]);
|
|
46
|
+
}
|
|
47
|
+
function collectSublayerError(layer) {
|
|
48
|
+
const errors = [];
|
|
49
|
+
for (const descendant of walkDescendants(layer)) {
|
|
50
|
+
const error = descendant.loadError;
|
|
51
|
+
if (error) {
|
|
52
|
+
errors.push(error);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (errors.length === 0) {
|
|
56
|
+
return void 0;
|
|
57
|
+
}
|
|
58
|
+
return new AggregateError(
|
|
59
|
+
errors,
|
|
60
|
+
`Layer '${layer.id}' has ${errors.length} sublayer(s) in error state`
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
function* walkDescendants(layer) {
|
|
64
|
+
const children = layer.children?.getItems({ includeInternalLayers: true });
|
|
65
|
+
if (!children) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
for (const child of children) {
|
|
69
|
+
yield child;
|
|
70
|
+
yield* walkDescendants(child);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function sublayerErrorsEqual(a, b) {
|
|
74
|
+
if (a === b) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
if (!a || !b) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
const aErrors = a.errors;
|
|
81
|
+
const bErrors = b.errors;
|
|
82
|
+
return shallowEqual(aErrors, bErrors);
|
|
83
|
+
}
|
|
84
|
+
function ownLoadState(layer) {
|
|
85
|
+
if (isSublayer(layer)) {
|
|
86
|
+
return worseState(layer.parentLayer.loadState, layer.loadState);
|
|
87
|
+
}
|
|
88
|
+
return layer.loadState;
|
|
89
|
+
}
|
|
90
|
+
const STATE_SEVERITY = {
|
|
91
|
+
loaded: 0,
|
|
92
|
+
"not-loaded": 1,
|
|
93
|
+
loading: 2,
|
|
94
|
+
error: 3
|
|
95
|
+
};
|
|
96
|
+
function worseState(a, b) {
|
|
97
|
+
return STATE_SEVERITY[a] >= STATE_SEVERITY[b] ? a : b;
|
|
98
|
+
}
|
|
38
99
|
|
|
39
|
-
export { useChildLayers, useLayers, useLoadState, useVisibleInScale };
|
|
100
|
+
export { useChildLayers, useLayers, useLoadState, useSublayerError, useVisibleInScale };
|
|
40
101
|
//# sourceMappingURL=hooks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","sources":["hooks.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 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 =\n map.layers.getOperationalLayers({\n sortByDisplayOrder: true,\n includeInternalLayers: true //internal status is handled by LayerItems\n }) ?? [];\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({\n sortByDisplayOrder: true,\n includeInternalLayers: true //internal status is handled by LayerItems\n });\n children?.reverse(); // render topmost layer first\n return children;\n }, [layer]);\n}\n\n/** Returns the layers current
|
|
1
|
+
{"version":3,"file":"hooks.js","sources":["hooks.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { computed } from \"@conterra/reactivity-core\";\nimport { shallowEqual } from \"@open-pioneer/core\";\nimport { AnyLayer, isLayer, isSublayer, Layer, LayerLoadState, MapModel } from \"@open-pioneer/map\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { useMemo } from \"react\";\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 =\n map.layers.getOperationalLayers({\n sortByDisplayOrder: true,\n includeInternalLayers: true //internal status is handled by LayerItems\n }) ?? [];\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({\n sortByDisplayOrder: true,\n includeInternalLayers: true //internal status is handled by LayerItems\n });\n children?.reverse(); // render topmost layer first\n return children;\n }, [layer]);\n}\n\nexport function useLoadState(layer: AnyLayer): LayerLoadState {\n return useReactiveSnapshot(() => ownLoadState(layer), [layer]);\n}\n\n/** Returns the layers current visibility. */\nexport function useVisibleInScale(layer: AnyLayer): boolean {\n return useReactiveSnapshot(() => {\n // for sublayers, use the state of the parent\n const target = isSublayer(layer) ? layer.parentLayer : layer;\n\n return target.visibleInScale;\n }, [layer]);\n}\n\n/**\n * Returns the combined errors of all descendants\n * or `undefined` if no descendant is in an error state.\n */\nexport function useSublayerError(layer: AnyLayer): AggregateError | undefined {\n const sublayerError = useMemo(\n () =>\n computed(() => (isLayer(layer) ? collectSublayerError(layer) : undefined), {\n equal: sublayerErrorsEqual\n }),\n [layer]\n );\n return useReactiveSnapshot(() => sublayerError.value, [sublayerError]);\n}\n\nfunction collectSublayerError(layer: Layer): AggregateError | undefined {\n const errors: Error[] = [];\n for (const descendant of walkDescendants(layer)) {\n const error = descendant.loadError;\n if (error) {\n errors.push(error);\n }\n }\n if (errors.length === 0) {\n return undefined;\n }\n return new AggregateError(\n errors,\n `Layer '${layer.id}' has ${errors.length} sublayer(s) in error state`\n );\n}\n\nfunction* walkDescendants(layer: AnyLayer): Generator<AnyLayer> {\n const children = layer.children?.getItems({ includeInternalLayers: true });\n if (!children) {\n return;\n }\n for (const child of children) {\n yield child;\n yield* walkDescendants(child);\n }\n}\n\nfunction sublayerErrorsEqual(\n a: AggregateError | undefined,\n b: AggregateError | undefined\n): boolean {\n if (a === b) {\n return true;\n }\n if (!a || !b) {\n return false;\n }\n const aErrors = a.errors as Error[];\n const bErrors = b.errors as Error[];\n return shallowEqual(aErrors, bErrors);\n}\n\n/**\n * The layer load state.\n *\n * Sublayer combines the parent layer's load state with their own state.\n */\nfunction ownLoadState(layer: AnyLayer): LayerLoadState {\n if (isSublayer(layer)) {\n return worseState(layer.parentLayer.loadState, layer.loadState);\n }\n return layer.loadState;\n}\n\nconst STATE_SEVERITY: Record<LayerLoadState, number> = {\n loaded: 0,\n \"not-loaded\": 1,\n loading: 2,\n error: 3\n};\n\n/** Returns the worse (higher severity) of two load states: error > loading > not-loaded > loaded. */\nfunction worseState(a: LayerLoadState, b: LayerLoadState): LayerLoadState {\n return STATE_SEVERITY[a] >= STATE_SEVERITY[b] ? a : b;\n}\n"],"names":[],"mappings":"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"}
|
package/ui/Toc.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toc.js","sources":["Toc.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Box, Flex, Spacer, Text } from \"@chakra-ui/react\";\nimport { BasemapSwitcher, BasemapSwitcherProps } from \"@open-pioneer/basemap-switcher\";\nimport { MapModel, MapModelProps, useMapModelValue } from \"@open-pioneer/map\";\nimport {\n CommonComponentProps,\n SectionHeading,\n TitledSection,\n useCommonComponentProps,\n useEvent\n} from \"@open-pioneer/react-utils\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { FC, useEffect, useId, useRef } from \"react\";\nimport {\n createOptions,\n TocApi,\n TocApiImpl,\n TocDisposedEvent,\n TocModel,\n TocModelProvider,\n TocReadyEvent\n} from \"../model\";\nimport { TopLevelLayerList } from \"./LayerList/LayerList\";\nimport { Tools } from \"./Tools\";\n\n/**\n * Props supported by the {@link Toc} component.\n */\nexport interface TocProps extends CommonComponentProps, MapModelProps {\n /**\n * Defines whether the tool component is shown in the toc.\n *\n * Defaults to `false`.\n */\n showTools?: boolean;\n\n /**\n * Properties for the embedded tool component.\n */\n toolsConfig?: ToolsConfig;\n\n /**\n * Defines whether the basemap switcher is shown in the toc.\n *\n * Defaults to `true`.\n */\n showBasemapSwitcher?: boolean;\n\n /**\n * Properties for the embedded basemap switcher.\n *\n * Property `mapId` is not applied (the basemap switcher uses the same map as the toc).\n */\n basemapSwitcherProps?: Omit<BasemapSwitcherProps, \"mapId\">;\n\n /**\n * If `true`, groups in the toc can be collapsed and expanded.\n * This property should only be `true` if the map actually contains layer groups.\n *\n * Defaults to `false`.\n */\n collapsibleGroups?: boolean;\n\n /**\n * If `true` groups in the toc are collapsed initially.\n *\n * Defaults to `false`. If {@link collapsibleGroups} is `false` this property should also be `false`. Otherwise, only the top level layers will appear in the toc.\n */\n initiallyCollapsed?: boolean;\n\n /**\n * Show the parent layers when a child layer is made visible.\n *\n * Defaults to `true`.\n */\n autoShowParents?: boolean;\n\n /**\n * Callback that is triggered once when the Toc is initialized.\n * The Toc API can be accessed by the `api` property of the {@link TocReadyEvent}.\n */\n onReady?: (event: TocReadyEvent) => void;\n\n /**\n * Callback that is triggered once when the Toc is disposed and unmounted.\n */\n onDisposed?: (event: TocDisposedEvent) => void;\n}\n\n/**\n * Props supported by the {@link Tools} component.\n */\nexport interface ToolsConfig {\n /**\n * Optional property to show the `hide all layers` entry.\n *\n * Defaults to `true`.\n */\n showHideAllLayers?: boolean;\n\n /**\n * Optional property to show the `collapse all groups` entry.\n *\n * Defaults to `true`. Only applicable if {@link TocProps.collapsibleGroups} is `true`.\n */\n showCollapseAllGroups?: boolean;\n}\n\n/**\n * Layer attributes to specifically configure how a layer is displayed in the Toc.\n */\nexport interface LayerTocAttributes {\n /**\n * The {@link ListMode} is used to hide the layer (or it's children) in the Toc.\n */\n listMode?: ListMode;\n}\n\n/**\n * ListMode determines if a layer item is displayed in the Toc for the layer.\n * The option `\"hide-children\"` provides a shortcut to hide all child layers (e.g. sublayers of group) of the layer in the Toc.\n * It has the same effect as manually setting the `listMode` to `\"hide\"` on all child layers.\n *\n * ListMode has precedence over the layer's `internal` attribute but specifically configures the layer's display in the Toc.\n */\nexport type ListMode = \"show\" | \"hide\" | \"hide-children\";\n\nconst PADDING = 2;\n\n/**\n * Displays the layers of the configured map.\n */\nexport const Toc: FC<TocProps> = (props: TocProps) => {\n const { containerProps } = useCommonComponentProps(\"toc\", props);\n const map = useMapModelValue(props);\n\n return (\n <Flex {...containerProps} direction=\"column\" gap={PADDING}>\n <TocContent {...props} map={map} />\n </Flex>\n );\n};\n\n/** This component is rendered once we have a reference to the loaded map model. */\nfunction TocContent(props: TocProps & { map: MapModel }) {\n const {\n map,\n showTools = false,\n toolsConfig,\n showBasemapSwitcher = true,\n basemapSwitcherProps,\n onReady,\n onDisposed\n } = props;\n const intl = useIntl();\n const model = useTocModel(props);\n useTocAPI(model, onReady, onDisposed);\n\n const basemapsHeadingId = useId();\n const basemapSwitcher = showBasemapSwitcher && (\n <Box className=\"toc-basemap-switcher\" mb={PADDING}>\n <TitledSection\n title={\n <SectionHeading id={basemapsHeadingId} size={\"sm\"} mb={PADDING}>\n {intl.formatMessage({ id: \"basemapsLabel\" })}\n </SectionHeading>\n }\n >\n <BasemapSwitcher\n map={map}\n aria-labelledby={basemapsHeadingId}\n {...basemapSwitcherProps}\n />\n </TitledSection>\n </Box>\n );\n\n const layerList = (\n <Box className=\"toc-operational-layers\">\n <TitledSection\n title={\n <SectionHeading size=\"sm\">\n <Flex>\n <Text>\n {intl.formatMessage({\n id: \"operationalLayerLabel\"\n })}\n </Text>\n <Spacer />\n {showTools && <Tools map={map} {...toolsConfig} />}\n </Flex>\n </SectionHeading>\n }\n >\n <TopLevelLayerList\n map={map}\n aria-label={intl.formatMessage({ id: \"operationalLayerLabel\" })}\n />\n </TitledSection>\n </Box>\n );\n\n return (\n <TocModelProvider value={model}>\n {basemapSwitcher}\n {layerList}\n </TocModelProvider>\n );\n}\n\nfunction useTocModel(props: TocProps): TocModel {\n const initialProps = useRef(props);\n const tocModelRef = useRef<TocModel>(null);\n if (!tocModelRef.current) {\n tocModelRef.current = new TocModel(\n createOptions(\n initialProps.current.autoShowParents,\n initialProps.current.collapsibleGroups,\n initialProps.current.initiallyCollapsed\n )\n );\n }\n\n // Sync props to model\n useEffect(() => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n tocModelRef.current!.updateOptions(\n createOptions(props.autoShowParents, props.collapsibleGroups, props.initiallyCollapsed)\n );\n }, [\n props.autoShowParents,\n props.collapsibleGroups,\n props.initiallyCollapsed,\n tocModelRef.current.options\n ]);\n return tocModelRef.current;\n}\n\nfunction useTocAPI(\n model: TocModel,\n onReady: TocProps[\"onReady\"] | undefined,\n onDisposed: TocProps[\"onDisposed\"] | undefined\n) {\n const apiRef = useRef<TocApi>(null);\n if (!apiRef.current) {\n apiRef.current = new TocApiImpl(model);\n }\n\n const api = apiRef.current;\n\n const readyTrigger = useEvent(() => {\n onReady?.({\n api\n });\n });\n\n const disposeTrigger = useEvent(() => {\n onDisposed?.({});\n });\n\n // Trigger ready / dispose on mount / unmount, but if the callbacks change.\n // useEvent() returns a stable function reference.\n useEffect(() => {\n readyTrigger();\n return disposeTrigger;\n }, [readyTrigger, disposeTrigger]);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Toc.js","sources":["Toc.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Box, Flex, Spacer, Text } from \"@chakra-ui/react\";\nimport { BasemapSwitcher, BasemapSwitcherProps } from \"@open-pioneer/basemap-switcher\";\nimport { MapModel, MapModelProps, useMapModelValue } from \"@open-pioneer/map\";\nimport {\n CommonComponentProps,\n SectionHeading,\n TitledSection,\n useCommonComponentProps,\n useEvent\n} from \"@open-pioneer/react-utils\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { FC, useEffect, useId, useRef } from \"react\";\nimport {\n createOptions,\n TocApi,\n TocApiImpl,\n TocDisposedEvent,\n TocModel,\n TocModelProvider,\n TocReadyEvent\n} from \"../model\";\nimport { TopLevelLayerList } from \"./LayerList/LayerList\";\nimport { Tools } from \"./Tools\";\n\n/**\n * Props supported by the {@link Toc} component.\n */\nexport interface TocProps extends CommonComponentProps, MapModelProps {\n /**\n * Defines whether the tool component is shown in the toc.\n *\n * Defaults to `false`.\n */\n showTools?: boolean;\n\n /**\n * Properties for the embedded tool component.\n */\n toolsConfig?: ToolsConfig;\n\n /**\n * Defines whether the basemap switcher is shown in the toc.\n *\n * Defaults to `true`.\n */\n showBasemapSwitcher?: boolean;\n\n /**\n * Properties for the embedded basemap switcher.\n *\n * Property `mapId` is not applied (the basemap switcher uses the same map as the toc).\n */\n basemapSwitcherProps?: Omit<BasemapSwitcherProps, \"mapId\">;\n\n /**\n * If `true`, groups in the toc can be collapsed and expanded.\n * This property should only be `true` if the map actually contains layer groups.\n *\n * Defaults to `false`.\n */\n collapsibleGroups?: boolean;\n\n /**\n * If `true` groups in the toc are collapsed initially.\n *\n * Defaults to `false`. If {@link collapsibleGroups} is `false` this property should also be `false`. Otherwise, only the top level layers will appear in the toc.\n */\n initiallyCollapsed?: boolean;\n\n /**\n * Show the parent layers when a child layer is made visible.\n *\n * Defaults to `true`.\n */\n autoShowParents?: boolean;\n\n /**\n * Callback that is triggered once when the Toc is initialized.\n * The Toc API can be accessed by the `api` property of the {@link TocReadyEvent}.\n */\n onReady?: (event: TocReadyEvent) => void;\n\n /**\n * Callback that is triggered once when the Toc is disposed and unmounted.\n */\n onDisposed?: (event: TocDisposedEvent) => void;\n}\n\n/**\n * Props supported by the {@link Tools} component.\n */\nexport interface ToolsConfig {\n /**\n * Optional property to show the `hide all layers` entry.\n *\n * Defaults to `true`.\n */\n showHideAllLayers?: boolean;\n\n /**\n * Optional property to show the `collapse all groups` entry.\n *\n * Defaults to `true`. Only applicable if {@link TocProps.collapsibleGroups} is `true`.\n */\n showCollapseAllGroups?: boolean;\n}\n\n/**\n * Layer attributes to specifically configure how a layer is displayed in the Toc.\n */\nexport interface LayerTocAttributes {\n /**\n * The {@link ListMode} is used to hide the layer (or it's children) in the Toc.\n */\n listMode?: ListMode;\n}\n\n/**\n * ListMode determines if a layer item is displayed in the Toc for the layer.\n * The option `\"hide-children\"` provides a shortcut to hide all child layers (e.g. sublayers of group) of the layer in the Toc.\n * It has the same effect as manually setting the `listMode` to `\"hide\"` on all child layers.\n *\n * ListMode has precedence over the layer's `internal` attribute but specifically configures the layer's display in the Toc.\n */\nexport type ListMode = \"show\" | \"hide\" | \"hide-children\";\n\nconst PADDING = 2;\n\n/**\n * Displays the layers of the configured map.\n */\nexport const Toc: FC<TocProps> = (props: TocProps) => {\n const { containerProps } = useCommonComponentProps(\"toc\", props);\n const map = useMapModelValue(props);\n\n return (\n <Flex {...containerProps} direction=\"column\" gap={PADDING}>\n <TocContent {...props} map={map} />\n </Flex>\n );\n};\n\n/** This component is rendered once we have a reference to the loaded map model. */\nfunction TocContent(props: TocProps & { map: MapModel }) {\n const {\n map,\n showTools = false,\n toolsConfig,\n showBasemapSwitcher = true,\n basemapSwitcherProps,\n onReady,\n onDisposed\n } = props;\n const intl = useIntl();\n const model = useTocModel(props);\n useTocAPI(model, onReady, onDisposed);\n\n const basemapsHeadingId = useId();\n const basemapSwitcher = showBasemapSwitcher && (\n <Box className=\"toc-basemap-switcher\" mb={PADDING}>\n <TitledSection\n title={\n <SectionHeading id={basemapsHeadingId} size={\"sm\"} mb={PADDING}>\n {intl.formatMessage({ id: \"basemapsLabel\" })}\n </SectionHeading>\n }\n >\n <BasemapSwitcher\n map={map}\n aria-labelledby={basemapsHeadingId}\n {...basemapSwitcherProps}\n />\n </TitledSection>\n </Box>\n );\n\n const layerList = (\n <Box className=\"toc-operational-layers\">\n <TitledSection\n title={\n <SectionHeading size=\"sm\">\n <Flex>\n <Text>\n {intl.formatMessage({\n id: \"operationalLayerLabel\"\n })}\n </Text>\n <Spacer />\n {showTools && <Tools map={map} {...toolsConfig} />}\n </Flex>\n </SectionHeading>\n }\n >\n <TopLevelLayerList\n map={map}\n aria-label={intl.formatMessage({ id: \"operationalLayerLabel\" })}\n />\n </TitledSection>\n </Box>\n );\n\n return (\n <TocModelProvider value={model}>\n {basemapSwitcher}\n {layerList}\n </TocModelProvider>\n );\n}\n\nfunction useTocModel(props: TocProps): TocModel {\n const initialProps = useRef(props);\n const tocModelRef = useRef<TocModel>(null);\n if (!tocModelRef.current) {\n tocModelRef.current = new TocModel(\n createOptions(\n initialProps.current.autoShowParents,\n initialProps.current.collapsibleGroups,\n initialProps.current.initiallyCollapsed\n )\n );\n }\n\n // Sync props to model\n useEffect(() => {\n // oxlint-disable-next-line @typescript-eslint/no-non-null-assertion\n tocModelRef.current!.updateOptions(\n createOptions(props.autoShowParents, props.collapsibleGroups, props.initiallyCollapsed)\n );\n }, [\n props.autoShowParents,\n props.collapsibleGroups,\n props.initiallyCollapsed,\n tocModelRef.current.options\n ]);\n return tocModelRef.current;\n}\n\nfunction useTocAPI(\n model: TocModel,\n onReady: TocProps[\"onReady\"] | undefined,\n onDisposed: TocProps[\"onDisposed\"] | undefined\n) {\n const apiRef = useRef<TocApi>(null);\n if (!apiRef.current) {\n apiRef.current = new TocApiImpl(model);\n }\n\n const api = apiRef.current;\n\n const readyTrigger = useEvent(() => {\n onReady?.({\n api\n });\n });\n\n const disposeTrigger = useEvent(() => {\n onDisposed?.({});\n });\n\n // Trigger ready / dispose on mount / unmount, but if the callbacks change.\n // useEvent() returns a stable function reference.\n useEffect(() => {\n readyTrigger();\n return disposeTrigger;\n }, [readyTrigger, disposeTrigger]);\n}\n"],"names":[],"mappings":"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"}
|
package/ui/Tools.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { Box, Menu, Portal, IconButton, Icon } from '@chakra-ui/react';
|
|
3
|
+
import { Tooltip } from '@open-pioneer/chakra-snippets/tooltip';
|
|
4
|
+
import { useReactiveSnapshot } from '@open-pioneer/reactivity';
|
|
3
5
|
import { useIntl } from '../_virtual/hooks.js';
|
|
4
6
|
import { memo, useId } from 'react';
|
|
5
7
|
import { LuEllipsisVertical } from 'react-icons/lu';
|
|
6
8
|
import { useTocModel } from '../model/context.js';
|
|
7
9
|
import '@conterra/reactivity-core';
|
|
8
|
-
import { useReactiveSnapshot } from '@open-pioneer/reactivity';
|
|
9
|
-
import { Tooltip } from '@open-pioneer/chakra-snippets/tooltip';
|
|
10
10
|
|
|
11
11
|
const Tools = memo(function Tools2(props) {
|
|
12
12
|
const intl = useIntl();
|
package/ui/Tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tools.js","sources":["Tools.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Box, IconButton, Menu, Portal, Icon } from \"@chakra-ui/react\";\nimport { AnyLayer, MapModel } from \"@open-pioneer/map\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { FC, memo, useId } from \"react\";\nimport { LuEllipsisVertical } from \"react-icons/lu\";\nimport { TocModel, useTocModel } from \"../model\";\nimport { ToolsConfig } from \"./Toc\";\
|
|
1
|
+
{"version":3,"file":"Tools.js","sources":["Tools.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Box, IconButton, Menu, Portal, Icon } from \"@chakra-ui/react\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { AnyLayer, MapModel } from \"@open-pioneer/map\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { FC, memo, useId } from \"react\";\nimport { LuEllipsisVertical } from \"react-icons/lu\";\nimport { TocModel, useTocModel } from \"../model\";\nimport { ToolsConfig } from \"./Toc\";\n\nexport interface ToolsProps extends ToolsConfig {\n map: MapModel;\n}\n\nexport const Tools: FC<ToolsProps> = memo(function Tools(props: ToolsProps) {\n const intl = useIntl();\n const tocModel = useTocModel();\n const collapsibleGroups = useReactiveSnapshot(\n () => tocModel.options.collapsibleGroups,\n [tocModel]\n );\n const {\n map,\n showHideAllLayers = true,\n showCollapseAllGroups: showCollapseAllGroupsProp = collapsibleGroups\n } = props;\n\n // Only respected if groups are collapsible\n const showCollapseAllGroups = collapsibleGroups && showCollapseAllGroupsProp;\n const hasContent = showHideAllLayers || showCollapseAllGroups;\n\n const triggerId = useId(); // see https://chakra-ui.com/docs/components/tooltip#with-menutrigger\n\n return (\n hasContent && (\n <Box className=\"toc-tools\">\n <Menu.Root ids={{ trigger: triggerId }} positioning={{ placement: \"bottom-start\" }}>\n <TriggerButton triggerId={triggerId} />\n <Portal>\n <Menu.Positioner>\n <Menu.Content className=\"toc-tools-menu\">\n {showHideAllLayers && (\n <Menu.Item\n aria-label={intl.formatMessage({\n id: \"tools.hideAllLayers\"\n })}\n onClick={() => {\n hideAllLayers(map);\n }}\n value=\"hideAllLayers\"\n >\n {intl.formatMessage({ id: \"tools.hideAllLayers\" })}\n </Menu.Item>\n )}\n {showCollapseAllGroups && (\n <Menu.Item\n aria-label={intl.formatMessage({\n id: \"tools.collapseAllGroups\"\n })}\n onClick={() => {\n collapseAllGroups(tocModel);\n }}\n value=\"collapseAllGroups\"\n >\n {intl.formatMessage({ id: \"tools.collapseAllGroups\" })}\n </Menu.Item>\n )}\n </Menu.Content>\n </Menu.Positioner>\n </Portal>\n </Menu.Root>\n </Box>\n )\n );\n});\n\nfunction TriggerButton(props: { triggerId: string }) {\n const { triggerId } = props;\n const intl = useIntl();\n const label = intl.formatMessage({ id: \"toolsLabel\" });\n return (\n <Tooltip ids={{ trigger: triggerId }} content={label}>\n <Menu.Trigger asChild>\n <IconButton\n className=\"toc-tools-button\"\n aria-label={label}\n borderRadius=\"full\"\n focusRingOffset=\"-2px\"\n variant=\"ghost\"\n padding={0}\n size=\"sm\"\n >\n <Icon>\n <LuEllipsisVertical spacing={0} />\n </Icon>\n </IconButton>\n </Menu.Trigger>\n </Tooltip>\n );\n}\n\nfunction hideAllLayers(map: MapModel | undefined) {\n const hide = (layer: AnyLayer) => {\n layer.setVisible(false);\n\n const children = layer.children?.getItems();\n if (children) {\n for (const child of children) {\n hide(child);\n }\n }\n };\n\n map?.layers.getOperationalLayers().forEach((layer) => {\n hide(layer);\n });\n}\n\nfunction collapseAllGroups(tocModel: TocModel) {\n tocModel.getItems().forEach((item) => item.setExpanded(false));\n}\n"],"names":["Tools"],"mappings":"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"}
|