@helpscout/hsds-react
Version:
React component library for Help Scout's Design System
457 lines (337 loc) • 15.7 kB
JavaScript
"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;