UNPKG

react-lightning-design-system

Version:

Salesforce Lightning Design System components built with React

310 lines (298 loc) 12.5 kB
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