chakra-ui
Version:
Responsive and accessible React UI components built with React and Emotion
155 lines (141 loc) • 4.43 kB
JavaScript
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
/** @jsx jsx */
import { jsx } from "@emotion/core";
import { Children, cloneElement, forwardRef, useState } from "react";
import Icon from "../Icon";
import { genId } from "../utils";
import { useMenuContext } from ".";
import { MenuGroup } from "./MenuGroup";
import { useMenuItemStyle } from "./MenuItem";
import Flex from "../Flex";
import Box from "../Box";
export var MenuItemOption = forwardRef(function (_ref, ref) {
var isDisabled = _ref.isDisabled,
children = _ref.children,
onSelect = _ref.onSelect,
type = _ref.type,
onBlur = _ref.onBlur,
onFocus = _ref.onFocus,
isChecked = _ref.isChecked,
props = _objectWithoutProperties(_ref, ["isDisabled", "children", "onSelect", "type", "onBlur", "onFocus", "isChecked"]);
var _useMenuContext = useMenuContext(),
focusableItems = _useMenuContext.focusableItems,
focusAtIndex = _useMenuContext.focusAtIndex;
var role = "menuitem".concat(type);
var onClick = function onClick(event) {
if (isDisabled) {
event.stopPropagation();
event.preventDefault();
return;
}
onSelect && onSelect();
};
var onKeyDown = function onKeyDown(event) {
if (isDisabled) return;
if (["Enter", " "].includes(event.key)) {
event.preventDefault();
onSelect && onSelect();
}
};
var onMouseEnter = function onMouseEnter(event) {
if (isDisabled) {
event.stopPropagation();
event.preventDefault();
return;
}
var nextIndex = focusableItems.current.indexOf(event.currentTarget);
focusAtIndex(nextIndex);
};
var onMouseLeave = function onMouseLeave(event) {
focusAtIndex(-1);
};
var styleProps = useMenuItemStyle();
return jsx(Flex, _extends({
ref: ref,
as: "button",
minHeight: "32px",
alignItems: "center",
onClick: onClick,
role: role,
tabIndex: -1,
"aria-checked": isChecked,
disabled: isDisabled,
"aria-disabled": isDisabled ? "" : undefined,
onMouseEnter: onMouseEnter,
onMouseLeave: onMouseLeave,
onBlur: onBlur,
onFocus: onFocus,
onKeyDown: onKeyDown
}, styleProps, props), jsx(Icon, {
name: "check",
opacity: isChecked ? 1 : 0,
color: "currentColor",
size: "1em",
ml: "1rem",
mr: "-4px",
"aria-hidden": true,
"data-menuitem-icon": ""
}), jsx(Box, {
textAlign: "left",
as: "span",
mx: "1rem",
flex: "1"
}, children));
});
MenuItemOption.displayName = "MenuItemOption";
export var MenuItemRadio = function MenuItemRadio(props) {
return jsx(MenuItemOption, _extends({
type: "radio"
}, props));
};
export var MenuItemCheckbox = function MenuItemCheckbox(props) {
return jsx(MenuItemOption, _extends({
type: "checkbox"
}, props));
};
export var MenuOptionsGroup = function MenuOptionsGroup(_ref2) {
var children = _ref2.children,
_ref2$type = _ref2.type,
type = _ref2$type === void 0 ? "radio" : _ref2$type,
title = _ref2.title,
valueProp = _ref2.value,
name = _ref2.name,
onChange = _ref2.onChange;
var _useState = useState(valueProp || ""),
_useState2 = _slicedToArray(_useState, 2),
value = _useState2[0],
setValue = _useState2[1];
var handleChange = function handleChange(_value) {
if (type === "radio") {
setValue(_value);
onChange && onChange(_value);
} else {
var newValue = value.includes(_value) ? value.filter(function (i) {
return i !== _value;
}) : [].concat(_toConsumableArray(value), [_value]);
setValue(newValue);
onChange && onChange(newValue);
}
};
return jsx(MenuGroup, {
title: title
}, Children.map(children, function (child) {
var typeProps = type === "radio" ? {
name: name || genId("radio"),
isChecked: child.props.value === value
} : {
name: child.props.name,
isChecked: value.includes(child.props.value)
};
return cloneElement(child, _extends({
type: type,
key: child.props.value,
onSelect: function onSelect() {
return handleChange(child.props.value);
}
}, typeProps));
}));
};