UNPKG

grommet

Version:

focus on the essential experience

171 lines (169 loc) 8.71 kB
"use strict"; exports.__esModule = true; exports.SelectMultipleValue = void 0; var _react = _interopRequireWildcard(require("react")); var _Box = require("../Box"); var _Button = require("../Button"); var _CheckBox = require("../CheckBox"); var _StyledSelect = require("../Select/StyledSelect"); var _utils = require("../Select/utils"); var _MessageContext = require("../../contexts/MessageContext"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } var SelectMultipleValue = exports.SelectMultipleValue = function SelectMultipleValue(_ref) { var _theme$selectMultiple2, _theme$selectMultiple3; var allOptions = _ref.allOptions, children = _ref.children, disabled = _ref.disabled, disabledKey = _ref.disabledKey, dropButtonRef = _ref.dropButtonRef, labelKey = _ref.labelKey, messages = _ref.messages, onRequestOpen = _ref.onRequestOpen, onSelectChange = _ref.onSelectChange, theme = _ref.theme, value = _ref.value, valueKey = _ref.valueKey; var _useState = (0, _react.useState)(false), showA11yDiv = _useState[0], setShowA11yDiv = _useState[1]; var _useContext = (0, _react.useContext)(_MessageContext.MessageContext), format = _useContext.format; var isDisabled = (0, _utils.useDisabled)(disabled, disabledKey, allOptions, valueKey || labelKey); var visibleValue = (0, _react.useCallback)(function (i) { var optionValue = valueKey && valueKey.reduce ? (0, _utils.applyKey)(i, valueKey) : i; var optionSelected = (0, _utils.arrayIncludes)(value, optionValue, valueKey || labelKey); var indexOptions = (0, _utils.getOptionIndex)(allOptions, i, valueKey || labelKey); var optionLabel = (0, _utils.getOptionLabel)(indexOptions, allOptions, labelKey || valueKey); var optionDisabled = isDisabled(indexOptions); var valueIndex = (0, _utils.getOptionIndex)(value, optionValue, valueKey || labelKey); if (valueIndex < theme.selectMultiple.maxInline) { var _theme$selectMultiple; var child; if (children) { child = children(i, indexOptions, allOptions, { active: false, disabled: optionDisabled, selected: true }); } return /*#__PURE__*/_react["default"].createElement(_StyledSelect.SelectOption, { role: "option", a11yTitle: format({ id: optionSelected ? 'selectMultiple.optionSelected' : 'selectMultiple.optionNotSelected', messages: messages, values: { optionLabel: optionLabel } }), "aria-setsize": value.length, "aria-posinset": valueIndex + 1, "aria-selected": optionSelected, "aria-disabled": optionDisabled, plain: true, hoverIndicator: !optionDisabled, fill: "horizontal", tabIndex: "0", onClick: function onClick(event) { if (!optionDisabled) { var intermediate = [].concat(value); if ((0, _utils.arrayIncludes)(intermediate, optionValue, valueKey || labelKey)) { onSelectChange(event, { option: optionValue, value: intermediate.filter(function (v) { return typeof v === 'object' ? (0, _utils.applyKey)(v, valueKey || labelKey) !== (0, _utils.applyKey)(optionValue, valueKey || labelKey) : v !== optionValue; }) }); if (valueIndex !== intermediate.length - 1) { setTimeout(function () { var nextFocus = document.getElementById("selected-" + intermediate[valueIndex + 1]); if (nextFocus) nextFocus.focus(); var result = intermediate[valueIndex + 1]; setShowA11yDiv("Unselected " + optionLabel + ". \n Focus moved to " + (0, _utils.getOptionLabel)((0, _utils.getOptionIndex)(allOptions, result, valueKey || labelKey), allOptions, labelKey || valueKey)); }, 200); // Timeout needed to allow screen reader // time to announce and next item to display on // screen. Based on testing, 200ms is enough time } else if (intermediate.length !== 1) { setTimeout(function () { var nextFocus = document.getElementById("selected-" + intermediate[valueIndex - 1]); if (nextFocus) nextFocus.focus(); var result = intermediate[valueIndex - 1]; setShowA11yDiv("Unselected " + optionLabel + ". Focus moved to \n " + (0, _utils.getOptionLabel)((0, _utils.getOptionIndex)(allOptions, result, valueKey || labelKey), allOptions, labelKey || valueKey)); }, 200); // Timeout needed to allow screen reader // time to announce and next item to display on // screen. Based on testing, 200ms is enough time } else if (dropButtonRef.current) dropButtonRef.current.focus(); } } }, key: optionLabel, id: "selected-" + optionValue }, child || /*#__PURE__*/_react["default"].createElement(_CheckBox.CheckBox, { disabled: optionDisabled, label: /*#__PURE__*/_react["default"].createElement(_Box.Box, { alignSelf: "center", align: "start" }, optionLabel), key: optionLabel, pad: (_theme$selectMultiple = theme.selectMultiple) == null || (_theme$selectMultiple = _theme$selectMultiple.option) == null ? void 0 : _theme$selectMultiple.pad, tabIndex: "-1", checked: optionSelected, inert: _utils.inertTrueValue, containerProps: { // in Firefox when we have inert set, the checkbox // click event gets swallowed by the checkbox. // We need the click event to go the the button // around the checkbox so we use pointerEvents = // none. For code clarity we decided an inline // style made sense here. style: { pointerEvents: 'none' } } })); } return undefined; }, [allOptions, children, dropButtonRef, format, isDisabled, labelKey, messages, onSelectChange, theme.selectMultiple.maxInline, (_theme$selectMultiple2 = theme.selectMultiple) == null || (_theme$selectMultiple2 = _theme$selectMultiple2.option) == null ? void 0 : _theme$selectMultiple2.pad, value, valueKey]); // After announcing set showA11yDiv to undefined so it won't // be read out again (0, _react.useEffect)(function () { if (showA11yDiv !== undefined) { setTimeout(function () { setShowA11yDiv(undefined); }, 1000); } }, [showA11yDiv]); return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(_Box.Box, { width: "100%", role: "listbox", "aria-multiselectable": true, a11yTitle: format({ id: 'selectMultiple.selectedOptions', messages: messages }) }, value && allOptions.filter(function (i) { return (0, _utils.arrayIncludes)(value, valueKey && valueKey.reduce ? (0, _utils.applyKey)(i, valueKey) : i, valueKey || labelKey); }).map(function (i) { return visibleValue(i); }), showA11yDiv && /*#__PURE__*/_react["default"].createElement(_Box.Box, { height: "0px", width: "0px", overflow: "hidden" // announce when an item is removed from selected options , "aria-live": "assertive", role: "alert" }, showA11yDiv)), value && value.length > theme.selectMultiple.maxInline && /*#__PURE__*/_react["default"].createElement(_Box.Box, { pad: (_theme$selectMultiple3 = theme.selectMultiple) == null || (_theme$selectMultiple3 = _theme$selectMultiple3.showMore) == null ? void 0 : _theme$selectMultiple3.pad, alignSelf: "start" }, /*#__PURE__*/_react["default"].createElement(_Button.Button, { onClick: onRequestOpen, size: "small", label: format({ id: 'selectMultiple.showMore', messages: messages, values: { remaining: value.length - theme.selectMultiple.maxInline } }) }))); };