react-lightning-design-system
Version:
Salesforce Lightning Design System components built with React
310 lines (298 loc) • 12.5 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
var _excluded = ["className", "label", "icon", "iconRight", "selected", "disabled", "divider", "tabIndex", "eventKey", "onClick", "onBlur", "onFocus", "submenu", "submenuItems", "children", "level"],
_excluded2 = ["key"],
_excluded3 = ["className", "size", "header", "nubbin", "nubbinTop", "hoverPopup", "children", "style", "alignment", "autoAlignContentRef", "elementRef", "onFocus", "onBlur", "onMenuSelect", "onMenuClose"];
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; }
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; }
import React, { createContext, useContext, useRef, useMemo, useState, useId } from 'react';
import classnames from 'classnames';
import { Icon } from './Icon';
import { AutoAlign } from './AutoAlign';
import { useEventCallback, useMergeRefs } from './hooks';
/**
*
*/
/**
*
*/
/**
*
*/
export var DropdownMenuHeader = function DropdownMenuHeader(_ref) {
var divider = _ref.divider,
className = _ref.className,
children = _ref.children;
var menuHeaderClass = classnames('slds-dropdown__header', 'slds-truncate', divider ? "slds-has-divider_".concat(divider, "-space") : undefined, className);
return /*#__PURE__*/React.createElement("li", {
className: menuHeaderClass,
role: "presentation"
}, /*#__PURE__*/React.createElement("span", null, children));
};
export var MenuHeader = DropdownMenuHeader;
/**
*
*/
export var DropdownMenuHandlerContext = /*#__PURE__*/createContext({});
export var OpenSubmenuContext = /*#__PURE__*/createContext({
openSubmenuKeys: {},
handleSubmenuOpen: function handleSubmenuOpen() {}
});
/**
*
*/
/**
*
*/
export var DropdownMenuItem = function DropdownMenuItem(props) {
var _openSubmenuKeys$subm, _openSubmenuKeys$subm2;
var className = props.className,
label = props.label,
icon = props.icon,
iconRight = props.iconRight,
selected = props.selected,
disabled = props.disabled,
divider = props.divider,
_props$tabIndex = props.tabIndex,
tabIndex = _props$tabIndex === void 0 ? 0 : _props$tabIndex,
eventKey = props.eventKey,
onClick = props.onClick,
onBlur = props.onBlur,
onFocus = props.onFocus,
submenu_ = props.submenu,
submenuItems = props.submenuItems,
children = props.children,
_props$level = props.level,
level = _props$level === void 0 ? 0 : _props$level,
rprops = _objectWithoutProperties(props, _excluded);
var _useContext = useContext(DropdownMenuHandlerContext),
onMenuSelect = _useContext.onMenuSelect,
onMenuBlur = _useContext.onMenuBlur,
onMenuFocus = _useContext.onMenuFocus;
var _useContext2 = useContext(OpenSubmenuContext),
openSubmenuKeys = _useContext2.openSubmenuKeys,
handleSubmenuOpen = _useContext2.handleSubmenuOpen;
var submenuKey = useId();
var onKeyDown = useEventCallback(function (e) {
if (e.keyCode === 13 || e.keyCode === 32) {
// return or space
e.preventDefault();
e.stopPropagation();
onMenuItemClick(e);
} else if (e.keyCode === 38 /* up */ || e.keyCode === 40 /* down */) {
e.preventDefault();
e.stopPropagation();
var currentEl = e.currentTarget.parentElement;
var itemEl = currentEl ? e.keyCode === 40 ? currentEl.nextElementSibling : currentEl.previousElementSibling : null;
while (itemEl) {
var anchorEl = itemEl.querySelector('.react-slds-menuitem[tabIndex]');
if (anchorEl && !anchorEl.ariaDisabled) {
anchorEl.focus();
return;
}
itemEl = e.keyCode === 40 ? itemEl.nextElementSibling : itemEl.previousElementSibling;
}
} else if (submenuItems && (e.keyCode === 39 /* right */ || e.keyCode === 37) /* left */) {
var _e$currentTarget$pare;
e.preventDefault();
e.stopPropagation();
var submenuEl = (_e$currentTarget$pare = e.currentTarget.parentElement) === null || _e$currentTarget$pare === void 0 ? void 0 : _e$currentTarget$pare.querySelector('.slds-dropdown__list');
if (submenuEl) {
var _anchorEl = submenuEl.querySelector('.react-slds-menuitem[tabIndex]');
if (_anchorEl) {
_anchorEl.focus();
}
}
}
});
var onMenuItemClick = useEventCallback(function (e) {
if (submenu) {
handleSubmenuOpen(submenuKey, level + 1);
return;
}
onClick === null || onClick === void 0 || onClick(e);
if (eventKey != null) {
onMenuSelect === null || onMenuSelect === void 0 || onMenuSelect(eventKey);
}
});
var onMenuItemBlur = useEventCallback(function (e) {
onBlur === null || onBlur === void 0 || onBlur(e);
onMenuBlur === null || onMenuBlur === void 0 || onMenuBlur(e);
});
var onMenuItemFocus = useEventCallback(function (e) {
onFocus === null || onFocus === void 0 || onFocus(e);
onMenuFocus === null || onMenuFocus === void 0 || onMenuFocus(e);
});
var submenu = submenu_ !== null && submenu_ !== void 0 ? submenu_ : submenuItems ? /*#__PURE__*/React.createElement(DropdownSubmenu, {
label: label
}, submenuItems === null || submenuItems === void 0 ? void 0 : submenuItems.map(function (_ref2) {
var key = _ref2.key,
itemProps = _objectWithoutProperties(_ref2, _excluded2);
return /*#__PURE__*/React.createElement(DropdownMenuItem, _extends({
key: key,
level: level + 1
}, itemProps));
})) : undefined;
var submenuExpanded = (_openSubmenuKeys$subm = (_openSubmenuKeys$subm2 = openSubmenuKeys[submenuKey]) === null || _openSubmenuKeys$subm2 === void 0 ? void 0 : _openSubmenuKeys$subm2.isOpen) !== null && _openSubmenuKeys$subm !== void 0 ? _openSubmenuKeys$subm : false;
var menuItemClass = classnames('slds-dropdown__item', {
'slds-is-selected': selected
}, submenu ? 'slds-has-submenu' : undefined, className);
return /*#__PURE__*/React.createElement(React.Fragment, null, divider === 'top' ? /*#__PURE__*/React.createElement("li", {
className: "slds-has-divider_".concat(divider, "-space"),
role: "separator"
}) : null, /*#__PURE__*/React.createElement("li", {
className: menuItemClass,
role: "presentation"
}, /*#__PURE__*/React.createElement("a", _extends({
role: "menuitem"
}, rprops, {
className: "react-slds-menuitem",
"aria-disabled": disabled,
"aria-haspopup": submenu != null,
"aria-expanded": submenuExpanded,
tabIndex: disabled ? undefined : tabIndex,
onClick: disabled ? undefined : onMenuItemClick,
onBlur: disabled ? undefined : onMenuItemBlur,
onFocus: disabled ? undefined : onMenuItemFocus,
onKeyDown: disabled ? undefined : onKeyDown
}), /*#__PURE__*/React.createElement("span", {
className: "slds-truncate",
title: typeof label === 'string' ? label : undefined
}, icon ? /*#__PURE__*/React.createElement(Icon, {
icon: icon,
size: "x-small",
align: "left"
}) : null, label || children), iconRight || submenu ? /*#__PURE__*/React.createElement(Icon, {
icon: iconRight !== null && iconRight !== void 0 ? iconRight : 'right',
size: "x-small",
align: "right"
}) : null), submenu && submenuExpanded ? submenu : undefined), divider === 'bottom' ? /*#__PURE__*/React.createElement("li", {
className: "slds-has-divider_".concat(divider, "-space"),
role: "separator"
}) : null);
};
export var MenuItem = DropdownMenuItem;
/**
*
*/
/**
*
*/
export var DropdownSubmenu = function DropdownSubmenu(props) {
var label = props.label,
_props$align = props.align,
align = _props$align === void 0 ? 'right' : _props$align,
children = props.children;
var submenuClassName = classnames('slds-dropdown', 'slds-dropdown_submenu', "slds-dropdown_submenu-".concat(align));
return /*#__PURE__*/React.createElement("div", {
className: submenuClassName
}, /*#__PURE__*/React.createElement("ul", {
className: "slds-dropdown__list",
role: "menu",
"aria-label": label
}, children));
};
/**
*
*/
/**
*
*/
var DropdownMenuInner = function DropdownMenuInner(props) {
var className = props.className,
size = props.size,
header = props.header,
nubbin_ = props.nubbin,
nubbinTop = props.nubbinTop,
hoverPopup = props.hoverPopup,
children = props.children,
style = props.style,
alignment = props.alignment,
autoAlignContentRef = props.autoAlignContentRef,
elementRef_ = props.elementRef,
onFocus = props.onFocus,
onBlur = props.onBlur,
onMenuSelect = props.onMenuSelect,
onMenuClose = props.onMenuClose,
rprops = _objectWithoutProperties(props, _excluded3);
var elRef = useRef(null);
var elementRef = useMergeRefs([elRef, autoAlignContentRef, elementRef_]);
var onKeyDown = useEventCallback(function (e) {
if (e.keyCode === 27) {
// ESC
onMenuClose === null || onMenuClose === void 0 || onMenuClose();
}
});
var nubbin = nubbinTop ? 'auto' : nubbin_;
var _alignment = _slicedToArray(alignment, 2),
vertAlign = _alignment[0],
align = _alignment[1];
var nubbinPosition = nubbin === 'auto' ? alignment.join('-') : nubbin === null || nubbin === void 0 ? void 0 : nubbin.split(' ').join('-');
var dropdownClassNames = classnames(className, 'slds-dropdown', vertAlign ? "slds-dropdown_".concat(vertAlign) : undefined, align ? "slds-dropdown_".concat(align) : undefined, size ? "slds-dropdown_".concat(size) : undefined, nubbinPosition ? "slds-nubbin_".concat(nubbinPosition) : undefined, {
'react-slds-no-hover-popup': !hoverPopup
});
var handlers = useMemo(function () {
return {
onMenuSelect: onMenuSelect,
onMenuBlur: onBlur,
onMenuFocus: onFocus
};
}, [onBlur, onFocus, onMenuSelect]);
var _useState = useState({}),
_useState2 = _slicedToArray(_useState, 2),
openSubmenuKeys = _useState2[0],
setOpenSubmenuKeys = _useState2[1];
var handleSubmenuOpen = function handleSubmenuOpen(key, level) {
setOpenSubmenuKeys(function (prevState) {
var _newState$key;
var newState = _objectSpread({}, prevState);
Object.keys(newState).forEach(function (submenuKey) {
if (newState[submenuKey].level >= level && key !== submenuKey) {
newState[submenuKey].isOpen = false;
}
});
newState[key] = {
isOpen: !((_newState$key = newState[key]) !== null && _newState$key !== void 0 && _newState$key.isOpen),
level: level
};
return newState;
});
};
return /*#__PURE__*/React.createElement("div", _extends({
className: dropdownClassNames,
ref: elementRef,
style: _objectSpread({
outline: 'none'
}, style),
onKeyDown: onKeyDown,
tabIndex: -1,
onFocus: onFocus,
onBlur: onBlur
}, rprops), /*#__PURE__*/React.createElement("ul", {
className: "slds-dropdown__list",
role: "menu",
"aria-label": header
}, header ? /*#__PURE__*/React.createElement(MenuHeader, null, header) : null, /*#__PURE__*/React.createElement(DropdownMenuHandlerContext.Provider, {
value: handlers
}, /*#__PURE__*/React.createElement(OpenSubmenuContext.Provider, {
value: {
openSubmenuKeys: openSubmenuKeys,
handleSubmenuOpen: handleSubmenuOpen
}
}, children))));
};
/**
*
*/
export var DropdownMenu = function DropdownMenu(props) {
return /*#__PURE__*/React.createElement(AutoAlign, _extends({}, props, {
preventPortalize: !!props.hoverPopup,
triggerSelector: ".slds-dropdown-trigger",
alignmentStyle: "menu"
}), function (injectedProps) {
return /*#__PURE__*/React.createElement(DropdownMenuInner, _extends({}, props, injectedProps));
});
};
//# sourceMappingURL=DropdownMenu.js.map