@deque/cauldron-react 5.8.0-canary.55b0441c → 5.8.0-canary.b09c14c1
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/components/Popover/index.d.ts +31 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +126 -0
- package/package.json +1 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import { Placement } from '@popperjs/core';
|
|
3
|
+
import { Cauldron } from '../../types';
|
|
4
|
+
export type PopoverVariant = 'prompt' | 'custom';
|
|
5
|
+
type BaseProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
6
|
+
target: React.RefObject<HTMLElement> | HTMLElement;
|
|
7
|
+
variant?: PopoverVariant;
|
|
8
|
+
show: boolean;
|
|
9
|
+
onClose: () => void;
|
|
10
|
+
placement?: Placement;
|
|
11
|
+
portal?: React.RefObject<HTMLElement> | HTMLElement;
|
|
12
|
+
};
|
|
13
|
+
type CustomProps = BaseProps & {
|
|
14
|
+
variant: 'custom';
|
|
15
|
+
applyButtonText?: string;
|
|
16
|
+
onApply?: () => void;
|
|
17
|
+
closeButtonText?: string;
|
|
18
|
+
infoText?: ReactNode;
|
|
19
|
+
children: ReactNode;
|
|
20
|
+
} & Cauldron.LabelProps;
|
|
21
|
+
type PromptProps = BaseProps & {
|
|
22
|
+
variant: 'prompt';
|
|
23
|
+
applyButtonText?: string;
|
|
24
|
+
onApply: () => void;
|
|
25
|
+
closeButtonText?: string;
|
|
26
|
+
infoText: ReactNode;
|
|
27
|
+
children?: ReactNode;
|
|
28
|
+
};
|
|
29
|
+
export type PopoverProps = PromptProps | CustomProps;
|
|
30
|
+
declare const Popover: React.ForwardRefExoticComponent<PopoverProps & React.RefAttributes<HTMLDivElement>>;
|
|
31
|
+
export default Popover;
|
package/lib/index.d.ts
CHANGED
|
@@ -53,6 +53,7 @@ export { default as Breadcrumb, BreadcrumbItem, BreadcrumbLink } from './compone
|
|
|
53
53
|
export { default as TwoColumnPanel, ColumnHeader, ColumnGroupHeader, ColumnLeft, ColumnRight, ColumnList } from './components/TwoColumnPanel';
|
|
54
54
|
export { default as Notice } from './components/Notice';
|
|
55
55
|
export { default as Listbox, ListboxOption, ListboxGroup } from './components/Listbox';
|
|
56
|
+
export { default as Popover } from './components/Popover';
|
|
56
57
|
/**
|
|
57
58
|
* Helpers / Utils
|
|
58
59
|
*/
|
package/lib/index.js
CHANGED
|
@@ -4162,6 +4162,131 @@ var ListboxGroup = React.forwardRef(function (_a, ref) {
|
|
|
4162
4162
|
});
|
|
4163
4163
|
ListboxGroup.displayName = 'ListboxGroup';
|
|
4164
4164
|
|
|
4165
|
+
var PromptPopoverContent = function (_a) {
|
|
4166
|
+
var onClose = _a.onClose, _b = _a.applyButtonText, applyButtonText = _b === void 0 ? 'Apply' : _b, onApply = _a.onApply, _c = _a.closeButtonText, closeButtonText = _c === void 0 ? 'Close' : _c, infoText = _a.infoText, infoTextId = _a.infoTextId;
|
|
4167
|
+
return (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
4168
|
+
React__default["default"].createElement("span", { id: infoTextId }, infoText),
|
|
4169
|
+
React__default["default"].createElement(Button, { className: "Popover__apply", onClick: onApply, thin: true }, applyButtonText),
|
|
4170
|
+
React__default["default"].createElement(Button, { className: "Popover__close", variant: "secondary", onClick: onClose, thin: true }, closeButtonText)));
|
|
4171
|
+
};
|
|
4172
|
+
var Popover = React.forwardRef(function (_a, ref) {
|
|
4173
|
+
var propId = _a.id, _b = _a.placement, initialPlacement = _b === void 0 ? 'auto' : _b, children = _a.children, portal = _a.portal, target = _a.target, _c = _a.variant, variant = _c === void 0 ? 'custom' : _c, _d = _a.show, show = _d === void 0 ? false : _d, onClose = _a.onClose, className = _a.className, applyButtonText = _a.applyButtonText, closeButtonText = _a.closeButtonText, infoText = _a.infoText, onApply = _a.onApply, props = tslib.__rest(_a, ["id", "placement", "children", "portal", "target", "variant", "show", "onClose", "className", "applyButtonText", "closeButtonText", "infoText", "onApply"]);
|
|
4174
|
+
var _e = tslib.__read(propId ? [propId] : nextId.useId(1, 'popover'), 1), id = _e[0];
|
|
4175
|
+
var _f = tslib.__read(React.useState(null), 2), targetElement = _f[0], setTargetElement = _f[1];
|
|
4176
|
+
var _g = tslib.__read(React.useState(null), 2), isolator = _g[0], setIsolator = _g[1];
|
|
4177
|
+
var popoverRef = useSharedRef(ref);
|
|
4178
|
+
var _h = tslib.__read(React.useState(null), 2), arrowElement = _h[0], setArrowElement = _h[1];
|
|
4179
|
+
var _j = reactPopper.usePopper(targetElement, popoverRef === null || popoverRef === void 0 ? void 0 : popoverRef.current, {
|
|
4180
|
+
placement: initialPlacement,
|
|
4181
|
+
modifiers: [
|
|
4182
|
+
{ name: 'preventOverflow', options: { padding: 8 } },
|
|
4183
|
+
{ name: 'flip' },
|
|
4184
|
+
{ name: 'offset', options: { offset: [0, 8] } },
|
|
4185
|
+
{ name: 'arrow', options: { padding: 5, element: arrowElement } }
|
|
4186
|
+
]
|
|
4187
|
+
}), styles = _j.styles, attributes = _j.attributes;
|
|
4188
|
+
var placement = (attributes.popper &&
|
|
4189
|
+
attributes.popper['data-popper-placement']) ||
|
|
4190
|
+
initialPlacement;
|
|
4191
|
+
var additionalProps = variant === 'prompt' ? { 'aria-labelledby': "".concat(id, "-label") } : {};
|
|
4192
|
+
// Keep targetElement in sync with target prop
|
|
4193
|
+
React.useEffect(function () {
|
|
4194
|
+
var targetElement = target && 'current' in target ? target.current : target;
|
|
4195
|
+
setTargetElement(targetElement);
|
|
4196
|
+
}, [target]);
|
|
4197
|
+
React.useEffect(function () {
|
|
4198
|
+
return function () {
|
|
4199
|
+
isolator === null || isolator === void 0 ? void 0 : isolator.deactivate();
|
|
4200
|
+
};
|
|
4201
|
+
}, []);
|
|
4202
|
+
React.useEffect(function () {
|
|
4203
|
+
if (!isolator)
|
|
4204
|
+
return;
|
|
4205
|
+
if (show) {
|
|
4206
|
+
isolator.activate();
|
|
4207
|
+
}
|
|
4208
|
+
else {
|
|
4209
|
+
isolator.deactivate();
|
|
4210
|
+
}
|
|
4211
|
+
return function () {
|
|
4212
|
+
isolator === null || isolator === void 0 ? void 0 : isolator.deactivate();
|
|
4213
|
+
};
|
|
4214
|
+
}, [show, isolator]);
|
|
4215
|
+
React.useEffect(function () {
|
|
4216
|
+
if (popoverRef.current)
|
|
4217
|
+
attachIsolator();
|
|
4218
|
+
}, [popoverRef.current]);
|
|
4219
|
+
React.useEffect(function () {
|
|
4220
|
+
if (show && popoverRef.current) {
|
|
4221
|
+
// Find the first focusable element inside the container
|
|
4222
|
+
var firstFocusableElement = popoverRef.current.querySelector(focusableSelector);
|
|
4223
|
+
if (firstFocusableElement instanceof HTMLElement) {
|
|
4224
|
+
firstFocusableElement.focus();
|
|
4225
|
+
}
|
|
4226
|
+
}
|
|
4227
|
+
targetElement === null || targetElement === void 0 ? void 0 : targetElement.setAttribute('aria-expanded', Boolean(show).toString());
|
|
4228
|
+
}, [show, popoverRef.current]);
|
|
4229
|
+
React.useEffect(function () {
|
|
4230
|
+
var handleEscape = function (event) {
|
|
4231
|
+
if (event.key === 'Escape' ||
|
|
4232
|
+
event.key === 'Esc' ||
|
|
4233
|
+
event.keyCode === 27) {
|
|
4234
|
+
handleClosePopover();
|
|
4235
|
+
}
|
|
4236
|
+
};
|
|
4237
|
+
if (show) {
|
|
4238
|
+
document.body.addEventListener('keyup', handleEscape);
|
|
4239
|
+
}
|
|
4240
|
+
else {
|
|
4241
|
+
document.body.removeEventListener('keyup', handleEscape);
|
|
4242
|
+
}
|
|
4243
|
+
return function () {
|
|
4244
|
+
document.body.removeEventListener('keyup', handleEscape);
|
|
4245
|
+
};
|
|
4246
|
+
}, [show]);
|
|
4247
|
+
React.useEffect(function () {
|
|
4248
|
+
var attrText = targetElement === null || targetElement === void 0 ? void 0 : targetElement.getAttribute('aria-controls');
|
|
4249
|
+
var hasPopupAttr = targetElement === null || targetElement === void 0 ? void 0 : targetElement.getAttribute('aria-haspopup');
|
|
4250
|
+
if (!(attrText === null || attrText === void 0 ? void 0 : attrText.includes(id)) && show) {
|
|
4251
|
+
targetElement === null || targetElement === void 0 ? void 0 : targetElement.setAttribute('aria-controls', id);
|
|
4252
|
+
}
|
|
4253
|
+
if (!hasPopupAttr) {
|
|
4254
|
+
targetElement === null || targetElement === void 0 ? void 0 : targetElement.setAttribute('aria-haspopup', 'true');
|
|
4255
|
+
}
|
|
4256
|
+
}, [targetElement, id, show]);
|
|
4257
|
+
var handleClickOutside = function () {
|
|
4258
|
+
if (show) {
|
|
4259
|
+
handleClosePopover();
|
|
4260
|
+
}
|
|
4261
|
+
};
|
|
4262
|
+
var attachIsolator = function () {
|
|
4263
|
+
if (popoverRef === null || popoverRef === void 0 ? void 0 : popoverRef.current) {
|
|
4264
|
+
setIsolator(new AriaIsolate(popoverRef === null || popoverRef === void 0 ? void 0 : popoverRef.current));
|
|
4265
|
+
}
|
|
4266
|
+
};
|
|
4267
|
+
var handleClosePopover = function () {
|
|
4268
|
+
isolator === null || isolator === void 0 ? void 0 : isolator.deactivate();
|
|
4269
|
+
if (show) {
|
|
4270
|
+
onClose();
|
|
4271
|
+
}
|
|
4272
|
+
};
|
|
4273
|
+
if (!show || !isBrowser())
|
|
4274
|
+
return null;
|
|
4275
|
+
return reactDom.createPortal(React__default["default"].createElement(FocusTrap__default["default"], { focusTrapOptions: {
|
|
4276
|
+
allowOutsideClick: true,
|
|
4277
|
+
fallbackFocus: '.Popover__borderLeft'
|
|
4278
|
+
} },
|
|
4279
|
+
React__default["default"].createElement(ClickOutsideListener, { onClickOutside: handleClickOutside },
|
|
4280
|
+
React__default["default"].createElement("div", tslib.__assign({ id: id, className: classNames__default["default"]('Popover', "Popover--".concat(placement), className, {
|
|
4281
|
+
'Popover--hidden': !show,
|
|
4282
|
+
'Popover--prompt': variant === 'prompt'
|
|
4283
|
+
}), ref: popoverRef, role: "dialog", style: styles.popper }, attributes.popper, props, additionalProps),
|
|
4284
|
+
React__default["default"].createElement("div", { className: "Popover__popoverArrow", ref: setArrowElement, style: styles.arrow }),
|
|
4285
|
+
React__default["default"].createElement("div", { className: "Popover__borderLeft" }),
|
|
4286
|
+
variant === 'prompt' ? (React__default["default"].createElement(PromptPopoverContent, { applyButtonText: applyButtonText, onApply: onApply, closeButtonText: closeButtonText, infoText: infoText || '', onClose: handleClosePopover, infoTextId: "".concat(id, "-label") })) : (children)))), (portal && 'current' in portal ? portal.current : portal) || document.body);
|
|
4287
|
+
});
|
|
4288
|
+
Popover.displayName = 'Popover';
|
|
4289
|
+
|
|
4165
4290
|
var LIGHT_THEME_CLASS = 'cauldron--theme-light';
|
|
4166
4291
|
var DARK_THEME_CLASS = 'cauldron--theme-dark';
|
|
4167
4292
|
var ThemeContext = React.createContext({
|
|
@@ -4293,6 +4418,7 @@ exports.PanelContent = PanelContent;
|
|
|
4293
4418
|
exports.PanelHeader = PanelHeader;
|
|
4294
4419
|
exports.PanelTrigger = PanelTrigger$1;
|
|
4295
4420
|
exports.Pointout = Pointout;
|
|
4421
|
+
exports.Popover = Popover;
|
|
4296
4422
|
exports.ProgressBar = ProgressBar;
|
|
4297
4423
|
exports.RadioCardGroup = RadioCardGroup;
|
|
4298
4424
|
exports.RadioGroup = RadioGroup;
|
package/package.json
CHANGED