react-lightning-design-system
Version:
Salesforce Lightning Design System components built with React
193 lines (191 loc) • 7.53 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _extends from "@babel/runtime/helpers/extends";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
var _excluded = ["className", "opened", "defaultOpened", "menuAlign", "menuSize", "menuHeader", "nubbinTop", "hoverPopup", "menuStyle", "type", "label", "children", "style", "buttonRef", "dropdownRef", "onBlur", "onClick", "onMenuSelect"];
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, { useRef, useContext, useEffect } from 'react';
import classnames from 'classnames';
import { Button } from './Button';
import { DropdownMenu } from './DropdownMenu';
import { registerStyle, isElInChildren } from './util';
import { ComponentSettingsContext } from './ComponentSettings';
import { ButtonGroupContext } from './ButtonGroup';
import { useControlledValue, useEventCallback, useMergeRefs } from './hooks';
/**
*
*/
function useInitComponentStyle() {
useEffect(function () {
registerStyle('no-hover-popup', [['.slds-dropdown-trigger:hover .slds-dropdown_menu.react-slds-no-hover-popup', '{ visibility: hidden; opacity: 0; }'], ['.slds-dropdown-trigger.react-slds-dropdown-opened .slds-dropdown_menu', '{ visibility: visible !important; opacity: 1 !important; }']]);
}, []);
}
function isFocusedInComponent(targetEl, rootEl, dropdownEl) {
return isElInChildren(rootEl, targetEl) || isElInChildren(dropdownEl, targetEl);
}
function focusToTargetItemEl(dropdownEl) {
if (!dropdownEl) {
return;
}
var firstItemEl = dropdownEl.querySelector('.slds-is-selected > .react-slds-menuitem[tabIndex]') || dropdownEl.querySelector('.react-slds-menuitem[tabIndex]');
if (firstItemEl) {
firstItemEl.focus();
}
}
/**
*
*/
/**
*
*/
export var DropdownButton = function DropdownButton(props) {
var _useContext2;
var className = props.className,
opened_ = props.opened,
defaultOpened = props.defaultOpened,
menuAlign = props.menuAlign,
menuSize = props.menuSize,
menuHeader = props.menuHeader,
nubbinTop = props.nubbinTop,
hoverPopup = props.hoverPopup,
menuStyle = props.menuStyle,
type = props.type,
label = props.label,
children = props.children,
style = props.style,
buttonRef_ = props.buttonRef,
dropdownRef_ = props.dropdownRef,
onBlur_ = props.onBlur,
onClick_ = props.onClick,
onMenuSelect_ = props.onMenuSelect,
rprops = _objectWithoutProperties(props, _excluded);
useInitComponentStyle();
var _useContext = useContext(ComponentSettingsContext),
getActiveElement = _useContext.getActiveElement;
var _ref = (_useContext2 = useContext(ButtonGroupContext)) !== null && _useContext2 !== void 0 ? _useContext2 : {},
grouped = _ref.grouped,
isFirstInGroup = _ref.isFirstInGroup,
isLastInGroup = _ref.isLastInGroup;
var elRef = useRef(null);
var buttonElRef = useRef(null);
var buttonRef = useMergeRefs([buttonElRef, buttonRef_]);
var dropdownElRef = useRef(null);
var dropdownRef = useMergeRefs([dropdownElRef, dropdownRef_]);
var _useControlledValue = useControlledValue(opened_, defaultOpened || false),
_useControlledValue2 = _slicedToArray(_useControlledValue, 2),
opened = _useControlledValue2[0],
setOpened = _useControlledValue2[1];
var onBlur = useEventCallback(function () {
setTimeout(function () {
var targetEl = getActiveElement();
if (!isFocusedInComponent(targetEl, elRef.current, dropdownElRef.current)) {
setOpened(false);
onBlur_ === null || onBlur_ === void 0 || onBlur_();
}
}, 10);
});
var onKeyDown = useEventCallback(function (e) {
if (e.keyCode === 40) {
// down
e.preventDefault();
e.stopPropagation();
if (!opened) {
setOpened(true);
onClick_ === null || onClick_ === void 0 || onClick_(e);
setTimeout(function () {
focusToTargetItemEl(dropdownElRef.current);
}, 20);
} else {
focusToTargetItemEl(dropdownElRef.current);
}
} else if (e.keyCode === 27) {
// ESC
e.preventDefault();
e.stopPropagation();
setOpened(false);
}
});
var onTriggerClick = useEventCallback(function (e) {
if (!hoverPopup) {
setOpened(function (opened) {
return !opened;
});
}
onClick_ === null || onClick_ === void 0 || onClick_(e);
});
var onMenuSelect = useEventCallback(function (eventKey) {
if (!hoverPopup) {
setTimeout(function () {
var _buttonElRef$current;
(_buttonElRef$current = buttonElRef.current) === null || _buttonElRef$current === void 0 || _buttonElRef$current.focus();
setOpened(false);
}, 10);
}
onMenuSelect_ === null || onMenuSelect_ === void 0 || onMenuSelect_(eventKey);
});
var onMenuClose = useEventCallback(function () {
var _buttonElRef$current2;
(_buttonElRef$current2 = buttonElRef.current) === null || _buttonElRef$current2 === void 0 || _buttonElRef$current2.focus();
setOpened(false);
});
var icon = props.icon;
var iconMore = undefined;
if (!label && !icon) {
icon = 'down';
}
if (label || type === 'icon-more') {
iconMore = 'down';
}
var button = /*#__PURE__*/React.createElement(Button, _extends({
type: type,
label: label,
icon: icon,
iconMore: iconMore
}, rprops, {
"aria-haspopup": true,
"aria-expanded": opened,
buttonRef: buttonRef,
onClick: onTriggerClick,
onKeyDown: onKeyDown,
onBlur: onBlur
}));
var dropdownClassNames = classnames(className, 'slds-dropdown-trigger', 'slds-dropdown-trigger_click', {
'slds-m-left_xx-small': !grouped,
'slds-is-open': opened,
'react-slds-dropdown-opened': opened
});
var noneStyle = {
display: 'none'
};
return /*#__PURE__*/React.createElement("div", {
className: dropdownClassNames,
style: style,
ref: elRef
}, grouped ? /*#__PURE__*/React.createElement("div", {
className: "slds-button-group"
}, isFirstInGroup ? null : /*#__PURE__*/React.createElement("button", {
type: "button",
className: "slds-button",
style: noneStyle
}), button, isLastInGroup ? null : /*#__PURE__*/React.createElement("button", {
type: "button",
className: "slds-button",
style: noneStyle
})) : button, hoverPopup || opened ? /*#__PURE__*/React.createElement(DropdownMenu, {
portalClassName: className,
align: menuAlign,
header: menuHeader,
size: menuSize,
nubbinTop: nubbinTop,
hoverPopup: hoverPopup,
elementRef: dropdownRef,
onMenuSelect: onMenuSelect,
onMenuClose: onMenuClose,
onBlur: onBlur,
style: _objectSpread({
transition: 'none'
}, menuStyle)
}, children) : undefined);
};
//# sourceMappingURL=DropdownButton.js.map