@itwin/map-layers 6.0.0-dev.0 → 6.0.0-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/ui/hooks/useCrossOriginPopup.d.ts +7 -0
- package/lib/cjs/ui/hooks/useCrossOriginPopup.d.ts.map +1 -0
- package/lib/cjs/ui/hooks/useCrossOriginPopup.js +123 -0
- package/lib/cjs/ui/hooks/useCrossOriginPopup.js.map +1 -0
- package/lib/cjs/ui/hooks/useInterval.d.ts +7 -0
- package/lib/cjs/ui/hooks/useInterval.d.ts.map +1 -0
- package/lib/cjs/ui/hooks/useInterval.js +60 -0
- package/lib/cjs/ui/hooks/useInterval.js.map +1 -0
- package/lib/cjs/ui/hooks/useResizeObserver.d.ts +2 -0
- package/lib/cjs/ui/hooks/useResizeObserver.d.ts.map +1 -0
- package/lib/cjs/ui/hooks/useResizeObserver.js +66 -0
- package/lib/cjs/ui/hooks/useResizeObserver.js.map +1 -0
- package/lib/cjs/ui/widget/AttachLayerPopupButton.d.ts.map +1 -1
- package/lib/cjs/ui/widget/AttachLayerPopupButton.js +26 -34
- package/lib/cjs/ui/widget/AttachLayerPopupButton.js.map +1 -1
- package/lib/cjs/ui/widget/CustomParamsSettings.d.ts +5 -1
- package/lib/cjs/ui/widget/CustomParamsSettings.d.ts.map +1 -1
- package/lib/cjs/ui/widget/CustomParamsSettings.js +30 -8
- package/lib/cjs/ui/widget/CustomParamsSettings.js.map +1 -1
- package/lib/cjs/ui/widget/FeatureInfoWidget.d.ts.map +1 -1
- package/lib/cjs/ui/widget/FeatureInfoWidget.js +5 -4
- package/lib/cjs/ui/widget/FeatureInfoWidget.js.map +1 -1
- package/lib/cjs/ui/widget/MapLayerDroppable.d.ts.map +1 -1
- package/lib/cjs/ui/widget/MapLayerDroppable.js +2 -2
- package/lib/cjs/ui/widget/MapLayerDroppable.js.map +1 -1
- package/lib/cjs/ui/widget/MapLayerSettingsPopupButton.d.ts.map +1 -1
- package/lib/cjs/ui/widget/MapLayerSettingsPopupButton.js +5 -25
- package/lib/cjs/ui/widget/MapLayerSettingsPopupButton.js.map +1 -1
- package/lib/cjs/ui/widget/MapLayerSettingsPopupButton.scss +2 -2
- package/lib/cjs/ui/widget/MapManagerSettings.d.ts +5 -1
- package/lib/cjs/ui/widget/MapManagerSettings.d.ts.map +1 -1
- package/lib/cjs/ui/widget/MapManagerSettings.js +9 -7
- package/lib/cjs/ui/widget/MapManagerSettings.js.map +1 -1
- package/lib/cjs/ui/widget/MapUrlDialog.d.ts +0 -1
- package/lib/cjs/ui/widget/MapUrlDialog.d.ts.map +1 -1
- package/lib/cjs/ui/widget/MapUrlDialog.js +2 -3
- package/lib/cjs/ui/widget/MapUrlDialog.js.map +1 -1
- package/lib/cjs/ui/widget/SubLayersPopupButton.d.ts.map +1 -1
- package/lib/cjs/ui/widget/SubLayersPopupButton.js +1 -13
- package/lib/cjs/ui/widget/SubLayersPopupButton.js.map +1 -1
- package/lib/cjs/ui/widget/SubLayersTree.d.ts.map +1 -1
- package/lib/cjs/ui/widget/SubLayersTree.js +9 -11
- package/lib/cjs/ui/widget/SubLayersTree.js.map +1 -1
- package/lib/cjs/ui/widget/TransparencyPopupButton.d.ts.map +1 -1
- package/lib/cjs/ui/widget/TransparencyPopupButton.js +4 -10
- package/lib/cjs/ui/widget/TransparencyPopupButton.js.map +1 -1
- package/lib/esm/ui/hooks/useCrossOriginPopup.d.ts +7 -0
- package/lib/esm/ui/hooks/useCrossOriginPopup.d.ts.map +1 -0
- package/lib/esm/ui/hooks/useCrossOriginPopup.js +96 -0
- package/lib/esm/ui/hooks/useCrossOriginPopup.js.map +1 -0
- package/lib/esm/ui/hooks/useInterval.d.ts +7 -0
- package/lib/esm/ui/hooks/useInterval.d.ts.map +1 -0
- package/lib/esm/ui/hooks/useInterval.js +33 -0
- package/lib/esm/ui/hooks/useInterval.js.map +1 -0
- package/lib/esm/ui/hooks/useResizeObserver.d.ts +2 -0
- package/lib/esm/ui/hooks/useResizeObserver.d.ts.map +1 -0
- package/lib/esm/ui/hooks/useResizeObserver.js +39 -0
- package/lib/esm/ui/hooks/useResizeObserver.js.map +1 -0
- package/lib/esm/ui/widget/AttachLayerPopupButton.d.ts.map +1 -1
- package/lib/esm/ui/widget/AttachLayerPopupButton.js +27 -35
- package/lib/esm/ui/widget/AttachLayerPopupButton.js.map +1 -1
- package/lib/esm/ui/widget/CustomParamsSettings.d.ts +5 -1
- package/lib/esm/ui/widget/CustomParamsSettings.d.ts.map +1 -1
- package/lib/esm/ui/widget/CustomParamsSettings.js +30 -8
- package/lib/esm/ui/widget/CustomParamsSettings.js.map +1 -1
- package/lib/esm/ui/widget/FeatureInfoWidget.d.ts.map +1 -1
- package/lib/esm/ui/widget/FeatureInfoWidget.js +5 -4
- package/lib/esm/ui/widget/FeatureInfoWidget.js.map +1 -1
- package/lib/esm/ui/widget/MapLayerDroppable.d.ts.map +1 -1
- package/lib/esm/ui/widget/MapLayerDroppable.js +2 -2
- package/lib/esm/ui/widget/MapLayerDroppable.js.map +1 -1
- package/lib/esm/ui/widget/MapLayerSettingsPopupButton.d.ts.map +1 -1
- package/lib/esm/ui/widget/MapLayerSettingsPopupButton.js +7 -27
- package/lib/esm/ui/widget/MapLayerSettingsPopupButton.js.map +1 -1
- package/lib/esm/ui/widget/MapLayerSettingsPopupButton.scss +2 -2
- package/lib/esm/ui/widget/MapManagerSettings.d.ts +5 -1
- package/lib/esm/ui/widget/MapManagerSettings.d.ts.map +1 -1
- package/lib/esm/ui/widget/MapManagerSettings.js +10 -8
- package/lib/esm/ui/widget/MapManagerSettings.js.map +1 -1
- package/lib/esm/ui/widget/MapUrlDialog.d.ts +0 -1
- package/lib/esm/ui/widget/MapUrlDialog.d.ts.map +1 -1
- package/lib/esm/ui/widget/MapUrlDialog.js +1 -2
- package/lib/esm/ui/widget/MapUrlDialog.js.map +1 -1
- package/lib/esm/ui/widget/SubLayersPopupButton.d.ts.map +1 -1
- package/lib/esm/ui/widget/SubLayersPopupButton.js +3 -15
- package/lib/esm/ui/widget/SubLayersPopupButton.js.map +1 -1
- package/lib/esm/ui/widget/SubLayersTree.d.ts.map +1 -1
- package/lib/esm/ui/widget/SubLayersTree.js +10 -12
- package/lib/esm/ui/widget/SubLayersTree.js.map +1 -1
- package/lib/esm/ui/widget/TransparencyPopupButton.d.ts.map +1 -1
- package/lib/esm/ui/widget/TransparencyPopupButton.js +6 -12
- package/lib/esm/ui/widget/TransparencyPopupButton.js.map +1 -1
- package/package.json +18 -56
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransparencyPopupButton.d.ts","sourceRoot":"","sources":["../../../../src/ui/widget/TransparencyPopupButton.tsx"],"names":[],"mappings":"AAKA,OAAO,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"TransparencyPopupButton.d.ts","sourceRoot":"","sources":["../../../../src/ui/widget/TransparencyPopupButton.tsx"],"names":[],"mappings":"AAKA,OAAO,gCAAgC,CAAC;AAKxC,aAAa;AACb,MAAM,WAAW,4BAA4B;IAC3C,6BAA6B;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,oBAAoB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,uBAAuB;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,aAAa;AACb,wBAAgB,uBAAuB,CAAC,EAAE,YAAY,EAAE,oBAAoB,EAAE,aAAa,EAAE,QAAQ,EAAE,EAAE,4BAA4B,2CA4DpI"}
|
|
@@ -31,9 +31,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
31
31
|
*--------------------------------------------------------------------------------------------*/
|
|
32
32
|
require("./TransparencyPopupButton.scss");
|
|
33
33
|
const React = __importStar(require("react"));
|
|
34
|
-
const appui_abstract_1 = require("@itwin/appui-abstract");
|
|
35
34
|
const core_frontend_1 = require("@itwin/core-frontend");
|
|
36
|
-
const core_react_1 = require("@itwin/core-react");
|
|
37
35
|
const itwinui_react_1 = require("@itwin/itwinui-react");
|
|
38
36
|
/** @alpha */
|
|
39
37
|
function TransparencyPopupButton({ transparency, onTransparencyChange, buttonToolTip, disabled }) {
|
|
@@ -41,13 +39,9 @@ function TransparencyPopupButton({ transparency, onTransparencyChange, buttonToo
|
|
|
41
39
|
const [defaultTransparencyLabel] = React.useState(core_frontend_1.IModelApp.localization.getLocalizedString("mapLayers:TransparencyPopup.SetTransparency"));
|
|
42
40
|
const toolTipLabel = React.useMemo(() => (buttonToolTip ? buttonToolTip : defaultTransparencyLabel), [buttonToolTip, defaultTransparencyLabel]);
|
|
43
41
|
const buttonRef = React.useRef(null);
|
|
44
|
-
const togglePopupDisplay = React.useCallback((
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}, [setIsSettingsOpen]);
|
|
48
|
-
const handleCloseSetting = React.useCallback(() => {
|
|
49
|
-
setIsSettingsOpen(false);
|
|
50
|
-
}, [setIsSettingsOpen]);
|
|
42
|
+
const togglePopupDisplay = React.useCallback(() => {
|
|
43
|
+
setIsSettingsOpen(!isSettingsOpen);
|
|
44
|
+
}, [isSettingsOpen]);
|
|
51
45
|
const handleTransparencyChange = React.useCallback((values) => {
|
|
52
46
|
if (values.length) {
|
|
53
47
|
const newTransparency = values[0];
|
|
@@ -58,7 +52,7 @@ function TransparencyPopupButton({ transparency, onTransparencyChange, buttonToo
|
|
|
58
52
|
}
|
|
59
53
|
}
|
|
60
54
|
}, [onTransparencyChange, transparency]);
|
|
61
|
-
return ((0, jsx_runtime_1.
|
|
55
|
+
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(itwinui_react_1.Popover, { content: (0, jsx_runtime_1.jsx)("div", { className: "map-transparency-popup-panel", children: (0, jsx_runtime_1.jsx)("div", { className: "map-transparency-slider-container", children: (0, jsx_runtime_1.jsx)(itwinui_react_1.Slider, { min: 0, max: 100, values: [transparency * 100], step: 1, onChange: handleTransparencyChange }) }) }), visible: isSettingsOpen, onVisibleChange: setIsSettingsOpen, placement: "bottom-end", applyBackground: true, positionReference: buttonRef.current ?? undefined, children: (0, jsx_runtime_1.jsx)(itwinui_react_1.Button, { disabled: disabled, size: "small", styleType: "borderless", title: toolTipLabel, className: "map-transparency-popup-button", onClick: togglePopupDisplay, ref: buttonRef, children: (0, jsx_runtime_1.jsx)("div", { className: "transparent-button", children: (0, jsx_runtime_1.jsx)("svg", { className: disabled ? "checkered-disabled" : "checkered", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { d: "m21.00427 0h-18.00854a2.9957 2.9957 0 0 0 -2.99573 2.99567v18.0086a2.99575 2.99575 0 0 0 2.99573 2.99573h18.00854a2.99575 2.99575 0 0 0 2.99573-2.99573v-18.0086a2.9957 2.9957 0 0 0 -2.99573-2.99567zm-20.00427 21.00427v-9.00427h11v-11h9.00427a1.998 1.998 0 0 1 1.99573 1.99567v9.00433h-11v11h-9.00427a1.998 1.998 0 0 1 -1.99573-1.99573z" }) }) }) }) }) }));
|
|
62
56
|
}
|
|
63
57
|
exports.TransparencyPopupButton = TransparencyPopupButton;
|
|
64
58
|
//# sourceMappingURL=TransparencyPopupButton.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransparencyPopupButton.js","sourceRoot":"","sources":["../../../../src/ui/widget/TransparencyPopupButton.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;gGAGgG;AAEhG,0CAAwC;AACxC,6CAA+B;AAC/B,
|
|
1
|
+
{"version":3,"file":"TransparencyPopupButton.js","sourceRoot":"","sources":["../../../../src/ui/widget/TransparencyPopupButton.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;gGAGgG;AAEhG,0CAAwC;AACxC,6CAA+B;AAC/B,wDAAiD;AACjD,wDAA+D;AAa/D,aAAa;AACb,SAAgB,uBAAuB,CAAC,EAAE,YAAY,EAAE,oBAAoB,EAAE,aAAa,EAAE,QAAQ,EAAgC;IACnI,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClE,MAAM,CAAC,wBAAwB,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,yBAAS,CAAC,YAAY,CAAC,kBAAkB,CAAC,6CAA6C,CAAC,CAAC,CAAC;IAC5I,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,wBAAwB,CAAC,EAAE,CAAC,aAAa,EAAE,wBAAwB,CAAC,CAAC,CAAC;IAEhJ,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAoB,IAAI,CAAC,CAAC;IACxD,MAAM,kBAAkB,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QAC9C,iBAAiB,CAAC,CAAC,cAAc,CAAC,CAAC;IACrC,CAAC,EACD,CAAC,cAAc,CAAC,CACjB,CAAC;IAEF,MAAM,wBAAwB,GAAG,KAAK,CAAC,WAAW,CAChD,CAAC,MAAyB,EAAE,EAAE;QAC5B,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,eAAe,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YAClC,IAAI,eAAe,KAAK,YAAY,EAAE,CAAC;gBACrC,IAAI,oBAAoB,EAAE,CAAC;oBACzB,oBAAoB,CAAC,eAAe,GAAG,GAAG,CAAC,CAAC;gBAC9C,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC,EACD,CAAC,oBAAoB,EAAE,YAAY,CAAC,CACrC,CAAC;IAEF,OAAO,CACL,2DACE,uBAAC,uBAAO,IACN,OAAO,EACL,gCAAK,SAAS,EAAC,8BAA8B,YAC3C,gCAAK,SAAS,EAAC,mCAAmC,YAChD,uBAAC,sBAAM,IAAC,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,YAAY,GAAG,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,wBAAwB,GAAI,GACnG,GACF,EAER,OAAO,EAAE,cAAc,EACvB,eAAe,EAAE,iBAAiB,EAClC,SAAS,EAAC,YAAY,EACtB,eAAe,QACf,iBAAiB,EAAE,SAAS,CAAC,OAAO,IAAI,SAAS,YAEjD,uBAAC,sBAAM,IACL,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAC,OAAO,EACZ,SAAS,EAAC,YAAY,EACtB,KAAK,EAAE,YAAY,EACnB,SAAS,EAAC,+BAA+B,EACzC,OAAO,EAAE,kBAAkB,EAC3B,GAAG,EAAE,SAAS,YAEd,gCAAK,SAAS,EAAC,oBAAoB,YACjC,gCAAK,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,WAAW,EAAE,OAAO,EAAC,WAAW,YAChF,iCAAM,CAAC,EAAC,iVAAiV,GAAG,GACxV,GACF,GACC,GACD,GACT,CACJ,CAAC;AACJ,CAAC;AA5DD,0DA4DC","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 \"./TransparencyPopupButton.scss\";\nimport * as React from \"react\";\nimport { IModelApp } from \"@itwin/core-frontend\";\nimport { Button, Popover, Slider } from \"@itwin/itwinui-react\";\n\n/** @alpha */\nexport interface TransparencyPopupButtonProps {\n /** initialValue range 0-1 */\n transparency: number;\n /** function called when value changes. Returned value range 0-1 */\n onTransparencyChange: (value: number) => void;\n /** optional tooltip */\n buttonToolTip?: string;\n disabled?: boolean;\n}\n\n/** @alpha */\nexport function TransparencyPopupButton({ transparency, onTransparencyChange, buttonToolTip, disabled }: TransparencyPopupButtonProps) {\n const [isSettingsOpen, setIsSettingsOpen] = React.useState(false);\n const [defaultTransparencyLabel] = React.useState(IModelApp.localization.getLocalizedString(\"mapLayers:TransparencyPopup.SetTransparency\"));\n const toolTipLabel = React.useMemo(() => (buttonToolTip ? buttonToolTip : defaultTransparencyLabel), [buttonToolTip, defaultTransparencyLabel]);\n\n const buttonRef = React.useRef<HTMLButtonElement>(null);\n const togglePopupDisplay = React.useCallback(() => {\n setIsSettingsOpen(!isSettingsOpen);\n },\n [isSettingsOpen],\n );\n\n const handleTransparencyChange = React.useCallback(\n (values: readonly number[]) => {\n if (values.length) {\n const newTransparency = values[0];\n if (newTransparency !== transparency) {\n if (onTransparencyChange) {\n onTransparencyChange(newTransparency / 100);\n }\n }\n }\n },\n [onTransparencyChange, transparency],\n );\n\n return (\n <>\n <Popover\n content={\n <div className=\"map-transparency-popup-panel\">\n <div className=\"map-transparency-slider-container\">\n <Slider min={0} max={100} values={[transparency * 100]} step={1} onChange={handleTransparencyChange} />\n </div>\n </div>\n }\n visible={isSettingsOpen}\n onVisibleChange={setIsSettingsOpen}\n placement=\"bottom-end\"\n applyBackground\n positionReference={buttonRef.current ?? undefined}\n >\n <Button\n disabled={disabled}\n size=\"small\"\n styleType=\"borderless\"\n title={toolTipLabel}\n className=\"map-transparency-popup-button\"\n onClick={togglePopupDisplay}\n ref={buttonRef}\n >\n <div className=\"transparent-button\">\n <svg className={disabled ? \"checkered-disabled\" : \"checkered\"} viewBox=\"0 0 24 24\">\n <path d=\"m21.00427 0h-18.00854a2.9957 2.9957 0 0 0 -2.99573 2.99567v18.0086a2.99575 2.99575 0 0 0 2.99573 2.99573h18.00854a2.99575 2.99575 0 0 0 2.99573-2.99573v-18.0086a2.9957 2.9957 0 0 0 -2.99573-2.99567zm-20.00427 21.00427v-9.00427h11v-11h9.00427a1.998 1.998 0 0 1 1.99573 1.99567v9.00433h-11v11h-9.00427a1.998 1.998 0 0 1 -1.99573-1.99573z\" />\n </svg>\n </div>\n </Button>\n </Popover>\n </>\n );\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Hook that will show a popup window
|
|
2
|
+
* @internal
|
|
3
|
+
* Reference: https://github.com/iTwin/appui/commit/b8c0ac6eec4b8f1551cde3b7913df135ccd0f4f5
|
|
4
|
+
* Copied from: https://github.com/iTwin/appui/blob/master/ui/core-react/src/core-react/utils/hooks/useCrossOriginPopup.tsx
|
|
5
|
+
*/
|
|
6
|
+
export declare function useCrossOriginPopup(visible: boolean, url: string | undefined, title: string, width: number, height: number, onClose: () => void): void;
|
|
7
|
+
//# sourceMappingURL=useCrossOriginPopup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCrossOriginPopup.d.ts","sourceRoot":"","sources":["../../../../src/ui/hooks/useCrossOriginPopup.tsx"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,IAAI,QAsGpB"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
import { useInterval } from "./useInterval";
|
|
7
|
+
/** Hook that will show a popup window
|
|
8
|
+
* @internal
|
|
9
|
+
* Reference: https://github.com/iTwin/appui/commit/b8c0ac6eec4b8f1551cde3b7913df135ccd0f4f5
|
|
10
|
+
* Copied from: https://github.com/iTwin/appui/blob/master/ui/core-react/src/core-react/utils/hooks/useCrossOriginPopup.tsx
|
|
11
|
+
*/
|
|
12
|
+
export function useCrossOriginPopup(visible, url, title, width, height, onClose) {
|
|
13
|
+
const [checkPopupAliveDelay, setCheckPopupAliveDelay] = React.useState();
|
|
14
|
+
// ONLY re-render the popup when visibility changes, any other changes get deferred until next visibility change
|
|
15
|
+
// hence the massive use of 'useRef'
|
|
16
|
+
const popupWindow = React.useRef();
|
|
17
|
+
const savedUrl = React.useRef(url);
|
|
18
|
+
const savedTitle = React.useRef(title);
|
|
19
|
+
const savedWidth = React.useRef(width);
|
|
20
|
+
const savedHeight = React.useRef(height);
|
|
21
|
+
const savedOnClose = React.useRef(onClose);
|
|
22
|
+
React.useEffect(() => {
|
|
23
|
+
savedUrl.current = url;
|
|
24
|
+
}, [url]);
|
|
25
|
+
React.useEffect(() => {
|
|
26
|
+
savedTitle.current = title;
|
|
27
|
+
}, [title]);
|
|
28
|
+
React.useEffect(() => {
|
|
29
|
+
savedWidth.current = width;
|
|
30
|
+
}, [width]);
|
|
31
|
+
React.useEffect(() => {
|
|
32
|
+
savedHeight.current = height;
|
|
33
|
+
}, [height]);
|
|
34
|
+
React.useEffect(() => {
|
|
35
|
+
savedOnClose.current = onClose;
|
|
36
|
+
}, [onClose]);
|
|
37
|
+
// Cleanup method after a popup closure. Also calls the OnClose callback.
|
|
38
|
+
const handleClosedPopup = React.useCallback(() => {
|
|
39
|
+
savedOnClose.current();
|
|
40
|
+
setCheckPopupAliveDelay(undefined);
|
|
41
|
+
popupWindow.current = undefined;
|
|
42
|
+
}, []);
|
|
43
|
+
const closePopup = React.useCallback(() => {
|
|
44
|
+
if (popupWindow.current !== undefined) {
|
|
45
|
+
popupWindow.current.close(); // Manually close the popup
|
|
46
|
+
handleClosedPopup();
|
|
47
|
+
}
|
|
48
|
+
}, [handleClosedPopup]);
|
|
49
|
+
const checkPopupClosed = React.useCallback(() => {
|
|
50
|
+
if (popupWindow.current?.closed) {
|
|
51
|
+
// Popup has been closed by end-user, inform our host and cleanup
|
|
52
|
+
handleClosedPopup();
|
|
53
|
+
}
|
|
54
|
+
}, [handleClosedPopup]);
|
|
55
|
+
// Close popup when parent window get closed
|
|
56
|
+
React.useEffect(() => {
|
|
57
|
+
window.onbeforeunload = (_event) => {
|
|
58
|
+
closePopup();
|
|
59
|
+
};
|
|
60
|
+
return () => {
|
|
61
|
+
window.onbeforeunload = null;
|
|
62
|
+
};
|
|
63
|
+
}, [closePopup]);
|
|
64
|
+
// Whenever the hook is unloaded, make sure the underlying popup get closed.
|
|
65
|
+
// Note: An interval is used to check if popup was closed by user: because we access
|
|
66
|
+
// a cross domain resource inside the popup, we don't have access to popup window events.
|
|
67
|
+
// As a workaround, we periodically check if popup is still alive.
|
|
68
|
+
// Reference: https://stackoverflow.com/questions/9388380/capture-the-close-event-of-popup-window-in-javascript/48240128#48240128
|
|
69
|
+
React.useEffect(() => {
|
|
70
|
+
return () => {
|
|
71
|
+
closePopup();
|
|
72
|
+
};
|
|
73
|
+
}, [closePopup]);
|
|
74
|
+
// Timer that checks if popup was closed by end-user
|
|
75
|
+
useInterval(checkPopupClosed, checkPopupAliveDelay);
|
|
76
|
+
// ==> Main render effect
|
|
77
|
+
// Monitors visibility changes and open/close the popup accordingly.
|
|
78
|
+
React.useEffect(() => {
|
|
79
|
+
// If visible and a popup window is not already open, open a new popup window
|
|
80
|
+
if (visible && popupWindow.current === undefined) {
|
|
81
|
+
const popup = window.open(savedUrl.current, savedTitle.current, `width=${savedWidth.current},height=${savedHeight.current}`);
|
|
82
|
+
if (popup) {
|
|
83
|
+
popup.focus();
|
|
84
|
+
popupWindow.current = popup;
|
|
85
|
+
// Start and interval that will check if popup got closed by user
|
|
86
|
+
setCheckPopupAliveDelay(1000);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// If not visible but a previous popup window is still open, close it.
|
|
90
|
+
if (!visible && popupWindow.current !== undefined) {
|
|
91
|
+
popupWindow.current.close();
|
|
92
|
+
handleClosedPopup();
|
|
93
|
+
}
|
|
94
|
+
}, [handleClosedPopup, visible]);
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=useCrossOriginPopup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCrossOriginPopup.js","sourceRoot":"","sources":["../../../../src/ui/hooks/useCrossOriginPopup.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 * as React from \"react\";\nimport { useInterval } from \"./useInterval\";\n\n/** Hook that will show a popup window\n * @internal\n * Reference: https://github.com/iTwin/appui/commit/b8c0ac6eec4b8f1551cde3b7913df135ccd0f4f5\n * Copied from: https://github.com/iTwin/appui/blob/master/ui/core-react/src/core-react/utils/hooks/useCrossOriginPopup.tsx\n */\nexport function useCrossOriginPopup(\n visible: boolean,\n url: string | undefined,\n title: string,\n width: number,\n height: number,\n onClose: () => void\n) {\n const [checkPopupAliveDelay, setCheckPopupAliveDelay] = React.useState<\n number | undefined\n >();\n\n // ONLY re-render the popup when visibility changes, any other changes get deferred until next visibility change\n // hence the massive use of 'useRef'\n const popupWindow = React.useRef<Window>();\n const savedUrl = React.useRef(url);\n const savedTitle = React.useRef(title);\n const savedWidth = React.useRef(width);\n const savedHeight = React.useRef(height);\n const savedOnClose = React.useRef(onClose);\n\n React.useEffect(() => {\n savedUrl.current = url;\n }, [url]);\n React.useEffect(() => {\n savedTitle.current = title;\n }, [title]);\n React.useEffect(() => {\n savedWidth.current = width;\n }, [width]);\n React.useEffect(() => {\n savedHeight.current = height;\n }, [height]);\n React.useEffect(() => {\n savedOnClose.current = onClose;\n }, [onClose]);\n\n // Cleanup method after a popup closure. Also calls the OnClose callback.\n const handleClosedPopup = React.useCallback(() => {\n savedOnClose.current();\n setCheckPopupAliveDelay(undefined);\n popupWindow.current = undefined;\n }, []);\n\n const closePopup = React.useCallback(() => {\n if (popupWindow.current !== undefined) {\n popupWindow.current.close(); // Manually close the popup\n handleClosedPopup();\n }\n }, [handleClosedPopup]);\n\n const checkPopupClosed = React.useCallback(() => {\n if (popupWindow.current?.closed) {\n // Popup has been closed by end-user, inform our host and cleanup\n handleClosedPopup();\n }\n }, [handleClosedPopup]);\n\n // Close popup when parent window get closed\n React.useEffect(() => {\n window.onbeforeunload = (_event) => {\n closePopup();\n };\n return () => {\n window.onbeforeunload = null;\n };\n }, [closePopup]);\n\n // Whenever the hook is unloaded, make sure the underlying popup get closed.\n // Note: An interval is used to check if popup was closed by user: because we access\n // a cross domain resource inside the popup, we don't have access to popup window events.\n // As a workaround, we periodically check if popup is still alive.\n // Reference: https://stackoverflow.com/questions/9388380/capture-the-close-event-of-popup-window-in-javascript/48240128#48240128\n React.useEffect(() => {\n return () => {\n closePopup();\n };\n }, [closePopup]);\n\n // Timer that checks if popup was closed by end-user\n useInterval(checkPopupClosed, checkPopupAliveDelay);\n\n // ==> Main render effect\n // Monitors visibility changes and open/close the popup accordingly.\n React.useEffect(() => {\n // If visible and a popup window is not already open, open a new popup window\n if (visible && popupWindow.current === undefined) {\n const popup = window.open(\n savedUrl.current,\n savedTitle.current,\n `width=${savedWidth.current},height=${savedHeight.current}`\n );\n if (popup) {\n popup.focus();\n popupWindow.current = popup;\n\n // Start and interval that will check if popup got closed by user\n setCheckPopupAliveDelay(1000);\n }\n }\n\n // If not visible but a previous popup window is still open, close it.\n if (!visible && popupWindow.current !== undefined) {\n popupWindow.current.close();\n\n handleClosedPopup();\n }\n }, [handleClosedPopup, visible]);\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Hook that create an interval and clears it when unloaded
|
|
2
|
+
* Reference: https://github.com/gaearon/overreacted.io/blob/master/src/pages/making-setinterval-declarative-with-react-hooks/index.md
|
|
3
|
+
* @internal
|
|
4
|
+
* Copied from: https://github.com/iTwin/appui/blob/master/ui/core-react/src/core-react/utils/hooks/useInterval.tsx
|
|
5
|
+
*/
|
|
6
|
+
export declare function useInterval(callback: (...args: any[]) => void, delay: number | undefined): void;
|
|
7
|
+
//# sourceMappingURL=useInterval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useInterval.d.ts","sourceRoot":"","sources":["../../../../src/ui/hooks/useInterval.tsx"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,EAClC,KAAK,EAAE,MAAM,GAAG,SAAS,QAuB1B"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
/** Hook that create an interval and clears it when unloaded
|
|
7
|
+
* Reference: https://github.com/gaearon/overreacted.io/blob/master/src/pages/making-setinterval-declarative-with-react-hooks/index.md
|
|
8
|
+
* @internal
|
|
9
|
+
* Copied from: https://github.com/iTwin/appui/blob/master/ui/core-react/src/core-react/utils/hooks/useInterval.tsx
|
|
10
|
+
*/
|
|
11
|
+
export function useInterval(callback, delay) {
|
|
12
|
+
const savedCallback = React.useRef(callback);
|
|
13
|
+
// Remember the latest function.
|
|
14
|
+
React.useEffect(() => {
|
|
15
|
+
savedCallback.current = callback;
|
|
16
|
+
}, [callback]);
|
|
17
|
+
// Set up the interval.
|
|
18
|
+
React.useEffect(() => {
|
|
19
|
+
function tick() {
|
|
20
|
+
savedCallback.current();
|
|
21
|
+
}
|
|
22
|
+
if (delay !== undefined) {
|
|
23
|
+
const id = setInterval(tick, delay);
|
|
24
|
+
return () => {
|
|
25
|
+
clearInterval(id);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
}, [delay]);
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=useInterval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useInterval.js","sourceRoot":"","sources":["../../../../src/ui/hooks/useInterval.tsx"],"names":[],"mappings":"AAAA;;;gGAGgG;AAChG,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;;;GAIG;AACH,MAAM,UAAU,WAAW,CACzB,QAAkC,EAClC,KAAyB;IAEzB,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAA2B,QAAQ,CAAC,CAAC;IAEvE,gCAAgC;IAChC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,aAAa,CAAC,OAAO,GAAG,QAAQ,CAAC;IACnC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,uBAAuB;IACvB,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,SAAS,IAAI;YACX,aAAa,CAAC,OAAO,EAAE,CAAC;QAC1B,CAAC;QACD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACpC,OAAO,GAAG,EAAE;gBACV,aAAa,CAAC,EAAE,CAAC,CAAC;YACpB,CAAC,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;AACd,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 create an interval and clears it when unloaded\n * Reference: https://github.com/gaearon/overreacted.io/blob/master/src/pages/making-setinterval-declarative-with-react-hooks/index.md\n * @internal\n * Copied from: https://github.com/iTwin/appui/blob/master/ui/core-react/src/core-react/utils/hooks/useInterval.tsx\n */\nexport function useInterval(\n callback: (...args: any[]) => void,\n delay: number | undefined\n) {\n const savedCallback = React.useRef<(...args: any[]) => void>(callback);\n\n // Remember the latest function.\n React.useEffect(() => {\n savedCallback.current = callback;\n }, [callback]);\n\n // Set up the interval.\n React.useEffect(() => {\n function tick() {\n savedCallback.current();\n }\n if (delay !== undefined) {\n const id = setInterval(tick, delay);\n return () => {\n clearInterval(id);\n };\n } else {\n return undefined;\n }\n }, [delay]);\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useResizeObserver.d.ts","sourceRoot":"","sources":["../../../../src/ui/hooks/useResizeObserver.tsx"],"names":[],"mappings":"AAeA,eAAO,MAAM,iBAAiB,2CACX,eAAe,KAAK,IAAI,yBAK7B,CAAC,GAAG,IAAI,GAAG,SAAS,sCA2BjC,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
/** Hook that will observe Window Resize
|
|
7
|
+
* @internal
|
|
8
|
+
* Reference: https://github.com/iTwin/iTwinUI/blob/87bbc99316c17bd2b763a730135fbb45c84b0e82/packages/itwinui-react/src/utils/hooks/useResizeObserver.tsx
|
|
9
|
+
* Copied from: https://github.com/iTwin/appui/blob/master/ui/core-react/src/core-react/utils/hooks/useResizeObserver.tsx
|
|
10
|
+
*/
|
|
11
|
+
const getWindow = () => {
|
|
12
|
+
return typeof window === "undefined" ? undefined : window;
|
|
13
|
+
};
|
|
14
|
+
export const useResizeObserver = (onResize) => {
|
|
15
|
+
const resizeObserver = React.useRef();
|
|
16
|
+
const elementRef = React.useCallback((element) => {
|
|
17
|
+
if (!getWindow()?.ResizeObserver) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
resizeObserver.current?.disconnect?.();
|
|
21
|
+
if (element) {
|
|
22
|
+
resizeObserver.current = new ResizeObserver((entries) => {
|
|
23
|
+
// We wrap onResize with requestAnimationFrame to avoid this error - ResizeObserver loop limit exceeded
|
|
24
|
+
// See: https://github.com/iTwin/iTwinUI/issues/1317
|
|
25
|
+
// See: https://stackoverflow.com/a/58701523/11547064
|
|
26
|
+
window.requestAnimationFrame(() => {
|
|
27
|
+
if (!Array.isArray(entries) || !entries.length) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const [{ contentRect }] = entries;
|
|
31
|
+
return onResize(contentRect);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
resizeObserver.current?.observe?.(element);
|
|
35
|
+
}
|
|
36
|
+
}, [onResize]);
|
|
37
|
+
return [elementRef, resizeObserver.current];
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=useResizeObserver.js.map
|
|
@@ -0,0 +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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AttachLayerPopupButton.d.ts","sourceRoot":"","sources":["../../../../src/ui/widget/AttachLayerPopupButton.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AttachLayerPopupButton.d.ts","sourceRoot":"","sources":["../../../../src/ui/widget/AttachLayerPopupButton.tsx"],"names":[],"mappings":"AA8gBA,gBAAgB;AAChB,oBAAY,qBAAqB;IAC/B,OAAO,IAAA;IACP,IAAI,IAAA;IACJ,IAAI,IAAA;CACL;AACD,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,gBAAgB;AAChB,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,2CAsGxE"}
|
|
@@ -4,12 +4,10 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
4
4
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
5
|
*--------------------------------------------------------------------------------------------*/
|
|
6
6
|
import * as React from "react";
|
|
7
|
-
import { RelativePosition } from "@itwin/appui-abstract";
|
|
8
7
|
import { UiFramework } from "@itwin/appui-react";
|
|
9
8
|
import { IModelApp, MapLayerSource, MapLayerSourceStatus, NotifyMessageDetails, OutputMessagePriority } from "@itwin/core-frontend";
|
|
10
|
-
import * as UiCore from "@itwin/core-react";
|
|
11
9
|
import { SvgAdd, SvgDelete, SvgEdit } from "@itwin/itwinui-icons-react";
|
|
12
|
-
import { Button, IconButton, Input, List, ListItem, ProgressRadial, Text } from "@itwin/itwinui-react";
|
|
10
|
+
import { Button, IconButton, Input, List, ListItem, Popover, ProgressRadial, Text } from "@itwin/itwinui-react";
|
|
13
11
|
import { MapLayerPreferences } from "../../MapLayerPreferences";
|
|
14
12
|
import { MapLayersUI } from "../../mapLayers";
|
|
15
13
|
import { ConfirmMessageDialog } from "./ConfirmMessageDialog";
|
|
@@ -22,7 +20,7 @@ var LayerAction;
|
|
|
22
20
|
LayerAction[LayerAction["New"] = 0] = "New";
|
|
23
21
|
LayerAction[LayerAction["Edit"] = 1] = "Edit";
|
|
24
22
|
})(LayerAction || (LayerAction = {}));
|
|
25
|
-
function AttachLayerPanel({ isOverlay, onLayerAttached, onHandleOutsideClick }) {
|
|
23
|
+
function AttachLayerPanel({ isOverlay, onLayerAttached, onHandleOutsideClick, setMapUrlModalOpen }) {
|
|
26
24
|
const [layerNameToAdd, setLayerNameToAdd] = React.useState();
|
|
27
25
|
const [sourceFilterString, setSourceFilterString] = React.useState();
|
|
28
26
|
const { placeholderLabel, addCustomLayerLabel, addCustomLayerToolTip, loadingMapSources, removeLayerDefButtonTitle, editLayerDefButtonTitle, removeLayerDefDialogTitle, } = React.useMemo(() => {
|
|
@@ -159,6 +157,7 @@ function AttachLayerPanel({ isOverlay, onLayerAttached, onHandleOutsideClick })
|
|
|
159
157
|
validation.subLayers.length > 1);
|
|
160
158
|
}, []);
|
|
161
159
|
const handleModalUrlDialogOk = React.useCallback((action, sourceState) => {
|
|
160
|
+
setMapUrlModalOpen(false);
|
|
162
161
|
UiFramework.dialogs.modal.close();
|
|
163
162
|
if (LayerAction.New === action && sourceState && sourceState.validation.status === MapLayerSourceStatus.Valid) {
|
|
164
163
|
if (needsFeatureSelection(sourceState.source, sourceState.validation)) {
|
|
@@ -171,13 +170,14 @@ function AttachLayerPanel({ isOverlay, onLayerAttached, onHandleOutsideClick })
|
|
|
171
170
|
else {
|
|
172
171
|
resumeOutsideClick();
|
|
173
172
|
}
|
|
174
|
-
}, [attachLayer, needsFeatureSelection, openFeatureSelectionDialog, resumeOutsideClick]);
|
|
173
|
+
}, [attachLayer, needsFeatureSelection, openFeatureSelectionDialog, resumeOutsideClick, setMapUrlModalOpen]);
|
|
175
174
|
const handleModalUrlDialogCancel = React.useCallback(() => {
|
|
176
175
|
// close popup and refresh UI
|
|
177
176
|
setLoading(false);
|
|
177
|
+
setMapUrlModalOpen(false);
|
|
178
178
|
UiFramework.dialogs.modal.close();
|
|
179
179
|
resumeOutsideClick();
|
|
180
|
-
}, [setLoading, resumeOutsideClick]);
|
|
180
|
+
}, [setLoading, resumeOutsideClick, setMapUrlModalOpen]);
|
|
181
181
|
React.useEffect(() => {
|
|
182
182
|
async function attemptToAddLayer() {
|
|
183
183
|
if (layerNameToAdd && activeViewport) {
|
|
@@ -206,7 +206,8 @@ function AttachLayerPanel({ isOverlay, onLayerAttached, onHandleOutsideClick })
|
|
|
206
206
|
else if (sourceValidation.status === MapLayerSourceStatus.RequireAuth && isMounted.current) {
|
|
207
207
|
const layer = foundSource.toLayerSettings();
|
|
208
208
|
if (layer) {
|
|
209
|
-
|
|
209
|
+
setMapUrlModalOpen(true);
|
|
210
|
+
UiFramework.dialogs.modal.open(_jsx(MapUrlDialog, { activeViewport: activeViewport, signInModeArgs: { layer, validation: sourceValidation, source: foundSource }, onOkResult: (sourceState) => handleModalUrlDialogOk(LayerAction.New, sourceState), onCancelResult: handleModalUrlDialogCancel, mapLayerOptions: mapLayerOptions }));
|
|
210
211
|
}
|
|
211
212
|
if (onHandleOutsideClick) {
|
|
212
213
|
onHandleOutsideClick(false);
|
|
@@ -253,6 +254,7 @@ function AttachLayerPanel({ isOverlay, onLayerAttached, onHandleOutsideClick })
|
|
|
253
254
|
onHandleOutsideClick,
|
|
254
255
|
openFeatureSelectionDialog,
|
|
255
256
|
mapLayerOptions,
|
|
257
|
+
setMapUrlModalOpen,
|
|
256
258
|
]);
|
|
257
259
|
const options = React.useMemo(() => sources, [sources]);
|
|
258
260
|
const filteredOptions = React.useMemo(() => {
|
|
@@ -263,13 +265,14 @@ function AttachLayerPanel({ isOverlay, onLayerAttached, onHandleOutsideClick })
|
|
|
263
265
|
return options?.filter((option) => option.name.toLowerCase().includes(sourceFilterString?.toLowerCase()));
|
|
264
266
|
}
|
|
265
267
|
}, [options, sourceFilterString]);
|
|
266
|
-
const handleAddNewMapSource = React.useCallback(() => {
|
|
267
|
-
|
|
268
|
+
const handleAddNewMapSource = React.useCallback((event) => {
|
|
269
|
+
event.stopPropagation(); // We don't want the owning ListBox to react on mouse click.
|
|
270
|
+
setMapUrlModalOpen(true);
|
|
271
|
+
UiFramework.dialogs.modal.open(_jsx(MapUrlDialog, { activeViewport: activeViewport, onOkResult: (result) => handleModalUrlDialogOk(LayerAction.New, result), onCancelResult: handleModalUrlDialogCancel, mapLayerOptions: mapLayerOptions }));
|
|
268
272
|
if (onHandleOutsideClick) {
|
|
269
273
|
onHandleOutsideClick(false);
|
|
270
274
|
}
|
|
271
|
-
|
|
272
|
-
}, [activeViewport, handleModalUrlDialogCancel, handleModalUrlDialogOk, isOverlay, mapLayerOptions, onHandleOutsideClick]);
|
|
275
|
+
}, [activeViewport, handleModalUrlDialogCancel, handleModalUrlDialogOk, mapLayerOptions, onHandleOutsideClick, setMapUrlModalOpen]);
|
|
273
276
|
const handleAttach = React.useCallback((mapName) => {
|
|
274
277
|
setLayerNameToAdd(mapName);
|
|
275
278
|
}, []);
|
|
@@ -295,7 +298,7 @@ function AttachLayerPanel({ isOverlay, onLayerAttached, onHandleOutsideClick })
|
|
|
295
298
|
}, [iTwinId, iModelId, resumeOutsideClick]);
|
|
296
299
|
/*
|
|
297
300
|
Handle Remove layer button clicked
|
|
298
|
-
|
|
301
|
+
*/
|
|
299
302
|
const onItemRemoveButtonClicked = React.useCallback((source, event) => {
|
|
300
303
|
event.stopPropagation(); // We don't want the owning ListBox to react on mouse click.
|
|
301
304
|
const layerName = source.name;
|
|
@@ -316,12 +319,19 @@ function AttachLayerPanel({ isOverlay, onLayerAttached, onHandleOutsideClick })
|
|
|
316
319
|
if (matchingSource === undefined) {
|
|
317
320
|
return;
|
|
318
321
|
}
|
|
319
|
-
|
|
322
|
+
setMapUrlModalOpen(true);
|
|
323
|
+
UiFramework.dialogs.modal.open(_jsx(MapUrlDialog, { activeViewport: activeViewport, mapLayerSourceToEdit: matchingSource, onOkResult: (result) => handleModalUrlDialogOk(LayerAction.Edit, result), onCancelResult: handleModalUrlDialogCancel, mapLayerOptions: mapLayerOptions }));
|
|
320
324
|
if (onHandleOutsideClick) {
|
|
321
325
|
onHandleOutsideClick(false);
|
|
322
326
|
}
|
|
323
|
-
}, [activeViewport, handleModalUrlDialogCancel, handleModalUrlDialogOk,
|
|
324
|
-
return (_jsxs("div", { className: "map-manager-header", children: [(loading || loadingSources) && (_jsx(
|
|
327
|
+
}, [activeViewport, handleModalUrlDialogCancel, handleModalUrlDialogOk, mapLayerOptions, onHandleOutsideClick, setMapUrlModalOpen, sources]);
|
|
328
|
+
return (_jsxs("div", { className: "map-manager-header", children: [(loading || loadingSources) && (_jsx("div", { style: {
|
|
329
|
+
position: "absolute",
|
|
330
|
+
inset: 0,
|
|
331
|
+
display: "grid",
|
|
332
|
+
placeItems: "center",
|
|
333
|
+
zIndex: 100,
|
|
334
|
+
}, children: _jsx(ProgressRadial, { as: "div", children: _jsx(Text, { variant: 'small', children: loadingMapSources }) }) })), _jsxs("div", { className: "map-manager-source-listbox-header", children: [_jsx(Input, { type: "text", className: "map-manager-source-list-filter", placeholder: placeholderLabel, value: sourceFilterString, onChange: handleFilterTextChanged, size: "small" }), _jsx(Button, { className: "map-manager-add-source-button", title: addCustomLayerToolTip, onClick: handleAddNewMapSource, children: addCustomLayerLabel })] }), _jsx("div", { className: "map-manager-sources", children: _jsx(List, { id: "map-sources", as: "div", className: "map-manager-source-list", children: filteredOptions?.map((source) => (_jsxs(ListItem, { as: "div", className: "map-source-list-entry", actionable: true, onClick: () => handleAttach(source.name), onMouseEnter: () => setLayerNameUnderCursor(source.name), onMouseLeave: () => setLayerNameUnderCursor(undefined), children: [_jsx(ListItem.Content, { children: source.name }),
|
|
325
335
|
// Display the delete icon only when the mouse over a specific item
|
|
326
336
|
// otherwise list feels cluttered.
|
|
327
337
|
!!iTwinId && layerNameUnderCursor && layerNameUnderCursor === source.name && (_jsxs(_Fragment, { children: [_jsx(Button, { size: "small", styleType: "borderless", className: "map-source-list-entry-button", title: editLayerDefButtonTitle, onClick: onItemEditButtonClicked, children: _jsx(SvgEdit, {}) }), _jsx(Button, { size: "small", styleType: "borderless", className: "map-source-list-entry-button", title: removeLayerDefButtonTitle, onClick: (event) => {
|
|
@@ -345,6 +355,7 @@ export function AttachLayerPopupButton(props) {
|
|
|
345
355
|
};
|
|
346
356
|
}, []);
|
|
347
357
|
const [handleOutsideClick, setHandleOutsideClick] = React.useState(true);
|
|
358
|
+
const [mapUrlModalOpen, setMapUrlModalOpen] = React.useState(false);
|
|
348
359
|
const [popupOpen, setPopupOpen] = React.useState(false);
|
|
349
360
|
const buttonRef = React.useRef(null);
|
|
350
361
|
const panelRef = React.useRef(null);
|
|
@@ -360,24 +371,6 @@ export function AttachLayerPopupButton(props) {
|
|
|
360
371
|
const togglePopup = React.useCallback(() => {
|
|
361
372
|
setPopupOpen(!popupOpen);
|
|
362
373
|
}, [popupOpen]);
|
|
363
|
-
const handleClosePopup = React.useCallback(() => {
|
|
364
|
-
setPopupOpen(false);
|
|
365
|
-
}, []);
|
|
366
|
-
const onHandleOutsideClick = React.useCallback((event) => {
|
|
367
|
-
if (!handleOutsideClick) {
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
// If clicking on button that open panel - don't trigger outside click processing
|
|
371
|
-
if (buttonRef?.current && buttonRef?.current.contains(event.target)) {
|
|
372
|
-
return;
|
|
373
|
-
}
|
|
374
|
-
// If clicking the panel, this is not an outside clicked
|
|
375
|
-
if (panelRef.current && panelRef?.current.contains(event.target)) {
|
|
376
|
-
return;
|
|
377
|
-
}
|
|
378
|
-
// If we reach this point, we got an outside clicked, no close the popup
|
|
379
|
-
setPopupOpen(false);
|
|
380
|
-
}, [handleOutsideClick]);
|
|
381
374
|
const { refreshFromStyle } = useSourceMapContext();
|
|
382
375
|
const handleLayerAttached = React.useCallback(() => {
|
|
383
376
|
if (!isMounted.current) {
|
|
@@ -406,7 +399,6 @@ export function AttachLayerPopupButton(props) {
|
|
|
406
399
|
}
|
|
407
400
|
return button;
|
|
408
401
|
}
|
|
409
|
-
return (
|
|
410
|
-
, { isOpen: popupOpen, position: RelativePosition.BottomRight, onClose: handleClosePopup, onOutsideClick: onHandleOutsideClick, closeOnWheel: false, target: buttonRef.current, closeOnEnter: false, closeOnContextMenu: false, children: _jsx("div", { ref: panelRef, className: "map-sources-popup-panel", children: _jsx(AttachLayerPanel, { isOverlay: props.isOverlay, onLayerAttached: handleLayerAttached, onHandleOutsideClick: setHandleOutsideClick }) }) })] }));
|
|
402
|
+
return (_jsx(_Fragment, { children: _jsx(Popover, { content: _jsx("div", { ref: panelRef, className: "map-sources-popup-panel", children: _jsx(AttachLayerPanel, { isOverlay: props.isOverlay, onLayerAttached: handleLayerAttached, onHandleOutsideClick: setHandleOutsideClick, setMapUrlModalOpen: setMapUrlModalOpen }) }), applyBackground: true, visible: popupOpen || mapUrlModalOpen, onVisibleChange: setPopupOpen, closeOnOutsideClick: handleOutsideClick, placement: "bottom-end", children: renderButton() }) }));
|
|
411
403
|
}
|
|
412
404
|
//# sourceMappingURL=AttachLayerPopupButton.js.map
|