@longline/aqua-ui 1.0.222 → 1.0.224
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/containers/InfoBox/InfoBox.d.ts +1 -0
- package/containers/InfoBox/InfoBox.js +2 -0
- package/containers/InfoBox/elements/Row.d.ts +12 -0
- package/containers/InfoBox/elements/Row.js +19 -0
- package/containers/Openable/Openable.d.ts +3 -0
- package/containers/Openable/Openable.js +15 -24
- package/controls/ListView/ColumnsManager/ColumnsManager.js +8 -23
- package/formatters/DivisionFormatter/index.d.ts +1 -0
- package/formatters/DivisionFormatter/index.js +1 -0
- package/hooks/useOutsideClose/index.d.ts +1 -0
- package/hooks/useOutsideClose/index.js +1 -0
- package/hooks/useOutsideClose/useOutsideClose.d.ts +75 -0
- package/hooks/useOutsideClose/useOutsideClose.js +104 -0
- package/inputs/DateInput/DateInput.js +8 -15
- package/inputs/Dropdown/Dropdown.js +8 -17
- package/inputs/MonthRange/MonthRange.js +10 -21
- package/map/controls/Geocoder/Geocoder.js +8 -17
- package/map/controls/Geocoder/GeocoderEntry.js +2 -2
- package/map/controls/Geocoder/GeocoderList.js +1 -1
- package/modules/Filter/Filter.js +8 -20
- package/package.json +1 -1
- package/services/Dialog/Dialog.js +13 -17
|
@@ -58,5 +58,6 @@ interface IInfoBoxProps {
|
|
|
58
58
|
declare const InfoBox: {
|
|
59
59
|
({ width, minHeight, padded, scroll, ...props }: IInfoBoxProps): React.JSX.Element;
|
|
60
60
|
displayName: string;
|
|
61
|
+
Row: (props: import("./elements/Row").IInfoBoxRowProps) => React.JSX.Element;
|
|
61
62
|
};
|
|
62
63
|
export { InfoBox, IInfoBoxProps };
|
|
@@ -28,6 +28,7 @@ import * as React from 'react';
|
|
|
28
28
|
import styled from 'styled-components';
|
|
29
29
|
import { Content } from './elements/Content';
|
|
30
30
|
import { Footer } from './elements/Footer';
|
|
31
|
+
import { InfoBoxRow } from './elements/Row';
|
|
31
32
|
/**
|
|
32
33
|
* An `InfoBox` is a glass pane with an optional header and footer.
|
|
33
34
|
*/
|
|
@@ -79,5 +80,6 @@ var InfoBox = function (_a) {
|
|
|
79
80
|
return React.createElement(InfoBoxStyled, __assign({ width: width, minHeight: minHeight, padded: padded, scroll: scroll }, props));
|
|
80
81
|
};
|
|
81
82
|
InfoBox.displayName = "InfoBox";
|
|
83
|
+
InfoBox.Row = InfoBoxRow;
|
|
82
84
|
export { InfoBox };
|
|
83
85
|
var templateObject_1;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
interface IInfoBoxRowProps {
|
|
3
|
+
/** Name to show. */
|
|
4
|
+
name: React.ReactNode;
|
|
5
|
+
/** Value to show. */
|
|
6
|
+
value: React.ReactNode;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* An `InfoBoxRow` shows a name-value combination, in row format.
|
|
10
|
+
*/
|
|
11
|
+
declare const InfoBoxRow: (props: IInfoBoxRowProps) => React.JSX.Element;
|
|
12
|
+
export { InfoBoxRow, IInfoBoxRowProps };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
|
|
2
|
+
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
|
|
3
|
+
return cooked;
|
|
4
|
+
};
|
|
5
|
+
import * as React from 'react';
|
|
6
|
+
import styled from 'styled-components';
|
|
7
|
+
/**
|
|
8
|
+
* An `InfoBoxRow` shows a name-value combination, in row format.
|
|
9
|
+
*/
|
|
10
|
+
var InfoBoxRow = function (props) {
|
|
11
|
+
return React.createElement(Wrapper, null,
|
|
12
|
+
React.createElement(Name, null, props.name),
|
|
13
|
+
React.createElement(Value, null, props.value));
|
|
14
|
+
};
|
|
15
|
+
var Name = styled.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n white-space: nowrap;\n overflow-x: hidden;\n text-overflow: ellipsis;\n flex: 1;\n min-width: 65px;\n"], ["\n white-space: nowrap;\n overflow-x: hidden;\n text-overflow: ellipsis;\n flex: 1;\n min-width: 65px;\n"])));
|
|
16
|
+
var Value = styled.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n font-weight: 700;\n text-align: right;\n white-space: nowrap;\n overflow-x: hidden;\n text-overflow: ellipsis; \n"], ["\n font-weight: 700;\n text-align: right;\n white-space: nowrap;\n overflow-x: hidden;\n text-overflow: ellipsis; \n"])));
|
|
17
|
+
var Wrapper = styled.div(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n white-space: nowrap;\n gap: 16px;\n height: 28px;\n align-items: center;\n"], ["\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n white-space: nowrap;\n gap: 16px;\n height: 28px;\n align-items: center;\n"])));
|
|
18
|
+
export { InfoBoxRow };
|
|
19
|
+
var templateObject_1, templateObject_2, templateObject_3;
|
|
@@ -28,31 +28,20 @@ import * as React from 'react';
|
|
|
28
28
|
import styled from 'styled-components';
|
|
29
29
|
import { createPortal } from 'react-dom';
|
|
30
30
|
import { usePopper } from 'react-popper';
|
|
31
|
+
import { useOutsideClose } from '../../hooks/useOutsideClose';
|
|
31
32
|
var Openable = function (_a) {
|
|
32
|
-
var _b
|
|
33
|
+
var _b;
|
|
34
|
+
var _c = _a.width, width = _c === void 0 ? 250 : _c, props = __rest(_a, ["width"]);
|
|
33
35
|
var toggleRef = React.useRef(null);
|
|
34
36
|
var paneRef = React.useRef(null);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
};
|
|
44
|
-
}, []);
|
|
45
|
-
var handleClickOutside = function (e) {
|
|
46
|
-
var elem = e.target;
|
|
47
|
-
if (toggleRef.current && paneRef.current && !toggleRef.current.contains(elem) && !paneRef.current.contains(elem)) {
|
|
48
|
-
props.onClose();
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
var handleKeyDown = function (e) {
|
|
52
|
-
if (e.key == 'Escape')
|
|
53
|
-
props.onClose();
|
|
54
|
-
};
|
|
55
|
-
var _c = usePopper(toggleRef.current, paneRef.current, {
|
|
37
|
+
useOutsideClose({
|
|
38
|
+
open: props.open,
|
|
39
|
+
refs: [toggleRef, paneRef],
|
|
40
|
+
onClose: props.onClose,
|
|
41
|
+
escapeToClose: true,
|
|
42
|
+
blurToClose: true
|
|
43
|
+
});
|
|
44
|
+
var _d = usePopper(toggleRef.current, paneRef.current, {
|
|
56
45
|
placement: 'bottom-end',
|
|
57
46
|
modifiers: [
|
|
58
47
|
{
|
|
@@ -62,13 +51,15 @@ var Openable = function (_a) {
|
|
|
62
51
|
},
|
|
63
52
|
}
|
|
64
53
|
]
|
|
65
|
-
}), styles =
|
|
54
|
+
}), styles = _d.styles, attributes = _d.attributes, update = _d.update;
|
|
66
55
|
React.useEffect(function () {
|
|
67
56
|
update === null || update === void 0 ? void 0 : update();
|
|
68
57
|
}, [props.open]);
|
|
69
58
|
return (React.createElement("div", { ref: toggleRef },
|
|
70
59
|
props.toggle,
|
|
71
|
-
createPortal(React.createElement(Pane, __assign({ "$open": props.open, "$width": width, style: styles.popper }, attributes.popper, { ref: paneRef }), open && props.content),
|
|
60
|
+
createPortal(React.createElement(Pane, __assign({ "$open": props.open, "$width": width, style: styles.popper }, attributes.popper, { ref: paneRef }), props.open && props.content), // If in fullscreen mode, Openable must portal into fullscreen element,
|
|
61
|
+
// else content will be hidden.
|
|
62
|
+
(_b = document.fullscreenElement) !== null && _b !== void 0 ? _b : document.body)));
|
|
72
63
|
};
|
|
73
64
|
var Pane = styled.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n display: ", ";\n width: ", "px;\n z-index: 2500;\n"], ["\n display: ", ";\n width: ", "px;\n z-index: 2500;\n"])), function (p) { return p.$open ? 'block' : 'none'; }, function (p) { return p.$width; });
|
|
74
65
|
Openable.displayName = "Openable";
|
|
@@ -20,31 +20,16 @@ import { SourceColumns } from './SourceColumns';
|
|
|
20
20
|
import { OrderColumns } from './OrderColumns';
|
|
21
21
|
import { SecondaryButton } from '../../SecondaryButton';
|
|
22
22
|
import { SVG } from '../../../svg';
|
|
23
|
+
import { useOutsideClose } from '../../../hooks/useOutsideClose';
|
|
23
24
|
var ColumnsManagerBase = function (props) {
|
|
24
25
|
var wrapperRef = React.useRef(null);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// Clean up document-wide mousedown/keydown events when panel unmounts.
|
|
33
|
-
document.removeEventListener('mousedown', handleClickOutside);
|
|
34
|
-
document.removeEventListener('keydown', handleKeyDown);
|
|
35
|
-
};
|
|
36
|
-
}, []);
|
|
37
|
-
var handleKeyDown = function (e) {
|
|
38
|
-
if (e.key == 'Escape')
|
|
39
|
-
props.onClose();
|
|
40
|
-
};
|
|
41
|
-
// Handle document-wide mousedown event by closing the panel.
|
|
42
|
-
var handleClickOutside = function (event) {
|
|
43
|
-
var elem = event.target;
|
|
44
|
-
if (wrapperRef.current && !wrapperRef.current.contains(elem)) {
|
|
45
|
-
props.onClose();
|
|
46
|
-
}
|
|
47
|
-
};
|
|
26
|
+
useOutsideClose({
|
|
27
|
+
open: true,
|
|
28
|
+
refs: [wrapperRef],
|
|
29
|
+
onClose: props.onClose,
|
|
30
|
+
escapeToClose: true,
|
|
31
|
+
blurToClose: true
|
|
32
|
+
});
|
|
48
33
|
return (React.createElement("div", { className: props.className, ref: wrapperRef },
|
|
49
34
|
React.createElement(GlassPane, { animated: true, bordered: true },
|
|
50
35
|
React.createElement(Content, null,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DivisionFormatter';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DivisionFormatter';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './useOutsideClose';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './useOutsideClose';
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
type UseOutsideCloseOptions = {
|
|
3
|
+
/**
|
|
4
|
+
* Whether the outside-close behavior is active (the component that uses
|
|
5
|
+
* this is open)
|
|
6
|
+
*/
|
|
7
|
+
open: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Refs that should be considered "inside"
|
|
10
|
+
*/
|
|
11
|
+
refs: React.RefObject<HTMLElement>[];
|
|
12
|
+
/**
|
|
13
|
+
* Callback when the user clicks outside (or pressed Escape if enabled)
|
|
14
|
+
*/
|
|
15
|
+
onClose: () => void;
|
|
16
|
+
/**
|
|
17
|
+
* Whether Escape should also trigger `onClose`.
|
|
18
|
+
* @default false
|
|
19
|
+
*/
|
|
20
|
+
escapeToClose?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Whether blur (focus leaving all refs) should trigger `onClose`.
|
|
23
|
+
* @default false
|
|
24
|
+
*/
|
|
25
|
+
blurToClose?: boolean;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* React hook that closes a component (via `onClose`) when the user interacts
|
|
29
|
+
* outside of one or more referenced elements. Commonly used for dropdowns,
|
|
30
|
+
* popovers, tooltips, or modals.
|
|
31
|
+
*
|
|
32
|
+
* ## Features
|
|
33
|
+
* - Detects clicks outside the provided refs and calls `onClose`.
|
|
34
|
+
* - Optionally closes on `Escape` key press (`escapeToClose`).
|
|
35
|
+
* - Optionally closes when focus leaves all refs (`blurToClose`).
|
|
36
|
+
* - No-op when `active` is `false` (no listeners attached).
|
|
37
|
+
*
|
|
38
|
+
* ## Usage
|
|
39
|
+
* ```tsx
|
|
40
|
+
* const toggleRef = useRef<HTMLButtonElement>(null);
|
|
41
|
+
* const menuRef = useRef<HTMLDivElement>(null);
|
|
42
|
+
*
|
|
43
|
+
* useOutsideClose({
|
|
44
|
+
* open: isOpen,
|
|
45
|
+
* refs: [toggleRef, menuRef],
|
|
46
|
+
* onClose: () => setIsOpen(false),
|
|
47
|
+
* escapeToClose: true,
|
|
48
|
+
* blurToClose: true,
|
|
49
|
+
* });
|
|
50
|
+
*
|
|
51
|
+
* return (
|
|
52
|
+
* <div>
|
|
53
|
+
* <button ref={toggleRef} onClick={() => setIsOpen(v => !v)}>Toggle</button>
|
|
54
|
+
* {isOpen && <div ref={menuRef}>Menu content</div>}
|
|
55
|
+
* </div>
|
|
56
|
+
* );
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* ## Parameters
|
|
60
|
+
* @param {Object} options - Configuration object.
|
|
61
|
+
* @param {boolean} options.open - Whether the hook is active. If `false`, no listeners are attached.
|
|
62
|
+
* @param {React.RefObject<HTMLElement>[]} options.refs - Elements that are considered "inside".
|
|
63
|
+
* Interactions within these elements will not trigger `onClose`.
|
|
64
|
+
* @param {() => void} options.onClose - Callback fired when the user clicks outside, presses Escape
|
|
65
|
+
* (if enabled), or tabs focus away (if enabled).
|
|
66
|
+
* @param {boolean} [options.escapeToClose=false] - If `true`, pressing Escape will call `onClose`.
|
|
67
|
+
* @param {boolean} [options.blurToClose=false] - If `true`, moving focus outside all refs will call `onClose`.
|
|
68
|
+
*
|
|
69
|
+
* ## Notes
|
|
70
|
+
* - This hook attaches global listeners to `document` while active and cleans them up automatically.
|
|
71
|
+
* - The hook works with any number of refs. Make sure you pass **stable refs** (e.g. from `useRef`),
|
|
72
|
+
* not inline ref callbacks.
|
|
73
|
+
*/
|
|
74
|
+
declare function useOutsideClose({ open, refs, onClose, escapeToClose, blurToClose, }: UseOutsideCloseOptions): void;
|
|
75
|
+
export { useOutsideClose };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* React hook that closes a component (via `onClose`) when the user interacts
|
|
4
|
+
* outside of one or more referenced elements. Commonly used for dropdowns,
|
|
5
|
+
* popovers, tooltips, or modals.
|
|
6
|
+
*
|
|
7
|
+
* ## Features
|
|
8
|
+
* - Detects clicks outside the provided refs and calls `onClose`.
|
|
9
|
+
* - Optionally closes on `Escape` key press (`escapeToClose`).
|
|
10
|
+
* - Optionally closes when focus leaves all refs (`blurToClose`).
|
|
11
|
+
* - No-op when `active` is `false` (no listeners attached).
|
|
12
|
+
*
|
|
13
|
+
* ## Usage
|
|
14
|
+
* ```tsx
|
|
15
|
+
* const toggleRef = useRef<HTMLButtonElement>(null);
|
|
16
|
+
* const menuRef = useRef<HTMLDivElement>(null);
|
|
17
|
+
*
|
|
18
|
+
* useOutsideClose({
|
|
19
|
+
* open: isOpen,
|
|
20
|
+
* refs: [toggleRef, menuRef],
|
|
21
|
+
* onClose: () => setIsOpen(false),
|
|
22
|
+
* escapeToClose: true,
|
|
23
|
+
* blurToClose: true,
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* return (
|
|
27
|
+
* <div>
|
|
28
|
+
* <button ref={toggleRef} onClick={() => setIsOpen(v => !v)}>Toggle</button>
|
|
29
|
+
* {isOpen && <div ref={menuRef}>Menu content</div>}
|
|
30
|
+
* </div>
|
|
31
|
+
* );
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* ## Parameters
|
|
35
|
+
* @param {Object} options - Configuration object.
|
|
36
|
+
* @param {boolean} options.open - Whether the hook is active. If `false`, no listeners are attached.
|
|
37
|
+
* @param {React.RefObject<HTMLElement>[]} options.refs - Elements that are considered "inside".
|
|
38
|
+
* Interactions within these elements will not trigger `onClose`.
|
|
39
|
+
* @param {() => void} options.onClose - Callback fired when the user clicks outside, presses Escape
|
|
40
|
+
* (if enabled), or tabs focus away (if enabled).
|
|
41
|
+
* @param {boolean} [options.escapeToClose=false] - If `true`, pressing Escape will call `onClose`.
|
|
42
|
+
* @param {boolean} [options.blurToClose=false] - If `true`, moving focus outside all refs will call `onClose`.
|
|
43
|
+
*
|
|
44
|
+
* ## Notes
|
|
45
|
+
* - This hook attaches global listeners to `document` while active and cleans them up automatically.
|
|
46
|
+
* - The hook works with any number of refs. Make sure you pass **stable refs** (e.g. from `useRef`),
|
|
47
|
+
* not inline ref callbacks.
|
|
48
|
+
*/
|
|
49
|
+
function useOutsideClose(_a) {
|
|
50
|
+
var open = _a.open, refs = _a.refs, onClose = _a.onClose, _b = _a.escapeToClose, escapeToClose = _b === void 0 ? false : _b, _c = _a.blurToClose, blurToClose = _c === void 0 ? false : _c;
|
|
51
|
+
// Events get added to the component only when it opens, and removed
|
|
52
|
+
// when it closes. This way, components aren't listening for document-wide
|
|
53
|
+
// events when they're closed.
|
|
54
|
+
React.useEffect(function () {
|
|
55
|
+
// If component isn't open, then do nothing:
|
|
56
|
+
if (!open)
|
|
57
|
+
return undefined;
|
|
58
|
+
// When the HTML document gets clicked, see if the click in side one of
|
|
59
|
+
// the HTML elements that were passed in. If so, do nothing. It outside
|
|
60
|
+
// these elements, close the component.
|
|
61
|
+
var handleClick = function (e) {
|
|
62
|
+
var target = e.target;
|
|
63
|
+
var clickedInside = refs.some(function (ref) { return ref.current && ref.current.contains(target); });
|
|
64
|
+
if (!clickedInside) {
|
|
65
|
+
onClose();
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
// When the ESC key is pressed (and this feature has been enabled),
|
|
69
|
+
// close the component.
|
|
70
|
+
var handleKeyDown = function (e) {
|
|
71
|
+
if (escapeToClose && e.key === "Escape") {
|
|
72
|
+
onClose();
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
var handleBlur = function (e) {
|
|
76
|
+
if (!blurToClose)
|
|
77
|
+
return;
|
|
78
|
+
var target = e.relatedTarget; // where focus is going
|
|
79
|
+
var focusedInside = refs.some(function (ref) { return ref.current && target && ref.current.contains(target); });
|
|
80
|
+
if (!focusedInside) {
|
|
81
|
+
onClose();
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
// Add event listeners:
|
|
85
|
+
document.addEventListener("mousedown", handleClick);
|
|
86
|
+
if (escapeToClose) {
|
|
87
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
88
|
+
}
|
|
89
|
+
if (blurToClose) {
|
|
90
|
+
document.addEventListener("focusin", handleBlur); // focusin bubbles
|
|
91
|
+
}
|
|
92
|
+
// Remove event listeners:
|
|
93
|
+
return function () {
|
|
94
|
+
document.removeEventListener("mousedown", handleClick);
|
|
95
|
+
if (escapeToClose) {
|
|
96
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
97
|
+
}
|
|
98
|
+
if (blurToClose) {
|
|
99
|
+
document.removeEventListener("focusin", handleBlur);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}, [open, refs, onClose, escapeToClose, blurToClose]);
|
|
103
|
+
}
|
|
104
|
+
export { useOutsideClose };
|
|
@@ -30,6 +30,7 @@ import { createPortal } from 'react-dom';
|
|
|
30
30
|
import { usePopper } from 'react-popper';
|
|
31
31
|
import { Selector } from './Selector';
|
|
32
32
|
import { Body } from './Body';
|
|
33
|
+
import { useOutsideClose } from '../../hooks/useOutsideClose';
|
|
33
34
|
var DateInputBase = function (props) {
|
|
34
35
|
var wrapperRef = React.useRef(null);
|
|
35
36
|
var bodyRef = React.useRef(null);
|
|
@@ -47,21 +48,13 @@ var DateInputBase = function (props) {
|
|
|
47
48
|
};
|
|
48
49
|
var _a = React.useState(function () { return parseDate(props.value, null); }), value = _a[0], setValue = _a[1];
|
|
49
50
|
var _b = React.useState(false), open = _b[0], setOpen = _b[1];
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
// (This only happens if there actually is a Selector).
|
|
58
|
-
//
|
|
59
|
-
var handleClickOutside = function (e) {
|
|
60
|
-
var elem = e.target;
|
|
61
|
-
if (wrapperRef.current && bodyRef.current && !wrapperRef.current.contains(elem) && !bodyRef.current.contains(elem)) {
|
|
62
|
-
setOpen(false);
|
|
63
|
-
}
|
|
64
|
-
};
|
|
51
|
+
useOutsideClose({
|
|
52
|
+
open: open,
|
|
53
|
+
refs: [wrapperRef, bodyRef],
|
|
54
|
+
onClose: function () { return setOpen(false); },
|
|
55
|
+
escapeToClose: true,
|
|
56
|
+
blurToClose: true
|
|
57
|
+
});
|
|
65
58
|
// Open the dropdown.
|
|
66
59
|
var doOpen = function () {
|
|
67
60
|
setOpen(true);
|
|
@@ -81,6 +81,7 @@ import { Selector } from './Selector';
|
|
|
81
81
|
import { Pill } from './Pill';
|
|
82
82
|
import { ListRow } from '../../containers/List/ListRow';
|
|
83
83
|
import { ListCell } from '../../containers/List';
|
|
84
|
+
import { useOutsideClose } from '../../hooks/useOutsideClose';
|
|
84
85
|
var sameWidth = {
|
|
85
86
|
name: "sameWidth",
|
|
86
87
|
enabled: true,
|
|
@@ -107,27 +108,10 @@ var DropdownBase = function (props) {
|
|
|
107
108
|
var _b = React.useState(false), open = _b[0], setOpen = _b[1];
|
|
108
109
|
// Current search query.
|
|
109
110
|
var _c = React.useState(null), search = _c[0], setSearch = _c[1];
|
|
110
|
-
// A mousedown event listener is attached to the document. When the document
|
|
111
|
-
// is clicked anywhere but this Dropdown, the Dropdown closes.
|
|
112
|
-
React.useEffect(function () {
|
|
113
|
-
// Listen for document-wide mousedown/keydown events when Dropdown mounts.
|
|
114
|
-
document.addEventListener('mousedown', handleClickOutside);
|
|
115
|
-
return function () {
|
|
116
|
-
// Clean up document-wide mousedown/keydown events when Dropdown unmounts.
|
|
117
|
-
document.removeEventListener('mousedown', handleClickOutside);
|
|
118
|
-
};
|
|
119
|
-
}, []);
|
|
120
111
|
// When value props changes, change local state value also.
|
|
121
112
|
React.useEffect(function () {
|
|
122
113
|
setValue(props.value);
|
|
123
114
|
}, [props.value]);
|
|
124
|
-
// Handle document-wide mousedown event by closing the Dropdown.
|
|
125
|
-
var handleClickOutside = function (event) {
|
|
126
|
-
var elem = event.target;
|
|
127
|
-
if (wrapperRef.current && bodyRef.current && !wrapperRef.current.contains(elem) && !bodyRef.current.contains(elem)) {
|
|
128
|
-
doClose();
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
115
|
// Open the dropdown.
|
|
132
116
|
var doOpen = function () {
|
|
133
117
|
setOpen(true);
|
|
@@ -160,6 +144,13 @@ var DropdownBase = function (props) {
|
|
|
160
144
|
setTimeout(props.onClose, 300);
|
|
161
145
|
}
|
|
162
146
|
};
|
|
147
|
+
useOutsideClose({
|
|
148
|
+
open: open,
|
|
149
|
+
refs: [wrapperRef, bodyRef],
|
|
150
|
+
onClose: doClose,
|
|
151
|
+
escapeToClose: true,
|
|
152
|
+
blurToClose: true
|
|
153
|
+
});
|
|
163
154
|
// The selector was clicked, open the Dropdown, or close
|
|
164
155
|
// it if it was open.
|
|
165
156
|
var handleSelectorClicked = function () {
|
|
@@ -30,33 +30,22 @@ import { createPortal } from 'react-dom';
|
|
|
30
30
|
import { usePopper } from 'react-popper';
|
|
31
31
|
import { Selector } from './Selector';
|
|
32
32
|
import { Body } from './Body';
|
|
33
|
+
import { useOutsideClose } from '../../hooks/useOutsideClose';
|
|
33
34
|
var MonthRangeBase = function (props) {
|
|
34
35
|
var wrapperRef = React.useRef(null);
|
|
35
36
|
var bodyRef = React.useRef(null);
|
|
36
37
|
var _a = React.useState(props.value), value = _a[0], setValue = _a[1];
|
|
37
38
|
var _b = React.useState(false), open = _b[0], setOpen = _b[1];
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
// (This only happens if there actually is a Selector).
|
|
46
|
-
//
|
|
47
|
-
var handleClickOutside = function (e) {
|
|
48
|
-
var elem = e.target;
|
|
49
|
-
if (wrapperRef.current && bodyRef.current && !wrapperRef.current.contains(elem) && !bodyRef.current.contains(elem)) {
|
|
50
|
-
setOpen(false);
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
// Open the dropdown.
|
|
54
|
-
var doOpen = function () {
|
|
55
|
-
setOpen(true);
|
|
56
|
-
};
|
|
39
|
+
useOutsideClose({
|
|
40
|
+
open: open,
|
|
41
|
+
refs: [wrapperRef, bodyRef],
|
|
42
|
+
onClose: function () { return setOpen(false); },
|
|
43
|
+
escapeToClose: true,
|
|
44
|
+
blurToClose: true
|
|
45
|
+
});
|
|
57
46
|
var handleToggle = function () {
|
|
58
47
|
if (!open) {
|
|
59
|
-
|
|
48
|
+
setOpen(true);
|
|
60
49
|
// Update popper position.
|
|
61
50
|
if (update)
|
|
62
51
|
update();
|
|
@@ -76,7 +65,7 @@ var MonthRangeBase = function (props) {
|
|
|
76
65
|
if (props.ghost)
|
|
77
66
|
return;
|
|
78
67
|
if (e.key == ' ' && !open)
|
|
79
|
-
|
|
68
|
+
setOpen(true);
|
|
80
69
|
if (e.key == 'Escape' && open)
|
|
81
70
|
setOpen(false);
|
|
82
71
|
};
|
|
@@ -32,6 +32,7 @@ import { GeocoderEntry } from './GeocoderEntry';
|
|
|
32
32
|
import { GeocoderList } from './GeocoderList';
|
|
33
33
|
import { GeocoderSelector } from './GeocoderSelector';
|
|
34
34
|
import { MapControl } from '../base/MapControl';
|
|
35
|
+
import { useOutsideClose } from '../../../hooks/useOutsideClose';
|
|
35
36
|
var GeocoderBase = function (props) {
|
|
36
37
|
var wrapperRef = React.useRef(null);
|
|
37
38
|
var map = useMap().current;
|
|
@@ -54,6 +55,13 @@ var GeocoderBase = function (props) {
|
|
|
54
55
|
if (wrapperRef)
|
|
55
56
|
wrapperRef.current.querySelector('input').focus();
|
|
56
57
|
};
|
|
58
|
+
useOutsideClose({
|
|
59
|
+
open: features.length > 0,
|
|
60
|
+
refs: [wrapperRef],
|
|
61
|
+
onClose: clear,
|
|
62
|
+
escapeToClose: true,
|
|
63
|
+
blurToClose: true
|
|
64
|
+
});
|
|
57
65
|
//
|
|
58
66
|
// Call mapbox geocoder API, and store results in state.
|
|
59
67
|
//
|
|
@@ -82,15 +90,6 @@ var GeocoderBase = function (props) {
|
|
|
82
90
|
}
|
|
83
91
|
setTimer(window.setTimeout(function () { return lookup(q); }, 350));
|
|
84
92
|
};
|
|
85
|
-
//
|
|
86
|
-
// Handle document-wide mousedown event by closing the list.
|
|
87
|
-
//
|
|
88
|
-
var handleClickOutside = function () {
|
|
89
|
-
var elem = event.target;
|
|
90
|
-
if (wrapperRef && !wrapperRef.current.contains(elem)) {
|
|
91
|
-
clear();
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
93
|
var handleChange = function (newq) {
|
|
95
94
|
setQ(newq);
|
|
96
95
|
lookupDebounced(newq);
|
|
@@ -130,14 +129,6 @@ var GeocoderBase = function (props) {
|
|
|
130
129
|
break;
|
|
131
130
|
}
|
|
132
131
|
};
|
|
133
|
-
React.useEffect(function () {
|
|
134
|
-
// Listen for document-wide mousedown event when control mounts.
|
|
135
|
-
document.addEventListener('mousedown', handleClickOutside);
|
|
136
|
-
// Clean up document-wide mousedown event when control unmounts.
|
|
137
|
-
return function () {
|
|
138
|
-
document.removeEventListener('mousedown', handleClickOutside);
|
|
139
|
-
};
|
|
140
|
-
});
|
|
141
132
|
return (React.createElement(MapControl, { x: props.x, y: props.y },
|
|
142
133
|
React.createElement("div", { className: props.className, onKeyDown: function (e) { return handleKeyDown(e); }, ref: wrapperRef },
|
|
143
134
|
React.createElement(GeocoderSelector, { placeholder: props.placeholder, searchIcon: props.searchIcon, value: q, onChange: handleChange }),
|
|
@@ -5,10 +5,10 @@ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cook
|
|
|
5
5
|
/** @module @ignore */
|
|
6
6
|
import * as React from 'react';
|
|
7
7
|
import styled from 'styled-components';
|
|
8
|
-
import { ListRow } from '../../../containers/List';
|
|
8
|
+
import { ListCell, ListRow } from '../../../containers/List';
|
|
9
9
|
var GeocoderEntry = function (props) {
|
|
10
10
|
return React.createElement(ListRow, { onClick: props.onClick, active: props.selected },
|
|
11
|
-
React.createElement(
|
|
11
|
+
React.createElement(ListCell, null,
|
|
12
12
|
React.createElement(ResultText, null, props.feature.properties.name_preferred),
|
|
13
13
|
React.createElement(ResultPlace, null, props.feature.properties.full_address)));
|
|
14
14
|
};
|
|
@@ -11,7 +11,7 @@ import { List } from '../../../containers/List';
|
|
|
11
11
|
*/
|
|
12
12
|
var GeocoderListBase = function (props) {
|
|
13
13
|
return React.createElement("div", { className: props.className },
|
|
14
|
-
React.createElement(List, {
|
|
14
|
+
React.createElement(List, { maxItems: 5, contract: true }, props.children));
|
|
15
15
|
};
|
|
16
16
|
var GeocoderList = styled(GeocoderListBase)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n position: absolute;\n width: 100%;\n left: 0;\n ", "\n ", "\n \n"], ["\n position: absolute;\n width: 100%;\n left: 0;\n ", "\n ", "\n \n"])), function (p) { return !p.upwards && css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n top: 42px;\n "], ["\n top: 42px;\n "]))); }, function (p) { return p.upwards && css(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n bottom: 42px;\n "], ["\n bottom: 42px;\n "]))); });
|
|
17
17
|
export { GeocoderList };
|
package/modules/Filter/Filter.js
CHANGED
|
@@ -30,30 +30,18 @@ import { createPortal } from 'react-dom';
|
|
|
30
30
|
import { usePopper } from 'react-popper';
|
|
31
31
|
import { FilterButton } from '../../controls/FilterButton';
|
|
32
32
|
import { GlassPane } from '../../containers/GlassPane';
|
|
33
|
+
import { useOutsideClose } from '../../hooks/useOutsideClose';
|
|
33
34
|
var FilterBase = function (props) {
|
|
34
35
|
var buttonRef = React.useRef(null);
|
|
35
36
|
var paneRef = React.useRef(null);
|
|
36
37
|
var _a = React.useState(false), open = _a[0], setOpen = _a[1];
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
document.removeEventListener('keydown', handleKeyDown);
|
|
45
|
-
};
|
|
46
|
-
}, []);
|
|
47
|
-
var handleClickOutside = function (e) {
|
|
48
|
-
var elem = e.target;
|
|
49
|
-
if (buttonRef.current && paneRef.current && !buttonRef.current.contains(elem) && !paneRef.current.contains(elem)) {
|
|
50
|
-
setOpen(false);
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
var handleKeyDown = function (e) {
|
|
54
|
-
if (e.key == 'Escape')
|
|
55
|
-
setOpen(false);
|
|
56
|
-
};
|
|
38
|
+
useOutsideClose({
|
|
39
|
+
open: open,
|
|
40
|
+
refs: [paneRef, buttonRef],
|
|
41
|
+
onClose: function () { return setOpen(false); },
|
|
42
|
+
escapeToClose: true,
|
|
43
|
+
blurToClose: true
|
|
44
|
+
});
|
|
57
45
|
var _b = usePopper(buttonRef.current, paneRef.current, {
|
|
58
46
|
placement: 'bottom-end',
|
|
59
47
|
modifiers: [
|
package/package.json
CHANGED
|
@@ -32,6 +32,7 @@ import { DialogFooter } from './DialogFooter';
|
|
|
32
32
|
import { AlertDialog } from './AlertDialog';
|
|
33
33
|
import { ConfirmDialog } from './ConfirmDialog';
|
|
34
34
|
import { XhrDialog } from './XhrDialog';
|
|
35
|
+
import { useOutsideClose } from '../../hooks/useOutsideClose';
|
|
35
36
|
/**
|
|
36
37
|
* A Dialog is an overlay window that is shown when the Dialog’s `open`
|
|
37
38
|
* attribute is set to `true`. The calling code is responsible for setting
|
|
@@ -48,26 +49,21 @@ var DialogBase = function (props) {
|
|
|
48
49
|
preEnter: true,
|
|
49
50
|
unmountOnExit: true
|
|
50
51
|
}), _b = _a[0], status = _b.status, isMounted = _b.isMounted, isEnter = _b.isEnter, toggle = _a[1];
|
|
52
|
+
var close = function () {
|
|
53
|
+
if (!props.canClose && !props.onClose)
|
|
54
|
+
return;
|
|
55
|
+
props.onClose();
|
|
56
|
+
};
|
|
57
|
+
useOutsideClose({
|
|
58
|
+
open: props.open,
|
|
59
|
+
refs: [windowRef],
|
|
60
|
+
onClose: close,
|
|
61
|
+
escapeToClose: true,
|
|
62
|
+
blurToClose: true
|
|
63
|
+
});
|
|
51
64
|
React.useEffect(function () {
|
|
52
65
|
toggle(props.open);
|
|
53
66
|
}, [props.open]);
|
|
54
|
-
// Listen for document-wide mousedown event when component mounts.
|
|
55
|
-
React.useEffect(function () {
|
|
56
|
-
document.addEventListener('mousedown', handleClickOutside);
|
|
57
|
-
return function () {
|
|
58
|
-
// Clean up document-wide mousedown event when component unmounts.
|
|
59
|
-
document.removeEventListener('mousedown', handleClickOutside);
|
|
60
|
-
};
|
|
61
|
-
});
|
|
62
|
-
// Handle document-wide mousedown event by sending a dialog close event.
|
|
63
|
-
// When clicking outside of it, a Dialog can close only if its canClose
|
|
64
|
-
// prop is not set to false.
|
|
65
|
-
var handleClickOutside = function (event) {
|
|
66
|
-
var elem = event.target;
|
|
67
|
-
if (windowRef.current && !windowRef.current.contains(elem) && props.onClose && props.canClose !== false) {
|
|
68
|
-
props.onClose();
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
67
|
return (React.createElement(React.Fragment, null, isMounted && React.createElement(React.Fragment, null,
|
|
72
68
|
createPortal(React.createElement(DialogBackground, { status: status }), document.body),
|
|
73
69
|
createPortal(React.createElement(DialogWindow, { inverted: props.inverted, width: props.width, ref: windowRef, status: status }, props.children), document.body))));
|