@itwin/tree-widget-react 0.1.1
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/LICENSE.md +9 -0
- package/README.md +32 -0
- package/lib/cjs/TreeWidget.d.ts +27 -0
- package/lib/cjs/TreeWidget.js +57 -0
- package/lib/cjs/TreeWidget.js.map +1 -0
- package/lib/cjs/components/IconButton.d.ts +14 -0
- package/lib/cjs/components/IconButton.js +42 -0
- package/lib/cjs/components/IconButton.js.map +1 -0
- package/lib/cjs/components/IconButton.scss +73 -0
- package/lib/cjs/components/TreeFilteringState.d.ts +16 -0
- package/lib/cjs/components/TreeFilteringState.js +67 -0
- package/lib/cjs/components/TreeFilteringState.js.map +1 -0
- package/lib/cjs/components/TreeWidgetComponent.d.ts +8 -0
- package/lib/cjs/components/TreeWidgetComponent.js +41 -0
- package/lib/cjs/components/TreeWidgetComponent.js.map +1 -0
- package/lib/cjs/components/TreeWidgetComponent.scss +64 -0
- package/lib/cjs/components/TreeWidgetControl.d.ts +25 -0
- package/lib/cjs/components/TreeWidgetControl.js +64 -0
- package/lib/cjs/components/TreeWidgetControl.js.map +1 -0
- package/lib/cjs/components/TreeWidgetUiItemsProvider.d.ts +19 -0
- package/lib/cjs/components/TreeWidgetUiItemsProvider.js +81 -0
- package/lib/cjs/components/TreeWidgetUiItemsProvider.js.map +1 -0
- package/lib/cjs/components/header/TreeHeader.d.ts +14 -0
- package/lib/cjs/components/header/TreeHeader.js +43 -0
- package/lib/cjs/components/header/TreeHeader.js.map +1 -0
- package/lib/cjs/components/header/TreeHeader.scss +19 -0
- package/lib/cjs/components/rulesets/ClassificationSystems.json +122 -0
- package/lib/cjs/components/search-bar/Popup.d.ts +50 -0
- package/lib/cjs/components/search-bar/Popup.js +246 -0
- package/lib/cjs/components/search-bar/Popup.js.map +1 -0
- package/lib/cjs/components/search-bar/Popup.scss +316 -0
- package/lib/cjs/components/search-bar/SearchBar.d.ts +53 -0
- package/lib/cjs/components/search-bar/SearchBar.js +97 -0
- package/lib/cjs/components/search-bar/SearchBar.js.map +1 -0
- package/lib/cjs/components/search-bar/SearchBar.scss +110 -0
- package/lib/cjs/components/search-bar/SearchBox.d.ts +76 -0
- package/lib/cjs/components/search-bar/SearchBox.js +184 -0
- package/lib/cjs/components/search-bar/SearchBox.js.map +1 -0
- package/lib/cjs/components/search-bar/SearchBox.scss +91 -0
- package/lib/cjs/components/trees/CategoriesTree.d.ts +9 -0
- package/lib/cjs/components/trees/CategoriesTree.js +76 -0
- package/lib/cjs/components/trees/CategoriesTree.js.map +1 -0
- package/lib/cjs/components/trees/CategoriesTree.scss +13 -0
- package/lib/cjs/components/trees/ClassificationsTree.d.ts +6 -0
- package/lib/cjs/components/trees/ClassificationsTree.js +43 -0
- package/lib/cjs/components/trees/ClassificationsTree.js.map +1 -0
- package/lib/cjs/components/trees/ModelsTree.d.ts +10 -0
- package/lib/cjs/components/trees/ModelsTree.js +135 -0
- package/lib/cjs/components/trees/ModelsTree.js.map +1 -0
- package/lib/cjs/components/trees/ModelsTree.scss +14 -0
- package/lib/cjs/components/trees/SpatialTree.d.ts +3 -0
- package/lib/cjs/components/trees/SpatialTree.js +41 -0
- package/lib/cjs/components/trees/SpatialTree.js.map +1 -0
- package/lib/cjs/components/trees/TreeWithRuleset.d.ts +35 -0
- package/lib/cjs/components/trees/TreeWithRuleset.js +108 -0
- package/lib/cjs/components/trees/TreeWithRuleset.js.map +1 -0
- package/lib/cjs/components/trees/TreeWithRulesetTree.scss +17 -0
- package/lib/cjs/components/trees/index.d.ts +6 -0
- package/lib/cjs/components/trees/index.js +22 -0
- package/lib/cjs/components/trees/index.js.map +1 -0
- package/lib/cjs/tree-widget-react.d.ts +7 -0
- package/lib/cjs/tree-widget-react.js +23 -0
- package/lib/cjs/tree-widget-react.js.map +1 -0
- package/lib/esm/TreeWidget.d.ts +27 -0
- package/lib/esm/TreeWidget.js +53 -0
- package/lib/esm/TreeWidget.js.map +1 -0
- package/lib/esm/components/IconButton.d.ts +14 -0
- package/lib/esm/components/IconButton.js +16 -0
- package/lib/esm/components/IconButton.js.map +1 -0
- package/lib/esm/components/IconButton.scss +73 -0
- package/lib/esm/components/TreeFilteringState.d.ts +16 -0
- package/lib/esm/components/TreeFilteringState.js +44 -0
- package/lib/esm/components/TreeFilteringState.js.map +1 -0
- package/lib/esm/components/TreeWidgetComponent.d.ts +8 -0
- package/lib/esm/components/TreeWidgetComponent.js +18 -0
- package/lib/esm/components/TreeWidgetComponent.js.map +1 -0
- package/lib/esm/components/TreeWidgetComponent.scss +64 -0
- package/lib/esm/components/TreeWidgetControl.d.ts +25 -0
- package/lib/esm/components/TreeWidgetControl.js +57 -0
- package/lib/esm/components/TreeWidgetControl.js.map +1 -0
- package/lib/esm/components/TreeWidgetUiItemsProvider.d.ts +19 -0
- package/lib/esm/components/TreeWidgetUiItemsProvider.js +74 -0
- package/lib/esm/components/TreeWidgetUiItemsProvider.js.map +1 -0
- package/lib/esm/components/header/TreeHeader.d.ts +14 -0
- package/lib/esm/components/header/TreeHeader.js +20 -0
- package/lib/esm/components/header/TreeHeader.js.map +1 -0
- package/lib/esm/components/header/TreeHeader.scss +19 -0
- package/lib/esm/components/rulesets/ClassificationSystems.json +122 -0
- package/lib/esm/components/search-bar/Popup.d.ts +50 -0
- package/lib/esm/components/search-bar/Popup.js +220 -0
- package/lib/esm/components/search-bar/Popup.js.map +1 -0
- package/lib/esm/components/search-bar/Popup.scss +316 -0
- package/lib/esm/components/search-bar/SearchBar.d.ts +53 -0
- package/lib/esm/components/search-bar/SearchBar.js +71 -0
- package/lib/esm/components/search-bar/SearchBar.js.map +1 -0
- package/lib/esm/components/search-bar/SearchBar.scss +110 -0
- package/lib/esm/components/search-bar/SearchBox.d.ts +76 -0
- package/lib/esm/components/search-bar/SearchBox.js +158 -0
- package/lib/esm/components/search-bar/SearchBox.js.map +1 -0
- package/lib/esm/components/search-bar/SearchBox.scss +91 -0
- package/lib/esm/components/trees/CategoriesTree.d.ts +9 -0
- package/lib/esm/components/trees/CategoriesTree.js +53 -0
- package/lib/esm/components/trees/CategoriesTree.js.map +1 -0
- package/lib/esm/components/trees/CategoriesTree.scss +13 -0
- package/lib/esm/components/trees/ClassificationsTree.d.ts +6 -0
- package/lib/esm/components/trees/ClassificationsTree.js +17 -0
- package/lib/esm/components/trees/ClassificationsTree.js.map +1 -0
- package/lib/esm/components/trees/ModelsTree.d.ts +10 -0
- package/lib/esm/components/trees/ModelsTree.js +112 -0
- package/lib/esm/components/trees/ModelsTree.js.map +1 -0
- package/lib/esm/components/trees/ModelsTree.scss +14 -0
- package/lib/esm/components/trees/SpatialTree.d.ts +3 -0
- package/lib/esm/components/trees/SpatialTree.js +18 -0
- package/lib/esm/components/trees/SpatialTree.js.map +1 -0
- package/lib/esm/components/trees/TreeWithRuleset.d.ts +35 -0
- package/lib/esm/components/trees/TreeWithRuleset.js +83 -0
- package/lib/esm/components/trees/TreeWithRuleset.js.map +1 -0
- package/lib/esm/components/trees/TreeWithRulesetTree.scss +17 -0
- package/lib/esm/components/trees/index.d.ts +6 -0
- package/lib/esm/components/trees/index.js +10 -0
- package/lib/esm/components/trees/index.js.map +1 -0
- package/lib/esm/tree-widget-react.d.ts +7 -0
- package/lib/esm/tree-widget-react.js +11 -0
- package/lib/esm/tree-widget-react.js.map +1 -0
- package/lib/public/locales/en/TreeWidget.json +16 -0
- package/package.json +97 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "tree-widget-react/ClassificationSystems",
|
|
3
|
+
"rules": [
|
|
4
|
+
{
|
|
5
|
+
"ruleType": "RootNodes",
|
|
6
|
+
"specifications": [
|
|
7
|
+
{
|
|
8
|
+
"specType": "InstanceNodesOfSpecificClasses",
|
|
9
|
+
"classes": [
|
|
10
|
+
{
|
|
11
|
+
"schemaName": "ClassificationSystems",
|
|
12
|
+
"classNames": [
|
|
13
|
+
"ClassificationSystem"
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"arePolymorphic": false,
|
|
18
|
+
"groupByClass": false,
|
|
19
|
+
"groupByLabel": false
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"ruleType": "ChildNodes",
|
|
25
|
+
"condition": "ParentNode.IsOfClass(\"ClassificationSystem\", \"ClassificationSystems\")",
|
|
26
|
+
"specifications": [
|
|
27
|
+
{
|
|
28
|
+
"specType": "RelatedInstanceNodes",
|
|
29
|
+
"relationships": {
|
|
30
|
+
"schemaName": "ClassificationSystems",
|
|
31
|
+
"classNames": [
|
|
32
|
+
"ClassificationSystemOwnsClassificationTable"
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
"relatedClasses": {
|
|
36
|
+
"schemaName": "ClassificationSystems",
|
|
37
|
+
"classNames": [
|
|
38
|
+
"ClassificationTable"
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
"requiredDirection": "Forward",
|
|
42
|
+
"groupByClass": false,
|
|
43
|
+
"groupByLabel": false,
|
|
44
|
+
"doNotSort": true
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"ruleType": "ChildNodes",
|
|
50
|
+
"condition": "ParentNode.IsOfClass(\"ClassificationTable\", \"ClassificationSystems\")",
|
|
51
|
+
"specifications": [
|
|
52
|
+
{
|
|
53
|
+
"specType": "RelatedInstanceNodes",
|
|
54
|
+
"relationships": {
|
|
55
|
+
"schemaName": "BisCore",
|
|
56
|
+
"classNames": [
|
|
57
|
+
"ModelModelsElement"
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
"relatedClasses": {
|
|
61
|
+
"schemaName": "BisCore",
|
|
62
|
+
"classNames": [
|
|
63
|
+
"Model"
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
"requiredDirection": "Backward",
|
|
67
|
+
"groupByClass": false,
|
|
68
|
+
"groupByLabel": false,
|
|
69
|
+
"hideNodesInHierarchy": true
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"ruleType": "ChildNodes",
|
|
75
|
+
"condition": "ParentNode.IsOfClass(\"Model\", \"BisCore\")",
|
|
76
|
+
"specifications": [
|
|
77
|
+
{
|
|
78
|
+
"specType": "RelatedInstanceNodes",
|
|
79
|
+
"relationships": {
|
|
80
|
+
"schemaName": "BisCore",
|
|
81
|
+
"classNames": [
|
|
82
|
+
"ModelContainsElements"
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
"relatedClasses": {
|
|
86
|
+
"schemaName": "ClassificationSystems",
|
|
87
|
+
"classNames": [
|
|
88
|
+
"Classification"
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
"requiredDirection": "Forward",
|
|
92
|
+
"groupByClass": false,
|
|
93
|
+
"groupByLabel": false
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"ruleType": "ChildNodes",
|
|
99
|
+
"condition": "ParentNode.IsOfClass(\"Classification\", \"ClassificationSystems\")",
|
|
100
|
+
"specifications": [
|
|
101
|
+
{
|
|
102
|
+
"specType": "RelatedInstanceNodes",
|
|
103
|
+
"relationships": {
|
|
104
|
+
"schemaName": "ClassificationSystems",
|
|
105
|
+
"classNames": [
|
|
106
|
+
"ElementHasClassifications"
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
"relatedClasses": {
|
|
110
|
+
"schemaName": "BisCore",
|
|
111
|
+
"classNames": [
|
|
112
|
+
"Element"
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
"requiredDirection": "Backward",
|
|
116
|
+
"groupByClass": false,
|
|
117
|
+
"groupByLabel": false
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { CommonProps } from "@itwin/core-react";
|
|
3
|
+
import { RelativePosition } from "@itwin/appui-abstract";
|
|
4
|
+
import "./Popup.scss";
|
|
5
|
+
/** Properties for the [[Popup]] component */
|
|
6
|
+
export interface PopupProps extends CommonProps {
|
|
7
|
+
/** show or hide the box shadow */
|
|
8
|
+
showShadow: boolean;
|
|
9
|
+
/** show or hide the arrow */
|
|
10
|
+
showArrow: boolean;
|
|
11
|
+
/** indicate if the popup is shown or not */
|
|
12
|
+
isShown: boolean;
|
|
13
|
+
/** Direction (relative to the target) to which the popup is expanded */
|
|
14
|
+
position: RelativePosition;
|
|
15
|
+
/** Fixed position in the viewport */
|
|
16
|
+
fixedPosition?: {
|
|
17
|
+
top: number;
|
|
18
|
+
left: number;
|
|
19
|
+
};
|
|
20
|
+
/** target element */
|
|
21
|
+
context: HTMLElement | null;
|
|
22
|
+
/** Function called when the popup is opened */
|
|
23
|
+
onOpen?: () => void;
|
|
24
|
+
/** Function called when the popup is closed */
|
|
25
|
+
onClose?: () => void;
|
|
26
|
+
}
|
|
27
|
+
interface PopupState {
|
|
28
|
+
isShown: boolean;
|
|
29
|
+
position: RelativePosition;
|
|
30
|
+
}
|
|
31
|
+
/** Popup React component */
|
|
32
|
+
export declare class Popup extends React.Component<PopupProps, PopupState> {
|
|
33
|
+
private _popupRef;
|
|
34
|
+
private _targetElement?;
|
|
35
|
+
constructor(props: PopupProps, context?: any);
|
|
36
|
+
static defaultProps: Partial<PopupProps>;
|
|
37
|
+
componentDidMount(): void;
|
|
38
|
+
componentDidUpdate(previousProps: PopupProps): void;
|
|
39
|
+
componentWillUnmount(): void;
|
|
40
|
+
private _onBodyClick;
|
|
41
|
+
private _onEsc;
|
|
42
|
+
private _onShow;
|
|
43
|
+
private _onClose;
|
|
44
|
+
private _getContext;
|
|
45
|
+
private getPositionClassName;
|
|
46
|
+
private getPositionWithinViewport;
|
|
47
|
+
render(): JSX.Element;
|
|
48
|
+
}
|
|
49
|
+
export {};
|
|
50
|
+
//# sourceMappingURL=Popup.d.ts.map
|
|
@@ -0,0 +1,220 @@
|
|
|
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 classnames from "classnames";
|
|
7
|
+
import { RelativePosition } from "@itwin/appui-abstract";
|
|
8
|
+
import "./Popup.scss";
|
|
9
|
+
/** Popup React component */
|
|
10
|
+
export class Popup extends React.Component {
|
|
11
|
+
constructor(props, context) {
|
|
12
|
+
super(props, context);
|
|
13
|
+
this._popupRef = React.createRef();
|
|
14
|
+
this._onBodyClick = (event) => {
|
|
15
|
+
const context = this._getContext();
|
|
16
|
+
// Ignore clicks on the popover or button
|
|
17
|
+
if (context === event.target) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (context && context.contains(event.target)) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (this._popupRef.current &&
|
|
24
|
+
(this._popupRef.current === event.target ||
|
|
25
|
+
this._popupRef.current.contains(event.target))) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
this._onClose();
|
|
29
|
+
};
|
|
30
|
+
this._onEsc = (event) => {
|
|
31
|
+
// Esc key
|
|
32
|
+
if (event.key === "Escape") {
|
|
33
|
+
this._onClose();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
this._getContext = () => this.props.context || this._targetElement;
|
|
37
|
+
this.state = { isShown: this.props.isShown, position: this.props.position };
|
|
38
|
+
}
|
|
39
|
+
componentDidMount() {
|
|
40
|
+
const popupElement = this._popupRef.current;
|
|
41
|
+
if (popupElement && popupElement.parentElement) {
|
|
42
|
+
this._targetElement = popupElement.parentElement;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
componentDidUpdate(previousProps) {
|
|
46
|
+
if (this.props.isShown === previousProps.isShown)
|
|
47
|
+
return;
|
|
48
|
+
if (this.props.isShown) {
|
|
49
|
+
this._onShow();
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
this._onClose();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
componentWillUnmount() {
|
|
56
|
+
document.body.removeEventListener("click", this._onBodyClick, false);
|
|
57
|
+
document.body.removeEventListener("keydown", this._onEsc, false);
|
|
58
|
+
}
|
|
59
|
+
_onShow() {
|
|
60
|
+
if (this.state.isShown) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
document.addEventListener("click", this._onBodyClick, true);
|
|
64
|
+
document.addEventListener("keydown", this._onEsc, true);
|
|
65
|
+
const newPosition = this.getPositionWithinViewport();
|
|
66
|
+
this.setState({ position: newPosition, isShown: true }, () => {
|
|
67
|
+
if (this.props.onOpen)
|
|
68
|
+
this.props.onOpen();
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
_onClose() {
|
|
72
|
+
if (!this.state.isShown) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
document.removeEventListener("click", this._onBodyClick, true);
|
|
76
|
+
document.removeEventListener("keydown", this._onEsc, true);
|
|
77
|
+
// tslint:disable-next-line:tslint-react-set-state-usage
|
|
78
|
+
this.setState({ isShown: false, position: this.props.position }, () => {
|
|
79
|
+
if (this.props.onClose)
|
|
80
|
+
this.props.onClose();
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
getPositionClassName(position) {
|
|
84
|
+
switch (position) {
|
|
85
|
+
case RelativePosition.TopLeft:
|
|
86
|
+
return classnames("tree-widget-search-popup-top-left");
|
|
87
|
+
case RelativePosition.TopRight:
|
|
88
|
+
return classnames("tree-widget-search-popup-top-right");
|
|
89
|
+
case RelativePosition.BottomLeft:
|
|
90
|
+
return classnames("tree-widget-search-popup-bottom-left");
|
|
91
|
+
case RelativePosition.BottomRight:
|
|
92
|
+
return classnames("tree-widget-search-popup-bottom-right");
|
|
93
|
+
case RelativePosition.Top:
|
|
94
|
+
return classnames("tree-widget-search-popup-top");
|
|
95
|
+
case RelativePosition.Left:
|
|
96
|
+
return classnames("tree-widget-search-popup-left");
|
|
97
|
+
case RelativePosition.Right:
|
|
98
|
+
return classnames("tree-widget-search-popup-right");
|
|
99
|
+
default:
|
|
100
|
+
return classnames("tree-widget-search-popup-bottom");
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
getPositionWithinViewport() {
|
|
104
|
+
const popupElement = this._popupRef.current;
|
|
105
|
+
if (!popupElement || !this._targetElement)
|
|
106
|
+
return this.props.position;
|
|
107
|
+
// Note: Cannot use DOMRect yet since it's experimental and not available in all browsers (Nov. 2018)
|
|
108
|
+
const viewportRect = {
|
|
109
|
+
left: window.scrollX,
|
|
110
|
+
top: window.scrollY,
|
|
111
|
+
right: window.scrollX + window.innerWidth,
|
|
112
|
+
bottom: window.scrollY + window.innerHeight,
|
|
113
|
+
};
|
|
114
|
+
const targetRect = this._targetElement.getBoundingClientRect();
|
|
115
|
+
const popupRect = popupElement.getBoundingClientRect();
|
|
116
|
+
const containerStyle = window.getComputedStyle(this._targetElement);
|
|
117
|
+
const offset = this.props.showArrow ? 12 : 4;
|
|
118
|
+
switch (this.props.position) {
|
|
119
|
+
case RelativePosition.BottomRight: {
|
|
120
|
+
const bottomMargin = containerStyle.marginBottom
|
|
121
|
+
? parseFloat(containerStyle.marginBottom)
|
|
122
|
+
: 0;
|
|
123
|
+
if (targetRect.bottom + popupRect.height + bottomMargin + offset >
|
|
124
|
+
viewportRect.bottom) {
|
|
125
|
+
return RelativePosition.TopRight;
|
|
126
|
+
}
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
case RelativePosition.TopRight: {
|
|
130
|
+
const topMargin = containerStyle.marginTop
|
|
131
|
+
? parseFloat(containerStyle.marginTop)
|
|
132
|
+
: 0;
|
|
133
|
+
if (targetRect.top - popupRect.height - topMargin - offset <
|
|
134
|
+
viewportRect.top) {
|
|
135
|
+
return RelativePosition.BottomRight;
|
|
136
|
+
}
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
case RelativePosition.TopLeft: {
|
|
140
|
+
const topMargin = containerStyle.marginTop
|
|
141
|
+
? parseFloat(containerStyle.marginTop)
|
|
142
|
+
: 0;
|
|
143
|
+
if (targetRect.top - popupRect.height - topMargin - offset <
|
|
144
|
+
viewportRect.top) {
|
|
145
|
+
return RelativePosition.BottomLeft;
|
|
146
|
+
}
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
case RelativePosition.BottomLeft: {
|
|
150
|
+
const bottomMargin = containerStyle.marginBottom
|
|
151
|
+
? parseFloat(containerStyle.marginBottom)
|
|
152
|
+
: 0;
|
|
153
|
+
if (targetRect.bottom + popupRect.height + bottomMargin + offset >
|
|
154
|
+
viewportRect.bottom) {
|
|
155
|
+
return RelativePosition.TopLeft;
|
|
156
|
+
}
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
case RelativePosition.Bottom: {
|
|
160
|
+
const bottomMargin = containerStyle.marginBottom
|
|
161
|
+
? parseFloat(containerStyle.marginBottom)
|
|
162
|
+
: 0;
|
|
163
|
+
if (targetRect.bottom + popupRect.height + bottomMargin + offset >
|
|
164
|
+
viewportRect.bottom) {
|
|
165
|
+
return RelativePosition.Top;
|
|
166
|
+
}
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
case RelativePosition.Top: {
|
|
170
|
+
const topMargin = containerStyle.marginTop
|
|
171
|
+
? parseFloat(containerStyle.marginTop)
|
|
172
|
+
: 0;
|
|
173
|
+
if (targetRect.top - popupRect.height - topMargin - offset <
|
|
174
|
+
viewportRect.top) {
|
|
175
|
+
return RelativePosition.Bottom;
|
|
176
|
+
}
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
case RelativePosition.Left: {
|
|
180
|
+
const leftMargin = containerStyle.marginLeft
|
|
181
|
+
? parseFloat(containerStyle.marginLeft)
|
|
182
|
+
: 0;
|
|
183
|
+
if (targetRect.left - popupRect.width - leftMargin - offset <
|
|
184
|
+
viewportRect.left) {
|
|
185
|
+
return RelativePosition.Right;
|
|
186
|
+
}
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
case RelativePosition.Right: {
|
|
190
|
+
const rightMargin = containerStyle.marginRight
|
|
191
|
+
? parseFloat(containerStyle.marginRight)
|
|
192
|
+
: 0;
|
|
193
|
+
if (targetRect.right + popupRect.width + rightMargin + offset >
|
|
194
|
+
viewportRect.right) {
|
|
195
|
+
return RelativePosition.Left;
|
|
196
|
+
}
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return this.props.position;
|
|
201
|
+
}
|
|
202
|
+
render() {
|
|
203
|
+
const className = classnames("tree-widget-search-popup", this.getPositionClassName(this.state.position), this.props.showShadow && "tree-widget-search-popup-shadow", this.state.isShown && "visible", this.props.showArrow && "arrow", this.props.className);
|
|
204
|
+
let style;
|
|
205
|
+
if (this.props.fixedPosition) {
|
|
206
|
+
style = {
|
|
207
|
+
top: this.props.fixedPosition.top,
|
|
208
|
+
left: this.props.fixedPosition.left,
|
|
209
|
+
position: "fixed",
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
return (React.createElement("div", { style: style, className: className, ref: this._popupRef }, this.props.children));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
Popup.defaultProps = {
|
|
216
|
+
position: RelativePosition.Bottom,
|
|
217
|
+
showShadow: true,
|
|
218
|
+
showArrow: false,
|
|
219
|
+
};
|
|
220
|
+
//# sourceMappingURL=Popup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Popup.js","sourceRoot":"","sources":["../../../../src/components/search-bar/Popup.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 * as React from \"react\";\nimport classnames from \"classnames\";\nimport { CommonProps } from \"@itwin/core-react\";\nimport { RelativePosition } from \"@itwin/appui-abstract\";\nimport \"./Popup.scss\";\n\n/** Properties for the [[Popup]] component */\nexport interface PopupProps extends CommonProps {\n /** show or hide the box shadow */\n showShadow: boolean;\n /** show or hide the arrow */\n showArrow: boolean;\n /** indicate if the popup is shown or not */\n isShown: boolean;\n /** Direction (relative to the target) to which the popup is expanded */\n position: RelativePosition;\n /** Fixed position in the viewport */\n fixedPosition?: { top: number; left: number };\n /** target element */\n context: HTMLElement | null;\n /** Function called when the popup is opened */\n onOpen?: () => void;\n /** Function called when the popup is closed */\n onClose?: () => void;\n}\n\ninterface PopupState {\n isShown: boolean;\n position: RelativePosition;\n}\n\ninterface Rect {\n left: number;\n top: number;\n right: number;\n bottom: number;\n}\n\n/** Popup React component */\nexport class Popup extends React.Component<PopupProps, PopupState> {\n private _popupRef = React.createRef<HTMLDivElement>();\n private _targetElement?: HTMLElement; // target element owning the popup\n\n constructor(props: PopupProps, context?: any) {\n super(props, context);\n\n this.state = { isShown: this.props.isShown, position: this.props.position };\n }\n\n public static defaultProps: Partial<PopupProps> = {\n position: RelativePosition.Bottom,\n showShadow: true,\n showArrow: false,\n };\n\n public componentDidMount() {\n const popupElement = this._popupRef.current;\n if (popupElement && popupElement.parentElement) {\n this._targetElement = popupElement.parentElement;\n }\n }\n\n public componentDidUpdate(previousProps: PopupProps) {\n if (this.props.isShown === previousProps.isShown) return;\n\n if (this.props.isShown) {\n this._onShow();\n } else {\n this._onClose();\n }\n }\n\n public componentWillUnmount() {\n document.body.removeEventListener(\"click\", this._onBodyClick, false);\n document.body.removeEventListener(\"keydown\", this._onEsc, false);\n }\n\n private _onBodyClick = (event: MouseEvent): void => {\n const context = this._getContext();\n\n // Ignore clicks on the popover or button\n if (context === event.target) {\n return;\n }\n\n if (context && context.contains(event.target as Node)) {\n return;\n }\n\n if (\n this._popupRef.current &&\n (this._popupRef.current === event.target ||\n this._popupRef.current.contains(event.target as Node))\n ) {\n return;\n }\n\n this._onClose();\n };\n\n private _onEsc = (event: KeyboardEvent): void => {\n // Esc key\n if (event.key === \"Escape\") {\n this._onClose();\n }\n };\n\n private _onShow() {\n if (this.state.isShown) {\n return;\n }\n\n document.addEventListener(\"click\", this._onBodyClick, true);\n document.addEventListener(\"keydown\", this._onEsc, true);\n\n const newPosition = this.getPositionWithinViewport();\n this.setState({ position: newPosition, isShown: true }, () => {\n if (this.props.onOpen) this.props.onOpen();\n });\n }\n\n private _onClose() {\n if (!this.state.isShown) {\n return;\n }\n\n document.removeEventListener(\"click\", this._onBodyClick, true);\n document.removeEventListener(\"keydown\", this._onEsc, true);\n\n // tslint:disable-next-line:tslint-react-set-state-usage\n this.setState({ isShown: false, position: this.props.position }, () => {\n if (this.props.onClose) this.props.onClose();\n });\n }\n\n private _getContext = () => this.props.context || this._targetElement;\n\n private getPositionClassName(position: RelativePosition): string {\n switch (position) {\n case RelativePosition.TopLeft:\n return classnames(\"tree-widget-search-popup-top-left\");\n case RelativePosition.TopRight:\n return classnames(\"tree-widget-search-popup-top-right\");\n case RelativePosition.BottomLeft:\n return classnames(\"tree-widget-search-popup-bottom-left\");\n case RelativePosition.BottomRight:\n return classnames(\"tree-widget-search-popup-bottom-right\");\n case RelativePosition.Top:\n return classnames(\"tree-widget-search-popup-top\");\n case RelativePosition.Left:\n return classnames(\"tree-widget-search-popup-left\");\n case RelativePosition.Right:\n return classnames(\"tree-widget-search-popup-right\");\n default:\n return classnames(\"tree-widget-search-popup-bottom\");\n }\n }\n\n private getPositionWithinViewport(): RelativePosition {\n const popupElement = this._popupRef.current;\n\n if (!popupElement || !this._targetElement) return this.props.position;\n // Note: Cannot use DOMRect yet since it's experimental and not available in all browsers (Nov. 2018)\n const viewportRect: Rect = {\n left: window.scrollX,\n top: window.scrollY,\n right: window.scrollX + window.innerWidth,\n bottom: window.scrollY + window.innerHeight,\n };\n const targetRect = this._targetElement.getBoundingClientRect();\n const popupRect = popupElement.getBoundingClientRect();\n const containerStyle = window.getComputedStyle(this._targetElement);\n const offset = this.props.showArrow ? 12 : 4;\n\n switch (this.props.position) {\n case RelativePosition.BottomRight: {\n const bottomMargin = containerStyle.marginBottom\n ? parseFloat(containerStyle.marginBottom)\n : 0;\n if (\n targetRect.bottom + popupRect.height + bottomMargin + offset >\n viewportRect.bottom\n ) {\n return RelativePosition.TopRight;\n }\n break;\n }\n\n case RelativePosition.TopRight: {\n const topMargin = containerStyle.marginTop\n ? parseFloat(containerStyle.marginTop)\n : 0;\n if (\n targetRect.top - popupRect.height - topMargin - offset <\n viewportRect.top\n ) {\n return RelativePosition.BottomRight;\n }\n break;\n }\n\n case RelativePosition.TopLeft: {\n const topMargin = containerStyle.marginTop\n ? parseFloat(containerStyle.marginTop)\n : 0;\n if (\n targetRect.top - popupRect.height - topMargin - offset <\n viewportRect.top\n ) {\n return RelativePosition.BottomLeft;\n }\n break;\n }\n\n case RelativePosition.BottomLeft: {\n const bottomMargin = containerStyle.marginBottom\n ? parseFloat(containerStyle.marginBottom)\n : 0;\n if (\n targetRect.bottom + popupRect.height + bottomMargin + offset >\n viewportRect.bottom\n ) {\n return RelativePosition.TopLeft;\n }\n break;\n }\n\n case RelativePosition.Bottom: {\n const bottomMargin = containerStyle.marginBottom\n ? parseFloat(containerStyle.marginBottom)\n : 0;\n if (\n targetRect.bottom + popupRect.height + bottomMargin + offset >\n viewportRect.bottom\n ) {\n return RelativePosition.Top;\n }\n break;\n }\n\n case RelativePosition.Top: {\n const topMargin = containerStyle.marginTop\n ? parseFloat(containerStyle.marginTop)\n : 0;\n if (\n targetRect.top - popupRect.height - topMargin - offset <\n viewportRect.top\n ) {\n return RelativePosition.Bottom;\n }\n break;\n }\n\n case RelativePosition.Left: {\n const leftMargin = containerStyle.marginLeft\n ? parseFloat(containerStyle.marginLeft)\n : 0;\n if (\n targetRect.left - popupRect.width - leftMargin - offset <\n viewportRect.left\n ) {\n return RelativePosition.Right;\n }\n break;\n }\n\n case RelativePosition.Right: {\n const rightMargin = containerStyle.marginRight\n ? parseFloat(containerStyle.marginRight)\n : 0;\n if (\n targetRect.right + popupRect.width + rightMargin + offset >\n viewportRect.right\n ) {\n return RelativePosition.Left;\n }\n break;\n }\n }\n\n return this.props.position;\n }\n\n public render(): JSX.Element {\n const className = classnames(\n \"tree-widget-search-popup\",\n this.getPositionClassName(this.state.position),\n this.props.showShadow && \"tree-widget-search-popup-shadow\",\n this.state.isShown && \"visible\",\n this.props.showArrow && \"arrow\",\n this.props.className\n );\n\n let style: React.CSSProperties | undefined;\n if (this.props.fixedPosition) {\n style = {\n top: this.props.fixedPosition.top,\n left: this.props.fixedPosition.left,\n position: \"fixed\",\n };\n }\n\n return (\n <div style={style} className={className} ref={this._popupRef}>\n {this.props.children}\n </div>\n );\n }\n}\n"]}
|