@awsui/components-react
Version:
AWS UI is a collection of [React](https://reactjs.org/) components that help create intuitive, responsive, and accessible user experiences for web applications. It is developed by Amazon Web Services (AWS). This work is available under the terms of the [A
118 lines (117 loc) • 6.84 kB
JavaScript
import { __assign, __rest } from "tslib";
import { getBaseProps } from '../../base-component';
import styles from './styles.css.js';
import clsx from 'clsx';
import React, { useCallback, useEffect, useImperativeHandle, useLayoutEffect, useRef } from 'react';
import { getDropdownPosition, focusPreservingScroll, getInteriorDropdownPosition } from './dropdown-fit-handler';
import { fireNonCancelableEvent, fireCancelableEvent } from '../../events';
var getMouseTarget = function (containerRef, e) {
var element = e.target;
do {
if (element.dataset) {
var mouseTarget = element.dataset.mouseTarget;
if (mouseTarget) {
return { mouseTarget: mouseTarget };
}
}
element = element.parentNode;
} while (element && element !== containerRef.current);
return {};
};
var Dropdown = React.forwardRef(function (_a, ref) {
var _b, _c;
var children = _a.children, trigger = _a.trigger, open = _a.open, _d = _a.hideOverflow, hideOverflow = _d === void 0 ? true : _d, onDropdownClose = _a.onDropdownClose, onMouseDown = _a.onMouseDown, onMouseMove = _a.onMouseMove, header = _a.header, footer = _a.footer, _e = _a.display, display = _e === void 0 ? 'block' : _e, dropdownId = _a.dropdownId, _f = _a.nativeAttributes, nativeAttributes = _f === void 0 ? {} : _f, _g = _a.stretchWidth, stretchWidth = _g === void 0 ? true : _g, _h = _a.stretchHeight, stretchHeight = _h === void 0 ? false : _h, _j = _a.prefersDownDirection, prefersDownDirection = _j === void 0 ? false : _j, _k = _a.interior, interior = _k === void 0 ? false : _k, restProps = __rest(_a, ["children", "trigger", "open", "hideOverflow", "onDropdownClose", "onMouseDown", "onMouseMove", "header", "footer", "display", "dropdownId", "nativeAttributes", "stretchWidth", "stretchHeight", "prefersDownDirection", "interior"]);
var baseProps = getBaseProps(restProps);
var triggerRef = useRef(null);
var dropdownRef = useRef(null);
var verticalContainerRef = useRef(null);
var setDropdownPosition = function (position, target, verticalContainer, isInterior, entireWidth, entireHeight) {
if (isInterior === void 0) { isInterior = false; }
if (entireWidth === void 0) { entireWidth = false; }
if (entireHeight === void 0) { entireHeight = false; }
if (!entireHeight) {
verticalContainer.style.maxHeight = position.height;
}
if (entireWidth) {
target.classList.add(styles['occupy-entire-width']);
}
else {
target.style.width = position.width;
}
var isInteriorPosition = function (position) { return position.bottom !== undefined; };
if (isInterior && isInteriorPosition(position)) {
if (position.dropUp) {
target.style.bottom = position.bottom;
}
else {
target.style.top = position.top;
}
target.style.left = position.left;
return;
}
if (position.dropUp) {
target.classList.add(styles['dropdown-drop-up']);
}
else {
target.classList.remove(styles['dropdown-drop-up']);
}
target.classList.add(position.dropLeft ? styles['dropdown-drop-left'] : styles['dropdown-drop-right']);
};
useLayoutEffect(function () {
if (open && dropdownRef.current && triggerRef.current && verticalContainerRef.current && hideOverflow) {
verticalContainerRef.current.style.maxHeight = '';
dropdownRef.current.style.width = '';
dropdownRef.current.style.top = '';
dropdownRef.current.style.bottom = '';
dropdownRef.current.style.left = '';
dropdownRef.current.classList.remove(styles['dropdown-drop-left']);
dropdownRef.current.classList.remove(styles['dropdown-drop-right']);
dropdownRef.current.classList.remove(styles['dropdown-drop-up']);
dropdownRef.current.classList.add(styles.nowrap);
var position = interior
? getInteriorDropdownPosition(triggerRef.current, dropdownRef.current)
: getDropdownPosition(triggerRef.current, dropdownRef.current, prefersDownDirection);
setDropdownPosition(position, dropdownRef.current, verticalContainerRef.current, interior, !interior && stretchWidth, stretchHeight);
dropdownRef.current.classList.remove(styles.nowrap);
}
}, [open, hideOverflow, dropdownRef, triggerRef, verticalContainerRef, interior, stretchWidth]);
useImperativeHandle(ref, function () { return ({
focus: function () {
if (dropdownRef.current) {
focusPreservingScroll(dropdownRef.current);
}
}
}); }, []);
useEffect(function () {
var clickListener = function (e) {
if (dropdownRef.current && triggerRef.current && open) {
if (!(dropdownRef.current.contains(e.target) || triggerRef.current.contains(e.target))) {
fireNonCancelableEvent(onDropdownClose);
}
}
};
document.addEventListener('click', clickListener);
return function () { return document.removeEventListener('click', clickListener); };
}, [open, onDropdownClose]);
var handleMouseDown = useCallback(function (e) {
e.preventDefault();
fireCancelableEvent(onMouseDown, getMouseTarget(dropdownRef, e), e);
}, [onMouseDown]);
var handleMouseMove = useCallback(function (e) {
fireCancelableEvent(onMouseMove, getMouseTarget(dropdownRef, e), e);
}, [onMouseMove]);
return (React.createElement("div", __assign({}, baseProps, { className: clsx(styles.root, styles["root-" + display], stretchWidth ? styles.stretch : interior ? styles.interior : styles['root-inline'], baseProps.className), ref: ref }, nativeAttributes),
React.createElement("div", { ref: triggerRef, className: clsx(styles["trigger-" + display], (_b = {}, _b[styles['with-limited-width']] = !stretchWidth, _b)) }, trigger),
React.createElement("div", { className: clsx(styles.dropdown, (_c = {},
_c[styles['extra-margin']] = display === 'inline',
_c[styles.open] = open,
_c[styles['with-limited-width']] = !stretchWidth,
_c[styles['hide-upper-border']] = stretchWidth,
_c[styles.interior] = interior,
_c)), ref: dropdownRef, id: dropdownId, onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, "data-open": open },
React.createElement("div", { ref: verticalContainerRef, className: styles['ie11-wrapper'] },
header,
children,
footer))));
});
export default Dropdown;