@itwin/map-layers 6.1.0 → 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 (45) hide show
  1. package/CHANGELOG.md +10 -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 +4 -1
  7. package/lib/cjs/ui/FeatureInfoUiItemsProvider.d.ts.map +1 -1
  8. package/lib/cjs/ui/FeatureInfoUiItemsProvider.js +1 -1
  9. package/lib/cjs/ui/FeatureInfoUiItemsProvider.js.map +1 -1
  10. package/lib/cjs/ui/hooks/useResizeObserver.d.ts +5 -0
  11. package/lib/cjs/ui/hooks/useResizeObserver.d.ts.map +1 -1
  12. package/lib/cjs/ui/hooks/useResizeObserver.js +3 -3
  13. package/lib/cjs/ui/hooks/useResizeObserver.js.map +1 -1
  14. package/lib/cjs/ui/widget/CopyActionButton.d.ts +12 -0
  15. package/lib/cjs/ui/widget/CopyActionButton.d.ts.map +1 -0
  16. package/lib/cjs/ui/widget/CopyActionButton.js +49 -0
  17. package/lib/cjs/ui/widget/CopyActionButton.js.map +1 -0
  18. package/lib/cjs/ui/widget/FeatureInfoWidget.d.ts +22 -4
  19. package/lib/cjs/ui/widget/FeatureInfoWidget.d.ts.map +1 -1
  20. package/lib/cjs/ui/widget/FeatureInfoWidget.js +15 -17
  21. package/lib/cjs/ui/widget/FeatureInfoWidget.js.map +1 -1
  22. package/lib/cjs/ui/widget/FeatureInfoWidget.scss +0 -5
  23. package/lib/esm/map-layers.d.ts +1 -0
  24. package/lib/esm/map-layers.d.ts.map +1 -1
  25. package/lib/esm/map-layers.js +1 -0
  26. package/lib/esm/map-layers.js.map +1 -1
  27. package/lib/esm/public/locales/en/mapLayers.json +4 -1
  28. package/lib/esm/ui/FeatureInfoUiItemsProvider.d.ts.map +1 -1
  29. package/lib/esm/ui/FeatureInfoUiItemsProvider.js +1 -1
  30. package/lib/esm/ui/FeatureInfoUiItemsProvider.js.map +1 -1
  31. package/lib/esm/ui/hooks/useResizeObserver.d.ts +5 -0
  32. package/lib/esm/ui/hooks/useResizeObserver.d.ts.map +1 -1
  33. package/lib/esm/ui/hooks/useResizeObserver.js +3 -3
  34. package/lib/esm/ui/hooks/useResizeObserver.js.map +1 -1
  35. package/lib/esm/ui/widget/CopyActionButton.d.ts +12 -0
  36. package/lib/esm/ui/widget/CopyActionButton.d.ts.map +1 -0
  37. package/lib/esm/ui/widget/CopyActionButton.js +46 -0
  38. package/lib/esm/ui/widget/CopyActionButton.js.map +1 -0
  39. package/lib/esm/ui/widget/FeatureInfoWidget.d.ts +22 -4
  40. package/lib/esm/ui/widget/FeatureInfoWidget.d.ts.map +1 -1
  41. package/lib/esm/ui/widget/FeatureInfoWidget.js +16 -17
  42. package/lib/esm/ui/widget/FeatureInfoWidget.js.map +1 -1
  43. package/lib/esm/ui/widget/FeatureInfoWidget.scss +0 -5
  44. package/lib/public/locales/en/mapLayers.json +4 -1
  45. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,12 +1,20 @@
1
1
  # Change Log - @itwin/map-layers
2
2
 
3
- <!-- This log was last generated on Tue, 03 Mar 2026 14:55:43 GMT and should not be manually modified. -->
3
+ <!-- This log was last generated on Fri, 06 Mar 2026 19:28:08 GMT and should not be manually modified. -->
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 6.2.0
8
+
9
+ Fri, 06 Mar 2026 19:28:08 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - Export FeatureInfoWidget, localize strings, and update copy button ([#1622](https://github.com/iTwin/viewer-components-react/pull/1622))
14
+
7
15
  ## 6.1.0
8
16
 
9
- Tue, 03 Mar 2026 14:55:43 GMT
17
+ Tue, 03 Mar 2026 14:55:51 GMT
10
18
 
11
19
  ### Minor changes
12
20
 
@@ -6,4 +6,5 @@ export * from "./ui/MapLayersUiItemsProvider";
6
6
  export * from "./ui/FeatureInfoUiItemsProvider";
7
7
  export * from "./ui/widget/MapLayersWidget";
8
8
  export * from "./BaseMapPresets";
9
+ export { MapFeatureInfoWidget } from "./ui/widget/FeatureInfoWidget";
9
10
  //# sourceMappingURL=map-layers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"map-layers.d.ts","sourceRoot":"","sources":["../../src/map-layers.ts"],"names":[],"mappings":"AAIA,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"}
1
+ {"version":3,"file":"map-layers.d.ts","sourceRoot":"","sources":["../../src/map-layers.ts"],"names":[],"mappings":"AAIA,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"}
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.MapFeatureInfoWidget = void 0;
17
18
  /*---------------------------------------------------------------------------------------------
18
19
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
19
20
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -26,4 +27,6 @@ __exportStar(require("./ui/MapLayersUiItemsProvider"), exports);
26
27
  __exportStar(require("./ui/FeatureInfoUiItemsProvider"), exports);
27
28
  __exportStar(require("./ui/widget/MapLayersWidget"), exports);
28
29
  __exportStar(require("./BaseMapPresets"), exports);
30
+ var FeatureInfoWidget_1 = require("./ui/widget/FeatureInfoWidget");
31
+ Object.defineProperty(exports, "MapFeatureInfoWidget", { enumerable: true, get: function () { return FeatureInfoWidget_1.MapFeatureInfoWidget; } });
29
32
  //# 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,8CAA4B;AAC5B,uDAAqC;AACrC,gEAA8C;AAC9C,kDAAgC;AAChC,gEAA8C;AAC9C,kEAAgD;AAChD,8DAA4C;AAC5C,mDAAiC","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,8CAA4B;AAC5B,uDAAqC;AACrC,gEAA8C;AAC9C,kDAAgC;AAChC,gEAA8C;AAC9C,kEAAgD;AAChD,8DAA4C;AAC5C,mDAAiC;AACjC,mEAAqE;AAA5D,yHAAA,oBAAoB,OAAA","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,7 +130,10 @@
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",
@@ -1 +1 @@
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;CAoB9B"}
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"}
@@ -83,7 +83,7 @@ class FeatureInfoUiItemsProvider {
83
83
  id: FeatureInfoUiItemsProvider.widgetId,
84
84
  label: mapLayers_1.MapLayersUI.localization.getLocalizedString("mapLayers:FeatureInfoWidget.Label"),
85
85
  icon: (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgMapInfo, {}),
86
- content: (0, jsx_runtime_1.jsx)(FeatureInfoWidget_1.MapFeatureInfoWidget, { featureInfoOpts: this._featureInfoOpts }),
86
+ content: (0, jsx_runtime_1.jsx)(FeatureInfoWidget_1.MapFeatureInfoWidget, { widgetId: FeatureInfoUiItemsProvider.widgetId, isPropertySelectionEnabled: this._featureInfoOpts.propertyGridOptions?.isPropertySelectionEnabled }),
87
87
  defaultState: appui_react_1.WidgetState.Hidden,
88
88
  layouts: {
89
89
  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, 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 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,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"}
@@ -29,14 +29,14 @@ exports.useResizeObserver = void 0;
29
29
  * See LICENSE.md in the project root for license terms and full copyright notice.
30
30
  *--------------------------------------------------------------------------------------------*/
31
31
  const React = __importStar(require("react"));
32
+ const getWindow = () => {
33
+ return typeof window === "undefined" ? undefined : window;
34
+ };
32
35
  /** Hook that will observe Window Resize
33
36
  * @internal
34
37
  * Reference: https://github.com/iTwin/iTwinUI/blob/87bbc99316c17bd2b763a730135fbb45c84b0e82/packages/itwinui-react/src/utils/hooks/useResizeObserver.tsx
35
38
  * Copied from: https://github.com/iTwin/appui/blob/master/ui/core-react/src/core-react/utils/hooks/useResizeObserver.tsx
36
39
  */
37
- const getWindow = () => {
38
- return typeof window === "undefined" ? undefined : window;
39
- };
40
40
  const useResizeObserver = (onResize) => {
41
41
  const resizeObserver = React.useRef();
42
42
  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,6CAA+B;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;AAEK,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;AAjCW,QAAA,iBAAiB,qBAiC5B","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,6CAA+B;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;AACI,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;AAjCW,QAAA,iBAAiB,qBAiC5B","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,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CopyActionButton = CopyActionButton;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const itwinui_icons_react_1 = require("@itwin/itwinui-icons-react");
6
+ const itwinui_react_1 = require("@itwin/itwinui-react");
7
+ const react_1 = require("react");
8
+ const core_frontend_1 = require("@itwin/core-frontend");
9
+ const mapLayers_1 = require("../../mapLayers");
10
+ /**
11
+ * Renders an icon button that copies a value to the clipboard.
12
+ *
13
+ * After a click, the icon and label briefly switch to a copied state.
14
+ */
15
+ function CopyActionButton({ value, onCopy }) {
16
+ const [isCopied, setIsCopied] = (0, react_1.useState)(false);
17
+ const timeoutRef = (0, react_1.useRef)(undefined);
18
+ (0, react_1.useEffect)(() => {
19
+ return () => {
20
+ if (timeoutRef.current !== undefined) {
21
+ clearTimeout(timeoutRef.current);
22
+ }
23
+ };
24
+ }, []);
25
+ return ((0, jsx_runtime_1.jsx)(itwinui_react_1.IconButton, { styleType: "borderless", label: isCopied ? mapLayers_1.MapLayersUI.localization.getLocalizedString("mapLayers:FeatureInfoWidget.Copied") : mapLayers_1.MapLayersUI.localization.getLocalizedString("mapLayers:FeatureInfoWidget.Copy"), onClick: async () => {
26
+ try {
27
+ if (onCopy) {
28
+ await onCopy(value);
29
+ }
30
+ else {
31
+ await navigator.clipboard.writeText(value);
32
+ }
33
+ setIsCopied(true);
34
+ if (timeoutRef.current !== undefined) {
35
+ clearTimeout(timeoutRef.current);
36
+ }
37
+ timeoutRef.current = setTimeout(() => {
38
+ setIsCopied(false);
39
+ timeoutRef.current = undefined;
40
+ }, 1200);
41
+ }
42
+ catch {
43
+ const copyFailedMessage = mapLayers_1.MapLayersUI.localization.getLocalizedString("mapLayers:FeatureInfoWidget.CopyFailed");
44
+ core_frontend_1.IModelApp.notifications.outputMessage(new core_frontend_1.NotifyMessageDetails(core_frontend_1.OutputMessagePriority.Warning, copyFailedMessage));
45
+ }
46
+ }, disabled: isCopied, children: isCopied ? (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgCheckmarkSmall, {}) : (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgCopy, {}) }, String(isCopied)));
47
+ }
48
+ ;
49
+ //# sourceMappingURL=CopyActionButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CopyActionButton.js","sourceRoot":"","sources":["../../../../src/ui/widget/CopyActionButton.tsx"],"names":[],"mappings":";;AAkBA,4CA6CC;;AA/DD,oEAAwE;AACxE,wDAAkD;AAClD,iCAAoD;AAEpD,wDAA8F;AAE9F,+CAA8C;AAO9C;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAyB;IACvE,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,IAAA,cAAM,EAAqB,SAAS,CAAC,CAAC;IAEzD,IAAA,iBAAS,EAAC,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,uBAAC,0BAAU,IACT,SAAS,EAAC,YAAY,EACtB,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,uBAAW,CAAC,YAAY,CAAC,kBAAkB,CAAC,oCAAoC,CAAC,CAAC,CAAC,CAAC,uBAAW,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,uBAAW,CAAC,YAAY,CAAC,kBAAkB,CAAC,wCAAwC,CAAC,CAAC;gBAChH,yBAAS,CAAC,aAAa,CAAC,aAAa,CAAC,IAAI,oCAAoB,CAAC,qCAAqB,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC;YACpH,CAAC;QACH,CAAC,EACD,QAAQ,EAAE,QAAQ,YAIjB,QAAQ,CAAC,CAAC,CAAC,uBAAC,uCAAiB,KAAG,CAAC,CAAC,CAAC,uBAAC,6BAAO,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"}
@@ -23,7 +23,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.useSpecificWidgetDef = useSpecificWidgetDef;
27
26
  exports.MapFeatureInfoWidget = MapFeatureInfoWidget;
28
27
  const jsx_runtime_1 = require("react/jsx-runtime");
29
28
  /*---------------------------------------------------------------------------------------------
@@ -34,29 +33,33 @@ require("./FeatureInfoWidget.scss");
34
33
  const React = __importStar(require("react"));
35
34
  const appui_react_1 = require("@itwin/appui-react");
36
35
  const components_react_1 = require("@itwin/components-react");
37
- const itwinui_icons_react_1 = require("@itwin/itwinui-icons-react");
38
- const itwinui_react_1 = require("@itwin/itwinui-react");
39
- const mapLayers_1 = require("../../mapLayers");
40
- const FeatureInfoUiItemsProvider_1 = require("../FeatureInfoUiItemsProvider");
41
36
  const useResizeObserver_1 = require("../hooks/useResizeObserver");
37
+ const CopyActionButton_1 = require("./CopyActionButton");
42
38
  const FeatureInfoDataProvider_1 = require("./FeatureInfoDataProvider");
43
39
  function useSpecificWidgetDef(id) {
44
40
  const frontstageDef = (0, appui_react_1.useActiveFrontstageDef)();
45
41
  return frontstageDef?.findWidgetDef(id);
46
42
  }
47
- function MapFeatureInfoWidget({ featureInfoOpts }) {
43
+ /**
44
+ * Displays map feature info in a virtualized property grid and keeps the
45
+ * owning widget open/hidden based on whether records are available.
46
+ *
47
+ * @param props - Widget configuration and callbacks.
48
+ * @returns The feature info property grid UI, or `null` when no records are available.
49
+ */
50
+ function MapFeatureInfoWidget({ widgetId, isPropertySelectionEnabled, onDataChanged, onCopy }) {
48
51
  const dataProvider = React.useRef(null);
49
52
  const [hasData, setHasData] = React.useState(false);
50
- const [noRecordsMessage] = React.useState(mapLayers_1.MapLayersUI.localization.getLocalizedString("mapLayers:FeatureInfoWidget.NoRecords"));
51
53
  const [{ width, height }, setSize] = React.useState({ width: 0, height: 0 });
52
- const widgetDef = useSpecificWidgetDef(FeatureInfoUiItemsProvider_1.FeatureInfoUiItemsProvider.widgetId);
54
+ const widgetDef = useSpecificWidgetDef(widgetId);
53
55
  const handleDataChanged = React.useCallback(() => {
54
56
  const dataAvailable = dataProvider.current !== null && dataProvider.current.hasRecords;
55
57
  setHasData(dataAvailable);
56
58
  if (widgetDef) {
57
59
  widgetDef.setWidgetState(dataAvailable ? appui_react_1.WidgetState.Open : appui_react_1.WidgetState.Hidden);
58
60
  }
59
- }, [widgetDef]);
61
+ onDataChanged?.(dataAvailable);
62
+ }, [widgetDef, onDataChanged]);
60
63
  React.useEffect(() => {
61
64
  dataProvider.current = new FeatureInfoDataProvider_1.FeatureInfoDataProvider();
62
65
  return () => {
@@ -75,18 +78,13 @@ function MapFeatureInfoWidget({ featureInfoOpts }) {
75
78
  const [elementRef] = (0, useResizeObserver_1.useResizeObserver)((size) => {
76
79
  handleResize(size.width, size.height);
77
80
  });
78
- const copyButton = React.useCallback((props) => props.isPropertyHovered && ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(itwinui_react_1.IconButton, { styleType: "borderless", label: "Copy", onClick: () => {
79
- const value = props.property.value;
80
- if (value !== undefined && value.hasOwnProperty("displayValue")) {
81
- navigator.clipboard.writeText(value.displayValue ?? "").catch((_) => { });
82
- }
83
- }, children: (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgCopy, {}) }) })), []);
81
+ const copyButton = React.useCallback((props) => props.isPropertyHovered && ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(CopyActionButton_1.CopyActionButton, { value: props.property.value ? props.property.value.displayValue ?? "" : "", onCopy: onCopy }) })), [onCopy]);
84
82
  if (hasData && dataProvider.current) {
85
- return ((0, jsx_runtime_1.jsx)("div", { ref: elementRef, className: "feature-info-widget-container", children: (0, jsx_runtime_1.jsx)(components_react_1.VirtualizedPropertyGridWithDataProvider, { width: width, height: height, dataProvider: dataProvider.current, orientation: components_react_1.Orientation.Vertical, isPropertySelectionEnabled: featureInfoOpts?.propertyGridOptions?.isPropertySelectionEnabled, isPropertyHoverEnabled // This need to be turned on to have the action button appears only when property hovered
83
+ return ((0, jsx_runtime_1.jsx)("div", { ref: elementRef, className: "feature-info-widget-container", children: (0, jsx_runtime_1.jsx)(components_react_1.VirtualizedPropertyGridWithDataProvider, { width: width, height: height, dataProvider: dataProvider.current, orientation: components_react_1.Orientation.Vertical, isPropertySelectionEnabled: isPropertySelectionEnabled, isPropertyHoverEnabled // This need to be turned on to have the action button appears only when property hovered
86
84
  : true, actionButtonRenderers: [copyButton] }) }));
87
85
  }
88
86
  else {
89
- return ((0, jsx_runtime_1.jsx)(itwinui_react_1.Flex, { justifyContent: "center", className: "feature-info-widget-no-records", children: (0, jsx_runtime_1.jsx)("span", { children: (0, jsx_runtime_1.jsx)("i", { children: noRecordsMessage }) }) }));
87
+ return null;
90
88
  }
91
89
  }
92
90
  //# 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
- }
@@ -6,4 +6,5 @@ export * from "./ui/MapLayersUiItemsProvider";
6
6
  export * from "./ui/FeatureInfoUiItemsProvider";
7
7
  export * from "./ui/widget/MapLayersWidget";
8
8
  export * from "./BaseMapPresets";
9
+ export { MapFeatureInfoWidget } from "./ui/widget/FeatureInfoWidget";
9
10
  //# sourceMappingURL=map-layers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"map-layers.d.ts","sourceRoot":"","sources":["../../src/map-layers.ts"],"names":[],"mappings":"AAIA,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"}
1
+ {"version":3,"file":"map-layers.d.ts","sourceRoot":"","sources":["../../src/map-layers.ts"],"names":[],"mappings":"AAIA,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"}
@@ -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,7 +130,10 @@
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",
@@ -1 +1 @@
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;CAoB9B"}
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"}
@@ -79,7 +79,7 @@ export class FeatureInfoUiItemsProvider {
79
79
  id: FeatureInfoUiItemsProvider.widgetId,
80
80
  label: MapLayersUI.localization.getLocalizedString("mapLayers:FeatureInfoWidget.Label"),
81
81
  icon: _jsx(SvgMapInfo, {}),
82
- content: _jsx(MapFeatureInfoWidget, { featureInfoOpts: this._featureInfoOpts }),
82
+ content: _jsx(MapFeatureInfoWidget, { widgetId: FeatureInfoUiItemsProvider.widgetId, isPropertySelectionEnabled: this._featureInfoOpts.propertyGridOptions?.isPropertySelectionEnabled }),
83
83
  defaultState: WidgetState.Hidden,
84
84
  layouts: {
85
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, 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 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,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
- }
@@ -130,7 +130,10 @@
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",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/map-layers",
3
- "version": "6.1.0",
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",