@deque/cauldron-react 6.7.0-canary.2c00ffa4 → 6.7.0-canary.4be82cb3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cauldron.css +6 -0
- package/lib/components/ClickOutsideListener/index.d.ts +3 -19
- package/lib/components/Drawer/index.d.ts +15 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +228 -131
- package/lib/utils/resolveElement.d.ts +6 -0
- package/lib/utils/useEscapeKey.d.ts +17 -0
- package/package.json +1 -1
package/lib/cauldron.css
CHANGED
|
@@ -4,23 +4,7 @@ export interface ClickOutsideListenerProps<T extends HTMLElement = HTMLElement>
|
|
|
4
4
|
onClickOutside: (e: MouseEvent | TouchEvent) => void;
|
|
5
5
|
mouseEvent?: 'mousedown' | 'click' | 'mouseup' | false;
|
|
6
6
|
touchEvent?: 'touchstart' | 'touchend' | false;
|
|
7
|
-
target?: T
|
|
8
|
-
}
|
|
9
|
-
export default class ClickOutsideListener extends React.Component<ClickOutsideListenerProps> {
|
|
10
|
-
static displayName: string;
|
|
11
|
-
static defaultProps: {
|
|
12
|
-
mouseEvent: string;
|
|
13
|
-
touchEvent: string;
|
|
14
|
-
};
|
|
15
|
-
private nodeRef;
|
|
16
|
-
handleEvent: (event: MouseEvent | TouchEvent) => void;
|
|
17
|
-
componentDidMount(): void;
|
|
18
|
-
componentDidUpdate(prevProps: ClickOutsideListenerProps): void;
|
|
19
|
-
componentWillUnmount(): void;
|
|
20
|
-
private attachEventListeners;
|
|
21
|
-
private removeEventListeners;
|
|
22
|
-
resolveRef: (node: HTMLElement) => void;
|
|
23
|
-
render(): React.FunctionComponentElement<{
|
|
24
|
-
ref: (node: HTMLElement) => void;
|
|
25
|
-
}> | null;
|
|
7
|
+
target?: T | React.RefObject<T> | React.MutableRefObject<T>;
|
|
26
8
|
}
|
|
9
|
+
declare const _default: React.ForwardRefExoticComponent<ClickOutsideListenerProps<HTMLElement> & React.RefAttributes<HTMLElement>>;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface DrawerProps<T extends HTMLElement = HTMLElement> extends React.HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
position: 'top' | 'bottom' | 'left' | 'right';
|
|
5
|
+
open?: boolean;
|
|
6
|
+
behavior?: 'modal' | 'non-modal';
|
|
7
|
+
focusOptions?: {
|
|
8
|
+
initialFocus?: T | React.RefObject<T> | React.MutableRefObject<T>;
|
|
9
|
+
returnFocus?: T | React.RefObject<T> | React.MutableRefObject<T>;
|
|
10
|
+
};
|
|
11
|
+
onClose?: () => void;
|
|
12
|
+
portal?: React.RefObject<HTMLElement> | HTMLElement;
|
|
13
|
+
}
|
|
14
|
+
declare const Drawer: React.ForwardRefExoticComponent<DrawerProps<HTMLElement> & React.RefAttributes<HTMLDivElement>>;
|
|
15
|
+
export default Drawer;
|
package/lib/index.d.ts
CHANGED
|
@@ -59,6 +59,7 @@ export { default as Popover } from './components/Popover';
|
|
|
59
59
|
export { default as Timeline, TimelineItem } from './components/Timeline';
|
|
60
60
|
export { default as TextEllipsis } from './components/TextEllipsis';
|
|
61
61
|
export { default as CopyButton } from './components/CopyButton';
|
|
62
|
+
export { default as Drawer } from './components/Drawer';
|
|
62
63
|
/**
|
|
63
64
|
* Helpers / Utils
|
|
64
65
|
*/
|
package/lib/index.js
CHANGED
|
@@ -791,74 +791,70 @@ var OptionsMenuWrapper = function (_a) {
|
|
|
791
791
|
return (React__default["default"].createElement("div", tslib.__assign({ className: classNames__default["default"]('OptionsMenu', menuAlignment(align), className) }, other)));
|
|
792
792
|
};
|
|
793
793
|
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
if (event.defaultPrevented) {
|
|
802
|
-
return;
|
|
803
|
-
}
|
|
804
|
-
var eventTarget = event.target;
|
|
805
|
-
if ((target && !target.contains(eventTarget)) ||
|
|
806
|
-
(nodeRef && !nodeRef.contains(eventTarget))) {
|
|
807
|
-
onClickOutside(event);
|
|
808
|
-
}
|
|
809
|
-
};
|
|
810
|
-
_this.attachEventListeners = function () {
|
|
811
|
-
var _a = _this.props, mouseEvent = _a.mouseEvent, touchEvent = _a.touchEvent;
|
|
812
|
-
typeof mouseEvent === 'string' &&
|
|
813
|
-
document.addEventListener(mouseEvent, _this.handleEvent);
|
|
814
|
-
typeof touchEvent === 'string' &&
|
|
815
|
-
document.addEventListener(touchEvent, _this.handleEvent);
|
|
816
|
-
};
|
|
817
|
-
_this.removeEventListeners = function (mouseEvent, touchEvent) {
|
|
818
|
-
typeof mouseEvent === 'string' &&
|
|
819
|
-
document.removeEventListener(mouseEvent, _this.handleEvent);
|
|
820
|
-
typeof touchEvent === 'string' &&
|
|
821
|
-
document.removeEventListener(touchEvent, _this.handleEvent);
|
|
822
|
-
};
|
|
823
|
-
_this.resolveRef = function (node) {
|
|
824
|
-
_this.nodeRef = node;
|
|
825
|
-
// If child has its own ref, we want to update
|
|
826
|
-
// its ref with the newly cloned node
|
|
827
|
-
var ref = _this.props.children.ref;
|
|
828
|
-
setRef(ref, node);
|
|
829
|
-
};
|
|
830
|
-
return _this;
|
|
794
|
+
/**
|
|
795
|
+
* When an element can be passed as a value that is either an element or an
|
|
796
|
+
* elementRef, this will resolve the property down to the resulting element
|
|
797
|
+
*/
|
|
798
|
+
function resolveElement(elementOrRef) {
|
|
799
|
+
if (elementOrRef instanceof Element) {
|
|
800
|
+
return elementOrRef;
|
|
831
801
|
}
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
802
|
+
if (elementOrRef &&
|
|
803
|
+
typeof elementOrRef === 'object' &&
|
|
804
|
+
'current' in elementOrRef &&
|
|
805
|
+
elementOrRef.current instanceof Element) {
|
|
806
|
+
return elementOrRef.current;
|
|
807
|
+
}
|
|
808
|
+
return null;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
function ClickOutsideListener(_a, ref) {
|
|
812
|
+
var children = _a.children, _b = _a.mouseEvent, mouseEvent = _b === void 0 ? 'click' : _b, _c = _a.touchEvent, touchEvent = _c === void 0 ? 'touchend' : _c, target = _a.target, _d = _a.onClickOutside, onClickOutside = _d === void 0 ? function () { return null; } : _d;
|
|
813
|
+
var childElementRef = React.useRef();
|
|
814
|
+
var handleEvent = function (event) {
|
|
815
|
+
if (event.defaultPrevented) {
|
|
816
|
+
return;
|
|
817
|
+
}
|
|
818
|
+
var eventTarget = event.target;
|
|
819
|
+
var elementTarget = resolveElement(target);
|
|
820
|
+
if (target && !(elementTarget === null || elementTarget === void 0 ? void 0 : elementTarget.contains(eventTarget))) {
|
|
821
|
+
onClickOutside(event);
|
|
822
|
+
// If a target is passed in via a prop, we defer to utilizing that
|
|
823
|
+
// target instead of a child element target
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
if (childElementRef.current &&
|
|
827
|
+
!childElementRef.current.contains(eventTarget)) {
|
|
828
|
+
onClickOutside(event);
|
|
841
829
|
}
|
|
842
830
|
};
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
this
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
: React__default["default"].cloneElement(props.children, {
|
|
852
|
-
ref: resolveRef
|
|
853
|
-
});
|
|
854
|
-
};
|
|
855
|
-
ClickOutsideListener.displayName = 'ClickOutsideListener';
|
|
856
|
-
ClickOutsideListener.defaultProps = {
|
|
857
|
-
mouseEvent: 'click',
|
|
858
|
-
touchEvent: 'touchend'
|
|
831
|
+
var resolveRef = function (node) {
|
|
832
|
+
childElementRef.current = node;
|
|
833
|
+
// Ref for this component should pass-through to the child node
|
|
834
|
+
setRef(ref, node);
|
|
835
|
+
// If child has its own ref, we want to update
|
|
836
|
+
// its ref with the newly cloned node
|
|
837
|
+
var childRef = children.ref;
|
|
838
|
+
setRef(childRef, node);
|
|
859
839
|
};
|
|
860
|
-
|
|
861
|
-
|
|
840
|
+
React.useEffect(function () {
|
|
841
|
+
typeof mouseEvent === 'string' &&
|
|
842
|
+
document.addEventListener(mouseEvent, handleEvent);
|
|
843
|
+
typeof touchEvent === 'string' &&
|
|
844
|
+
document.addEventListener(touchEvent, handleEvent);
|
|
845
|
+
return function () {
|
|
846
|
+
typeof mouseEvent === 'string' &&
|
|
847
|
+
document.removeEventListener(mouseEvent, handleEvent);
|
|
848
|
+
typeof touchEvent === 'string' &&
|
|
849
|
+
document.removeEventListener(touchEvent, handleEvent);
|
|
850
|
+
};
|
|
851
|
+
}, [mouseEvent, touchEvent]);
|
|
852
|
+
return !children
|
|
853
|
+
? null
|
|
854
|
+
: React__default["default"].cloneElement(children, { ref: resolveRef });
|
|
855
|
+
}
|
|
856
|
+
ClickOutsideListener.displayName = 'ClickOutsideListener';
|
|
857
|
+
var ClickOutsideListener$1 = React__default["default"].forwardRef(ClickOutsideListener);
|
|
862
858
|
|
|
863
859
|
var _a$2 = tslib.__read([38, 40, 9, 13, 32, 27], 6), up = _a$2[0], down$1 = _a$2[1], tab = _a$2[2], enter = _a$2[3], space = _a$2[4], esc = _a$2[5];
|
|
864
860
|
var OptionsMenuList = /** @class */ (function (_super) {
|
|
@@ -964,7 +960,7 @@ var OptionsMenuList = /** @class */ (function (_super) {
|
|
|
964
960
|
// Key event is being handled in componentDidMount
|
|
965
961
|
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
|
966
962
|
/* eslint-disable jsx-a11y/role-supports-aria-props */
|
|
967
|
-
return (React__default["default"].createElement(ClickOutsideListener, { onClickOutside: this.handleClickOutside, mouseEvent: clickOutsideEventActive, touchEvent: clickOutsideEventActive },
|
|
963
|
+
return (React__default["default"].createElement(ClickOutsideListener$1, { onClickOutside: this.handleClickOutside, mouseEvent: clickOutsideEventActive, touchEvent: clickOutsideEventActive },
|
|
968
964
|
React__default["default"].createElement("ul", tslib.__assign({}, other, { className: classNames__default["default"]('OptionsMenu__list', className), "aria-expanded": show, role: "menu", onClick: handleClick, ref: function (el) {
|
|
969
965
|
_this.menuRef = el;
|
|
970
966
|
if (menuRef) {
|
|
@@ -1312,7 +1308,7 @@ var SideBar = /** @class */ (function (_super) {
|
|
|
1312
1308
|
var _b = this.props, children = _b.children, className = _b.className, show = _b.show; _b.onDismiss; var navProps = _b.navProps, other = tslib.__rest(_b, ["children", "className", "show", "onDismiss", "navProps"]);
|
|
1313
1309
|
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
|
|
1314
1310
|
return (React__default["default"].createElement(React.Fragment, null,
|
|
1315
|
-
React__default["default"].createElement(ClickOutsideListener, { onClickOutside: this.handleClickOutside },
|
|
1311
|
+
React__default["default"].createElement(ClickOutsideListener$1, { onClickOutside: this.handleClickOutside },
|
|
1316
1312
|
React__default["default"].createElement("nav", tslib.__assign({}, navProps),
|
|
1317
1313
|
React__default["default"].createElement("ul", tslib.__assign({ className: classNames__default["default"]('SideBar', className, animateClass) }, other, { ref: this.navList, onKeyDown: this.onKeyDown }), children))),
|
|
1318
1314
|
React__default["default"].createElement(Scrim, { show: !wide && show })));
|
|
@@ -1451,7 +1447,7 @@ var Dialog = /** @class */ (function (_super) {
|
|
|
1451
1447
|
escapeDeactivates: false,
|
|
1452
1448
|
fallbackFocus: '.Dialog__heading'
|
|
1453
1449
|
} },
|
|
1454
|
-
React__default["default"].createElement(ClickOutsideListener, { onClickOutside: this.handleClickOutside },
|
|
1450
|
+
React__default["default"].createElement(ClickOutsideListener$1, { onClickOutside: this.handleClickOutside },
|
|
1455
1451
|
React__default["default"].createElement("div", tslib.__assign({ role: "dialog", className: classNames__default["default"]('Dialog', className, {
|
|
1456
1452
|
'Dialog--show': show
|
|
1457
1453
|
}), ref: function (el) {
|
|
@@ -1667,6 +1663,46 @@ function hasIdRef(ids, id) {
|
|
|
1667
1663
|
return idRefs(ids).has(id);
|
|
1668
1664
|
}
|
|
1669
1665
|
|
|
1666
|
+
var isEscapeKey = function (event) {
|
|
1667
|
+
return event.key === 'Escape' || event.key === 'Esc' || event.keyCode === 27;
|
|
1668
|
+
};
|
|
1669
|
+
/**
|
|
1670
|
+
* When a component needs to implement an escape handler, such as in modal
|
|
1671
|
+
* dialogs, useEscapeKey will handle the events and call the provided callback
|
|
1672
|
+
* handler when an escape key event has been fired.
|
|
1673
|
+
*
|
|
1674
|
+
* @example
|
|
1675
|
+
* useEscapeKey(() => close())
|
|
1676
|
+
*/
|
|
1677
|
+
function useEscapeKey(options, dependencies) {
|
|
1678
|
+
if (dependencies === void 0) { dependencies = []; }
|
|
1679
|
+
var callback = options.callback;
|
|
1680
|
+
var event = options.event || 'keyup';
|
|
1681
|
+
var target = resolveElement(options.target) || document.body;
|
|
1682
|
+
var active = typeof options.active === 'boolean' ? options.active : true;
|
|
1683
|
+
React.useEffect(function () {
|
|
1684
|
+
var eventListener = function (event) {
|
|
1685
|
+
if (isEscapeKey(event) &&
|
|
1686
|
+
(options.defaultPrevented ? !event.defaultPrevented : true)) {
|
|
1687
|
+
callback(event);
|
|
1688
|
+
}
|
|
1689
|
+
};
|
|
1690
|
+
if (active) {
|
|
1691
|
+
target === null || target === void 0 ? void 0 : target.addEventListener(event, eventListener, options.capture);
|
|
1692
|
+
}
|
|
1693
|
+
return function () {
|
|
1694
|
+
target === null || target === void 0 ? void 0 : target.removeEventListener(event, eventListener, options.capture);
|
|
1695
|
+
};
|
|
1696
|
+
}, tslib.__spreadArray([
|
|
1697
|
+
active,
|
|
1698
|
+
callback,
|
|
1699
|
+
event,
|
|
1700
|
+
target,
|
|
1701
|
+
options.capture,
|
|
1702
|
+
options.defaultPrevented
|
|
1703
|
+
], tslib.__read(dependencies), false));
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1670
1706
|
var TIP_HIDE_DELAY = 100;
|
|
1671
1707
|
// fires a custom "cauldron:tooltip:show" / "cauldron:tooltip:hide" event
|
|
1672
1708
|
// to allow projects using cauldron to hook into when a tooltip is shown/hidden
|
|
@@ -1755,30 +1791,14 @@ function Tooltip(_a) {
|
|
|
1755
1791
|
attributes.popper['data-popper-placement']) ||
|
|
1756
1792
|
initialPlacement;
|
|
1757
1793
|
// Only listen to key ups when the tooltip is visible
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
};
|
|
1767
|
-
var targetElement = document.body;
|
|
1768
|
-
if (showTooltip && typeof showProp !== 'boolean') {
|
|
1769
|
-
targetElement.addEventListener('keyup', handleEscape, { capture: true });
|
|
1770
|
-
}
|
|
1771
|
-
else {
|
|
1772
|
-
targetElement.removeEventListener('keyup', handleEscape, {
|
|
1773
|
-
capture: true
|
|
1774
|
-
});
|
|
1775
|
-
}
|
|
1776
|
-
return function () {
|
|
1777
|
-
targetElement.removeEventListener('keyup', handleEscape, {
|
|
1778
|
-
capture: true
|
|
1779
|
-
});
|
|
1780
|
-
};
|
|
1781
|
-
}, [showTooltip, showProp]);
|
|
1794
|
+
useEscapeKey({
|
|
1795
|
+
callback: function (event) {
|
|
1796
|
+
event.preventDefault();
|
|
1797
|
+
setShowTooltip(false);
|
|
1798
|
+
},
|
|
1799
|
+
capture: true,
|
|
1800
|
+
active: showTooltip && typeof showProp !== 'boolean'
|
|
1801
|
+
}, [setShowTooltip]);
|
|
1782
1802
|
// Handle hover and focus events for the targetElement
|
|
1783
1803
|
React.useEffect(function () {
|
|
1784
1804
|
if (typeof showProp !== 'boolean') {
|
|
@@ -3294,25 +3314,10 @@ var TwoColumnPanel = React.forwardRef(function (_a, ref) {
|
|
|
3294
3314
|
mediaQueryList.removeEventListener('change', listener);
|
|
3295
3315
|
};
|
|
3296
3316
|
}, []);
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
event.keyCode === 27) {
|
|
3302
|
-
setCollapsed(true);
|
|
3303
|
-
}
|
|
3304
|
-
};
|
|
3305
|
-
var targetElement = document.body;
|
|
3306
|
-
if (isFocusTrap) {
|
|
3307
|
-
targetElement.addEventListener('keyup', handleEscape);
|
|
3308
|
-
}
|
|
3309
|
-
else {
|
|
3310
|
-
targetElement.removeEventListener('keyup', handleEscape);
|
|
3311
|
-
}
|
|
3312
|
-
return function () {
|
|
3313
|
-
targetElement.removeEventListener('keyup', handleEscape);
|
|
3314
|
-
};
|
|
3315
|
-
}, [isFocusTrap]);
|
|
3317
|
+
useEscapeKey({
|
|
3318
|
+
callback: function () { return setCollapsed(true); },
|
|
3319
|
+
active: isFocusTrap
|
|
3320
|
+
}, [setCollapsed]);
|
|
3316
3321
|
var handleClickOutside = function () {
|
|
3317
3322
|
if (!isCollapsed && isFocusTrap) {
|
|
3318
3323
|
setCollapsed(true);
|
|
@@ -3328,7 +3333,7 @@ var TwoColumnPanel = React.forwardRef(function (_a, ref) {
|
|
|
3328
3333
|
allowOutsideClick: true,
|
|
3329
3334
|
fallbackFocus: columnLeftRef.current
|
|
3330
3335
|
}, containerElements: [columnLeftRef.current] }),
|
|
3331
|
-
React__default["default"].createElement(ClickOutsideListener, { onClickOutside: handleClickOutside, target: columnLeftRef.current }),
|
|
3336
|
+
React__default["default"].createElement(ClickOutsideListener$1, { onClickOutside: handleClickOutside, target: columnLeftRef.current }),
|
|
3332
3337
|
isCollapsed ? null : skipLink,
|
|
3333
3338
|
showPanel ? ColumnLeftComponent : null,
|
|
3334
3339
|
ColumnRightComponent)));
|
|
@@ -4095,24 +4100,6 @@ var Popover = React.forwardRef(function (_a, ref) {
|
|
|
4095
4100
|
}
|
|
4096
4101
|
targetElement === null || targetElement === void 0 ? void 0 : targetElement.setAttribute('aria-expanded', Boolean(show).toString());
|
|
4097
4102
|
}, [show, popoverRef.current]);
|
|
4098
|
-
React.useEffect(function () {
|
|
4099
|
-
var handleEscape = function (event) {
|
|
4100
|
-
if (event.key === 'Escape' ||
|
|
4101
|
-
event.key === 'Esc' ||
|
|
4102
|
-
event.keyCode === 27) {
|
|
4103
|
-
handleClosePopover();
|
|
4104
|
-
}
|
|
4105
|
-
};
|
|
4106
|
-
if (show) {
|
|
4107
|
-
document.body.addEventListener('keyup', handleEscape);
|
|
4108
|
-
}
|
|
4109
|
-
else {
|
|
4110
|
-
document.body.removeEventListener('keyup', handleEscape);
|
|
4111
|
-
}
|
|
4112
|
-
return function () {
|
|
4113
|
-
document.body.removeEventListener('keyup', handleEscape);
|
|
4114
|
-
};
|
|
4115
|
-
}, [show]);
|
|
4116
4103
|
React.useEffect(function () {
|
|
4117
4104
|
var attrText = targetElement === null || targetElement === void 0 ? void 0 : targetElement.getAttribute('aria-controls');
|
|
4118
4105
|
var hasPopupAttr = targetElement === null || targetElement === void 0 ? void 0 : targetElement.getAttribute('aria-haspopup');
|
|
@@ -4139,13 +4126,17 @@ var Popover = React.forwardRef(function (_a, ref) {
|
|
|
4139
4126
|
onClose();
|
|
4140
4127
|
}
|
|
4141
4128
|
};
|
|
4129
|
+
useEscapeKey({
|
|
4130
|
+
callback: handleClosePopover,
|
|
4131
|
+
active: show
|
|
4132
|
+
}, [show]);
|
|
4142
4133
|
if (!show || !isBrowser())
|
|
4143
4134
|
return null;
|
|
4144
4135
|
return reactDom.createPortal(React__default["default"].createElement(FocusTrap__default["default"], { focusTrapOptions: {
|
|
4145
4136
|
allowOutsideClick: true,
|
|
4146
4137
|
fallbackFocus: '.Popover__borderLeft'
|
|
4147
4138
|
} },
|
|
4148
|
-
React__default["default"].createElement(ClickOutsideListener, { onClickOutside: handleClickOutside },
|
|
4139
|
+
React__default["default"].createElement(ClickOutsideListener$1, { onClickOutside: handleClickOutside },
|
|
4149
4140
|
React__default["default"].createElement("div", tslib.__assign({ id: id, className: classNames__default["default"]('Popover', "Popover--".concat(placement), className, {
|
|
4150
4141
|
'Popover--hidden': !show,
|
|
4151
4142
|
'Popover--prompt': variant === 'prompt'
|
|
@@ -4216,6 +4207,111 @@ var TextEllipsis = React__default["default"].forwardRef(function (_a, ref) {
|
|
|
4216
4207
|
});
|
|
4217
4208
|
TextEllipsis.displayName = 'TextEllipsis';
|
|
4218
4209
|
|
|
4210
|
+
var Drawer = React.forwardRef(function (_a, ref) {
|
|
4211
|
+
var children = _a.children, className = _a.className, position = _a.position, _b = _a.open, open = _b === void 0 ? false : _b, _c = _a.behavior, behavior = _c === void 0 ? 'modal' : _c, _d = _a.focusOptions, focusOptions = _d === void 0 ? {} : _d, portal = _a.portal, onClose = _a.onClose, style = _a.style, props = tslib.__rest(_a, ["children", "className", "position", "open", "behavior", "focusOptions", "portal", "onClose", "style"]);
|
|
4212
|
+
var drawerRef = useSharedRef(ref);
|
|
4213
|
+
var openRef = React.useRef(!!open);
|
|
4214
|
+
var previousActiveElementRef = React.useRef(null);
|
|
4215
|
+
var focusInitial = focusOptions.initialFocus, focusReturn = focusOptions.returnFocus;
|
|
4216
|
+
var _e = tslib.__read(React.useState(!!open), 2), isTransitioning = _e[0], setIsTransitioning = _e[1];
|
|
4217
|
+
var isModal = behavior === 'modal';
|
|
4218
|
+
var handleClose = React.useCallback(function () {
|
|
4219
|
+
// istanbul ignore next
|
|
4220
|
+
if (open && typeof onClose === 'function') {
|
|
4221
|
+
onClose();
|
|
4222
|
+
}
|
|
4223
|
+
}, [open, onClose]);
|
|
4224
|
+
React.useEffect(function () {
|
|
4225
|
+
// jsdom does not trigger transitionend event
|
|
4226
|
+
// istanbul ignore next
|
|
4227
|
+
var transitionEndHandler = function () { return setIsTransitioning(false); };
|
|
4228
|
+
document.addEventListener('transitionend', transitionEndHandler);
|
|
4229
|
+
return function () {
|
|
4230
|
+
document.removeEventListener('transitionend', transitionEndHandler);
|
|
4231
|
+
};
|
|
4232
|
+
}, [setIsTransitioning]);
|
|
4233
|
+
React.useEffect(function () {
|
|
4234
|
+
if (openRef.current !== open) {
|
|
4235
|
+
setIsTransitioning(true);
|
|
4236
|
+
}
|
|
4237
|
+
openRef.current = open;
|
|
4238
|
+
}, [open, setIsTransitioning]);
|
|
4239
|
+
React.useEffect(function () {
|
|
4240
|
+
if (!isModal) {
|
|
4241
|
+
return;
|
|
4242
|
+
}
|
|
4243
|
+
var isolator = new AriaIsolate(drawerRef.current);
|
|
4244
|
+
if (open) {
|
|
4245
|
+
isolator.activate();
|
|
4246
|
+
}
|
|
4247
|
+
else {
|
|
4248
|
+
isolator.deactivate();
|
|
4249
|
+
}
|
|
4250
|
+
return function () {
|
|
4251
|
+
isolator.deactivate();
|
|
4252
|
+
};
|
|
4253
|
+
}, [isModal, open]);
|
|
4254
|
+
React.useLayoutEffect(function () {
|
|
4255
|
+
var _a, _b, _c;
|
|
4256
|
+
if (open) {
|
|
4257
|
+
previousActiveElementRef.current =
|
|
4258
|
+
document.activeElement;
|
|
4259
|
+
var initialFocusElement = resolveElement(focusInitial);
|
|
4260
|
+
if (initialFocusElement) {
|
|
4261
|
+
initialFocusElement.focus();
|
|
4262
|
+
}
|
|
4263
|
+
else {
|
|
4264
|
+
var focusable = (_a = drawerRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(focusableSelector);
|
|
4265
|
+
if (focusable) {
|
|
4266
|
+
focusable.focus();
|
|
4267
|
+
}
|
|
4268
|
+
else {
|
|
4269
|
+
// fallback focus
|
|
4270
|
+
(_b = drawerRef.current) === null || _b === void 0 ? void 0 : _b.focus();
|
|
4271
|
+
}
|
|
4272
|
+
}
|
|
4273
|
+
}
|
|
4274
|
+
else if (previousActiveElementRef.current) {
|
|
4275
|
+
var returnFocusElement = resolveElement(focusReturn);
|
|
4276
|
+
if (returnFocusElement) {
|
|
4277
|
+
returnFocusElement.focus();
|
|
4278
|
+
}
|
|
4279
|
+
else {
|
|
4280
|
+
// fallback focus
|
|
4281
|
+
(_c = previousActiveElementRef.current) === null || _c === void 0 ? void 0 : _c.focus();
|
|
4282
|
+
}
|
|
4283
|
+
}
|
|
4284
|
+
}, [open, focusInitial, focusReturn]);
|
|
4285
|
+
useEscapeKey({ callback: handleClose, active: open, defaultPrevented: true }, [onClose]);
|
|
4286
|
+
// istanbul ignore next
|
|
4287
|
+
if (!isBrowser()) {
|
|
4288
|
+
return null;
|
|
4289
|
+
}
|
|
4290
|
+
var portalElement = resolveElement(portal);
|
|
4291
|
+
return reactDom.createPortal(React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
4292
|
+
React__default["default"].createElement(ClickOutsideListener$1, { onClickOutside: handleClose, mouseEvent: open ? undefined : false, touchEvent: open ? undefined : false, target: drawerRef },
|
|
4293
|
+
React__default["default"].createElement(FocusTrap__default["default"], { active: !!isModal && !!open, focusTrapOptions: {
|
|
4294
|
+
allowOutsideClick: true,
|
|
4295
|
+
escapeDeactivates: false,
|
|
4296
|
+
clickOutsideDeactivates: false,
|
|
4297
|
+
initialFocus: false,
|
|
4298
|
+
setReturnFocus: false,
|
|
4299
|
+
fallbackFocus: function () { return drawerRef.current; }
|
|
4300
|
+
} },
|
|
4301
|
+
React__default["default"].createElement("div", tslib.__assign({ ref: drawerRef, className: classNames__default["default"](className, 'Drawer', {
|
|
4302
|
+
'Drawer--open': !!open,
|
|
4303
|
+
'Drawer--top': position === 'top',
|
|
4304
|
+
'Drawer--bottom': position === 'bottom',
|
|
4305
|
+
'Drawer--left': position === 'left',
|
|
4306
|
+
'Drawer--right': position === 'right'
|
|
4307
|
+
}), "aria-hidden": !open || undefined, style: tslib.__assign({ visibility: !open && !isTransitioning ? 'hidden' : undefined }, style), tabIndex: open ? -1 : undefined }, props), children))),
|
|
4308
|
+
React__default["default"].createElement(Scrim, { show: !!open && !!isModal })), portalElement ||
|
|
4309
|
+
(
|
|
4310
|
+
// eslint-disable-next-line ssr-friendly/no-dom-globals-in-react-fc
|
|
4311
|
+
document === null || document === void 0 ? void 0 : document.body));
|
|
4312
|
+
});
|
|
4313
|
+
Drawer.displayName = 'Drawer';
|
|
4314
|
+
|
|
4219
4315
|
var LIGHT_THEME_CLASS = 'cauldron--theme-light';
|
|
4220
4316
|
var DARK_THEME_CLASS = 'cauldron--theme-dark';
|
|
4221
4317
|
var ThemeContext = React.createContext({
|
|
@@ -4300,7 +4396,7 @@ exports.BreadcrumbItem = BreadcrumbItem;
|
|
|
4300
4396
|
exports.BreadcrumbLink = BreadcrumbLink;
|
|
4301
4397
|
exports.Button = Button;
|
|
4302
4398
|
exports.Checkbox = Checkbox;
|
|
4303
|
-
exports.ClickOutsideListener = ClickOutsideListener;
|
|
4399
|
+
exports.ClickOutsideListener = ClickOutsideListener$1;
|
|
4304
4400
|
exports.Code = Code;
|
|
4305
4401
|
exports.ColumnGroupHeader = ColumnGroupHeader;
|
|
4306
4402
|
exports.ColumnHeader = ColumnHeader;
|
|
@@ -4318,6 +4414,7 @@ exports.DescriptionTerm = DescriptionTerm;
|
|
|
4318
4414
|
exports.Dialog = Dialog;
|
|
4319
4415
|
exports.DialogContent = DialogContent;
|
|
4320
4416
|
exports.DialogFooter = DialogFooter;
|
|
4417
|
+
exports.Drawer = Drawer;
|
|
4321
4418
|
exports.ExpandCollapsePanel = ExpandCollapsePanel;
|
|
4322
4419
|
exports.FieldWrap = FieldWrap;
|
|
4323
4420
|
exports.Icon = Icon;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RefObject, MutableRefObject } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* When an element can be passed as a value that is either an element or an
|
|
4
|
+
* elementRef, this will resolve the property down to the resulting element
|
|
5
|
+
*/
|
|
6
|
+
export default function resolveElement<T extends Element = Element>(elementOrRef: T | RefObject<T> | MutableRefObject<T> | undefined): T | null;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type DependencyList } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* When a component needs to implement an escape handler, such as in modal
|
|
4
|
+
* dialogs, useEscapeKey will handle the events and call the provided callback
|
|
5
|
+
* handler when an escape key event has been fired.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* useEscapeKey(() => close())
|
|
9
|
+
*/
|
|
10
|
+
export default function useEscapeKey<T extends HTMLElement = HTMLElement>(options: {
|
|
11
|
+
active?: boolean;
|
|
12
|
+
callback: (event: KeyboardEvent) => void;
|
|
13
|
+
event?: 'keydown' | 'keypress' | 'keyup';
|
|
14
|
+
target?: T | React.RefObject<T> | React.MutableRefObject<T>;
|
|
15
|
+
defaultPrevented?: boolean;
|
|
16
|
+
capture?: boolean;
|
|
17
|
+
}, dependencies?: DependencyList): void;
|
package/package.json
CHANGED