@canonical/react-components 2.0.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Card/Card.stories.d.ts +2 -2
- package/dist/components/CodeSnippet/CodeSnippet.stories.js +3 -2
- package/dist/components/Col/Col.stories.d.ts +2 -1
- package/dist/components/ConfirmationButton/ConfirmationButton.d.ts +7 -2
- package/dist/components/ConfirmationButton/ConfirmationButton.js +11 -3
- package/dist/components/ConfirmationButton/ConfirmationButton.stories.d.ts +1 -0
- package/dist/components/ConfirmationButton/ConfirmationButton.stories.js +23 -1
- package/dist/components/ContextualMenu/ContextualMenu.js +5 -5
- package/dist/components/ContextualMenu/ContextualMenuDropdown/ContextualMenuDropdown.d.ts +1 -1
- package/dist/components/ContextualMenu/ContextualMenuDropdown/ContextualMenuDropdown.js +2 -2
- package/dist/components/MainTable/MainTable.d.ts +3 -1
- package/dist/components/ModularTable/ModularTable.stories.js +2 -2
- package/dist/components/Navigation/Navigation.d.ts +1 -1
- package/dist/components/Notification/Notification.d.ts +1 -1
- package/dist/components/Notification/Notification.js +3 -1
- package/dist/components/NotificationProvider/NotificationProvider.js +2 -2
- package/dist/components/SearchAndFilter/SearchAndFilter.js +1 -4
- package/dist/components/SearchAndFilter/utils.d.ts +3 -2
- package/dist/components/SideNavigation/SideNavigation.js +1 -1
- package/dist/components/Tooltip/Tooltip.js +3 -3
- package/dist/esm/components/Card/Card.stories.d.ts +2 -2
- package/dist/esm/components/CodeSnippet/CodeSnippet.stories.js +3 -2
- package/dist/esm/components/Col/Col.stories.d.ts +2 -1
- package/dist/esm/components/ConfirmationButton/ConfirmationButton.d.ts +7 -2
- package/dist/esm/components/ConfirmationButton/ConfirmationButton.js +12 -4
- package/dist/esm/components/ConfirmationButton/ConfirmationButton.stories.d.ts +1 -0
- package/dist/esm/components/ConfirmationButton/ConfirmationButton.stories.js +22 -0
- package/dist/esm/components/ContextualMenu/ContextualMenu.js +4 -4
- package/dist/esm/components/ContextualMenu/ContextualMenuDropdown/ContextualMenuDropdown.d.ts +1 -1
- package/dist/esm/components/ContextualMenu/ContextualMenuDropdown/ContextualMenuDropdown.js +2 -2
- package/dist/esm/components/MainTable/MainTable.d.ts +3 -1
- package/dist/esm/components/ModularTable/ModularTable.stories.js +60 -12
- package/dist/esm/components/Navigation/Navigation.d.ts +1 -1
- package/dist/esm/components/Notification/Notification.d.ts +1 -1
- package/dist/esm/components/Notification/Notification.js +4 -2
- package/dist/esm/components/NotificationProvider/NotificationProvider.js +2 -2
- package/dist/esm/components/SearchAndFilter/SearchAndFilter.js +1 -4
- package/dist/esm/components/SearchAndFilter/utils.d.ts +3 -2
- package/dist/esm/components/SideNavigation/SideNavigation.js +1 -1
- package/dist/esm/components/Tooltip/Tooltip.js +2 -2
- package/dist/esm/external/index.d.ts +2 -0
- package/dist/esm/external/index.js +1 -0
- package/dist/esm/external/usePortal.d.ts +39 -0
- package/dist/esm/external/usePortal.js +125 -0
- package/dist/esm/external/usePortal.test.d.ts +5 -0
- package/dist/esm/external/useSSR.d.ts +19 -0
- package/dist/esm/external/useSSR.js +43 -0
- package/dist/esm/hooks/useWindowFitment.js +2 -2
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -1
- package/dist/external/index.d.ts +2 -0
- package/dist/external/index.js +12 -0
- package/dist/external/usePortal.d.ts +39 -0
- package/dist/external/usePortal.js +133 -0
- package/dist/external/usePortal.test.d.ts +5 -0
- package/dist/external/useSSR.d.ts +19 -0
- package/dist/external/useSSR.js +48 -0
- package/dist/hooks/useWindowFitment.js +2 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +9 -1
- package/package.json +37 -39
|
@@ -37,14 +37,22 @@ export var Default = {
|
|
|
37
37
|
columns: React.useMemo(() => [{
|
|
38
38
|
Header: "ID",
|
|
39
39
|
accessor: "buildId",
|
|
40
|
-
Cell:
|
|
40
|
+
Cell: function (_Cell) {
|
|
41
|
+
function Cell(_x) {
|
|
42
|
+
return _Cell.apply(this, arguments);
|
|
43
|
+
}
|
|
44
|
+
Cell.toString = function () {
|
|
45
|
+
return _Cell.toString();
|
|
46
|
+
};
|
|
47
|
+
return Cell;
|
|
48
|
+
}(_ref2 => {
|
|
41
49
|
var {
|
|
42
50
|
value
|
|
43
51
|
} = _ref2;
|
|
44
52
|
return /*#__PURE__*/React.createElement("a", {
|
|
45
53
|
href: "#test"
|
|
46
54
|
}, "#", value);
|
|
47
|
-
}
|
|
55
|
+
})
|
|
48
56
|
}, {
|
|
49
57
|
Header: "Architecture",
|
|
50
58
|
accessor: "arch"
|
|
@@ -55,7 +63,15 @@ export var Default = {
|
|
|
55
63
|
}, {
|
|
56
64
|
Header: "Result",
|
|
57
65
|
accessor: "result",
|
|
58
|
-
Cell:
|
|
66
|
+
Cell: function (_Cell2) {
|
|
67
|
+
function Cell(_x2) {
|
|
68
|
+
return _Cell2.apply(this, arguments);
|
|
69
|
+
}
|
|
70
|
+
Cell.toString = function () {
|
|
71
|
+
return _Cell2.toString();
|
|
72
|
+
};
|
|
73
|
+
return Cell;
|
|
74
|
+
}(_ref3 => {
|
|
59
75
|
var {
|
|
60
76
|
value
|
|
61
77
|
} = _ref3;
|
|
@@ -67,7 +83,7 @@ export var Default = {
|
|
|
67
83
|
default:
|
|
68
84
|
return "Unknown";
|
|
69
85
|
}
|
|
70
|
-
},
|
|
86
|
+
}),
|
|
71
87
|
getCellIcon: _ref4 => {
|
|
72
88
|
var {
|
|
73
89
|
value
|
|
@@ -155,14 +171,22 @@ export var Sortable = {
|
|
|
155
171
|
Header: "ID",
|
|
156
172
|
accessor: "buildId",
|
|
157
173
|
sortType: "basic",
|
|
158
|
-
Cell:
|
|
174
|
+
Cell: function (_Cell3) {
|
|
175
|
+
function Cell(_x3) {
|
|
176
|
+
return _Cell3.apply(this, arguments);
|
|
177
|
+
}
|
|
178
|
+
Cell.toString = function () {
|
|
179
|
+
return _Cell3.toString();
|
|
180
|
+
};
|
|
181
|
+
return Cell;
|
|
182
|
+
}(_ref6 => {
|
|
159
183
|
var {
|
|
160
184
|
value
|
|
161
185
|
} = _ref6;
|
|
162
186
|
return /*#__PURE__*/React.createElement("a", {
|
|
163
187
|
href: "#test"
|
|
164
188
|
}, "#", value);
|
|
165
|
-
}
|
|
189
|
+
})
|
|
166
190
|
}, {
|
|
167
191
|
Header: "Architecture",
|
|
168
192
|
accessor: "arch",
|
|
@@ -176,7 +200,15 @@ export var Sortable = {
|
|
|
176
200
|
Header: "Result",
|
|
177
201
|
accessor: "result",
|
|
178
202
|
sortType: "basic",
|
|
179
|
-
Cell:
|
|
203
|
+
Cell: function (_Cell4) {
|
|
204
|
+
function Cell(_x4) {
|
|
205
|
+
return _Cell4.apply(this, arguments);
|
|
206
|
+
}
|
|
207
|
+
Cell.toString = function () {
|
|
208
|
+
return _Cell4.toString();
|
|
209
|
+
};
|
|
210
|
+
return Cell;
|
|
211
|
+
}(_ref7 => {
|
|
180
212
|
var {
|
|
181
213
|
value
|
|
182
214
|
} = _ref7;
|
|
@@ -188,7 +220,7 @@ export var Sortable = {
|
|
|
188
220
|
default:
|
|
189
221
|
return "Unknown";
|
|
190
222
|
}
|
|
191
|
-
},
|
|
223
|
+
}),
|
|
192
224
|
getCellIcon: _ref8 => {
|
|
193
225
|
var {
|
|
194
226
|
value
|
|
@@ -247,16 +279,32 @@ export var Subrows = {
|
|
|
247
279
|
Header: "Flavour",
|
|
248
280
|
accessor: "flavour",
|
|
249
281
|
sortType: "basic",
|
|
250
|
-
Cell:
|
|
282
|
+
Cell: function (_Cell5) {
|
|
283
|
+
function Cell(_x5) {
|
|
284
|
+
return _Cell5.apply(this, arguments);
|
|
285
|
+
}
|
|
286
|
+
Cell.toString = function () {
|
|
287
|
+
return _Cell5.toString();
|
|
288
|
+
};
|
|
289
|
+
return Cell;
|
|
290
|
+
}(props => "depth" in props.row && props.row.depth === 0 ? /*#__PURE__*/React.createElement("strong", null, props.value) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("input", {
|
|
251
291
|
type: "checkbox"
|
|
252
|
-
}), " ", props.value)
|
|
292
|
+
}), " ", props.value))
|
|
253
293
|
}, {
|
|
254
294
|
Header: "Scoops",
|
|
255
295
|
accessor: "scoops",
|
|
256
296
|
sortType: "basic",
|
|
257
|
-
Cell:
|
|
297
|
+
Cell: function (_Cell6) {
|
|
298
|
+
function Cell(_x6) {
|
|
299
|
+
return _Cell6.apply(this, arguments);
|
|
300
|
+
}
|
|
301
|
+
Cell.toString = function () {
|
|
302
|
+
return _Cell6.toString();
|
|
303
|
+
};
|
|
304
|
+
return Cell;
|
|
305
|
+
}(props => "depth" in props.row && props.row.depth === 0 ? /*#__PURE__*/React.createElement("span", {
|
|
258
306
|
className: "u-text--muted"
|
|
259
|
-
}, props.value) : props.value
|
|
307
|
+
}, props.value) : props.value)
|
|
260
308
|
}], [])
|
|
261
309
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
262
310
|
,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactNode, HTMLProps } from "react";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import
|
|
3
|
+
import { GenerateLink, NavItem, LogoProps } from "./types";
|
|
4
4
|
import { PropsWithSpread, SubComponentProps } from "../../types";
|
|
5
5
|
import { SearchBoxProps } from "../SearchBox";
|
|
6
6
|
import { Theme } from "../../enums";
|
|
@@ -27,7 +27,7 @@ export type Props = PropsWithSpread<{
|
|
|
27
27
|
/**
|
|
28
28
|
* A list of up to two actions that the notification can perform.
|
|
29
29
|
*/
|
|
30
|
-
actions?: NotificationAction[];
|
|
30
|
+
actions?: (NotificationAction | ReactNode)[];
|
|
31
31
|
/**
|
|
32
32
|
* Whether the notification should not have a border.
|
|
33
33
|
*/
|
|
@@ -5,7 +5,7 @@ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) r
|
|
|
5
5
|
import classNames from "classnames";
|
|
6
6
|
import React, { useEffect, useRef } from "react";
|
|
7
7
|
import Button, { ButtonAppearance } from "../Button";
|
|
8
|
-
import { IS_DEV } from "../../utils";
|
|
8
|
+
import { IS_DEV, isReactNode } from "../../utils";
|
|
9
9
|
export var Label = /*#__PURE__*/function (Label) {
|
|
10
10
|
Label["Close"] = "Close notification";
|
|
11
11
|
return Label;
|
|
@@ -97,6 +97,7 @@ var Notification = _ref => {
|
|
|
97
97
|
}, title), inline && /*#__PURE__*/React.createElement(React.Fragment, null, "\u2002"), /*#__PURE__*/React.createElement("p", {
|
|
98
98
|
className: "p-notification__message"
|
|
99
99
|
}, children), onDismiss && /*#__PURE__*/React.createElement("button", {
|
|
100
|
+
type: "button",
|
|
100
101
|
className: "p-notification__close",
|
|
101
102
|
"data-testid": "notification-close-button",
|
|
102
103
|
onClick: onDismiss
|
|
@@ -108,7 +109,8 @@ var Notification = _ref => {
|
|
|
108
109
|
"data-testid": "notification-timestamp"
|
|
109
110
|
}, timestamp), hasActions ? /*#__PURE__*/React.createElement("div", {
|
|
110
111
|
className: "p-notification__actions"
|
|
111
|
-
}, actions.map((action, i) => /*#__PURE__*/React.createElement(Button, {
|
|
112
|
+
}, actions.map((action, i) => isReactNode(action) ? action : /*#__PURE__*/React.createElement(Button, {
|
|
113
|
+
type: "button",
|
|
112
114
|
appearance: ButtonAppearance.LINK,
|
|
113
115
|
className: "p-notification__action",
|
|
114
116
|
"data-testid": "notification-action",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { createContext, useContext, useEffect, useRef, useState } from "react";
|
|
2
|
-
import
|
|
2
|
+
import fastDeepEqual from "fast-deep-equal";
|
|
3
3
|
import { info as _info, failure as _failure, success as _success, queue } from "./messageBuilder";
|
|
4
4
|
import Notification, { DefaultTitles } from "../Notification/Notification";
|
|
5
5
|
var NotifyContext = /*#__PURE__*/createContext({
|
|
@@ -20,7 +20,7 @@ export var NotificationProvider = _ref => {
|
|
|
20
20
|
var [notification, setNotification] = useState(null);
|
|
21
21
|
var clear = () => notification !== null && setNotification(null);
|
|
22
22
|
var setDeduplicated = value => {
|
|
23
|
-
if (!
|
|
23
|
+
if (!fastDeepEqual(value, notification)) {
|
|
24
24
|
setNotification(value);
|
|
25
25
|
}
|
|
26
26
|
return value;
|
|
@@ -52,9 +52,6 @@ var SearchAndFilter = _ref => {
|
|
|
52
52
|
mounted = false;
|
|
53
53
|
};
|
|
54
54
|
}, [searchData, returnSearchData]);
|
|
55
|
-
var searchOnChange = searchTerm => {
|
|
56
|
-
setSearchTerm(searchTerm);
|
|
57
|
-
};
|
|
58
55
|
|
|
59
56
|
// Hide manual input form field when search container is inactive
|
|
60
57
|
useEffect(() => {
|
|
@@ -236,7 +233,7 @@ var SearchAndFilter = _ref => {
|
|
|
236
233
|
className: "p-search-and-filter__input",
|
|
237
234
|
id: "search-and-filter-input",
|
|
238
235
|
name: "search",
|
|
239
|
-
onChange: e =>
|
|
236
|
+
onChange: e => setSearchTerm(e.target.value),
|
|
240
237
|
placeholder: placeholder,
|
|
241
238
|
type: "search",
|
|
242
239
|
value: searchTerm
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
import { SearchAndFilterChip } from "./types";
|
|
1
2
|
/**
|
|
2
3
|
* Return number of overflowing chips given a row threshold
|
|
3
4
|
* @param {array} chips - An array of chips
|
|
4
5
|
* @param {Integer} overflowRowLimit - Number of rows to show before counting
|
|
5
6
|
* overflow
|
|
6
7
|
*/
|
|
7
|
-
export declare const overflowingChipsCount: (chips:
|
|
8
|
+
export declare const overflowingChipsCount: (chips: NodeListOf<HTMLElement>, overflowRowLimit: number) => number;
|
|
8
9
|
/**
|
|
9
10
|
* Check if supplied chip object already exists in searchData prop
|
|
10
11
|
* @param {Object} chip - A chip object {lead: 'foo', value: 'bar'}
|
|
11
12
|
* @param {Array} existingArr - An array of chip objects
|
|
12
13
|
*/
|
|
13
|
-
export declare const isChipInArray: (chip:
|
|
14
|
+
export declare const isChipInArray: (chip: SearchAndFilterChip, existingArr: SearchAndFilterChip[]) => boolean;
|
|
@@ -58,7 +58,7 @@ var generateItems = (groups, listClassName, linkComponent, dark) => {
|
|
|
58
58
|
};
|
|
59
59
|
var getHasIcons = groups => groups === null || groups === void 0 ? void 0 : groups.some(group => {
|
|
60
60
|
var _ref;
|
|
61
|
-
return (_ref =
|
|
61
|
+
return group && ((_ref = "items" in group ? group.items : group) === null || _ref === void 0 ? void 0 : _ref.some(item => isReactNode(item) ? false : item && "icon" in item && !!item.icon));
|
|
62
62
|
});
|
|
63
63
|
|
|
64
64
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import classNames from "classnames";
|
|
2
2
|
import React, { useCallback, useEffect, useId, useRef, useState } from "react";
|
|
3
|
-
import usePortal from "react-useportal";
|
|
4
3
|
import { useWindowFitment, useListener } from "../../hooks";
|
|
4
|
+
import { usePortal } from "../../external";
|
|
5
5
|
export var position = {
|
|
6
6
|
btmCenter: "btm-center",
|
|
7
7
|
btmLeft: "btm-left",
|
|
@@ -194,7 +194,7 @@ var Tooltip = _ref => {
|
|
|
194
194
|
return;
|
|
195
195
|
}
|
|
196
196
|
e.target.focus();
|
|
197
|
-
openPortal(
|
|
197
|
+
openPortal();
|
|
198
198
|
};
|
|
199
199
|
var delayedOpenPortal = useCallback(() => {
|
|
200
200
|
if (isOpen) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { usePortal } from "./usePortal";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This is a reference implementation of the usePortal hook from react-useportal: https://github.com/iamthesiz/react-useportal/blob/master/usePortal.ts
|
|
3
|
+
* The license for the content in this file is goverened by the original project's license: https://github.com/iamthesiz/react-useportal/blob/master/license.md
|
|
4
|
+
*/
|
|
5
|
+
import { ReactNode, SyntheticEvent, RefObject } from "react";
|
|
6
|
+
type CustomEvent<T = HTMLElement> = {
|
|
7
|
+
event?: SyntheticEvent<T, Event>;
|
|
8
|
+
portal: RefObject<HTMLElement>;
|
|
9
|
+
targetEl: RefObject<HTMLElement>;
|
|
10
|
+
} & SyntheticEvent<T, Event>;
|
|
11
|
+
type CustomEventHandler<T = HTMLElement> = (customEvent: CustomEvent<T>) => void;
|
|
12
|
+
export type UsePortalOptions = {
|
|
13
|
+
closeOnOutsideClick?: boolean;
|
|
14
|
+
closeOnEsc?: boolean;
|
|
15
|
+
bindTo?: RefObject<HTMLElement>;
|
|
16
|
+
isOpen?: boolean;
|
|
17
|
+
onOpen?: CustomEventHandler;
|
|
18
|
+
onClose?: CustomEventHandler;
|
|
19
|
+
onPortalClick?: CustomEventHandler;
|
|
20
|
+
programmaticallyOpen?: boolean;
|
|
21
|
+
};
|
|
22
|
+
export declare const errorMessage1 = "You must either add a `ref` to the element you are interacting with or pass an `event` to openPortal(e) or togglePortal(e) when the `programmaticallyOpen` option is not set to `true`.";
|
|
23
|
+
export declare const usePortal: ({ closeOnOutsideClick, closeOnEsc, bindTo, isOpen: defaultIsOpen, onOpen, onClose, onPortalClick, programmaticallyOpen, }?: UsePortalOptions) => (boolean | RefObject<HTMLElement> | ((e?: SyntheticEvent<HTMLElement, Event>) => void) | (({ children }: {
|
|
24
|
+
children: ReactNode;
|
|
25
|
+
}) => import("react").JSX.Element))[] & {
|
|
26
|
+
isOpen: boolean;
|
|
27
|
+
openPortal: (e?: SyntheticEvent<HTMLElement, Event>) => void;
|
|
28
|
+
ref: RefObject<HTMLElement>;
|
|
29
|
+
closePortal: (e?: SyntheticEvent<HTMLElement, Event>) => void;
|
|
30
|
+
togglePortal: (e?: SyntheticEvent<HTMLElement, Event>) => void;
|
|
31
|
+
Portal: ({ children }: {
|
|
32
|
+
children: ReactNode;
|
|
33
|
+
}) => import("react").JSX.Element;
|
|
34
|
+
portalRef: RefObject<HTMLElement>;
|
|
35
|
+
bind: {
|
|
36
|
+
ref: RefObject<HTMLElement>;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This is a reference implementation of the usePortal hook from react-useportal: https://github.com/iamthesiz/react-useportal/blob/master/usePortal.ts
|
|
3
|
+
* The license for the content in this file is goverened by the original project's license: https://github.com/iamthesiz/react-useportal/blob/master/license.md
|
|
4
|
+
*/
|
|
5
|
+
import { useState, useRef, useEffect, useCallback, useMemo } from "react";
|
|
6
|
+
import { createPortal } from "react-dom";
|
|
7
|
+
import { useSSR } from "./useSSR";
|
|
8
|
+
export var errorMessage1 = "You must either add a `ref` to the element you are interacting with or pass an `event` to openPortal(e) or togglePortal(e) when the `programmaticallyOpen` option is not set to `true`.";
|
|
9
|
+
export var usePortal = function usePortal() {
|
|
10
|
+
var {
|
|
11
|
+
closeOnOutsideClick = true,
|
|
12
|
+
closeOnEsc = true,
|
|
13
|
+
bindTo,
|
|
14
|
+
// attach the portal to this node in the DOM
|
|
15
|
+
isOpen: defaultIsOpen = false,
|
|
16
|
+
onOpen,
|
|
17
|
+
onClose,
|
|
18
|
+
onPortalClick,
|
|
19
|
+
programmaticallyOpen = false
|
|
20
|
+
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
21
|
+
var {
|
|
22
|
+
isServer,
|
|
23
|
+
isBrowser
|
|
24
|
+
} = useSSR();
|
|
25
|
+
var [isOpen, makeOpen] = useState(defaultIsOpen);
|
|
26
|
+
// we use this ref because `isOpen` is stale for handleOutsideMouseClick
|
|
27
|
+
var open = useRef(isOpen);
|
|
28
|
+
var setOpen = useCallback(v => {
|
|
29
|
+
// workaround to not have stale `isOpen` in the handleOutsideMouseClick
|
|
30
|
+
open.current = v;
|
|
31
|
+
makeOpen(v);
|
|
32
|
+
}, []);
|
|
33
|
+
var targetEl = useRef(null); // this is the element you are clicking/hovering/whatever, to trigger opening the portal
|
|
34
|
+
var portal = useRef(isBrowser ? document.createElement("div") : null);
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (isBrowser && !portal.current) portal.current = document.createElement("div");
|
|
37
|
+
}, [isBrowser, portal]);
|
|
38
|
+
var elToMountTo = useMemo(() => {
|
|
39
|
+
if (isServer) return null;
|
|
40
|
+
return bindTo && bindTo.current || document.body;
|
|
41
|
+
}, [isServer, bindTo]);
|
|
42
|
+
var createCustomEvent = e => {
|
|
43
|
+
if (!e) return {
|
|
44
|
+
portal,
|
|
45
|
+
targetEl,
|
|
46
|
+
event: e
|
|
47
|
+
};
|
|
48
|
+
var event = e || {};
|
|
49
|
+
if (event.persist) event.persist();
|
|
50
|
+
event.portal = portal;
|
|
51
|
+
event.targetEl = targetEl;
|
|
52
|
+
event.event = e;
|
|
53
|
+
var {
|
|
54
|
+
currentTarget
|
|
55
|
+
} = e;
|
|
56
|
+
if (!targetEl.current && currentTarget && currentTarget !== document) targetEl.current = event.currentTarget;
|
|
57
|
+
return event;
|
|
58
|
+
};
|
|
59
|
+
var openPortal = useCallback(e => {
|
|
60
|
+
if (isServer) return;
|
|
61
|
+
var customEvent = createCustomEvent(e);
|
|
62
|
+
// for some reason, when we don't have the event argument, there
|
|
63
|
+
// is a weird race condition. Would like to see if we can remove
|
|
64
|
+
// setTimeout, but for now this works
|
|
65
|
+
if (targetEl.current == null && !programmaticallyOpen) {
|
|
66
|
+
setTimeout(() => setOpen(true), 0);
|
|
67
|
+
throw Error(errorMessage1);
|
|
68
|
+
}
|
|
69
|
+
if (onOpen) onOpen(customEvent);
|
|
70
|
+
setOpen(true);
|
|
71
|
+
}, [isServer, portal, setOpen, targetEl, onOpen, programmaticallyOpen]);
|
|
72
|
+
var closePortal = useCallback(e => {
|
|
73
|
+
if (isServer) return;
|
|
74
|
+
var customEvent = createCustomEvent(e);
|
|
75
|
+
if (onClose && open.current) onClose(customEvent);
|
|
76
|
+
if (open.current) setOpen(false);
|
|
77
|
+
}, [isServer, onClose, setOpen]);
|
|
78
|
+
var togglePortal = useCallback(e => open.current ? closePortal(e) : openPortal(e), [closePortal, openPortal]);
|
|
79
|
+
var handleKeydown = useCallback(e => e.key === "Escape" && closeOnEsc ? closePortal(e) : undefined, [closeOnEsc, closePortal]);
|
|
80
|
+
var handleOutsideMouseClick = useCallback(e => {
|
|
81
|
+
var containsTarget = target => target.current.contains(e.target);
|
|
82
|
+
// There might not be a targetEl if the portal was opened programmatically.
|
|
83
|
+
if (containsTarget(portal) || e.button !== 0 || !open.current || targetEl.current && containsTarget(targetEl)) return;
|
|
84
|
+
if (closeOnOutsideClick) closePortal(e);
|
|
85
|
+
}, [isServer, closePortal, closeOnOutsideClick, portal]);
|
|
86
|
+
var handleMouseDown = useCallback(e => {
|
|
87
|
+
if (isServer || !(portal.current instanceof HTMLElement)) return;
|
|
88
|
+
var customEvent = createCustomEvent(e);
|
|
89
|
+
if (portal.current.contains(customEvent.target) && onPortalClick) onPortalClick(customEvent);
|
|
90
|
+
handleOutsideMouseClick(e);
|
|
91
|
+
}, [handleOutsideMouseClick, isServer]);
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
if (isServer) return null;
|
|
94
|
+
if (!(elToMountTo instanceof HTMLElement) || !(portal.current instanceof HTMLElement)) return null;
|
|
95
|
+
var node = portal.current;
|
|
96
|
+
elToMountTo.appendChild(portal.current);
|
|
97
|
+
document.addEventListener("keydown", handleKeydown);
|
|
98
|
+
document.addEventListener("mousedown", handleMouseDown);
|
|
99
|
+
return () => {
|
|
100
|
+
document.removeEventListener("keydown", handleKeydown);
|
|
101
|
+
document.removeEventListener("mousedown", handleMouseDown);
|
|
102
|
+
elToMountTo.removeChild(node);
|
|
103
|
+
};
|
|
104
|
+
}, [isServer, handleOutsideMouseClick, handleKeydown, elToMountTo, portal]);
|
|
105
|
+
var Portal = useCallback(_ref => {
|
|
106
|
+
var {
|
|
107
|
+
children
|
|
108
|
+
} = _ref;
|
|
109
|
+
if (portal.current != null) return /*#__PURE__*/createPortal(children, portal.current);
|
|
110
|
+
return null;
|
|
111
|
+
}, [portal]);
|
|
112
|
+
return Object.assign([openPortal, closePortal, open.current, Portal, togglePortal, targetEl, portal], {
|
|
113
|
+
isOpen: open.current,
|
|
114
|
+
openPortal,
|
|
115
|
+
ref: targetEl,
|
|
116
|
+
closePortal,
|
|
117
|
+
togglePortal,
|
|
118
|
+
Portal,
|
|
119
|
+
portalRef: portal,
|
|
120
|
+
bind: {
|
|
121
|
+
// used if you want to spread all html attributes onto the target element
|
|
122
|
+
ref: targetEl
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This is a reference implementation of the usePortal hook from react-useportal: https://github.com/iamthesiz/react-useportal/blob/master/usePortal.test.ts
|
|
3
|
+
* The license for the content in this file is goverened by the original project's license: https://github.com/iamthesiz/react-useportal/blob/master/license.md
|
|
4
|
+
*/
|
|
5
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This is a reference implementation of the useSSR hook from use-ssr: https://github.com/iamthesiz/use-ssr/blob/master/useSSR.ts
|
|
3
|
+
* The license for the content in this file is goverened by the original project's license: https://github.com/iamthesiz/use-ssr/blob/master/license.md
|
|
4
|
+
*/
|
|
5
|
+
interface UseSSRReturn {
|
|
6
|
+
isBrowser: boolean;
|
|
7
|
+
isServer: boolean;
|
|
8
|
+
device: Device;
|
|
9
|
+
canUseWorkers: boolean;
|
|
10
|
+
canUseEventListeners: boolean;
|
|
11
|
+
canUseViewport: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare enum Device {
|
|
14
|
+
Browser = "browser",
|
|
15
|
+
Server = "server"
|
|
16
|
+
}
|
|
17
|
+
export declare const weAreServer: () => void;
|
|
18
|
+
export declare const useSSR: () => UseSSRReturn;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
2
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
3
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
4
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
|
|
5
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
6
|
+
/**
|
|
7
|
+
* This is a reference implementation of the useSSR hook from use-ssr: https://github.com/iamthesiz/use-ssr/blob/master/useSSR.ts
|
|
8
|
+
* The license for the content in this file is goverened by the original project's license: https://github.com/iamthesiz/use-ssr/blob/master/license.md
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export var Device = /*#__PURE__*/function (Device) {
|
|
12
|
+
Device["Browser"] = "browser";
|
|
13
|
+
Device["Server"] = "server";
|
|
14
|
+
return Device;
|
|
15
|
+
}({});
|
|
16
|
+
var {
|
|
17
|
+
Browser,
|
|
18
|
+
Server
|
|
19
|
+
} = Device;
|
|
20
|
+
var canUseDOM = !!(typeof window !== "undefined" && window.document && window.document.createElement);
|
|
21
|
+
var device = canUseDOM ? Browser : Server;
|
|
22
|
+
var SSRObject = {
|
|
23
|
+
isBrowser: device === Browser,
|
|
24
|
+
isServer: device === Server,
|
|
25
|
+
device,
|
|
26
|
+
canUseWorkers: typeof Worker !== "undefined",
|
|
27
|
+
canUseEventListeners: device === Browser && !!window.addEventListener,
|
|
28
|
+
canUseViewport: device === Browser && !!window.screen
|
|
29
|
+
};
|
|
30
|
+
var assign = function assign() {
|
|
31
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
32
|
+
args[_key] = arguments[_key];
|
|
33
|
+
}
|
|
34
|
+
return args.reduce((acc, obj) => _objectSpread(_objectSpread({}, acc), obj), {});
|
|
35
|
+
};
|
|
36
|
+
var values = obj => Object.keys(obj).map(key => obj[key]);
|
|
37
|
+
var toArrayObject = () => assign((values(SSRObject), SSRObject));
|
|
38
|
+
var useSSRObject = toArrayObject();
|
|
39
|
+
export var weAreServer = () => {
|
|
40
|
+
SSRObject.isServer = true;
|
|
41
|
+
useSSRObject = toArrayObject();
|
|
42
|
+
};
|
|
43
|
+
export var useSSR = () => useSSRObject;
|
|
@@ -23,8 +23,8 @@ export var useWindowFitment = function useWindowFitment(targetNode, referenceNod
|
|
|
23
23
|
referenceCoordinates = {
|
|
24
24
|
// The mouse is a single point so use 0 for the height and width.
|
|
25
25
|
height: 0,
|
|
26
|
-
left: evt.x || 0,
|
|
27
|
-
top: evt.y || 0,
|
|
26
|
+
left: ("x" in evt && typeof evt.x === "number" ? evt.x : null) || 0,
|
|
27
|
+
top: ("y" in evt && typeof evt.y === "number" ? evt.y : null) || 0,
|
|
28
28
|
width: 0
|
|
29
29
|
};
|
|
30
30
|
}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -138,3 +138,5 @@ export type { WindowFitment } from "./hooks";
|
|
|
138
138
|
export { isNavigationAnchor, isNavigationButton } from "./utils";
|
|
139
139
|
export type { ClassName, Headings, PropsWithSpread, SortDirection, SubComponentProps, TSFixMe, ValueOf, } from "./types";
|
|
140
140
|
export { Theme } from "./enums";
|
|
141
|
+
export type { UsePortalOptions } from "./external";
|
|
142
|
+
export { usePortal } from "./external";
|
package/dist/esm/index.js
CHANGED
|
@@ -70,4 +70,5 @@ export { default as TablePaginationControls } from "./components/TablePagination
|
|
|
70
70
|
export { default as CustomSelect } from "./components/CustomSelect";
|
|
71
71
|
export { useOnClickOutside, useClickOutside, useId, useListener, useOnEscapePressed, usePagination, usePrevious, useThrottle, useWindowFitment } from "./hooks";
|
|
72
72
|
export { isNavigationAnchor, isNavigationButton } from "./utils";
|
|
73
|
-
export { Theme } from "./enums";
|
|
73
|
+
export { Theme } from "./enums";
|
|
74
|
+
export { usePortal } from "./external";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "usePortal", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _usePortal.usePortal;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
var _usePortal = require("./usePortal");
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This is a reference implementation of the usePortal hook from react-useportal: https://github.com/iamthesiz/react-useportal/blob/master/usePortal.ts
|
|
3
|
+
* The license for the content in this file is goverened by the original project's license: https://github.com/iamthesiz/react-useportal/blob/master/license.md
|
|
4
|
+
*/
|
|
5
|
+
import { ReactNode, SyntheticEvent, RefObject } from "react";
|
|
6
|
+
type CustomEvent<T = HTMLElement> = {
|
|
7
|
+
event?: SyntheticEvent<T, Event>;
|
|
8
|
+
portal: RefObject<HTMLElement>;
|
|
9
|
+
targetEl: RefObject<HTMLElement>;
|
|
10
|
+
} & SyntheticEvent<T, Event>;
|
|
11
|
+
type CustomEventHandler<T = HTMLElement> = (customEvent: CustomEvent<T>) => void;
|
|
12
|
+
export type UsePortalOptions = {
|
|
13
|
+
closeOnOutsideClick?: boolean;
|
|
14
|
+
closeOnEsc?: boolean;
|
|
15
|
+
bindTo?: RefObject<HTMLElement>;
|
|
16
|
+
isOpen?: boolean;
|
|
17
|
+
onOpen?: CustomEventHandler;
|
|
18
|
+
onClose?: CustomEventHandler;
|
|
19
|
+
onPortalClick?: CustomEventHandler;
|
|
20
|
+
programmaticallyOpen?: boolean;
|
|
21
|
+
};
|
|
22
|
+
export declare const errorMessage1 = "You must either add a `ref` to the element you are interacting with or pass an `event` to openPortal(e) or togglePortal(e) when the `programmaticallyOpen` option is not set to `true`.";
|
|
23
|
+
export declare const usePortal: ({ closeOnOutsideClick, closeOnEsc, bindTo, isOpen: defaultIsOpen, onOpen, onClose, onPortalClick, programmaticallyOpen, }?: UsePortalOptions) => (boolean | RefObject<HTMLElement> | ((e?: SyntheticEvent<HTMLElement, Event>) => void) | (({ children }: {
|
|
24
|
+
children: ReactNode;
|
|
25
|
+
}) => import("react").JSX.Element))[] & {
|
|
26
|
+
isOpen: boolean;
|
|
27
|
+
openPortal: (e?: SyntheticEvent<HTMLElement, Event>) => void;
|
|
28
|
+
ref: RefObject<HTMLElement>;
|
|
29
|
+
closePortal: (e?: SyntheticEvent<HTMLElement, Event>) => void;
|
|
30
|
+
togglePortal: (e?: SyntheticEvent<HTMLElement, Event>) => void;
|
|
31
|
+
Portal: ({ children }: {
|
|
32
|
+
children: ReactNode;
|
|
33
|
+
}) => import("react").JSX.Element;
|
|
34
|
+
portalRef: RefObject<HTMLElement>;
|
|
35
|
+
bind: {
|
|
36
|
+
ref: RefObject<HTMLElement>;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export {};
|