@itwin/map-layers 6.0.9 → 6.2.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +18 -2
  2. package/lib/cjs/map-layers.d.ts +1 -0
  3. package/lib/cjs/map-layers.d.ts.map +1 -1
  4. package/lib/cjs/map-layers.js +3 -0
  5. package/lib/cjs/map-layers.js.map +1 -1
  6. package/lib/cjs/public/locales/en/mapLayers.json +6 -2
  7. package/lib/cjs/ui/FeatureInfoUiItemsProvider.d.ts +2 -1
  8. package/lib/cjs/ui/FeatureInfoUiItemsProvider.d.ts.map +1 -1
  9. package/lib/cjs/ui/FeatureInfoUiItemsProvider.js +6 -4
  10. package/lib/cjs/ui/FeatureInfoUiItemsProvider.js.map +1 -1
  11. package/lib/cjs/ui/Interfaces.d.ts +9 -0
  12. package/lib/cjs/ui/Interfaces.d.ts.map +1 -1
  13. package/lib/cjs/ui/Interfaces.js.map +1 -1
  14. package/lib/cjs/ui/hooks/useResizeObserver.d.ts +5 -0
  15. package/lib/cjs/ui/hooks/useResizeObserver.d.ts.map +1 -1
  16. package/lib/cjs/ui/hooks/useResizeObserver.js +3 -3
  17. package/lib/cjs/ui/hooks/useResizeObserver.js.map +1 -1
  18. package/lib/cjs/ui/widget/CopyActionButton.d.ts +12 -0
  19. package/lib/cjs/ui/widget/CopyActionButton.d.ts.map +1 -0
  20. package/lib/cjs/ui/widget/CopyActionButton.js +49 -0
  21. package/lib/cjs/ui/widget/CopyActionButton.js.map +1 -0
  22. package/lib/cjs/ui/widget/FeatureInfoWidget.d.ts +22 -4
  23. package/lib/cjs/ui/widget/FeatureInfoWidget.d.ts.map +1 -1
  24. package/lib/cjs/ui/widget/FeatureInfoWidget.js +15 -17
  25. package/lib/cjs/ui/widget/FeatureInfoWidget.js.map +1 -1
  26. package/lib/cjs/ui/widget/FeatureInfoWidget.scss +0 -5
  27. package/lib/cjs/ui/widget/MapLayerSettingsMenu.js +1 -1
  28. package/lib/cjs/ui/widget/MapLayerSettingsMenu.js.map +1 -1
  29. package/lib/esm/map-layers.d.ts +1 -0
  30. package/lib/esm/map-layers.d.ts.map +1 -1
  31. package/lib/esm/map-layers.js +1 -0
  32. package/lib/esm/map-layers.js.map +1 -1
  33. package/lib/esm/public/locales/en/mapLayers.json +6 -2
  34. package/lib/esm/ui/FeatureInfoUiItemsProvider.d.ts +2 -1
  35. package/lib/esm/ui/FeatureInfoUiItemsProvider.d.ts.map +1 -1
  36. package/lib/esm/ui/FeatureInfoUiItemsProvider.js +7 -5
  37. package/lib/esm/ui/FeatureInfoUiItemsProvider.js.map +1 -1
  38. package/lib/esm/ui/Interfaces.d.ts +9 -0
  39. package/lib/esm/ui/Interfaces.d.ts.map +1 -1
  40. package/lib/esm/ui/Interfaces.js.map +1 -1
  41. package/lib/esm/ui/hooks/useResizeObserver.d.ts +5 -0
  42. package/lib/esm/ui/hooks/useResizeObserver.d.ts.map +1 -1
  43. package/lib/esm/ui/hooks/useResizeObserver.js +3 -3
  44. package/lib/esm/ui/hooks/useResizeObserver.js.map +1 -1
  45. package/lib/esm/ui/widget/CopyActionButton.d.ts +12 -0
  46. package/lib/esm/ui/widget/CopyActionButton.d.ts.map +1 -0
  47. package/lib/esm/ui/widget/CopyActionButton.js +46 -0
  48. package/lib/esm/ui/widget/CopyActionButton.js.map +1 -0
  49. package/lib/esm/ui/widget/FeatureInfoWidget.d.ts +22 -4
  50. package/lib/esm/ui/widget/FeatureInfoWidget.d.ts.map +1 -1
  51. package/lib/esm/ui/widget/FeatureInfoWidget.js +16 -17
  52. package/lib/esm/ui/widget/FeatureInfoWidget.js.map +1 -1
  53. package/lib/esm/ui/widget/FeatureInfoWidget.scss +0 -5
  54. package/lib/esm/ui/widget/MapLayerSettingsMenu.js +1 -1
  55. package/lib/esm/ui/widget/MapLayerSettingsMenu.js.map +1 -1
  56. package/lib/public/locales/en/mapLayers.json +6 -2
  57. package/package.json +6 -8
@@ -10,4 +10,5 @@ export * from "./ui/MapLayersUiItemsProvider";
10
10
  export * from "./ui/FeatureInfoUiItemsProvider";
11
11
  export * from "./ui/widget/MapLayersWidget";
12
12
  export * from "./BaseMapPresets";
13
+ export { MapFeatureInfoWidget } from "./ui/widget/FeatureInfoWidget";
13
14
  //# sourceMappingURL=map-layers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"map-layers.js","sourceRoot":"","sources":["../../src/map-layers.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAChG,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iBAAiB,CAAC;AAChC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kBAAkB,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\nexport * from \"./mapLayers\";\nexport * from \"./MapLayersActionIds\";\nexport * from \"./MapLayersPrefBrowserStorage\";\nexport * from \"./ui/Interfaces\";\nexport * from \"./ui/MapLayersUiItemsProvider\";\nexport * from \"./ui/FeatureInfoUiItemsProvider\";\nexport * from \"./ui/widget/MapLayersWidget\";\nexport * from \"./BaseMapPresets\";\n"]}
1
+ {"version":3,"file":"map-layers.js","sourceRoot":"","sources":["../../src/map-layers.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAChG,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iBAAiB,CAAC;AAChC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\nexport * from \"./mapLayers\";\nexport * from \"./MapLayersActionIds\";\nexport * from \"./MapLayersPrefBrowserStorage\";\nexport * from \"./ui/Interfaces\";\nexport * from \"./ui/MapLayersUiItemsProvider\";\nexport * from \"./ui/FeatureInfoUiItemsProvider\";\nexport * from \"./ui/widget/MapLayersWidget\";\nexport * from \"./BaseMapPresets\";\nexport { MapFeatureInfoWidget } from \"./ui/widget/FeatureInfoWidget\";\n"]}
@@ -130,11 +130,15 @@
130
130
  },
131
131
  "FeatureInfoWidget": {
132
132
  "Label": "Map Layers Info",
133
- "NoRecords": "No Results"
133
+ "NoRecords": "No Results",
134
+ "Copy": "Copy",
135
+ "Copied": "Copied!",
136
+ "CopyFailed": "Copy failed"
134
137
  },
135
138
  "LayerMenu": {
136
139
  "Detach": "Detach",
137
- "ZoomToLayer": "Zoom to layer"
140
+ "ZoomToLayer": "Zoom to layer",
141
+ "MoreOptions": "More options"
138
142
  },
139
143
  "Settings": {
140
144
  "ElevationOffset": "Elevation Offset",
@@ -1,6 +1,7 @@
1
+ import { ToolbarOrientation } from "@itwin/appui-react";
1
2
  import type { ToolbarActionItem, ToolbarItem, UiItemsProvider, Widget } from "@itwin/appui-react";
2
3
  import type { MapFeatureInfoOptions } from "./Interfaces";
3
- export declare const getMapFeatureInfoToolItemDef: (itemPriority: number) => ToolbarActionItem;
4
+ export declare const getMapFeatureInfoToolItemDef: (itemPriority: number, toolbarOrientation?: ToolbarOrientation) => ToolbarActionItem;
4
5
  export declare class FeatureInfoUiItemsProvider implements UiItemsProvider {
5
6
  private _featureInfoOpts;
6
7
  readonly id = "FeatureInfoUiItemsProvider";
@@ -1 +1 @@
1
- {"version":3,"file":"FeatureInfoUiItemsProvider.d.ts","sourceRoot":"","sources":["../../../src/ui/FeatureInfoUiItemsProvider.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAGlG,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AA4B1D,eAAO,MAAM,4BAA4B,iBAAkB,MAAM,KAAG,iBAqBnE,CAAC;AAEF,qBAAa,0BAA2B,YAAW,eAAe;IAI7C,OAAO,CAAC,gBAAgB;IAH3C,SAAgB,EAAE,gCAAgC;IAClD,gBAAuB,QAAQ,qCAAqC;gBAEzC,gBAAgB,EAAE,qBAAqB;IAE3D,eAAe,IAAI,aAAa,CAAC,WAAW,CAAC;IAQ7C,UAAU,IAAI,MAAM,EAAE;CAiB9B"}
1
+ {"version":3,"file":"FeatureInfoUiItemsProvider.d.ts","sourceRoot":"","sources":["../../../src/ui/FeatureInfoUiItemsProvider.tsx"],"names":[],"mappings":"AAMA,OAAO,EACwD,kBAAkB,EAChF,MAAM,oBAAoB,CAAC;AAS5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAGlG,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AA4B1D,eAAO,MAAM,4BAA4B,iBAAkB,MAAM,8CAAqD,iBAqBrH,CAAC;AAEF,qBAAa,0BAA2B,YAAW,eAAe;IAI7C,OAAO,CAAC,gBAAgB;IAH3C,SAAgB,EAAE,gCAAgC;IAClD,gBAAuB,QAAQ,qCAAqC;gBAEzC,gBAAgB,EAAE,qBAAqB;IAE3D,eAAe,IAAI,aAAa,CAAC,WAAW,CAAC;IAQ7C,UAAU,IAAI,MAAM,EAAE;CAqB9B"}
@@ -4,7 +4,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
4
4
  * See LICENSE.md in the project root for license terms and full copyright notice.
5
5
  *--------------------------------------------------------------------------------------------*/
6
6
  import { ConditionalBooleanValue } from "@itwin/appui-abstract";
7
- import { StagePanelLocation, StagePanelSection, ToolbarItemUtilities, ToolbarOrientation, ToolbarUsage, WidgetState } from "@itwin/appui-react";
7
+ import { StagePanelLocation, StagePanelSection, ToolbarItemUtilities, ToolbarOrientation, ToolbarUsage, WidgetState, } from "@itwin/appui-react";
8
8
  import { IModelApp } from "@itwin/core-frontend";
9
9
  import { SvgMapInfo } from "@itwin/itwinui-icons-react";
10
10
  import { MapFeatureInfoTool } from "@itwin/map-layers-formats";
@@ -36,7 +36,7 @@ const isMapFeatureInfoSupported = () => {
36
36
  }
37
37
  return false;
38
38
  };
39
- export const getMapFeatureInfoToolItemDef = (itemPriority) => {
39
+ export const getMapFeatureInfoToolItemDef = (itemPriority, toolbarOrientation = ToolbarOrientation.Vertical) => {
40
40
  return ToolbarItemUtilities.createActionItem({
41
41
  id: MapFeatureInfoTool.toolId,
42
42
  icon: _jsx(SvgMapInfo, {}), // TODO: Update to iconNode when moving to 5.x appui-react
@@ -52,7 +52,7 @@ export const getMapFeatureInfoToolItemDef = (itemPriority) => {
52
52
  }, [MapLayersSyncUiEventId.MapImageryChanged]),
53
53
  layouts: {
54
54
  standard: {
55
- orientation: ToolbarOrientation.Vertical,
55
+ orientation: toolbarOrientation,
56
56
  usage: ToolbarUsage.ContentManipulation,
57
57
  }
58
58
  }
@@ -67,17 +67,19 @@ export class FeatureInfoUiItemsProvider {
67
67
  }
68
68
  getToolbarItems() {
69
69
  if (!this._featureInfoOpts?.disableDefaultFeatureInfoTool) {
70
- return [getMapFeatureInfoToolItemDef(60)];
70
+ return [getMapFeatureInfoToolItemDef(this._featureInfoOpts?.itemPriority ?? 60, this._featureInfoOpts?.toolbarOrientation)];
71
71
  }
72
72
  return [];
73
73
  }
74
74
  getWidgets() {
75
+ if (this._featureInfoOpts?.disableDefaultFeatureInfoWidget)
76
+ return [];
75
77
  const widgets = [];
76
78
  widgets.push({
77
79
  id: FeatureInfoUiItemsProvider.widgetId,
78
80
  label: MapLayersUI.localization.getLocalizedString("mapLayers:FeatureInfoWidget.Label"),
79
81
  icon: _jsx(SvgMapInfo, {}),
80
- content: _jsx(MapFeatureInfoWidget, { featureInfoOpts: this._featureInfoOpts }),
82
+ content: _jsx(MapFeatureInfoWidget, { widgetId: FeatureInfoUiItemsProvider.widgetId, isPropertySelectionEnabled: this._featureInfoOpts.propertyGridOptions?.isPropertySelectionEnabled }),
81
83
  defaultState: WidgetState.Hidden,
82
84
  layouts: {
83
85
  standard: {
@@ -1 +1 @@
1
- {"version":3,"file":"FeatureInfoUiItemsProvider.js","sourceRoot":"","sources":["../../../src/ui/FeatureInfoUiItemsProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ConditionalBooleanValue } from \"@itwin/appui-abstract\";\nimport {\n StagePanelLocation,\n StagePanelSection,\n ToolbarItemUtilities,\n ToolbarOrientation,\n ToolbarUsage,\n WidgetState\n} from \"@itwin/appui-react\";\nimport { IModelApp } from \"@itwin/core-frontend\";\nimport { SvgMapInfo } from \"@itwin/itwinui-icons-react\";\nimport { MapFeatureInfoTool } from \"@itwin/map-layers-formats\";\nimport { MapLayersUI } from \"../mapLayers\";\nimport { MapLayersSyncUiEventId } from \"../MapLayersActionIds\";\nimport { MapFeatureInfoWidget } from \"./widget/FeatureInfoWidget\";\n\nimport type { ToolbarActionItem, ToolbarItem, UiItemsProvider, Widget } from \"@itwin/appui-react\";\nimport type { ScreenViewport } from \"@itwin/core-frontend\";\nimport type { MapLayerProps } from \"@itwin/core-common\";\nimport type { MapFeatureInfoOptions } from \"./Interfaces\";\nconst supportsMapFeatureInfo = (vp: ScreenViewport, isOverlay: boolean, mapLayerProps: MapLayerProps[]): boolean => {\n for (let mapLayerIndex = 0; mapLayerIndex < mapLayerProps.length; mapLayerIndex++) {\n if (mapLayerProps[mapLayerIndex].visible && mapLayerProps[mapLayerIndex].transparency !== 1.0) {\n const layerProvider = vp.getMapLayerImageryProvider({ index: mapLayerIndex, isOverlay });\n if (layerProvider?.supportsMapFeatureInfo) {\n return true;\n }\n }\n }\n return false;\n};\n\nconst isMapFeatureInfoSupported = (): boolean => {\n const vp = IModelApp.viewManager.selectedView;\n if (vp?.viewFlags.backgroundMap) {\n const backgroundLayers = vp.displayStyle.settings.mapImagery.backgroundLayers.map((value) => value.toJSON());\n if (supportsMapFeatureInfo(vp, false, backgroundLayers)) {\n return true;\n }\n const overlayLayers = vp.displayStyle.settings.mapImagery.overlayLayers.map((value) => value.toJSON());\n if (supportsMapFeatureInfo(vp, true, overlayLayers)) {\n return true;\n }\n }\n return false;\n};\n\nexport const getMapFeatureInfoToolItemDef = (itemPriority: number): ToolbarActionItem => {\n return ToolbarItemUtilities.createActionItem({\n id: MapFeatureInfoTool.toolId,\n icon: <SvgMapInfo />, // TODO: Update to iconNode when moving to 5.x appui-react\n label: MapLayersUI.localization.getLocalizedString(\"mapLayers:FeatureInfoWidget.Label\"),\n description: MapFeatureInfoTool.description,\n itemPriority,\n execute: async () => {\n await IModelApp.tools.run(MapFeatureInfoTool.toolId);\n },\n isHidden: new ConditionalBooleanValue(() => {\n // Hide the MapFeatureInfoTool if the Map Layers toggle is off or no ArcGISFeature layers are active\n return !isMapFeatureInfoSupported();\n }, [MapLayersSyncUiEventId.MapImageryChanged]),\n layouts: {\n standard: {\n orientation: ToolbarOrientation.Vertical,\n usage: ToolbarUsage.ContentManipulation,\n }\n }\n });\n};\n\nexport class FeatureInfoUiItemsProvider implements UiItemsProvider {\n public readonly id = \"FeatureInfoUiItemsProvider\";\n public static readonly widgetId = \"map-layers:mapFeatureInfoWidget\";\n\n public constructor(private _featureInfoOpts: MapFeatureInfoOptions) {}\n\n public getToolbarItems(): ReadonlyArray<ToolbarItem> {\n if (!this._featureInfoOpts?.disableDefaultFeatureInfoTool) {\n return [getMapFeatureInfoToolItemDef(60)];\n }\n\n return [];\n }\n\n public getWidgets(): Widget[] {\n const widgets: Widget[] = [];\n widgets.push({\n id: FeatureInfoUiItemsProvider.widgetId,\n label: MapLayersUI.localization.getLocalizedString(\"mapLayers:FeatureInfoWidget.Label\"),\n icon: <SvgMapInfo />,\n content: <MapFeatureInfoWidget featureInfoOpts={this._featureInfoOpts} />,\n defaultState: WidgetState.Hidden,\n layouts: {\n standard: {\n location: StagePanelLocation.Right,\n section: StagePanelSection.End,\n },\n },\n });\n return widgets;\n }\n}\n"]}
1
+ {"version":3,"file":"FeatureInfoUiItemsProvider.js","sourceRoot":"","sources":["../../../src/ui/FeatureInfoUiItemsProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ConditionalBooleanValue } from \"@itwin/appui-abstract\";\nimport {\n StagePanelLocation, StagePanelSection, ToolbarItemUtilities, ToolbarOrientation, ToolbarUsage, WidgetState,\n} from \"@itwin/appui-react\";\nimport { IModelApp } from \"@itwin/core-frontend\";\nimport { SvgMapInfo } from \"@itwin/itwinui-icons-react\";\nimport { MapFeatureInfoTool } from \"@itwin/map-layers-formats\";\n\nimport { MapLayersUI } from \"../mapLayers\";\nimport { MapLayersSyncUiEventId } from \"../MapLayersActionIds\";\nimport { MapFeatureInfoWidget } from \"./widget/FeatureInfoWidget\";\n\nimport type { ToolbarActionItem, ToolbarItem, UiItemsProvider, Widget } from \"@itwin/appui-react\";\nimport type { ScreenViewport } from \"@itwin/core-frontend\";\nimport type { MapLayerProps } from \"@itwin/core-common\";\nimport type { MapFeatureInfoOptions } from \"./Interfaces\";\nconst supportsMapFeatureInfo = (vp: ScreenViewport, isOverlay: boolean, mapLayerProps: MapLayerProps[]): boolean => {\n for (let mapLayerIndex = 0; mapLayerIndex < mapLayerProps.length; mapLayerIndex++) {\n if (mapLayerProps[mapLayerIndex].visible && mapLayerProps[mapLayerIndex].transparency !== 1.0) {\n const layerProvider = vp.getMapLayerImageryProvider({ index: mapLayerIndex, isOverlay });\n if (layerProvider?.supportsMapFeatureInfo) {\n return true;\n }\n }\n }\n return false;\n};\n\nconst isMapFeatureInfoSupported = (): boolean => {\n const vp = IModelApp.viewManager.selectedView;\n if (vp?.viewFlags.backgroundMap) {\n const backgroundLayers = vp.displayStyle.settings.mapImagery.backgroundLayers.map((value) => value.toJSON());\n if (supportsMapFeatureInfo(vp, false, backgroundLayers)) {\n return true;\n }\n const overlayLayers = vp.displayStyle.settings.mapImagery.overlayLayers.map((value) => value.toJSON());\n if (supportsMapFeatureInfo(vp, true, overlayLayers)) {\n return true;\n }\n }\n return false;\n};\n\nexport const getMapFeatureInfoToolItemDef = (itemPriority: number, toolbarOrientation = ToolbarOrientation.Vertical): ToolbarActionItem => {\n return ToolbarItemUtilities.createActionItem({\n id: MapFeatureInfoTool.toolId,\n icon: <SvgMapInfo />, // TODO: Update to iconNode when moving to 5.x appui-react\n label: MapLayersUI.localization.getLocalizedString(\"mapLayers:FeatureInfoWidget.Label\"),\n description: MapFeatureInfoTool.description,\n itemPriority,\n execute: async () => {\n await IModelApp.tools.run(MapFeatureInfoTool.toolId);\n },\n isHidden: new ConditionalBooleanValue(() => {\n // Hide the MapFeatureInfoTool if the Map Layers toggle is off or no ArcGISFeature layers are active\n return !isMapFeatureInfoSupported();\n }, [MapLayersSyncUiEventId.MapImageryChanged]),\n layouts: {\n standard: {\n orientation: toolbarOrientation,\n usage: ToolbarUsage.ContentManipulation,\n }\n }\n });\n};\n\nexport class FeatureInfoUiItemsProvider implements UiItemsProvider {\n public readonly id = \"FeatureInfoUiItemsProvider\";\n public static readonly widgetId = \"map-layers:mapFeatureInfoWidget\";\n\n public constructor(private _featureInfoOpts: MapFeatureInfoOptions) {}\n\n public getToolbarItems(): ReadonlyArray<ToolbarItem> {\n if (!this._featureInfoOpts?.disableDefaultFeatureInfoTool) {\n return [getMapFeatureInfoToolItemDef(this._featureInfoOpts?.itemPriority ?? 60, this._featureInfoOpts?.toolbarOrientation)];\n }\n\n return [];\n }\n\n public getWidgets(): Widget[] {\n if (this._featureInfoOpts?.disableDefaultFeatureInfoWidget)\n return [];\n\n const widgets: Widget[] = [];\n widgets.push({\n id: FeatureInfoUiItemsProvider.widgetId,\n label: MapLayersUI.localization.getLocalizedString(\"mapLayers:FeatureInfoWidget.Label\"),\n icon: <SvgMapInfo />,\n content: <MapFeatureInfoWidget widgetId={FeatureInfoUiItemsProvider.widgetId}\n isPropertySelectionEnabled={this._featureInfoOpts.propertyGridOptions?.isPropertySelectionEnabled} />,\n defaultState: WidgetState.Hidden,\n layouts: {\n standard: {\n location: StagePanelLocation.Right,\n section: StagePanelSection.End,\n },\n },\n });\n return widgets;\n }\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import type { BeEvent } from "@itwin/core-bentley";
2
2
  import type { BaseMapLayerSettings, MapSubLayerProps } from "@itwin/core-common";
3
3
  import type { HitDetail, MapLayerImageryProvider, MapTileTreeScaleRangeVisibility } from "@itwin/core-frontend";
4
+ import type { ToolbarOrientation } from "@itwin/appui-react";
4
5
  export interface StyleMapLayerSettings {
5
6
  /** Name */
6
7
  name: string;
@@ -48,6 +49,14 @@ export interface MapFeatureInfoOptions {
48
49
  disableDefaultFeatureInfoTool?: boolean;
49
50
  showLoadProgressAnimation?: boolean;
50
51
  propertyGridOptions?: MapFeatureInfoPropertyGridOptions;
52
+ toolbarOrientation?: ToolbarOrientation;
53
+ itemPriority?: number;
54
+ /**
55
+ * Optional flag to disable the default feature info widget.
56
+ * When true, the default widget will not be created, allowing you to display
57
+ * the feature info content in a custom widget.
58
+ */
59
+ disableDefaultFeatureInfoWidget?: boolean;
51
60
  }
52
61
  export interface CustomParamItem {
53
62
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"Interfaces.d.ts","sourceRoot":"","sources":["../../../src/ui/Interfaces.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,uBAAuB,EAAE,+BAA+B,EAAE,MAAM,sBAAsB,CAAC;AAEhH,MAAM,WAAW,qBAAqB;IACpC,WAAW;IACX,IAAI,EAAE,MAAM,CAAC;IACb,qFAAqF;IACrF,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,+BAA+B,CAAC;IAChD,2MAA2M;IAC3M,YAAY,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,qCAAqC;IACrC,SAAS,EAAE,OAAO,CAAC;IACnB,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/B,iCAAiC;IACjC,aAAa,EAAE,OAAO,CAAC;IACvB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,uBAAuB,CAAC;IAEnC,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,wBAAwB,EAAE,OAAO,CAAC;CAC5C;AAED,MAAM,WAAW,eAAe;IAC9B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,cAAc,CAAC,EAAE,eAAe,CAAC;IAEjC,iFAAiF;IACjF,aAAa,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAEvC,qGAAqG;IACrG,iCAAiC,CAAC,EAAE,OAAO,CAAC;IAE5C,uCAAuC;IACvC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,iCAAiC;IAChD,0BAA0B,CAAC,EAAE,OAAO,CAAC;CACtC;AAED,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC,CAAC;AAE5D,MAAM,WAAW,qBAAqB;IACpC,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,mBAAmB,CAAC,EAAE,iCAAiC,CAAC;CACzD;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B"}
1
+ {"version":3,"file":"Interfaces.d.ts","sourceRoot":"","sources":["../../../src/ui/Interfaces.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,uBAAuB,EAAE,+BAA+B,EAAE,MAAM,sBAAsB,CAAC;AAChH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,MAAM,WAAW,qBAAqB;IACpC,WAAW;IACX,IAAI,EAAE,MAAM,CAAC;IACb,qFAAqF;IACrF,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,+BAA+B,CAAC;IAChD,2MAA2M;IAC3M,YAAY,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,qCAAqC;IACrC,SAAS,EAAE,OAAO,CAAC;IACnB,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/B,iCAAiC;IACjC,aAAa,EAAE,OAAO,CAAC;IACvB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,uBAAuB,CAAC;IAEnC,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,wBAAwB,EAAE,OAAO,CAAC;CAC5C;AAED,MAAM,WAAW,eAAe;IAC9B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,cAAc,CAAC,EAAE,eAAe,CAAC;IAEjC,iFAAiF;IACjF,aAAa,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAEvC,qGAAqG;IACrG,iCAAiC,CAAC,EAAE,OAAO,CAAC;IAE5C,uCAAuC;IACvC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,iCAAiC;IAChD,0BAA0B,CAAC,EAAE,OAAO,CAAC;CACtC;AAED,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC,CAAC;AAE5D,MAAM,WAAW,qBAAqB;IACpC,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,mBAAmB,CAAC,EAAE,iCAAiC,CAAC;IACxD,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,+BAA+B,CAAC,EAAE,OAAO,CAAC;CAC3C;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B"}
@@ -1 +1 @@
1
- {"version":3,"file":"Interfaces.js","sourceRoot":"","sources":["../../../src/ui/Interfaces.ts"],"names":[],"mappings":"","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\nimport type { BeEvent } from \"@itwin/core-bentley\";\nimport type { BaseMapLayerSettings, MapSubLayerProps } from \"@itwin/core-common\";\nimport type { HitDetail, MapLayerImageryProvider, MapTileTreeScaleRangeVisibility } from \"@itwin/core-frontend\";\n\nexport interface StyleMapLayerSettings {\n /** Name */\n name: string;\n /** source (i.URL for ImageMapLayerSettings or modelId for ModelMapLayerSettings) */\n source: string;\n /** Controls visibility of layer */\n visible: boolean;\n treeVisibility: MapTileTreeScaleRangeVisibility;\n /** A transparency value from 0.0 (fully opaque) to 1.0 (fully transparent) to apply to map graphics when drawing, or false to indicate the transparency should not be overridden. Default value: false. */\n transparency: number;\n /** Transparent background */\n transparentBackground: boolean;\n /** set map as underlay or overlay */\n isOverlay: boolean;\n /** layer index in the viewport */\n layerIndex: number;\n /** Available map sub-layer */\n subLayers?: MapSubLayerProps[];\n /** sub-layer panel displayed. */\n showSubLayers: boolean;\n /** Some format can publish only a single layer at a time (i.e WMTS) */\n provider?: MapLayerImageryProvider;\n\n selected: boolean;\n}\n\nexport interface MapTypesOptions {\n readonly supportTileUrl: boolean;\n readonly supportWmsAuthentication: boolean;\n}\n\nexport interface MapLayerOptions {\n hideExternalMapLayers?: boolean;\n fetchPublicMapLayerSources?: boolean;\n mapTypeOptions?: MapTypesOptions;\n\n /** Optional list of base map-layers to display in the base map select control */\n baseMapLayers?: BaseMapLayerSettings[];\n\n /** Optionally show the user preferences storage options(i.e. iTwin vs iModel). Defaults to false */\n showUserPreferencesStorageOptions?: boolean;\n\n /** Optionally hide the header label */\n hideHeaderLabel?: boolean;\n}\n\nexport interface MapFeatureInfoPropertyGridOptions {\n isPropertySelectionEnabled?: boolean;\n}\n\nexport type MapHitEvent = BeEvent<(hit: HitDetail) => void>;\n\nexport interface MapFeatureInfoOptions {\n disableDefaultFeatureInfoTool?: boolean;\n showLoadProgressAnimation?: boolean;\n propertyGridOptions?: MapFeatureInfoPropertyGridOptions;\n}\n\nexport interface CustomParamItem {\n name: string;\n key: string;\n value: string;\n secret: boolean;\n}\n\nexport interface CustomParamsMappingItem {\n customParamNames: string[];\n}\n"]}
1
+ {"version":3,"file":"Interfaces.js","sourceRoot":"","sources":["../../../src/ui/Interfaces.ts"],"names":[],"mappings":"","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\nimport type { BeEvent } from \"@itwin/core-bentley\";\nimport type { BaseMapLayerSettings, MapSubLayerProps } from \"@itwin/core-common\";\nimport type { HitDetail, MapLayerImageryProvider, MapTileTreeScaleRangeVisibility } from \"@itwin/core-frontend\";\nimport type { ToolbarOrientation } from \"@itwin/appui-react\";\n\nexport interface StyleMapLayerSettings {\n /** Name */\n name: string;\n /** source (i.URL for ImageMapLayerSettings or modelId for ModelMapLayerSettings) */\n source: string;\n /** Controls visibility of layer */\n visible: boolean;\n treeVisibility: MapTileTreeScaleRangeVisibility;\n /** A transparency value from 0.0 (fully opaque) to 1.0 (fully transparent) to apply to map graphics when drawing, or false to indicate the transparency should not be overridden. Default value: false. */\n transparency: number;\n /** Transparent background */\n transparentBackground: boolean;\n /** set map as underlay or overlay */\n isOverlay: boolean;\n /** layer index in the viewport */\n layerIndex: number;\n /** Available map sub-layer */\n subLayers?: MapSubLayerProps[];\n /** sub-layer panel displayed. */\n showSubLayers: boolean;\n /** Some format can publish only a single layer at a time (i.e WMTS) */\n provider?: MapLayerImageryProvider;\n\n selected: boolean;\n}\n\nexport interface MapTypesOptions {\n readonly supportTileUrl: boolean;\n readonly supportWmsAuthentication: boolean;\n}\n\nexport interface MapLayerOptions {\n hideExternalMapLayers?: boolean;\n fetchPublicMapLayerSources?: boolean;\n mapTypeOptions?: MapTypesOptions;\n\n /** Optional list of base map-layers to display in the base map select control */\n baseMapLayers?: BaseMapLayerSettings[];\n\n /** Optionally show the user preferences storage options(i.e. iTwin vs iModel). Defaults to false */\n showUserPreferencesStorageOptions?: boolean;\n\n /** Optionally hide the header label */\n hideHeaderLabel?: boolean;\n}\n\nexport interface MapFeatureInfoPropertyGridOptions {\n isPropertySelectionEnabled?: boolean;\n}\n\nexport type MapHitEvent = BeEvent<(hit: HitDetail) => void>;\n\nexport interface MapFeatureInfoOptions {\n disableDefaultFeatureInfoTool?: boolean;\n showLoadProgressAnimation?: boolean;\n propertyGridOptions?: MapFeatureInfoPropertyGridOptions;\n toolbarOrientation?: ToolbarOrientation;\n itemPriority?: number;\n /**\n * Optional flag to disable the default feature info widget.\n * When true, the default widget will not be created, allowing you to display\n * the feature info content in a custom widget.\n */\n disableDefaultFeatureInfoWidget?: boolean;\n}\n\nexport interface CustomParamItem {\n name: string;\n key: string;\n value: string;\n secret: boolean;\n}\n\nexport interface CustomParamsMappingItem {\n customParamNames: string[];\n}\n"]}
@@ -1,2 +1,7 @@
1
+ /** Hook that will observe Window Resize
2
+ * @internal
3
+ * Reference: https://github.com/iTwin/iTwinUI/blob/87bbc99316c17bd2b763a730135fbb45c84b0e82/packages/itwinui-react/src/utils/hooks/useResizeObserver.tsx
4
+ * Copied from: https://github.com/iTwin/appui/blob/master/ui/core-react/src/core-react/utils/hooks/useResizeObserver.tsx
5
+ */
1
6
  export declare const useResizeObserver: <T extends HTMLElement>(onResize: (size: DOMRectReadOnly) => void) => readonly [(element: T | null | undefined) => void, ResizeObserver | undefined];
2
7
  //# sourceMappingURL=useResizeObserver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useResizeObserver.d.ts","sourceRoot":"","sources":["../../../../src/ui/hooks/useResizeObserver.tsx"],"names":[],"mappings":"AAeA,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,WAAW,YAC3C,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,yBAK7B,CAAC,GAAG,IAAI,GAAG,SAAS,sCA2BjC,CAAC"}
1
+ {"version":3,"file":"useResizeObserver.d.ts","sourceRoot":"","sources":["../../../../src/ui/hooks/useResizeObserver.tsx"],"names":[],"mappings":"AAUA;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,WAAW,YAC3C,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,yBAK7B,CAAC,GAAG,IAAI,GAAG,SAAS,sCA2BjC,CAAC"}
@@ -3,14 +3,14 @@
3
3
  * See LICENSE.md in the project root for license terms and full copyright notice.
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import * as React from "react";
6
+ const getWindow = () => {
7
+ return typeof window === "undefined" ? undefined : window;
8
+ };
6
9
  /** Hook that will observe Window Resize
7
10
  * @internal
8
11
  * Reference: https://github.com/iTwin/iTwinUI/blob/87bbc99316c17bd2b763a730135fbb45c84b0e82/packages/itwinui-react/src/utils/hooks/useResizeObserver.tsx
9
12
  * Copied from: https://github.com/iTwin/appui/blob/master/ui/core-react/src/core-react/utils/hooks/useResizeObserver.tsx
10
13
  */
11
- const getWindow = () => {
12
- return typeof window === "undefined" ? undefined : window;
13
- };
14
14
  export const useResizeObserver = (onResize) => {
15
15
  const resizeObserver = React.useRef();
16
16
  const elementRef = React.useCallback((element) => {
@@ -1 +1 @@
1
- {"version":3,"file":"useResizeObserver.js","sourceRoot":"","sources":["../../../../src/ui/hooks/useResizeObserver.tsx"],"names":[],"mappings":"AAAA;;;gGAGgG;AAChG,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;;;GAIG;AACH,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,OAAO,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;AAC5D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,QAAyC,EACzC,EAAE;IACF,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,EAAkB,CAAC;IAEtD,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,CAClC,CAAC,OAA6B,EAAE,EAAE;QAChC,IAAI,CAAC,SAAS,EAAE,EAAE,cAAc,EAAE,CAAC;YACjC,OAAO;QACT,CAAC;QAED,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC;QACvC,IAAI,OAAO,EAAE,CAAC;YACZ,cAAc,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC,CAAC,OAAO,EAAE,EAAE;gBACtD,uGAAuG;gBACvG,oDAAoD;gBACpD,qDAAqD;gBACrD,MAAM,CAAC,qBAAqB,CAAC,GAAG,EAAE;oBAChC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;wBAC/C,OAAO;oBACT,CAAC;oBAED,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC,GAAG,OAAO,CAAC;oBAClC,OAAO,QAAQ,CAAC,WAAW,CAAC,CAAC;gBAC/B,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YACH,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAC;IAEF,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,OAAO,CAAU,CAAC;AACvD,CAAC,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\nimport * as React from \"react\";\n\n/** Hook that will observe Window Resize\n * @internal\n * Reference: https://github.com/iTwin/iTwinUI/blob/87bbc99316c17bd2b763a730135fbb45c84b0e82/packages/itwinui-react/src/utils/hooks/useResizeObserver.tsx\n * Copied from: https://github.com/iTwin/appui/blob/master/ui/core-react/src/core-react/utils/hooks/useResizeObserver.tsx\n */\nconst getWindow = () => {\n return typeof window === \"undefined\" ? undefined : window;\n};\n\nexport const useResizeObserver = <T extends HTMLElement>(\n onResize: (size: DOMRectReadOnly) => void,\n) => {\n const resizeObserver = React.useRef<ResizeObserver>();\n\n const elementRef = React.useCallback(\n (element: T | null | undefined) => {\n if (!getWindow()?.ResizeObserver) {\n return;\n }\n\n resizeObserver.current?.disconnect?.();\n if (element) {\n resizeObserver.current = new ResizeObserver((entries) => {\n // We wrap onResize with requestAnimationFrame to avoid this error - ResizeObserver loop limit exceeded\n // See: https://github.com/iTwin/iTwinUI/issues/1317\n // See: https://stackoverflow.com/a/58701523/11547064\n window.requestAnimationFrame(() => {\n if (!Array.isArray(entries) || !entries.length) {\n return;\n }\n\n const [{ contentRect }] = entries;\n return onResize(contentRect);\n });\n });\n resizeObserver.current?.observe?.(element);\n }\n },\n [onResize],\n );\n\n return [elementRef, resizeObserver.current] as const;\n};\n"]}
1
+ {"version":3,"file":"useResizeObserver.js","sourceRoot":"","sources":["../../../../src/ui/hooks/useResizeObserver.tsx"],"names":[],"mappings":"AAAA;;;gGAGgG;AAChG,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,OAAO,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;AAC5D,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,QAAyC,EACzC,EAAE;IACF,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,EAAkB,CAAC;IAEtD,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,CAClC,CAAC,OAA6B,EAAE,EAAE;QAChC,IAAI,CAAC,SAAS,EAAE,EAAE,cAAc,EAAE,CAAC;YACjC,OAAO;QACT,CAAC;QAED,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC;QACvC,IAAI,OAAO,EAAE,CAAC;YACZ,cAAc,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC,CAAC,OAAO,EAAE,EAAE;gBACtD,uGAAuG;gBACvG,oDAAoD;gBACpD,qDAAqD;gBACrD,MAAM,CAAC,qBAAqB,CAAC,GAAG,EAAE;oBAChC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;wBAC/C,OAAO;oBACT,CAAC;oBAED,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC,GAAG,OAAO,CAAC;oBAClC,OAAO,QAAQ,CAAC,WAAW,CAAC,CAAC;gBAC/B,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YACH,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAC;IAEF,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,OAAO,CAAU,CAAC;AACvD,CAAC,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\nimport * as React from \"react\";\n\nconst getWindow = () => {\n return typeof window === \"undefined\" ? undefined : window;\n};\n\n/** Hook that will observe Window Resize\n * @internal\n * Reference: https://github.com/iTwin/iTwinUI/blob/87bbc99316c17bd2b763a730135fbb45c84b0e82/packages/itwinui-react/src/utils/hooks/useResizeObserver.tsx\n * Copied from: https://github.com/iTwin/appui/blob/master/ui/core-react/src/core-react/utils/hooks/useResizeObserver.tsx\n */\nexport const useResizeObserver = <T extends HTMLElement>(\n onResize: (size: DOMRectReadOnly) => void,\n) => {\n const resizeObserver = React.useRef<ResizeObserver>();\n\n const elementRef = React.useCallback(\n (element: T | null | undefined) => {\n if (!getWindow()?.ResizeObserver) {\n return;\n }\n\n resizeObserver.current?.disconnect?.();\n if (element) {\n resizeObserver.current = new ResizeObserver((entries) => {\n // We wrap onResize with requestAnimationFrame to avoid this error - ResizeObserver loop limit exceeded\n // See: https://github.com/iTwin/iTwinUI/issues/1317\n // See: https://stackoverflow.com/a/58701523/11547064\n window.requestAnimationFrame(() => {\n if (!Array.isArray(entries) || !entries.length) {\n return;\n }\n\n const [{ contentRect }] = entries;\n return onResize(contentRect);\n });\n });\n resizeObserver.current?.observe?.(element);\n }\n },\n [onResize],\n );\n\n return [elementRef, resizeObserver.current] as const;\n};\n"]}
@@ -0,0 +1,12 @@
1
+ interface CopyActionButtonProps {
2
+ value: string;
3
+ onCopy?: (value: string) => Promise<void> | void;
4
+ }
5
+ /**
6
+ * Renders an icon button that copies a value to the clipboard.
7
+ *
8
+ * After a click, the icon and label briefly switch to a copied state.
9
+ */
10
+ export declare function CopyActionButton({ value, onCopy }: CopyActionButtonProps): import("react/jsx-runtime").JSX.Element;
11
+ export {};
12
+ //# sourceMappingURL=CopyActionButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CopyActionButton.d.ts","sourceRoot":"","sources":["../../../../src/ui/widget/CopyActionButton.tsx"],"names":[],"mappings":"AAQA,UAAU,qBAAqB;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAClD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,qBAAqB,2CA6CxE"}
@@ -0,0 +1,46 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { SvgCheckmarkSmall, SvgCopy } from "@itwin/itwinui-icons-react";
3
+ import { IconButton } from "@itwin/itwinui-react";
4
+ import { useEffect, useRef, useState } from "react";
5
+ import { IModelApp, NotifyMessageDetails, OutputMessagePriority } from "@itwin/core-frontend";
6
+ import { MapLayersUI } from "../../mapLayers";
7
+ /**
8
+ * Renders an icon button that copies a value to the clipboard.
9
+ *
10
+ * After a click, the icon and label briefly switch to a copied state.
11
+ */
12
+ export function CopyActionButton({ value, onCopy }) {
13
+ const [isCopied, setIsCopied] = useState(false);
14
+ const timeoutRef = useRef(undefined);
15
+ useEffect(() => {
16
+ return () => {
17
+ if (timeoutRef.current !== undefined) {
18
+ clearTimeout(timeoutRef.current);
19
+ }
20
+ };
21
+ }, []);
22
+ return (_jsx(IconButton, { styleType: "borderless", label: isCopied ? MapLayersUI.localization.getLocalizedString("mapLayers:FeatureInfoWidget.Copied") : MapLayersUI.localization.getLocalizedString("mapLayers:FeatureInfoWidget.Copy"), onClick: async () => {
23
+ try {
24
+ if (onCopy) {
25
+ await onCopy(value);
26
+ }
27
+ else {
28
+ await navigator.clipboard.writeText(value);
29
+ }
30
+ setIsCopied(true);
31
+ if (timeoutRef.current !== undefined) {
32
+ clearTimeout(timeoutRef.current);
33
+ }
34
+ timeoutRef.current = setTimeout(() => {
35
+ setIsCopied(false);
36
+ timeoutRef.current = undefined;
37
+ }, 1200);
38
+ }
39
+ catch {
40
+ const copyFailedMessage = MapLayersUI.localization.getLocalizedString("mapLayers:FeatureInfoWidget.CopyFailed");
41
+ IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Warning, copyFailedMessage));
42
+ }
43
+ }, disabled: isCopied, children: isCopied ? _jsx(SvgCheckmarkSmall, {}) : _jsx(SvgCopy, {}) }, String(isCopied)));
44
+ }
45
+ ;
46
+ //# sourceMappingURL=CopyActionButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CopyActionButton.js","sourceRoot":"","sources":["../../../../src/ui/widget/CopyActionButton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE9F,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAO9C;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAyB;IACvE,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,MAAM,CAAqB,SAAS,CAAC,CAAC;IAEzD,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,GAAG,EAAE;YACV,IAAI,UAAU,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gBACrC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACnC,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,KAAC,UAAU,IACT,SAAS,EAAC,YAAY,EACtB,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,YAAY,CAAC,kBAAkB,CAAC,oCAAoC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,YAAY,CAAC,kBAAkB,CAAC,kCAAkC,CAAC,EACrL,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,IAAI,CAAC;gBACH,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;gBACtB,CAAC;qBAAM,CAAC;oBACN,MAAM,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBAC7C,CAAC;gBACD,WAAW,CAAC,IAAI,CAAC,CAAC;gBAElB,IAAI,UAAU,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;oBACrC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBACnC,CAAC;gBAED,UAAU,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;oBACnC,WAAW,CAAC,KAAK,CAAC,CAAC;oBACnB,UAAU,CAAC,OAAO,GAAG,SAAS,CAAC;gBACjC,CAAC,EAAE,IAAI,CAAC,CAAC;YACX,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,iBAAiB,GAAG,WAAW,CAAC,YAAY,CAAC,kBAAkB,CAAC,wCAAwC,CAAC,CAAC;gBAChH,SAAS,CAAC,aAAa,CAAC,aAAa,CAAC,IAAI,oBAAoB,CAAC,qBAAqB,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC;YACpH,CAAC;QACH,CAAC,EACD,QAAQ,EAAE,QAAQ,YAIjB,QAAQ,CAAC,CAAC,CAAC,KAAC,iBAAiB,KAAG,CAAC,CAAC,CAAC,KAAC,OAAO,KAAG,IAF1C,MAAM,CAAC,QAAQ,CAAC,CAGV,CACd,CAAC;AACJ,CAAC;AAAA,CAAC","sourcesContent":["import { SvgCheckmarkSmall, SvgCopy } from \"@itwin/itwinui-icons-react\";\nimport { IconButton } from \"@itwin/itwinui-react\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { IModelApp, NotifyMessageDetails, OutputMessagePriority } from \"@itwin/core-frontend\";\n\nimport { MapLayersUI } from \"../../mapLayers\";\n\ninterface CopyActionButtonProps {\n value: string;\n onCopy?: (value: string) => Promise<void> | void;\n}\n\n/**\n * Renders an icon button that copies a value to the clipboard.\n *\n * After a click, the icon and label briefly switch to a copied state.\n */\nexport function CopyActionButton({ value, onCopy }: CopyActionButtonProps) {\n const [isCopied, setIsCopied] = useState(false);\n const timeoutRef = useRef<number | undefined>(undefined);\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current !== undefined) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n return (\n <IconButton\n styleType=\"borderless\"\n label={isCopied ? MapLayersUI.localization.getLocalizedString(\"mapLayers:FeatureInfoWidget.Copied\") : MapLayersUI.localization.getLocalizedString(\"mapLayers:FeatureInfoWidget.Copy\")}\n onClick={async () => {\n try {\n if (onCopy) {\n await onCopy(value);\n } else {\n await navigator.clipboard.writeText(value);\n }\n setIsCopied(true);\n\n if (timeoutRef.current !== undefined) {\n clearTimeout(timeoutRef.current);\n }\n\n timeoutRef.current = setTimeout(() => {\n setIsCopied(false);\n timeoutRef.current = undefined;\n }, 1200);\n } catch {\n const copyFailedMessage = MapLayersUI.localization.getLocalizedString(\"mapLayers:FeatureInfoWidget.CopyFailed\");\n IModelApp.notifications.outputMessage(new NotifyMessageDetails(OutputMessagePriority.Warning, copyFailedMessage));\n }\n }}\n disabled={isCopied}\n // Use key to reset internal state of IconButton when isCopied changes, ensuring the label updates immediately.\n key={String(isCopied)}\n >\n {isCopied ? <SvgCheckmarkSmall /> : <SvgCopy />}\n </IconButton>\n );\n};\n"]}
@@ -1,9 +1,27 @@
1
1
  import "./FeatureInfoWidget.scss";
2
- import type { MapFeatureInfoOptions } from "../Interfaces";
3
- export declare function useSpecificWidgetDef(id: string): import("@itwin/appui-react").WidgetDef | undefined;
2
+ /**
3
+ * Props for {@link MapFeatureInfoWidget}.
4
+ */
4
5
  interface MapFeatureInfoWidgetProps {
5
- featureInfoOpts: MapFeatureInfoOptions;
6
+ /** The widget that will be shown/hidden based on feature info data availability. */
7
+ widgetId: string;
8
+ /** Enables property selection support in the property grid when set. */
9
+ isPropertySelectionEnabled?: boolean;
10
+ /** Invoked when feature info data availability changes. */
11
+ onDataChanged?: (hasData: boolean) => void;
12
+ /**
13
+ * Optional copy handler used by the copy action button.
14
+ * When omitted, the component copies values using the browser clipboard API.
15
+ */
16
+ onCopy?: (value: string) => Promise<void> | void;
6
17
  }
7
- export declare function MapFeatureInfoWidget({ featureInfoOpts }: MapFeatureInfoWidgetProps): import("react/jsx-runtime").JSX.Element;
18
+ /**
19
+ * Displays map feature info in a virtualized property grid and keeps the
20
+ * owning widget open/hidden based on whether records are available.
21
+ *
22
+ * @param props - Widget configuration and callbacks.
23
+ * @returns The feature info property grid UI, or `null` when no records are available.
24
+ */
25
+ export declare function MapFeatureInfoWidget({ widgetId, isPropertySelectionEnabled, onDataChanged, onCopy }: MapFeatureInfoWidgetProps): import("react/jsx-runtime").JSX.Element | null;
8
26
  export {};
9
27
  //# sourceMappingURL=FeatureInfoWidget.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FeatureInfoWidget.d.ts","sourceRoot":"","sources":["../../../../src/ui/widget/FeatureInfoWidget.tsx"],"names":[],"mappings":"AAIA,OAAO,0BAA0B,CAAC;AAalC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3D,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,sDAG9C;AAGD,UAAU,yBAAyB;IACjC,eAAe,EAAE,qBAAqB,CAAC;CACxC;AAED,wBAAgB,oBAAoB,CAAC,EAAE,eAAe,EAAE,EAAE,yBAAyB,2CAmFlF"}
1
+ {"version":3,"file":"FeatureInfoWidget.d.ts","sourceRoot":"","sources":["../../../../src/ui/widget/FeatureInfoWidget.tsx"],"names":[],"mappings":"AAIA,OAAO,0BAA0B,CAAC;AAiBlC;;GAEG;AACH,UAAU,yBAAyB;IACjC,oFAAoF;IACpF,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,2DAA2D;IAC3D,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAClD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,QAAQ,EAAE,0BAA0B,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,yBAAyB,kDAiE9H"}
@@ -7,29 +7,33 @@ import "./FeatureInfoWidget.scss";
7
7
  import * as React from "react";
8
8
  import { useActiveFrontstageDef, WidgetState } from "@itwin/appui-react";
9
9
  import { Orientation, VirtualizedPropertyGridWithDataProvider } from "@itwin/components-react";
10
- import { SvgCopy } from "@itwin/itwinui-icons-react";
11
- import { Flex, IconButton } from "@itwin/itwinui-react";
12
- import { MapLayersUI } from "../../mapLayers";
13
- import { FeatureInfoUiItemsProvider } from "../FeatureInfoUiItemsProvider";
14
10
  import { useResizeObserver } from "../hooks/useResizeObserver";
11
+ import { CopyActionButton } from "./CopyActionButton";
15
12
  import { FeatureInfoDataProvider } from "./FeatureInfoDataProvider";
16
- export function useSpecificWidgetDef(id) {
13
+ function useSpecificWidgetDef(id) {
17
14
  const frontstageDef = useActiveFrontstageDef();
18
15
  return frontstageDef?.findWidgetDef(id);
19
16
  }
20
- export function MapFeatureInfoWidget({ featureInfoOpts }) {
17
+ /**
18
+ * Displays map feature info in a virtualized property grid and keeps the
19
+ * owning widget open/hidden based on whether records are available.
20
+ *
21
+ * @param props - Widget configuration and callbacks.
22
+ * @returns The feature info property grid UI, or `null` when no records are available.
23
+ */
24
+ export function MapFeatureInfoWidget({ widgetId, isPropertySelectionEnabled, onDataChanged, onCopy }) {
21
25
  const dataProvider = React.useRef(null);
22
26
  const [hasData, setHasData] = React.useState(false);
23
- const [noRecordsMessage] = React.useState(MapLayersUI.localization.getLocalizedString("mapLayers:FeatureInfoWidget.NoRecords"));
24
27
  const [{ width, height }, setSize] = React.useState({ width: 0, height: 0 });
25
- const widgetDef = useSpecificWidgetDef(FeatureInfoUiItemsProvider.widgetId);
28
+ const widgetDef = useSpecificWidgetDef(widgetId);
26
29
  const handleDataChanged = React.useCallback(() => {
27
30
  const dataAvailable = dataProvider.current !== null && dataProvider.current.hasRecords;
28
31
  setHasData(dataAvailable);
29
32
  if (widgetDef) {
30
33
  widgetDef.setWidgetState(dataAvailable ? WidgetState.Open : WidgetState.Hidden);
31
34
  }
32
- }, [widgetDef]);
35
+ onDataChanged?.(dataAvailable);
36
+ }, [widgetDef, onDataChanged]);
33
37
  React.useEffect(() => {
34
38
  dataProvider.current = new FeatureInfoDataProvider();
35
39
  return () => {
@@ -48,18 +52,13 @@ export function MapFeatureInfoWidget({ featureInfoOpts }) {
48
52
  const [elementRef] = useResizeObserver((size) => {
49
53
  handleResize(size.width, size.height);
50
54
  });
51
- const copyButton = React.useCallback((props) => props.isPropertyHovered && (_jsx("div", { children: _jsx(IconButton, { styleType: "borderless", label: "Copy", onClick: () => {
52
- const value = props.property.value;
53
- if (value !== undefined && value.hasOwnProperty("displayValue")) {
54
- navigator.clipboard.writeText(value.displayValue ?? "").catch((_) => { });
55
- }
56
- }, children: _jsx(SvgCopy, {}) }) })), []);
55
+ const copyButton = React.useCallback((props) => props.isPropertyHovered && (_jsx("div", { children: _jsx(CopyActionButton, { value: props.property.value ? props.property.value.displayValue ?? "" : "", onCopy: onCopy }) })), [onCopy]);
57
56
  if (hasData && dataProvider.current) {
58
- return (_jsx("div", { ref: elementRef, className: "feature-info-widget-container", children: _jsx(VirtualizedPropertyGridWithDataProvider, { width: width, height: height, dataProvider: dataProvider.current, orientation: Orientation.Vertical, isPropertySelectionEnabled: featureInfoOpts?.propertyGridOptions?.isPropertySelectionEnabled, isPropertyHoverEnabled // This need to be turned on to have the action button appears only when property hovered
57
+ return (_jsx("div", { ref: elementRef, className: "feature-info-widget-container", children: _jsx(VirtualizedPropertyGridWithDataProvider, { width: width, height: height, dataProvider: dataProvider.current, orientation: Orientation.Vertical, isPropertySelectionEnabled: isPropertySelectionEnabled, isPropertyHoverEnabled // This need to be turned on to have the action button appears only when property hovered
59
58
  : true, actionButtonRenderers: [copyButton] }) }));
60
59
  }
61
60
  else {
62
- return (_jsx(Flex, { justifyContent: "center", className: "feature-info-widget-no-records", children: _jsx("span", { children: _jsx("i", { children: noRecordsMessage }) }) }));
61
+ return null;
63
62
  }
64
63
  }
65
64
  //# sourceMappingURL=FeatureInfoWidget.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FeatureInfoWidget.js","sourceRoot":"","sources":["../../../../src/ui/widget/FeatureInfoWidget.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\nimport \"./FeatureInfoWidget.scss\";\nimport * as React from \"react\";\nimport { useActiveFrontstageDef, WidgetState } from \"@itwin/appui-react\";\nimport { Orientation, VirtualizedPropertyGridWithDataProvider } from \"@itwin/components-react\";\nimport { SvgCopy } from \"@itwin/itwinui-icons-react\";\nimport { Flex, IconButton } from \"@itwin/itwinui-react\";\nimport { MapLayersUI } from \"../../mapLayers\";\nimport { FeatureInfoUiItemsProvider } from \"../FeatureInfoUiItemsProvider\";\nimport { useResizeObserver } from \"../hooks/useResizeObserver\";\nimport { FeatureInfoDataProvider } from \"./FeatureInfoDataProvider\";\n\nimport type { PrimitiveValue } from \"@itwin/appui-abstract\";\nimport type { ActionButtonRendererProps } from \"@itwin/components-react\";\nimport type { MapFeatureInfoOptions } from \"../Interfaces\";\nexport function useSpecificWidgetDef(id: string) {\n const frontstageDef = useActiveFrontstageDef();\n return frontstageDef?.findWidgetDef(id);\n}\n\n// MapFeatureInfoWidgetProps\ninterface MapFeatureInfoWidgetProps {\n featureInfoOpts: MapFeatureInfoOptions;\n}\n\nexport function MapFeatureInfoWidget({ featureInfoOpts }: MapFeatureInfoWidgetProps) {\n const dataProvider = React.useRef<FeatureInfoDataProvider | null>(null);\n const [hasData, setHasData] = React.useState<boolean>(false);\n\n const [noRecordsMessage] = React.useState(MapLayersUI.localization.getLocalizedString(\"mapLayers:FeatureInfoWidget.NoRecords\"));\n\n const [{ width, height }, setSize] = React.useState({ width: 0, height: 0 });\n\n const widgetDef = useSpecificWidgetDef(FeatureInfoUiItemsProvider.widgetId);\n const handleDataChanged = React.useCallback(() => {\n const dataAvailable = dataProvider.current !== null && dataProvider.current.hasRecords;\n setHasData(dataAvailable);\n if (widgetDef) {\n widgetDef.setWidgetState(dataAvailable ? WidgetState.Open : WidgetState.Hidden);\n }\n }, [widgetDef]);\n\n React.useEffect(() => {\n dataProvider.current = new FeatureInfoDataProvider();\n return () => {\n dataProvider?.current?.onUnload();\n };\n }, []);\n\n React.useEffect(() => {\n dataProvider.current?.onDataChanged.addListener(handleDataChanged);\n return () => {\n dataProvider.current?.onDataChanged.removeListener(handleDataChanged);\n };\n }, [handleDataChanged]);\n\n const handleResize = React.useCallback((w: number, h: number) => {\n setSize({ width: w, height: h });\n }, []);\n\n const [elementRef] = useResizeObserver<HTMLDivElement>((size) => {\n handleResize(size.width, size.height);\n });\n\n const copyButton = React.useCallback(\n (props: ActionButtonRendererProps) =>\n props.isPropertyHovered && (\n <div>\n <IconButton\n styleType=\"borderless\"\n label=\"Copy\"\n onClick={() => {\n const value = props.property.value;\n if (value !== undefined && value.hasOwnProperty(\"displayValue\")) {\n navigator.clipboard.writeText((value as PrimitiveValue).displayValue ?? \"\").catch((_) => {});\n }\n }}\n >\n <SvgCopy />\n </IconButton>\n </div>\n ),\n [],\n );\n\n if (hasData && dataProvider.current) {\n return (\n <div ref={elementRef} className=\"feature-info-widget-container\">\n <VirtualizedPropertyGridWithDataProvider\n width={width}\n height={height}\n dataProvider={dataProvider.current}\n orientation={Orientation.Vertical}\n isPropertySelectionEnabled={featureInfoOpts?.propertyGridOptions?.isPropertySelectionEnabled}\n isPropertyHoverEnabled // This need to be turned on to have the action button appears only when property hovered\n actionButtonRenderers={[copyButton]}\n />\n </div>\n );\n } else {\n return (\n <Flex justifyContent=\"center\" className=\"feature-info-widget-no-records\">\n <span>\n <i>{noRecordsMessage}</i>\n </span>\n </Flex>\n );\n }\n}\n"]}
1
+ {"version":3,"file":"FeatureInfoWidget.js","sourceRoot":"","sources":["../../../../src/ui/widget/FeatureInfoWidget.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\nimport \"./FeatureInfoWidget.scss\";\nimport * as React from \"react\";\nimport { useActiveFrontstageDef, WidgetState } from \"@itwin/appui-react\";\nimport { Orientation, VirtualizedPropertyGridWithDataProvider } from \"@itwin/components-react\";\n\nimport { useResizeObserver } from \"../hooks/useResizeObserver\";\nimport { CopyActionButton } from \"./CopyActionButton\";\nimport { FeatureInfoDataProvider } from \"./FeatureInfoDataProvider\";\n\nimport type { PrimitiveValue } from \"@itwin/appui-abstract\";\nimport type { ActionButtonRendererProps } from \"@itwin/components-react\";\n\nfunction useSpecificWidgetDef(id: string) {\n const frontstageDef = useActiveFrontstageDef();\n return frontstageDef?.findWidgetDef(id);\n}\n\n/**\n * Props for {@link MapFeatureInfoWidget}.\n */\ninterface MapFeatureInfoWidgetProps {\n /** The widget that will be shown/hidden based on feature info data availability. */\n widgetId: string;\n /** Enables property selection support in the property grid when set. */\n isPropertySelectionEnabled?: boolean;\n /** Invoked when feature info data availability changes. */\n onDataChanged?: (hasData: boolean) => void;\n /**\n * Optional copy handler used by the copy action button.\n * When omitted, the component copies values using the browser clipboard API.\n */\n onCopy?: (value: string) => Promise<void> | void;\n}\n\n/**\n * Displays map feature info in a virtualized property grid and keeps the\n * owning widget open/hidden based on whether records are available.\n *\n * @param props - Widget configuration and callbacks.\n * @returns The feature info property grid UI, or `null` when no records are available.\n */\nexport function MapFeatureInfoWidget({ widgetId, isPropertySelectionEnabled, onDataChanged, onCopy }: MapFeatureInfoWidgetProps) {\n const dataProvider = React.useRef<FeatureInfoDataProvider | null>(null);\n const [hasData, setHasData] = React.useState(false);\n\n const [{ width, height }, setSize] = React.useState({ width: 0, height: 0 });\n\n const widgetDef = useSpecificWidgetDef(widgetId);\n const handleDataChanged = React.useCallback(() => {\n const dataAvailable = dataProvider.current !== null && dataProvider.current.hasRecords;\n setHasData(dataAvailable);\n if (widgetDef) {\n widgetDef.setWidgetState(dataAvailable ? WidgetState.Open : WidgetState.Hidden);\n }\n onDataChanged?.(dataAvailable);\n }, [widgetDef, onDataChanged]);\n\n React.useEffect(() => {\n dataProvider.current = new FeatureInfoDataProvider();\n return () => {\n dataProvider?.current?.onUnload();\n };\n }, []);\n\n React.useEffect(() => {\n dataProvider.current?.onDataChanged.addListener(handleDataChanged);\n return () => {\n dataProvider.current?.onDataChanged.removeListener(handleDataChanged);\n };\n }, [handleDataChanged]);\n\n const handleResize = React.useCallback((w: number, h: number) => {\n setSize({ width: w, height: h });\n }, []);\n\n const [elementRef] = useResizeObserver<HTMLDivElement>((size) => {\n handleResize(size.width, size.height);\n });\n\n const copyButton = React.useCallback(\n (props: ActionButtonRendererProps) =>\n props.isPropertyHovered && (\n <div>\n <CopyActionButton value={props.property.value ? (props.property.value as PrimitiveValue).displayValue ?? \"\" : \"\"} onCopy={onCopy} />\n </div>\n ),\n [onCopy],\n );\n\n if (hasData && dataProvider.current) {\n return (\n <div ref={elementRef} className=\"feature-info-widget-container\">\n <VirtualizedPropertyGridWithDataProvider\n width={width}\n height={height}\n dataProvider={dataProvider.current}\n orientation={Orientation.Vertical}\n isPropertySelectionEnabled={isPropertySelectionEnabled}\n isPropertyHoverEnabled // This need to be turned on to have the action button appears only when property hovered\n actionButtonRenderers={[copyButton]}\n />\n </div>\n );\n } else {\n return null;\n }\n}\n"]}
@@ -7,8 +7,3 @@
7
7
  width: 100%;
8
8
  height: 100%;
9
9
  }
10
-
11
- .feature-info-widget-no-records {
12
- width: 100%;
13
- height: 100%;
14
- }
@@ -59,6 +59,6 @@ export function MapLayerSettingsMenu({ mapLayerSettings, onMenuItemSelection, ac
59
59
  _jsx(MenuItem, { onClick: () => handleRemoveLayer(), children: labelDetach }, 1),
60
60
  _jsx(MenuItem, { children: _jsx(Slider, { className: "map-manager-item-dropdown-slider", min: 0, max: 100, values: [transparency * 100], step: 1, onChange: handleTransparencyChange }) }, 2),
61
61
  ];
62
- return (_jsx(_Fragment, { children: _jsx(DropdownMenu, { as: "div", placement: "bottom-start", menuItems: dropdownMenuItems, "aria-disabled": disabled, children: _jsx(IconButton, { size: "small", styleType: "borderless", children: _jsx(SvgMoreVertical, {}) }) }) }));
62
+ return (_jsx(_Fragment, { children: _jsx(DropdownMenu, { as: "div", placement: "bottom-start", menuItems: dropdownMenuItems, "aria-disabled": disabled, children: _jsx(IconButton, { size: "small", styleType: "borderless", "aria-label": MapLayersUI.localization.getLocalizedString("mapLayers:LayerMenu.MoreOptions"), children: _jsx(SvgMoreVertical, {}) }) }) }));
63
63
  }
64
64
  //# sourceMappingURL=MapLayerSettingsMenu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MapLayerSettingsMenu.js","sourceRoot":"","sources":["../../../../src/ui/widget/MapLayerSettingsMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\nimport \"./MapLayerManager.scss\";\nimport * as React from \"react\";\nimport { SvgMoreVertical } from \"@itwin/itwinui-icons-react\";\nimport { DropdownMenu, IconButton, MenuItem, Slider } from \"@itwin/itwinui-react\";\nimport { MapLayersUI } from \"../../mapLayers\";\n\nimport type { ScreenViewport } from \"@itwin/core-frontend\";\nimport type { StyleMapLayerSettings } from \"../Interfaces\";\ninterface MapLayerSettingsMenuProps {\n mapLayerSettings: StyleMapLayerSettings;\n onMenuItemSelection: (action: string, mapLayerSettings: StyleMapLayerSettings) => void;\n activeViewport: ScreenViewport;\n disabled?: boolean;\n}\n\nexport function MapLayerSettingsMenu({ mapLayerSettings, onMenuItemSelection, activeViewport, disabled }: MapLayerSettingsMenuProps) {\n const [labelDetach] = React.useState(MapLayersUI.localization.getLocalizedString(\"mapLayers:LayerMenu.Detach\"));\n const [labelZoomToLayer] = React.useState(MapLayersUI.localization.getLocalizedString(\"mapLayers:LayerMenu.ZoomToLayer\"));\n const [hasRangeData, setHasRangeData] = React.useState<boolean | undefined>();\n const [transparency, setTransparency] = React.useState(mapLayerSettings.transparency);\n\n React.useEffect(() => {\n async function fetchRangeData() {\n let hasRange = false;\n const indexInDisplayStyle = activeViewport?.displayStyle.findMapLayerIndexByNameAndSource(\n mapLayerSettings.name,\n mapLayerSettings.source,\n mapLayerSettings.isOverlay,\n );\n if (undefined !== indexInDisplayStyle) {\n hasRange = undefined !== (await activeViewport.getMapLayerRange({ index: indexInDisplayStyle, isOverlay: mapLayerSettings.isOverlay }));\n }\n setHasRangeData(hasRange);\n }\n fetchRangeData(); // eslint-disable-line @typescript-eslint/no-floating-promises\n }, [activeViewport, mapLayerSettings]);\n\n const handleRemoveLayer = React.useCallback(() => {\n onMenuItemSelection(\"delete\", mapLayerSettings);\n }, [onMenuItemSelection, mapLayerSettings]);\n\n const handleZoomToLayer = React.useCallback(() => {\n onMenuItemSelection(\"zoom-to-layer\", mapLayerSettings);\n }, [onMenuItemSelection, mapLayerSettings]);\n\n const applyTransparencyChange = React.useCallback(\n (value: number) => {\n if (activeViewport) {\n const newTransparency = value;\n const displayStyle = activeViewport.displayStyle;\n const indexInDisplayStyle = displayStyle.findMapLayerIndexByNameAndSource(mapLayerSettings.name, mapLayerSettings.source, mapLayerSettings.isOverlay);\n if (-1 !== indexInDisplayStyle) {\n const styleTransparency = displayStyle.mapLayerAtIndex({ index: indexInDisplayStyle, isOverlay: mapLayerSettings.isOverlay })?.transparency;\n const styleTransparencyValue = styleTransparency ? styleTransparency : 0;\n if (Math.abs(styleTransparencyValue - newTransparency) > 0.01) {\n // update the display style\n displayStyle.changeMapLayerProps({ transparency: newTransparency }, { index: indexInDisplayStyle, isOverlay: mapLayerSettings.isOverlay });\n }\n }\n }\n },\n [activeViewport, mapLayerSettings],\n );\n\n const handleTransparencyChange = React.useCallback(\n (values: readonly number[]) => {\n if (values.length) {\n const newTransparency = values[0] / 100.0;\n if (newTransparency !== transparency) {\n setTransparency(newTransparency);\n applyTransparencyChange(newTransparency);\n }\n }\n },\n [transparency, applyTransparencyChange],\n );\n\n const dropdownMenuItems = () => [\n <MenuItem disabled={!hasRangeData} key={0} onClick={() => handleZoomToLayer()}>\n {labelZoomToLayer}\n </MenuItem>,\n <MenuItem key={1} onClick={() => handleRemoveLayer()}>\n {labelDetach}\n </MenuItem>,\n <MenuItem key={2}>\n <Slider className=\"map-manager-item-dropdown-slider\" min={0} max={100} values={[transparency * 100]} step={1} onChange={handleTransparencyChange} />\n </MenuItem>,\n ];\n\n return (\n <>\n <DropdownMenu as=\"div\" placement=\"bottom-start\" menuItems={dropdownMenuItems} aria-disabled={disabled}>\n <IconButton size=\"small\" styleType=\"borderless\">\n <SvgMoreVertical />\n </IconButton>\n </DropdownMenu>\n </>\n );\n}\n"]}
1
+ {"version":3,"file":"MapLayerSettingsMenu.js","sourceRoot":"","sources":["../../../../src/ui/widget/MapLayerSettingsMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\nimport \"./MapLayerManager.scss\";\nimport * as React from \"react\";\nimport { SvgMoreVertical } from \"@itwin/itwinui-icons-react\";\nimport { DropdownMenu, IconButton, MenuItem, Slider } from \"@itwin/itwinui-react\";\nimport { MapLayersUI } from \"../../mapLayers\";\n\nimport type { ScreenViewport } from \"@itwin/core-frontend\";\nimport type { StyleMapLayerSettings } from \"../Interfaces\";\ninterface MapLayerSettingsMenuProps {\n mapLayerSettings: StyleMapLayerSettings;\n onMenuItemSelection: (action: string, mapLayerSettings: StyleMapLayerSettings) => void;\n activeViewport: ScreenViewport;\n disabled?: boolean;\n}\n\nexport function MapLayerSettingsMenu({ mapLayerSettings, onMenuItemSelection, activeViewport, disabled }: MapLayerSettingsMenuProps) {\n const [labelDetach] = React.useState(MapLayersUI.localization.getLocalizedString(\"mapLayers:LayerMenu.Detach\"));\n const [labelZoomToLayer] = React.useState(MapLayersUI.localization.getLocalizedString(\"mapLayers:LayerMenu.ZoomToLayer\"));\n const [hasRangeData, setHasRangeData] = React.useState<boolean | undefined>();\n const [transparency, setTransparency] = React.useState(mapLayerSettings.transparency);\n\n React.useEffect(() => {\n async function fetchRangeData() {\n let hasRange = false;\n const indexInDisplayStyle = activeViewport?.displayStyle.findMapLayerIndexByNameAndSource(\n mapLayerSettings.name,\n mapLayerSettings.source,\n mapLayerSettings.isOverlay,\n );\n if (undefined !== indexInDisplayStyle) {\n hasRange = undefined !== (await activeViewport.getMapLayerRange({ index: indexInDisplayStyle, isOverlay: mapLayerSettings.isOverlay }));\n }\n setHasRangeData(hasRange);\n }\n fetchRangeData(); // eslint-disable-line @typescript-eslint/no-floating-promises\n }, [activeViewport, mapLayerSettings]);\n\n const handleRemoveLayer = React.useCallback(() => {\n onMenuItemSelection(\"delete\", mapLayerSettings);\n }, [onMenuItemSelection, mapLayerSettings]);\n\n const handleZoomToLayer = React.useCallback(() => {\n onMenuItemSelection(\"zoom-to-layer\", mapLayerSettings);\n }, [onMenuItemSelection, mapLayerSettings]);\n\n const applyTransparencyChange = React.useCallback(\n (value: number) => {\n if (activeViewport) {\n const newTransparency = value;\n const displayStyle = activeViewport.displayStyle;\n const indexInDisplayStyle = displayStyle.findMapLayerIndexByNameAndSource(mapLayerSettings.name, mapLayerSettings.source, mapLayerSettings.isOverlay);\n if (-1 !== indexInDisplayStyle) {\n const styleTransparency = displayStyle.mapLayerAtIndex({ index: indexInDisplayStyle, isOverlay: mapLayerSettings.isOverlay })?.transparency;\n const styleTransparencyValue = styleTransparency ? styleTransparency : 0;\n if (Math.abs(styleTransparencyValue - newTransparency) > 0.01) {\n // update the display style\n displayStyle.changeMapLayerProps({ transparency: newTransparency }, { index: indexInDisplayStyle, isOverlay: mapLayerSettings.isOverlay });\n }\n }\n }\n },\n [activeViewport, mapLayerSettings],\n );\n\n const handleTransparencyChange = React.useCallback(\n (values: readonly number[]) => {\n if (values.length) {\n const newTransparency = values[0] / 100.0;\n if (newTransparency !== transparency) {\n setTransparency(newTransparency);\n applyTransparencyChange(newTransparency);\n }\n }\n },\n [transparency, applyTransparencyChange],\n );\n\n const dropdownMenuItems = () => [\n <MenuItem disabled={!hasRangeData} key={0} onClick={() => handleZoomToLayer()}>\n {labelZoomToLayer}\n </MenuItem>,\n <MenuItem key={1} onClick={() => handleRemoveLayer()}>\n {labelDetach}\n </MenuItem>,\n <MenuItem key={2}>\n <Slider className=\"map-manager-item-dropdown-slider\" min={0} max={100} values={[transparency * 100]} step={1} onChange={handleTransparencyChange} />\n </MenuItem>,\n ];\n\n return (\n <>\n <DropdownMenu as=\"div\" placement=\"bottom-start\" menuItems={dropdownMenuItems} aria-disabled={disabled}>\n <IconButton size=\"small\" styleType=\"borderless\" aria-label={MapLayersUI.localization.getLocalizedString(\"mapLayers:LayerMenu.MoreOptions\")}>\n <SvgMoreVertical />\n </IconButton>\n </DropdownMenu>\n </>\n );\n}\n"]}
@@ -130,11 +130,15 @@
130
130
  },
131
131
  "FeatureInfoWidget": {
132
132
  "Label": "Map Layers Info",
133
- "NoRecords": "No Results"
133
+ "NoRecords": "No Results",
134
+ "Copy": "Copy",
135
+ "Copied": "Copied!",
136
+ "CopyFailed": "Copy failed"
134
137
  },
135
138
  "LayerMenu": {
136
139
  "Detach": "Detach",
137
- "ZoomToLayer": "Zoom to layer"
140
+ "ZoomToLayer": "Zoom to layer",
141
+ "MoreOptions": "More options"
138
142
  },
139
143
  "Settings": {
140
144
  "ElevationOffset": "Elevation Offset",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/map-layers",
3
- "version": "6.0.9",
3
+ "version": "6.2.0",
4
4
  "description": "Extension that adds a Map Layers Widget",
5
5
  "main": "lib/cjs/map-layers.js",
6
6
  "module": "lib/esm/map-layers.js",
@@ -64,13 +64,12 @@
64
64
  "@testing-library/react": "^16.3.0",
65
65
  "@testing-library/react-hooks": "^8.0.1",
66
66
  "@testing-library/user-event": "^14.6.1",
67
- "@types/jsdom-global": "^3.0.7",
68
- "@types/node": "^18.19.87",
67
+ "@types/node": "^22.13.9",
69
68
  "@types/react": "^18.3.20",
70
69
  "@types/react-beautiful-dnd": "^13.1.8",
71
70
  "@typescript-eslint/eslint-plugin": "^8.31.1",
72
71
  "@typescript-eslint/parser": "^8.31.1",
73
- "@vitest/coverage-v8": "^2.1.9",
72
+ "@vitest/coverage-v8": "^4.0.18",
74
73
  "cpx2": "^3.0.2",
75
74
  "eslint": "^9.25.1",
76
75
  "eslint-config-prettier": "^10.1.2",
@@ -78,20 +77,19 @@
78
77
  "eslint-plugin-react": "^7.37.5",
79
78
  "eslint-plugin-unused-imports": "^4.1.4",
80
79
  "ignore-styles": "^5.0.1",
81
- "jsdom": "^22.1.0",
82
- "jsdom-global": "^3.0.2",
80
+ "jsdom": "^28.0.0",
83
81
  "raf": "^3.4.1",
84
82
  "react": "^18.3.1",
85
83
  "react-dom": "^18.3.1",
86
84
  "react-redux": "^7.2.9",
87
85
  "redux": "^4.2.1",
88
86
  "rimraf": "^3.0.2",
89
- "sass-embedded": "^1.87.0",
87
+ "sass": "^1.97.3",
90
88
  "source-map-support": "^0.5.21",
91
89
  "ts-node": "^10.9.2",
92
90
  "typemoq": "^2.1.0",
93
91
  "typescript": "~5.6.3",
94
- "vitest": "^2.1.9"
92
+ "vitest": "^4.0.18"
95
93
  },
96
94
  "peerDependencies": {
97
95
  "@itwin/appui-abstract": "^5.0.0",