@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @open-pioneer/toc
2
2
 
3
- ## 1.0.0-dev.20251021074813
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.27.1
44
+ - 2abcaaf: Update to chakra-ui 3.28.0
45
45
 
46
46
  ### Patch Changes
47
47
 
48
48
  - 10d2fe7: Update dependencies
49
- - 9e9bc6e: Use new option `includeInternalLayers === true` for layer retrieval because internal layers are already handled by the Toc itself.
50
- - 138d85b: Update core packages to 4.1.0
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-dev.20251021074813
75
- - @open-pioneer/basemap-switcher@1.0.0-dev.20251021074813
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-dev.20251021074813",
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-dev.20251021072202",
19
- "@open-pioneer/runtime": "4.2.0-dev.20251021072202",
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-dev.20251021072202",
24
+ "@open-pioneer/reactivity": "^4.2.0",
25
25
  "@conterra/reactivity-core": "^0.8.0",
26
- "@open-pioneer/chakra-snippets": "4.2.0-dev.20251021072202",
27
- "@open-pioneer/basemap-switcher": "1.0.0-dev.20251021074813",
28
- "@open-pioneer/map": "1.0.0-dev.20251021074813"
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 [tocItem, _tocModel, tocOptions, tocItemElemRef] = useTocItem(layer);
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 = displayLayerItem(childLayer);
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
- if (!layers.length) {
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\n if (!layers.length) {\n return (\n <Text className=\"toc-missing-layers\" aria-label={ariaLabel}>\n {intl.formatMessage({ id: \"missingLayers\" })}\n </Text>\n );\n }\n\n return <LayerList layers={layers} aria-label={ariaLabel} />;\n});\n\n/**\n * Renders the given layers as a list (<ul>).\n */\nexport const LayerList = memo(function LayerList(props: { layers: AnyLayer[] } & 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"],"names":["TopLevelLayerList","LayerList"],"mappings":";;;;;;;AAmBO,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;AAE5B,EAAA,IAAI,CAAC,OAAO,MAAA,EAAQ;AAChB,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;;;;"}
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,5 @@
1
+ import { AnyLayer } from "@open-pioneer/map";
2
+ /**
3
+ * Checks if a layer should be displayed in the Toc.
4
+ */
5
+ export declare function displayItemForLayer(layer: AnyLayer): boolean;
@@ -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;;;;"}