@open-pioneer/toc 1.0.0-dev.20251021074813 → 1.0.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 +9 -6
- package/package.json +7 -7
- package/ui/LayerList/LayerItem.js +9 -17
- package/ui/LayerList/LayerItem.js.map +1 -1
- package/ui/LayerList/LayerList.js +8 -1
- package/ui/LayerList/LayerList.js.map +1 -1
- package/utils/displayLayer.d.ts +5 -0
- package/utils/displayLayer.js +14 -0
- package/utils/displayLayer.js.map +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @open-pioneer/toc
|
|
2
2
|
|
|
3
|
-
## 1.0.0
|
|
3
|
+
## 1.0.0
|
|
4
4
|
|
|
5
5
|
### Minor Changes
|
|
6
6
|
|
|
@@ -41,17 +41,19 @@
|
|
|
41
41
|
|
|
42
42
|
- cb5368f: Introduce Toc API for programmatic control of toc items, see [PR](https://github.com/open-pioneer/trails-openlayers-base-packages/pull/420).
|
|
43
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.
|
|
44
|
+
- 2abcaaf: Update to chakra-ui 3.28.0
|
|
45
45
|
|
|
46
46
|
### Patch Changes
|
|
47
47
|
|
|
48
48
|
- 10d2fe7: Update dependencies
|
|
49
|
-
- 9e9bc6e:
|
|
50
|
-
|
|
49
|
+
- 9e9bc6e: The implementation now uses the map model's `includeInternalLayers === true` option to retrieve layers.
|
|
50
|
+
Internal layers are not shown by default, unless their `listMode` is configured.
|
|
51
|
+
- 138d85b: Update core packages to 4.2.0
|
|
51
52
|
- da6a410: Update dependencies
|
|
52
53
|
- Updated dependencies [c6180c6]
|
|
53
54
|
- Updated dependencies [29a10df]
|
|
54
55
|
- Updated dependencies [10d2fe7]
|
|
56
|
+
- Updated dependencies [4f1e7bd]
|
|
55
57
|
- Updated dependencies [2702df4]
|
|
56
58
|
- Updated dependencies [12561fe]
|
|
57
59
|
- Updated dependencies [5df900f]
|
|
@@ -59,6 +61,7 @@
|
|
|
59
61
|
- Updated dependencies [b3709f1]
|
|
60
62
|
- Updated dependencies [14c484e]
|
|
61
63
|
- Updated dependencies [138d85b]
|
|
64
|
+
- Updated dependencies [4f1e7bd]
|
|
62
65
|
- Updated dependencies [aeb9000]
|
|
63
66
|
- Updated dependencies [9e9bc6e]
|
|
64
67
|
- Updated dependencies [b3709f1]
|
|
@@ -71,8 +74,8 @@
|
|
|
71
74
|
- Updated dependencies [773fa2d]
|
|
72
75
|
- Updated dependencies [2abcaaf]
|
|
73
76
|
- Updated dependencies [da6a410]
|
|
74
|
-
- @open-pioneer/map@1.0.0
|
|
75
|
-
- @open-pioneer/basemap-switcher@1.0.0
|
|
77
|
+
- @open-pioneer/map@1.0.0
|
|
78
|
+
- @open-pioneer/basemap-switcher@1.0.0
|
|
76
79
|
|
|
77
80
|
## 0.11.0
|
|
78
81
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@open-pioneer/toc",
|
|
4
|
-
"version": "1.0.0
|
|
4
|
+
"version": "1.0.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"
|
|
@@ -15,17 +15,17 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@chakra-ui/react": "^3.28.0",
|
|
18
|
-
"@open-pioneer/react-utils": "4.2.0
|
|
19
|
-
"@open-pioneer/runtime": "4.2.0
|
|
18
|
+
"@open-pioneer/react-utils": "^4.2.0",
|
|
19
|
+
"@open-pioneer/runtime": "^4.2.0",
|
|
20
20
|
"classnames": "^2.5.1",
|
|
21
21
|
"ol": "^10.6.1",
|
|
22
22
|
"react": "^19.2.0",
|
|
23
23
|
"react-icons": "^5.5.0",
|
|
24
|
-
"@open-pioneer/reactivity": "4.2.0
|
|
24
|
+
"@open-pioneer/reactivity": "^4.2.0",
|
|
25
25
|
"@conterra/reactivity-core": "^0.8.0",
|
|
26
|
-
"@open-pioneer/chakra-snippets": "4.2.0
|
|
27
|
-
"@open-pioneer/basemap-switcher": "1.0.0
|
|
28
|
-
"@open-pioneer/map": "1.0.0
|
|
26
|
+
"@open-pioneer/chakra-snippets": "^4.2.0",
|
|
27
|
+
"@open-pioneer/basemap-switcher": "^1.0.0",
|
|
28
|
+
"@open-pioneer/map": "^1.0.0"
|
|
29
29
|
},
|
|
30
30
|
"exports": {
|
|
31
31
|
"./package.json": "./package.json",
|
|
@@ -14,11 +14,13 @@ import { slug } from '../../utils/slug.js';
|
|
|
14
14
|
import { useLoadState, 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';
|
|
17
18
|
|
|
18
19
|
const LayerItem = memo(function LayerItem2(props) {
|
|
19
20
|
const { layer } = props;
|
|
20
21
|
const intl = useIntl();
|
|
21
|
-
const
|
|
22
|
+
const display = useReactiveSnapshot(() => displayItemForLayer(layer), [layer]);
|
|
23
|
+
const [tocItem, _tocModel, tocOptions, tocItemElemRef] = useTocItem(layer, display);
|
|
22
24
|
const expanded = useReactiveSnapshot(() => tocItem.isExpanded, [tocItem]);
|
|
23
25
|
const isCollapsible = tocOptions ? tocOptions.collapsibleGroups : false;
|
|
24
26
|
const layerGroupId = useId();
|
|
@@ -30,14 +32,12 @@ const LayerItem = memo(function LayerItem2(props) {
|
|
|
30
32
|
title: layer.title,
|
|
31
33
|
description: layer.description,
|
|
32
34
|
isVisible: layer.visible,
|
|
33
|
-
isInternal: layer.internal,
|
|
34
35
|
allChildrenHidden: !hasShownChildren(layer)
|
|
35
36
|
//re-evaluates if a child layer's list mode or internal state changes
|
|
36
37
|
};
|
|
37
38
|
}, [layer]);
|
|
38
39
|
const nestedChildren = useNestedChildren(layerGroupId, title, layer, intl);
|
|
39
40
|
let hasNestedChildren = !!nestedChildren;
|
|
40
|
-
const display = displayLayerItem(layer);
|
|
41
41
|
if (!display) {
|
|
42
42
|
return null;
|
|
43
43
|
}
|
|
@@ -159,7 +159,7 @@ function CollapseButton(props) {
|
|
|
159
159
|
}
|
|
160
160
|
);
|
|
161
161
|
}
|
|
162
|
-
function useTocItem(layer) {
|
|
162
|
+
function useTocItem(layer, display) {
|
|
163
163
|
const tocModel = useTocModel();
|
|
164
164
|
const options = useReactiveSnapshot(() => tocModel.options, [tocModel]);
|
|
165
165
|
const tocItemElemRef = useRef(null);
|
|
@@ -167,13 +167,16 @@ function useTocItem(layer) {
|
|
|
167
167
|
return new TocItemImpl(layer, tocModel, !options.initiallyCollapsed);
|
|
168
168
|
}, [layer, options.initiallyCollapsed, tocModel]);
|
|
169
169
|
useEffect(() => {
|
|
170
|
+
if (!display) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
170
173
|
tocItem.setHtmlElement(tocItemElemRef.current ?? void 0);
|
|
171
174
|
tocModel.registerItem(tocItem);
|
|
172
175
|
return () => {
|
|
173
176
|
tocItem.setHtmlElement(void 0);
|
|
174
177
|
tocModel.unregisterItem(tocItem);
|
|
175
178
|
};
|
|
176
|
-
}, [tocModel, tocItem]);
|
|
179
|
+
}, [tocModel, tocItem, display]);
|
|
177
180
|
return [tocItem, tocModel, options, tocItemElemRef];
|
|
178
181
|
}
|
|
179
182
|
function useListMode(layer) {
|
|
@@ -196,22 +199,11 @@ function hasShownChildren(layer) {
|
|
|
196
199
|
return false;
|
|
197
200
|
} else {
|
|
198
201
|
return layer.children.getItems().some((childLayer) => {
|
|
199
|
-
const isDisplayed =
|
|
202
|
+
const isDisplayed = displayItemForLayer(childLayer);
|
|
200
203
|
return isDisplayed;
|
|
201
204
|
});
|
|
202
205
|
}
|
|
203
206
|
}
|
|
204
|
-
function displayLayerItem(layer) {
|
|
205
|
-
const isInternal = layer.internal;
|
|
206
|
-
const listMode = layer.attributes.toc?.listMode;
|
|
207
|
-
if (listMode === "show" || listMode === "hide-children") {
|
|
208
|
-
return true;
|
|
209
|
-
} else if (isInternal || listMode === "hide") {
|
|
210
|
-
return false;
|
|
211
|
-
} else {
|
|
212
|
-
return true;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
207
|
|
|
216
208
|
export { LayerItem };
|
|
217
209
|
//# sourceMappingURL=LayerItem.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LayerItem.js","sources":["LayerItem.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n Box,\n Collapsible,\n CollapsibleContent,\n Flex,\n Icon,\n IconButton,\n Spacer\n} from \"@chakra-ui/react\";\nimport { Checkbox } from \"@open-pioneer/chakra-snippets/checkbox\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { AnyLayer } from \"@open-pioneer/map\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport classNames from \"classnames\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { memo, ReactNode, useEffect, useId, useMemo, useRef } from \"react\";\nimport { LuTriangleAlert, LuChevronDown, LuChevronRight } from \"react-icons/lu\";\nimport { TocItemImpl, useTocModel } from \"../../model/\";\nimport { slug } from \"../../utils/slug\";\nimport { useChildLayers, useLoadState } from \"./hooks\";\nimport { LayerItemMenu } from \"./LayerItemMenu\";\nimport { LayerList } from \"./LayerList\";\nimport { LayerTocAttributes } from \"../Toc\";\n\n/**\n * Renders a single layer as a list item.\n *\n * The item may have further nested list items if there are sublayers present.\n */\nexport const LayerItem = memo(function LayerItem(props: { layer: AnyLayer }): ReactNode {\n const { layer } = props;\n const intl = useIntl();\n const [tocItem, _tocModel, tocOptions, tocItemElemRef] = useTocItem(layer);\n const expanded = useReactiveSnapshot(() => tocItem.isExpanded, [tocItem]);\n const isCollapsible = tocOptions ? tocOptions.collapsibleGroups : false;\n\n const layerGroupId = useId();\n const isAvailable = useLoadState(layer) !== \"error\";\n const listMode = useListMode(layer)?.listMode;\n const notAvailableLabel = intl.formatMessage({ id: \"layerNotAvailable\" });\n const { title, description, isVisible, allChildrenHidden } = useReactiveSnapshot(() => {\n return {\n title: layer.title,\n description: layer.description,\n isVisible: layer.visible,\n isInternal: layer.internal,\n allChildrenHidden: !hasShownChildren(layer) //re-evaluates if a child layer's list mode or internal state changes\n };\n }, [layer]);\n\n const nestedChildren = useNestedChildren(layerGroupId, title, layer, intl);\n let hasNestedChildren = !!nestedChildren;\n\n const display = displayLayerItem(layer);\n if (!display) {\n return null;\n }\n //all children hidden => do not render collapse button and child entries\n if (allChildrenHidden || listMode === \"hide-children\") {\n hasNestedChildren = false;\n }\n\n return (\n <Box\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={title + (!isAvailable ? \" \" + notAvailableLabel : \"\")}\n checked={isVisible}\n disabled={!isAvailable}\n onCheckedChange={(event) =>\n updateLayerVisibility(\n layer,\n event.checked === true,\n tocOptions.autoShowParents\n )\n }\n >\n {title}\n </Checkbox>\n {!isAvailable && (\n <Tooltip\n content={notAvailableLabel}\n positioning={{ placement: \"right\" }}\n openDelay={500}\n contentProps={{ className: \"toc-layer-item-content-tooltip\" }}\n >\n <span>\n <LuTriangleAlert\n className=\"toc-layer-item-content-icon\"\n color={\"red\"}\n aria-label={notAvailableLabel}\n />\n </span>\n </Tooltip>\n )}\n <Spacer />\n <LayerItemMenu layer={layer} title={title} description={description} intl={intl} />\n </Flex>\n {hasNestedChildren && (\n <Collapsible.Root open={expanded} className=\"toc-collapsible-item\">\n <CollapsibleContent>{nestedChildren}</CollapsibleContent>\n </Collapsible.Root>\n )}\n </Box>\n );\n});\n\nfunction useNestedChildren(\n layerGroupId: string,\n title: string,\n layer: AnyLayer,\n intl: PackageIntl\n) {\n const childLayers = useChildLayers(layer);\n const children = useMemo(() => {\n if (childLayers?.length) {\n return (\n <LayerList\n id={layerGroupId}\n layers={childLayers}\n ml={4}\n aria-label={intl.formatMessage({ id: \"childgroupLabel\" }, { title: title })}\n />\n );\n }\n return undefined;\n }, [layerGroupId, intl, title, childLayers]);\n return children;\n}\n\nfunction CollapseButton(props: {\n layerTitle: string;\n layerGroupId: string;\n expanded: boolean;\n onClick: () => void;\n hasNestedChildren: boolean;\n}) {\n const { layerTitle, layerGroupId, expanded, onClick, hasNestedChildren } = props;\n const icon = expanded ? <LuChevronDown /> : <LuChevronRight />;\n const intl = useIntl();\n return (\n <IconButton\n variant=\"ghost\"\n borderRadius=\"full\"\n padding={0}\n className=\"toc-layer-item-collapse-button\"\n onClick={onClick}\n size=\"sm\"\n focusRingOffset=\"-2px\"\n aria-label={\n expanded\n ? intl.formatMessage({ id: \"group.collapse\" }, { title: layerTitle })\n : intl.formatMessage({ id: \"group.expand\" }, { title: layerTitle })\n }\n aria-expanded={expanded}\n aria-controls={layerGroupId}\n //use visible:hidden for layers without children for correct indent\n visibility={hasNestedChildren ? \"visible\" : \"hidden\"}\n css={{\n // Chakra theme adds a background to components with \"aria-expanded\" by default.\n \"&:is([aria-expanded='true']):not(:hover)\": {\n background: \"none\"\n }\n }}\n >\n <Icon>{icon}</Icon>\n </IconButton>\n );\n}\n\n// Creates a toc item and registers it with the shared toc model.\nfunction useTocItem(layer: AnyLayer) {\n const tocModel = useTocModel();\n const options = useReactiveSnapshot(() => tocModel.options, [tocModel]);\n const 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 tocItem.setHtmlElement(tocItemElemRef.current ?? undefined);\n tocModel.registerItem(tocItem);\n return () => {\n tocItem.setHtmlElement(undefined);\n tocModel.unregisterItem(tocItem);\n };\n }, [tocModel, tocItem]);\n\n return [tocItem, tocModel, options, tocItemElemRef] as const;\n}\n\nfunction useListMode(layer: AnyLayer): LayerTocAttributes | undefined {\n return useReactiveSnapshot(\n () => layer.attributes.toc as LayerTocAttributes | undefined,\n [layer]\n );\n}\n\nfunction updateLayerVisibility(layer: AnyLayer, visible: boolean, autoShowParents: boolean) {\n layer.setVisible(visible);\n if (visible && autoShowParents && layer.parent) {\n updateLayerVisibility(layer.parent, true, true);\n }\n}\n\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 * @param layer\n * @returns true if at least one child layer's display mode is not `hide`\n */\nfunction hasShownChildren(layer: AnyLayer): boolean {\n if (!layer.children || layer.children.getItems().length === 0) {\n return false;\n } else {\n return layer.children.getItems().some((childLayer) => {\n const isDisplayed = displayLayerItem(childLayer);\n return isDisplayed;\n });\n }\n}\n\n/**\n * Checks if a layer should be displayed in the Toc.\n */\nfunction displayLayerItem(layer: AnyLayer): boolean {\n const isInternal = layer.internal;\n const listMode = (layer.attributes.toc as LayerTocAttributes | undefined)?.listMode;\n\n if (listMode === \"show\" || listMode === \"hide-children\") {\n return true;\n } else if (isInternal || listMode === \"hide\") {\n return false;\n } else {\n return true;\n }\n}\n"],"names":["LayerItem"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LayerItem.js","sources":["LayerItem.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n Box,\n Collapsible,\n CollapsibleContent,\n Flex,\n Icon,\n IconButton,\n Spacer\n} from \"@chakra-ui/react\";\nimport { Checkbox } from \"@open-pioneer/chakra-snippets/checkbox\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { AnyLayer } from \"@open-pioneer/map\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport classNames from \"classnames\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { memo, ReactNode, useEffect, useId, useMemo, useRef } from \"react\";\nimport { LuTriangleAlert, LuChevronDown, LuChevronRight } from \"react-icons/lu\";\nimport { TocItemImpl, useTocModel } from \"../../model/\";\nimport { slug } from \"../../utils/slug\";\nimport { useChildLayers, useLoadState } from \"./hooks\";\nimport { LayerItemMenu } from \"./LayerItemMenu\";\nimport { LayerList } from \"./LayerList\";\nimport { LayerTocAttributes } from \"../Toc\";\nimport { displayItemForLayer } from \"../../utils/displayLayer\";\n\n/**\n * Renders a single layer as a list item.\n *\n * The item may have further nested list items if there are sublayers present.\n */\nexport const LayerItem = memo(function LayerItem(props: { layer: AnyLayer }): ReactNode {\n const { layer } = props;\n const intl = useIntl();\n const 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 isAvailable = useLoadState(layer) !== \"error\";\n const listMode = useListMode(layer)?.listMode;\n const notAvailableLabel = intl.formatMessage({ id: \"layerNotAvailable\" });\n const { title, description, isVisible, allChildrenHidden } = useReactiveSnapshot(() => {\n return {\n title: layer.title,\n description: layer.description,\n isVisible: layer.visible,\n allChildrenHidden: !hasShownChildren(layer) //re-evaluates if a child layer's list mode or internal state changes\n };\n }, [layer]);\n\n const nestedChildren = useNestedChildren(layerGroupId, title, layer, intl);\n let hasNestedChildren = !!nestedChildren;\n\n\n if (!display) {\n return null;\n } \n //all children hidden => do not render collapse button and child entries\n if (allChildrenHidden || listMode === \"hide-children\") {\n hasNestedChildren = false;\n }\n\n return (\n <Box\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={title + (!isAvailable ? \" \" + notAvailableLabel : \"\")}\n checked={isVisible}\n disabled={!isAvailable}\n onCheckedChange={(event) =>\n updateLayerVisibility(\n layer,\n event.checked === true,\n tocOptions.autoShowParents\n )\n }\n >\n {title}\n </Checkbox>\n {!isAvailable && (\n <Tooltip\n content={notAvailableLabel}\n positioning={{ placement: \"right\" }}\n openDelay={500}\n contentProps={{ className: \"toc-layer-item-content-tooltip\" }}\n >\n <span>\n <LuTriangleAlert\n className=\"toc-layer-item-content-icon\"\n color={\"red\"}\n aria-label={notAvailableLabel}\n />\n </span>\n </Tooltip>\n )}\n <Spacer />\n <LayerItemMenu layer={layer} title={title} description={description} intl={intl} />\n </Flex>\n {hasNestedChildren && (\n <Collapsible.Root open={expanded} className=\"toc-collapsible-item\">\n <CollapsibleContent>{nestedChildren}</CollapsibleContent>\n </Collapsible.Root>\n )}\n </Box>\n );\n});\n\nfunction useNestedChildren(\n layerGroupId: string,\n title: string,\n layer: AnyLayer,\n intl: PackageIntl\n) {\n const childLayers = useChildLayers(layer);\n const children = useMemo(() => {\n if (childLayers?.length) {\n return (\n <LayerList\n id={layerGroupId}\n layers={childLayers}\n ml={4}\n aria-label={intl.formatMessage({ id: \"childgroupLabel\" }, { title: title })}\n />\n );\n }\n return undefined;\n }, [layerGroupId, intl, title, childLayers]);\n return children;\n}\n\nfunction CollapseButton(props: {\n layerTitle: string;\n layerGroupId: string;\n expanded: boolean;\n onClick: () => void;\n hasNestedChildren: boolean;\n}) {\n const { layerTitle, layerGroupId, expanded, onClick, hasNestedChildren } = props;\n const icon = expanded ? <LuChevronDown /> : <LuChevronRight />;\n const intl = useIntl();\n return (\n <IconButton\n variant=\"ghost\"\n borderRadius=\"full\"\n padding={0}\n className=\"toc-layer-item-collapse-button\"\n onClick={onClick}\n size=\"sm\"\n focusRingOffset=\"-2px\"\n aria-label={\n expanded\n ? intl.formatMessage({ id: \"group.collapse\" }, { title: layerTitle })\n : intl.formatMessage({ id: \"group.expand\" }, { title: layerTitle })\n }\n aria-expanded={expanded}\n aria-controls={layerGroupId}\n //use visible:hidden for layers without children for correct indent\n visibility={hasNestedChildren ? \"visible\" : \"hidden\"}\n css={{\n // Chakra theme adds a background to components with \"aria-expanded\" by default.\n \"&:is([aria-expanded='true']):not(:hover)\": {\n background: \"none\"\n }\n }}\n >\n <Icon>{icon}</Icon>\n </IconButton>\n );\n}\n\n// Creates a toc item and registers it with the shared toc model.\nfunction useTocItem(layer: AnyLayer, 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 useListMode(layer: AnyLayer): LayerTocAttributes | undefined {\n return useReactiveSnapshot(\n () => layer.attributes.toc as LayerTocAttributes | undefined,\n [layer]\n );\n}\n\nfunction updateLayerVisibility(layer: AnyLayer, visible: boolean, autoShowParents: boolean) {\n layer.setVisible(visible);\n if (visible && autoShowParents && layer.parent) {\n updateLayerVisibility(layer.parent, true, true);\n }\n}\n\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 * @param layer\n * @returns true if at least one child layer's display mode is not `hide`\n */\nfunction hasShownChildren(layer: AnyLayer): boolean {\n if (!layer.children || layer.children.getItems().length === 0) {\n return false;\n } else {\n return layer.children.getItems().some((childLayer) => {\n const isDisplayed = displayItemForLayer(childLayer);\n return isDisplayed;\n });\n }\n}\n\n\n"],"names":["LayerItem"],"mappings":"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"}
|
|
@@ -4,12 +4,15 @@ import { useIntl } from '../../_virtual/_virtual-pioneer-module_react-hooks.js';
|
|
|
4
4
|
import { memo, useMemo } from 'react';
|
|
5
5
|
import { LayerItem } from './LayerItem.js';
|
|
6
6
|
import { useLayers } from './hooks.js';
|
|
7
|
+
import { displayItemForLayer } from '../../utils/displayLayer.js';
|
|
8
|
+
import { useReactiveSnapshot } from '@open-pioneer/reactivity';
|
|
7
9
|
|
|
8
10
|
const TopLevelLayerList = memo(function TopLevelLayerList2(props) {
|
|
9
11
|
const { map, "aria-label": ariaLabel } = props;
|
|
10
12
|
const intl = useIntl();
|
|
11
13
|
const layers = useLayers(map);
|
|
12
|
-
|
|
14
|
+
const empty = useReactiveSnapshot(() => isEmpty(layers), [layers]);
|
|
15
|
+
if (empty) {
|
|
13
16
|
return /* @__PURE__ */ jsx(Text, { className: "toc-missing-layers", "aria-label": ariaLabel, children: intl.formatMessage({ id: "missingLayers" }) });
|
|
14
17
|
}
|
|
15
18
|
return /* @__PURE__ */ jsx(LayerList, { layers, "aria-label": ariaLabel });
|
|
@@ -31,6 +34,10 @@ const LayerList = memo(function LayerList2(props) {
|
|
|
31
34
|
}
|
|
32
35
|
);
|
|
33
36
|
});
|
|
37
|
+
function isEmpty(layers) {
|
|
38
|
+
const isEmpty2 = !layers.length || layers.every((l) => !displayItemForLayer(l));
|
|
39
|
+
return isEmpty2;
|
|
40
|
+
}
|
|
34
41
|
|
|
35
42
|
export { LayerList, TopLevelLayerList };
|
|
36
43
|
//# sourceMappingURL=LayerList.js.map
|
|
@@ -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 } from \"@open-pioneer/map\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { memo, useMemo } from \"react\";\nimport { LayerItem } from \"./LayerItem\";\nimport { useLayers } from \"./hooks\";\n\ninterface TopLevelLayerListProps {\n map: MapModel;\n\n /** The label of the list group (<ul>) */\n \"aria-label\"?: string;\n}\n\n/**\n * Lists the operational layers in the map.\n */\nexport const TopLevelLayerList = memo(function TopLevelLayerList(props: TopLevelLayerListProps) {\n const { map, \"aria-label\": ariaLabel } = props;\n const intl = useIntl();\n const layers = useLayers(map);\n
|
|
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 { useIntl } from \"open-pioneer:react-hooks\";\nimport { memo, useMemo } from \"react\";\nimport { LayerItem } from \"./LayerItem\";\nimport { useLayers } from \"./hooks\";\nimport { displayItemForLayer } from \"../../utils/displayLayer\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\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":";;;;;;;;;AAqBO,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;;;;"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
function displayItemForLayer(layer) {
|
|
2
|
+
const isInternal = layer.internal;
|
|
3
|
+
const listMode = layer.attributes.toc?.listMode;
|
|
4
|
+
if (listMode === "show" || listMode === "hide-children") {
|
|
5
|
+
return true;
|
|
6
|
+
} else if (isInternal || listMode === "hide") {
|
|
7
|
+
return false;
|
|
8
|
+
} else {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export { displayItemForLayer };
|
|
14
|
+
//# sourceMappingURL=displayLayer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"displayLayer.js","sources":["displayLayer.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { AnyLayer } from \"@open-pioneer/map\";\nimport { LayerTocAttributes } from \"../ui/Toc\";\n\n/**\n * Checks if a layer should be displayed in the Toc.\n */\nexport function displayItemForLayer(layer: AnyLayer): boolean {\n const isInternal = layer.internal;\n const listMode = (layer.attributes.toc as LayerTocAttributes | undefined)?.listMode;\n\n if (listMode === \"show\" || listMode === \"hide-children\") {\n return true;\n } else if (isInternal || listMode === \"hide\") {\n return false;\n } else {\n return true;\n }\n}\n"],"names":[],"mappings":"AASO,SAAS,oBAAoB,KAAA,EAA0B;AAC1D,EAAA,MAAM,aAAa,KAAA,CAAM,QAAA;AACzB,EAAA,MAAM,QAAA,GAAY,KAAA,CAAM,UAAA,CAAW,GAAA,EAAwC,QAAA;AAE3E,EAAA,IAAI,QAAA,KAAa,MAAA,IAAU,QAAA,KAAa,eAAA,EAAiB;AACrD,IAAA,OAAO,IAAA;AAAA,EACX,CAAA,MAAA,IAAW,UAAA,IAAc,QAAA,KAAa,MAAA,EAAQ;AAC1C,IAAA,OAAO,KAAA;AAAA,EACX,CAAA,MAAO;AACH,IAAA,OAAO,IAAA;AAAA,EACX;AACJ;;;;"}
|