UNPKG

@helpscout/hsds-react

Version:

React component library for Help Scout's Design System

457 lines (337 loc) 15.7 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.focusWithoutScrolling = exports.renderRenderPropComponent = exports.getSelectedItemIndex = exports.isSelectedItemEmpty = exports.filterNonStoreProps = exports.getItemProps = exports.itemIsSelected = exports.itemIsOpen = exports.itemIsHover = exports.isDropRight = exports.getIndexMapFromItems = exports.getUniqueKeyFromItem = exports.filterNonFocusableItemFromItems = exports.filterDividerFromItems = exports.filterDisabledFromItems = exports.filterGroupHeaderFromItems = exports.isItemsEmpty = exports.flattenGroupedItems = exports.hasGroups = exports.itemHasSubMenu = exports.getCustomItemProps = exports.getItemFromCollection = exports.processSelectionOfItem = exports.itemIsActive = exports.decrementPathIndex = exports.incrementPathIndex = exports.getNextChildPath = exports.getParentPath = exports.isPathActive = exports.pathResolve = exports.SELECTORS = exports.DELIMETER = exports.getWindowFromNode = void 0; var _extends5 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); var _react = _interopRequireDefault(require("react")); var _Dropdown = require("./Dropdown.store"); var _component = require("../../utilities/component"); var _classnames = _interopRequireDefault(require("classnames")); var _lodash = _interopRequireDefault(require("lodash.isnil")); var _lodash2 = _interopRequireDefault(require("lodash.isstring")); var _lodash3 = _interopRequireDefault(require("lodash.isplainobject")); var _lodash4 = _interopRequireDefault(require("lodash.isfunction")); var _lodash5 = require("lodash.get"); var _node = require("../../utilities/node"); function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } var getWindowFromNode = function getWindowFromNode(node) { if (!(0, _node.isNodeElement)(node)) return window; return (0, _lodash5.get)(node, 'ownerDocument.defaultView', window); }; exports.getWindowFromNode = getWindowFromNode; var DELIMETER = '.'; exports.DELIMETER = DELIMETER; var SELECTORS = { actionAttribute: 'data-hsds-dd-menu-action', itemAttribute: 'data-hsds-dd-menu-item', menuRootAttribute: 'data-hsds-dd-menu-root', menuAttribute: 'data-hsds-dd-menu', wrapperAttribute: 'data-hsds-dd-menu-wrapper', indexAttribute: 'data-hsds-dd-menu-item-path', triggerAttribute: 'data-hsds-dd-menu-trigger', valueAttribute: 'data-hsds-dd-menu-item-value' }; /** * Path Helpers */ exports.SELECTORS = SELECTORS; var pathResolve = function pathResolve() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var path = args[0], rest = args.slice(1); var nextPath = rest.filter(function (p) { return !(0, _lodash.default)(p); }).join(DELIMETER); if ((0, _lodash.default)(path)) return "" + nextPath; if (rest.length) { return [path, nextPath].join(DELIMETER); } return "" + path; }; exports.pathResolve = pathResolve; var isPathActive = function isPathActive(path, index) { if ((0, _lodash.default)(path)) return false; if ((0, _lodash.default)(index)) return false; var matchPath = path.split(DELIMETER).slice(0, index.split(DELIMETER).length).join(DELIMETER); return matchPath === index; }; exports.isPathActive = isPathActive; var getParentPath = function getParentPath(path) { if ((0, _lodash.default)(path)) return ''; var paths = path.split(DELIMETER); if (paths.length <= 1) return "" + paths[0]; return paths.slice(0, paths.length - 1).join(DELIMETER); }; exports.getParentPath = getParentPath; var getNextChildPath = function getNextChildPath(path) { if ((0, _lodash.default)(path)) return ''; return "" + path + DELIMETER + "0"; }; exports.getNextChildPath = getNextChildPath; var incrementPathIndex = function incrementPathIndex(path, amount) { if (amount === void 0) { amount = 1; } var paths = path.split(DELIMETER); var nextIndexBase = paths.pop(); if (!nextIndexBase) return path; var nextIndex = parseInt(nextIndexBase, 10) + amount; return [].concat(paths, [nextIndex]).join(DELIMETER); }; exports.incrementPathIndex = incrementPathIndex; var decrementPathIndex = function decrementPathIndex(path, amount) { if (amount === void 0) { amount = 1; } var paths = path.split(DELIMETER); var nextIndexBase = paths.pop(); if (!nextIndexBase) return path; var nextIndex = parseInt(nextIndexBase, 10) - amount; if (nextIndex < 0) { nextIndex = 0; } return [].concat(paths, [nextIndex]).join(DELIMETER); }; /** * Item Helpers */ exports.decrementPathIndex = decrementPathIndex; var itemIsActive = function itemIsActive(selectedItem, item) { if (Array.isArray(selectedItem)) { for (var _iterator = _createForOfIteratorHelperLoose(selectedItem), _step; !(_step = _iterator()).done;) { var selItem = _step.value; if (itemIsActive(selItem, item)) return true; } return false; } if ((0, _lodash3.default)(item) && (0, _lodash3.default)(selectedItem)) { var id = selectedItem.id, value = selectedItem.value; if (!(0, _lodash.default)(value) && !(0, _lodash.default)(item.value)) { // Loose comparison, as number/string values may match return value == item.value; } if (!(0, _lodash.default)(id) && !(0, _lodash.default)(item.id)) { return id === item.id; } } if ((0, _lodash2.default)(selectedItem) && (0, _lodash3.default)(item)) { if (!(0, _lodash.default)(item.value)) { // Loose comparison, as number/string values may match return selectedItem == item.value; } if (!(0, _lodash.default)(item.id)) { return selectedItem === item.id; } } return selectedItem === item; }; exports.itemIsActive = itemIsActive; var processSelectionOfItem = function processSelectionOfItem(currentSelection, item) { var removed = false; var selection = []; for (var _iterator2 = _createForOfIteratorHelperLoose(currentSelection), _step2; !(_step2 = _iterator2()).done;) { var presentItem = _step2.value; if (itemIsActive(presentItem, item)) { removed = true; } else { selection.push(presentItem); } } return removed ? selection : selection.concat(item); }; exports.processSelectionOfItem = processSelectionOfItem; var getItemFromCollection = function getItemFromCollection(items, value) { for (var _iterator3 = _createForOfIteratorHelperLoose(items), _step3; !(_step3 = _iterator3()).done;) { var item = _step3.value; if (itemIsActive(value, item)) { return item; } if (item.items) { var child = getItemFromCollection(item.items, value); if (child) return child; } } return undefined; }; exports.getItemFromCollection = getItemFromCollection; var getCustomItemProps = function getCustomItemProps(props) { var renderItem = props.renderItem, rest = (0, _objectWithoutPropertiesLoose2.default)(props, ["renderItem"]); return rest; }; exports.getCustomItemProps = getCustomItemProps; var itemHasSubMenu = function itemHasSubMenu(itemProps) { var items = itemProps.items; return !!(items && items.length); }; exports.itemHasSubMenu = itemHasSubMenu; var hasGroups = function hasGroups(items) { return !!items.find(function (i) { return i.type === 'group'; }); }; exports.hasGroups = hasGroups; var flattenGroupedItems = function flattenGroupedItems(items) { return items.reduce(function (collection, group) { var items = group.items, groupHeader = (0, _objectWithoutPropertiesLoose2.default)(group, ["items"]); return [].concat(collection, [groupHeader], items); }, []); }; exports.flattenGroupedItems = flattenGroupedItems; var isItemsEmpty = function isItemsEmpty(items) { var collection = items; if (hasGroups(items)) { collection = flattenGroupedItems(items).filter(function (item) { return item.type !== 'group'; }); } return collection.length === 0; }; exports.isItemsEmpty = isItemsEmpty; var filterGroupHeaderFromItems = function filterGroupHeaderFromItems(item) { return !(item && item.type && item.type === 'group'); }; exports.filterGroupHeaderFromItems = filterGroupHeaderFromItems; var filterDisabledFromItems = function filterDisabledFromItems(item) { return !(item && item.disabled === true); }; exports.filterDisabledFromItems = filterDisabledFromItems; var filterDividerFromItems = function filterDividerFromItems(item) { return !(item && item.type && item.type === 'divider'); }; exports.filterDividerFromItems = filterDividerFromItems; var filterNonFocusableItemFromItems = function filterNonFocusableItemFromItems(item) { return filterDisabledFromItems(item) && filterDividerFromItems(item); }; exports.filterNonFocusableItemFromItems = filterNonFocusableItemFromItems; var getUniqueKeyFromItem = function getUniqueKeyFromItem(item) { return item && (item.id || item.value || item.label); }; exports.getUniqueKeyFromItem = getUniqueKeyFromItem; var getIndexMapFromItems = function getIndexMapFromItems(items, path) { var collection = items; if (hasGroups(items)) { collection = flattenGroupedItems(items).filter(filterGroupHeaderFromItems); } collection = collection.filter(filterNonFocusableItemFromItems); return collection.reduce(function (indexMap, item, index) { var _extends2; var itemIndex = pathResolve(path, index); var childItems = item.items ? getIndexMapFromItems(item.items, itemIndex) : {}; if (!indexMap[itemIndex]) {// TODO: validate if this place is suppose to do something //indexMap } var key = getUniqueKeyFromItem(item); return (0, _extends5.default)({}, indexMap, (_extends2 = {}, _extends2[itemIndex] = key, _extends2), childItems); }, {}); }; exports.getIndexMapFromItems = getIndexMapFromItems; var isDropRight = function isDropRight(state) { return state.direction === 'right'; }; exports.isDropRight = isDropRight; var itemIsHover = function itemIsHover(state, itemIndex) { var index = state.index; if (!index) return false; return isPathActive(index, itemIndex); }; exports.itemIsHover = itemIsHover; var itemIsOpen = function itemIsOpen(state, itemIndex) { var index = state.index; if (!index) return false; return itemIsHover(state, itemIndex) && itemIndex.length < index.length; }; exports.itemIsOpen = itemIsOpen; var itemIsSelected = function itemIsSelected(state, itemIndex) { return state.index === itemIndex; }; exports.itemIsSelected = itemIsSelected; var getItemProps = function getItemProps(state, item, index) { var _extends3; if (!state) return item; var dropUp = state.dropUp, id = state.id, enableTabNavigation = state.enableTabNavigation, indexMap = state.indexMap, selectedItem = state.selectedItem; var className = item.className, value = item.value, rest = (0, _objectWithoutPropertiesLoose2.default)(item, ["className", "value"]); var dropRight = isDropRight(state); var indexKey = getUniqueKeyFromItem(item); var itemIndex; if (indexMap) { itemIndex = Object.keys(indexMap).find(function (key) { return indexMap[key] === indexKey; }); } if (!(0, _lodash.default)(index)) { itemIndex = !(0, _lodash2.default)(index) ? index.toString() : index; } var isActive = itemIsActive(selectedItem, item); var hasSubMenu = itemHasSubMenu(item); var isSelected = itemIsSelected(state, itemIndex); var itemId = pathResolve(id, itemIndex); var key = (0, _component.getComponentKey)(item, index) || indexKey || "unsafeComponentKey-" + item.toString(); return (0, _extends5.default)({}, rest, (_extends3 = { className: (0, _classnames.default)('c-DropdownItem', hasSubMenu && 'has-subMenu', isActive && 'is-active', className), 'aria-selected': isSelected, 'aria-haspopup': hasSubMenu }, _extends3[SELECTORS.indexAttribute] = itemIndex, _extends3[SELECTORS.valueAttribute] = value, _extends3.actionId = pathResolve(itemId, 'action'), _extends3.key = key, _extends3.role = 'option', _extends3.index = itemIndex, _extends3.dropRight = dropRight, _extends3.dropUp = dropUp, _extends3.id = itemId, _extends3.isActive = isActive, _extends3.isSelected = isSelected, _extends3.hasSubMenu = hasSubMenu, _extends3.subMenuId = pathResolve(itemId, 'sub-menu'), _extends3.tabIndex = enableTabNavigation ? 0 : null, _extends3.value = value, _extends3)); }; exports.getItemProps = getItemProps; var filterNonStoreProps = function filterNonStoreProps(props) { var storeKeys = Object.keys(_Dropdown.initialState); return storeKeys.reduce(function (nextProps, key) { if (props.hasOwnProperty(key)) { var _extends4; return (0, _extends5.default)({}, nextProps, (_extends4 = {}, _extends4[key] = props[key], _extends4)); } return nextProps; }, {}); }; exports.filterNonStoreProps = filterNonStoreProps; var isSelectedItemEmpty = function isSelectedItemEmpty(selectedItem) { if (selectedItem == null) return true; if (selectedItem === '') return true; if (Array.isArray(selectedItem) && selectedItem.length === 0) return true; return false; }; exports.isSelectedItemEmpty = isSelectedItemEmpty; var getSelectedItemIndex = function getSelectedItemIndex(state) { var selectedItem = state.selectedItem, indexMap = state.indexMap; var selectedKey = getUniqueKeyFromItem(selectedItem); return Object.keys(indexMap).find(function (key) { return indexMap[key] === selectedKey; }); }; exports.getSelectedItemIndex = getSelectedItemIndex; var renderRenderPropComponent = function renderRenderPropComponent(renderProp, props) { if (props === void 0) { props = {}; } if ( /*#__PURE__*/_react.default.isValidElement(renderProp)) { return /*#__PURE__*/_react.default.cloneElement(renderProp, props); } if ((0, _lodash4.default)(renderProp)) { return renderProp(props); } return null; }; exports.renderRenderPropComponent = renderRenderPropComponent; var focusWithoutScrolling = function focusWithoutScrolling(node) { var _window = getWindowFromNode(node); // Cache the current position var scrollX = _window.scrollX, scrollY = _window.scrollY; node.focus(); // Immediately scroll to the cached position _window.scrollTo(scrollX, scrollY); }; exports.focusWithoutScrolling = focusWithoutScrolling;