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