UNPKG

@helpscout/hsds-react

Version:

React component library for Help Scout's Design System

272 lines (200 loc) 9.19 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.setAriaActiveOnMenuFromItemNode = exports.resetSubMenuScrollPositionFromItemNode = exports.setMenuPositionStyles = exports.didCloseSubMenu = exports.didOpenSubMenu = exports.isOpenFromIndex = exports.itemHasSubMenu = exports.getSubMenuDOMNodeFromItemDOMNode = exports.isDOMNodeValidItem = exports.findClosestItemDOMNode = exports.findMenuDOMNodesFromItemNode = exports.findFocusedItemDOMNodes = exports.findFocusedItemDOMNode = exports.findOpenItemDOMNodes = exports.findSingleItemDOMNode = exports.findItemDOMNodes = exports.findItemDOMNodeById = exports.findItemDOMNode = exports.findTriggerNode = exports.getValueFromItemDOMNode = exports.getIdFromItemDOMNode = exports.getIndexFromItemDOMNode = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _Dropdown = require("./Dropdown.utils"); // Deprecated /* istanbul ignore file */ // TODO: // Ensure the correct envNode is passed into these functions. // At the moment, it assumes window.document, which does not work for iFrames. var getIndexFromItemDOMNode = function getIndexFromItemDOMNode(itemNode) { var index = itemNode && itemNode.getAttribute(_Dropdown.SELECTORS.indexAttribute); return index || ''; }; exports.getIndexFromItemDOMNode = getIndexFromItemDOMNode; var getIdFromItemDOMNode = function getIdFromItemDOMNode(itemNode) { var id = itemNode && itemNode.getAttribute('id'); return id || ''; }; exports.getIdFromItemDOMNode = getIdFromItemDOMNode; var getValueFromItemDOMNode = function getValueFromItemDOMNode(itemNode) { var value = itemNode && itemNode.getAttribute(_Dropdown.SELECTORS.valueAttribute); return value || ''; }; exports.getValueFromItemDOMNode = getValueFromItemDOMNode; var findTriggerNode = function findTriggerNode(envNode) { if (envNode === void 0) { envNode = document; } return envNode.querySelector("[" + _Dropdown.SELECTORS.triggerAttribute + "]"); }; exports.findTriggerNode = findTriggerNode; var findItemDOMNode = function findItemDOMNode(index, envNode) { if (envNode === void 0) { envNode = document; } return envNode.querySelector("[" + _Dropdown.SELECTORS.indexAttribute + "=\"" + index + "\"]"); }; exports.findItemDOMNode = findItemDOMNode; var findItemDOMNodeById = function findItemDOMNodeById(item, envNode) { if (envNode === void 0) { envNode = document; } return item && item.id && envNode.getElementById(item.id); }; exports.findItemDOMNodeById = findItemDOMNodeById; var findItemDOMNodes = function findItemDOMNodes(envNode) { if (envNode === void 0) { envNode = document; } return envNode.querySelectorAll("[" + _Dropdown.SELECTORS.indexAttribute + "]"); }; exports.findItemDOMNodes = findItemDOMNodes; var findSingleItemDOMNode = function findSingleItemDOMNode(envNode) { if (envNode === void 0) { envNode = document; } return envNode.querySelector("[" + _Dropdown.SELECTORS.indexAttribute + "]"); }; exports.findSingleItemDOMNode = findSingleItemDOMNode; var findOpenItemDOMNodes = function findOpenItemDOMNodes(envNode, openClassName) { if (envNode === void 0) { envNode = document; } if (openClassName === void 0) { openClassName = 'is-open'; } return envNode.querySelectorAll("[" + _Dropdown.SELECTORS.indexAttribute + "]." + openClassName); }; exports.findOpenItemDOMNodes = findOpenItemDOMNodes; var findFocusedItemDOMNode = function findFocusedItemDOMNode(envNode, focusClassName) { if (envNode === void 0) { envNode = document; } if (focusClassName === void 0) { focusClassName = 'is-focused'; } return envNode.querySelector("[" + _Dropdown.SELECTORS.indexAttribute + "]." + focusClassName); }; exports.findFocusedItemDOMNode = findFocusedItemDOMNode; var findFocusedItemDOMNodes = function findFocusedItemDOMNodes(envNode, focusClassName) { if (envNode === void 0) { envNode = document; } if (focusClassName === void 0) { focusClassName = 'is-focused'; } return envNode.querySelectorAll("[" + _Dropdown.SELECTORS.indexAttribute + "]." + focusClassName); }; exports.findFocusedItemDOMNodes = findFocusedItemDOMNodes; var findMenuDOMNodesFromItemNode = function findMenuDOMNodesFromItemNode(itemNode, envNode) { if (envNode === void 0) { envNode = document; } return itemNode && itemNode.querySelectorAll("[" + _Dropdown.SELECTORS.menuAttribute + "]"); }; exports.findMenuDOMNodesFromItemNode = findMenuDOMNodesFromItemNode; var findClosestItemDOMNode = function findClosestItemDOMNode(node) { return node && node.closest && node.closest("[" + _Dropdown.SELECTORS.indexAttribute + "]"); }; exports.findClosestItemDOMNode = findClosestItemDOMNode; var isDOMNodeValidItem = function isDOMNodeValidItem(node) { return !!getIndexFromItemDOMNode(node); }; // Enhancement: Use these functions to calculate sub-menu position on render exports.isDOMNodeValidItem = isDOMNodeValidItem; var getSubMenuDOMNodeFromItemDOMNode = function getSubMenuDOMNodeFromItemDOMNode(itemNode) { if (!itemNode) return false; return itemNode.querySelector("[" + _Dropdown.SELECTORS.menuAttribute + "]"); }; exports.getSubMenuDOMNodeFromItemDOMNode = getSubMenuDOMNodeFromItemDOMNode; var itemHasSubMenu = function itemHasSubMenu(itemNode) { if (!itemNode) return false; return !!getSubMenuDOMNodeFromItemDOMNode(itemNode); }; exports.itemHasSubMenu = itemHasSubMenu; var isOpenFromIndex = function isOpenFromIndex(path, index) { if (!path || !index) return false; return (0, _Dropdown.isPathActive)(path, index) && path !== index; }; exports.isOpenFromIndex = isOpenFromIndex; var didOpenSubMenu = function didOpenSubMenu(previousIndex, index) { if (!previousIndex || !index) return false; return previousIndex.length < index.length; }; exports.didOpenSubMenu = didOpenSubMenu; var didCloseSubMenu = function didCloseSubMenu(previousIndex, index) { if (!previousIndex || !index) return false; return previousIndex.length > index.length; }; // TODO: Recalculate on EVERY show // Going to be ignoring chunks of this from test coverage, since DOM related // calculations are difficult to mock/test within JSDOM. exports.didCloseSubMenu = didCloseSubMenu; var setMenuPositionStyles = function setMenuPositionStyles(props) { var defaultProps = { dropRight: true, dropUp: false }; var _defaultProps$props = (0, _extends2.default)({}, defaultProps, props), contentWindow = _defaultProps$props.contentWindow, dropRight = _defaultProps$props.dropRight, dropUp = _defaultProps$props.dropUp, menuNode = _defaultProps$props.menuNode, itemNode = _defaultProps$props.itemNode, wrapperNode = _defaultProps$props.wrapperNode, triggerNode = _defaultProps$props.triggerNode; if (!menuNode || !itemNode || !wrapperNode || !triggerNode) return; var translateY; // Hard-coded dimensions var menuOffset = 9; var menuBuffer = 20; var _itemNode$getBounding = itemNode.getBoundingClientRect(), top = _itemNode$getBounding.top; var _wrapperNode$getBound = wrapperNode.getBoundingClientRect(), height = _wrapperNode$getBound.height; var triggerNodeMenu = triggerNode.closest("[" + _Dropdown.SELECTORS.menuAttribute + "]"); var translateYUp = wrapperNode.clientHeight - menuOffset; translateY = triggerNode.offsetHeight + (triggerNodeMenu ? triggerNodeMenu.scrollTop : 0) + menuOffset; var predictedOffsetBottom = translateY + height + top; var predictedFlippedOffsetTop = top - translateY - height; var shouldDropUp = contentWindow.innerHeight < predictedOffsetBottom && predictedFlippedOffsetTop > 0; if (!dropRight) { wrapperNode.style.right = '100%'; wrapperNode.style.paddingLeft = '0px'; wrapperNode.style.paddingRight = menuBuffer + "px"; } else { wrapperNode.style.left = '100%'; wrapperNode.style.paddingLeft = menuBuffer + "px"; wrapperNode.style.paddingRight = '0px'; } if (dropUp) { if (shouldDropUp) { translateY = translateYUp; } } else { if (shouldDropUp) { translateY = translateYUp; } } wrapperNode.style.transform = "translateY(-" + translateY + "px)"; }; exports.setMenuPositionStyles = setMenuPositionStyles; var resetSubMenuScrollPositionFromItemNode = function resetSubMenuScrollPositionFromItemNode(itemNode) { if (!itemNode) return; var previousMenuNodes = findMenuDOMNodesFromItemNode(itemNode); if (!previousMenuNodes) return; Array.from(previousMenuNodes).forEach(function (node) { if (node.scrollTop) { node.scrollTop = 0; } }); }; exports.resetSubMenuScrollPositionFromItemNode = resetSubMenuScrollPositionFromItemNode; var setAriaActiveOnMenuFromItemNode = function setAriaActiveOnMenuFromItemNode(itemNode) { if (!itemNode) return; var menuNode = itemNode.closest("[" + _Dropdown.SELECTORS.menuAttribute + "]"); if (!menuNode) return; var id = getIdFromItemDOMNode(itemNode); menuNode.setAttribute('aria-activedescendant', id); }; exports.setAriaActiveOnMenuFromItemNode = setAriaActiveOnMenuFromItemNode;