@mapbox/mr-ui
Version:
UI components for Mapbox projects
132 lines (131 loc) • 6.07 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = ContextMenu;
var _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var ContextMenuPrimitive = _interopRequireWildcard(require("@radix-ui/react-context-menu"));
var _icon = _interopRequireDefault(require("../icon"));
var _classnames = _interopRequireDefault(require("classnames"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function ContextMenu(_ref) {
let {
children,
onChange,
onOpenChange,
options,
themeControlWrapper = 'bg-white round shadow-darken10 px6 py6 txt-s wmin240',
themeItem = 'px6 py6 round color-blue-on-hover bg-darken5-on-hover',
themeTitle = 'px6 py6 txt-bold',
themeSeparator = 'border-t border--gray-light my6'
} = _ref;
const renderOption = (_ref2, index) => {
let {
label,
value,
keyCode,
disabled = false,
options: subOptions
} = _ref2;
const itemClass = (0, _classnames.default)(`flex flex--space-between-main ${themeItem}`, {
'events-none opacity25': disabled
});
if (subOptions) {
return /*#__PURE__*/_react.default.createElement(ContextMenuPrimitive.Sub, {
key: index
}, /*#__PURE__*/_react.default.createElement(ContextMenuPrimitive.SubTrigger, {
disabled: disabled,
className: itemClass
}, /*#__PURE__*/_react.default.createElement("span", {
className: "w-3/4 txt-truncate"
}, label), /*#__PURE__*/_react.default.createElement(_icon.default, {
name: "chevron-right"
})), /*#__PURE__*/_react.default.createElement(ContextMenuPrimitive.Portal, null, /*#__PURE__*/_react.default.createElement(ContextMenuPrimitive.SubContent, {
className: themeControlWrapper
}, subOptions.map(renderOptions))));
}
let key = keyCode;
if (typeof keyCode === 'string') {
key = /*#__PURE__*/_react.default.createElement("span", {
className: "txt-code"
}, keyCode);
}
return /*#__PURE__*/_react.default.createElement(ContextMenuPrimitive.Item, {
disabled: disabled,
key: index,
onSelect: () => onChange(value),
className: itemClass
}, /*#__PURE__*/_react.default.createElement("span", {
className: "w-3/4 txt-truncate"
}, label), keyCode && /*#__PURE__*/_react.default.createElement("span", {
className: "w-1/4 align-r txt-truncate"
}, key));
};
const renderOptions = (_ref3, index) => {
let {
title,
options: groupOptions
} = _ref3;
return /*#__PURE__*/_react.default.createElement(_react.Fragment, {
key: index
}, index !== 0 && /*#__PURE__*/_react.default.createElement(ContextMenuPrimitive.Separator, {
className: themeSeparator
}), title && /*#__PURE__*/_react.default.createElement(ContextMenuPrimitive.Label, {
className: themeTitle
}, title), groupOptions.map(renderOption));
};
return /*#__PURE__*/_react.default.createElement(ContextMenuPrimitive.Root, {
onOpenChange: onOpenChange
}, /*#__PURE__*/_react.default.createElement(ContextMenuPrimitive.Trigger, {
asChild: true
}, children), /*#__PURE__*/_react.default.createElement(ContextMenuPrimitive.Portal, null, /*#__PURE__*/_react.default.createElement(ContextMenuPrimitive.Content, {
className: themeControlWrapper
}, options.map(renderOptions))));
}
ContextMenu.propTypes = {
/**
* The trigger element.
*/
children: _propTypes.default.node.isRequired,
/**
* An array of objects that represent each option group.
* Each object contains two fields:
* - `title` an optional property to name a group
* - `options` an array of objects that represent an item:
* - `label` which can either be a string or valid JSX
* - `value` a unique string value
* - `keyCode` An optional string if there is a keybinding associated with the option
* - `options` an array of objects that matches these object properties for a submenu
*
* Any additional fields added will be passed as attributes to the input
* element.
*/
options: _propTypes.default.arrayOf(_propTypes.default.shape({
title: _propTypes.default.string,
options: _propTypes.default.arrayOf(_propTypes.default.shape({
label: _propTypes.default.node.isRequired,
value: _propTypes.default.string.isRequired,
keyCode: _propTypes.default.node
})).isRequired
})).isRequired,
/**
* Invoked when the control's value changes.
* Passed two arguments:
*
* - The value. A string matching the `value` field of one of the `options`
*/
onChange: _propTypes.default.func.isRequired,
/** Event handler called when the open state of the context menu changes. */
onOpenChange: _propTypes.default.func,
/** Assembly classes to apply to the menu container */
themeControlWrapper: _propTypes.default.string,
/** Assembly classes to apply to menu items */
themeItem: _propTypes.default.string,
/** Assembly classes to apply to menu title items */
themeTitle: _propTypes.default.string,
/** Assembly classes to apply to menu group separator */
themeSeparator: _propTypes.default.string
};