@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.
@@ -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;
@@ -17,6 +17,9 @@ interface IOpenableProps {
17
17
  * @default 250
18
18
  */
19
19
  width?: number;
20
+ /**
21
+ * Fired when Openable must close.
22
+ */
20
23
  onClose: () => void;
21
24
  }
22
25
  declare const Openable: {
@@ -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 = _a.width, width = _b === void 0 ? 250 : _b, props = __rest(_a, ["width"]);
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
- React.useEffect(function () {
36
- // Listen for document-wide mousedown/keydown events when panel mounts.
37
- document.addEventListener('mousedown', handleClickOutside);
38
- document.addEventListener('keydown', handleKeyDown);
39
- return function () {
40
- // Clean up document-wide mousedown/keydown events when panel unmounts.
41
- document.removeEventListener('mousedown', handleClickOutside);
42
- document.removeEventListener('keydown', handleKeyDown);
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 = _c.styles, attributes = _c.attributes, update = _c.update;
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), document.body)));
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
- // A mousedown event listener is attached to the document. When the document
26
- // is clicked anywhere but this panel, the panel closes.
27
- React.useEffect(function () {
28
- // Listen for document-wide mousedown/keydown events when panel mounts.
29
- document.addEventListener('mousedown', handleClickOutside);
30
- document.addEventListener('keydown', handleKeyDown);
31
- return function () {
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
- // Add (and remove) document-wide event listener for mousedown.
51
- React.useEffect(function () {
52
- document.addEventListener('mousedown', handleClickOutside);
53
- return function () { return document.removeEventListener('mousedown', handleClickOutside); };
54
- }, []);
55
- //
56
- // Handle document-wide mousedown event by closing the Selector.
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
- // Add (and remove) document-wide event listener for mousedown.
39
- React.useEffect(function () {
40
- document.addEventListener('mousedown', handleClickOutside);
41
- return function () { return document.removeEventListener('mousedown', handleClickOutside); };
42
- }, []);
43
- //
44
- // Handle document-wide mousedown event by closing the Selector.
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
- doOpen();
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
- doOpen();
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("div", { style: { width: '100%' } },
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, { tall: true, maxItems: 5, contract: true }, props.children));
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 };
@@ -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
- React.useEffect(function () {
38
- // Listen for document-wide mousedown/keydown events when panel mounts.
39
- document.addEventListener('mousedown', handleClickOutside);
40
- document.addEventListener('keydown', handleKeyDown);
41
- return function () {
42
- // Clean up document-wide mousedown/keydown events when panel unmounts.
43
- document.removeEventListener('mousedown', handleClickOutside);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@longline/aqua-ui",
3
- "version": "1.0.222",
3
+ "version": "1.0.224",
4
4
  "description": "AquaUI",
5
5
  "author": "Alexander van Oostenrijk / Longline Environment",
6
6
  "license": "Commercial",
@@ -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))));