UNPKG

suomifi-ui-components

Version:
273 lines (270 loc) 9.64 kB
import { __rest, __assign, __makeTemplateObject } from 'tslib'; import React, { useState, useRef, useEffect } from 'react'; import { styled } from 'styled-components'; import { usePopper } from 'react-popper'; import classnames from 'classnames'; import { useEnhancedEffect } from '../../../utils/common/common.js'; import { SuomifiThemeConsumer } from '../../theme/SuomifiThemeProvider/SuomifiThemeProvider.js'; import '../../theme/SuomifiTheme/SuomifiTheme.js'; import '../../theme/SpacingProvider/SpacingProvider.js'; import '../../../reset/HtmlA/HtmlA.js'; import '../../../reset/HtmlButton/HtmlButton.js'; import { HtmlDivWithRef, HtmlDiv } from '../../../reset/HtmlDiv/HtmlDiv.js'; import '../../../reset/HtmlFieldSet/HtmlFieldSet.js'; import '../../../reset/HtmlH/HtmlH.js'; import '../../../reset/HtmlInput/HtmlInput.js'; import '../../../reset/HtmlLabel/HtmlLabel.js'; import '../../../reset/HtmlLegend/HtmlLegend.js'; import '../../../reset/HtmlLi/HtmlLi.js'; import '../../../reset/HtmlNav/HtmlNav.js'; import '../../../reset/HtmlOl/HtmlOl.js'; import '../../../reset/HtmlSpan/HtmlSpan.js'; import '../../../reset/HtmlTextarea/HtmlTextarea.js'; import '../../../reset/HtmlUl/HtmlUl.js'; import '../../../reset/HtmlTable/HtmlTable.js'; import '../../../reset/HtmlTable/HtmlTableCaption.js'; import '../../../reset/HtmlTable/HtmlTableHeader.js'; import '../../../reset/HtmlTable/HtmlTableRow.js'; import '../../../reset/HtmlTable/HtmlTableBody.js'; import '../../../reset/HtmlTable/HtmlTableHeaderCell.js'; import '../../../reset/HtmlTable/HtmlTableCell.js'; import { getLogger } from '../../../utils/log/logger.js'; import { baseStyles } from './LanguageMenuPopover.baseStyles.js'; var baseClassName = 'fi-language-menu-popover'; var languageMenuPopoverClassNames = { baseClassName: baseClassName, hidden: "".concat(baseClassName, "--hidden"), list: "".concat(baseClassName, "_list"), popperArrow: "".concat(baseClassName, "_popper-arrow") }; var defaultProviderValue = { onItemClick: function onItemClick() { return null; }, onItemMouseOver: function onItemMouseOver() { return null; }, activeDescendantIndex: -1, parentId: '' }; var _a = /*#__PURE__*/React.createContext(defaultProviderValue), LanguageMenuProvider = _a.Provider, LanguageMenuConsumer = _a.Consumer; var scrollItemList = function scrollItemList(elementId, wrapperRef) { var _a, _b; var wrapperOffsetPx = 10; if (wrapperRef !== null && wrapperRef.current !== null) { var elementOffsetTop = ((_a = document.getElementById(elementId)) === null || _a === void 0 ? void 0 : _a.offsetTop) || 0; var elementOffsetHeight = ((_b = document.getElementById(elementId)) === null || _b === void 0 ? void 0 : _b.offsetHeight) || 0; if (elementOffsetTop < wrapperRef.current.scrollTop) { wrapperRef.current.scrollTop = elementOffsetTop - wrapperOffsetPx; } else { var offsetBottom = elementOffsetTop + elementOffsetHeight; var scrollBottom = wrapperRef.current.scrollTop + wrapperRef.current.offsetHeight; if (offsetBottom > scrollBottom) { wrapperRef.current.scrollTop = offsetBottom - wrapperRef.current.offsetHeight + wrapperOffsetPx; } } } }; var BaseLanguageMenuPopover = function BaseLanguageMenuPopover(props) { var _a; var _b; var openButtonRef = props.openButtonRef, onClose = props.onClose, className = props.className, children = props.children, menuId = props.menuId, parentId = props.parentId, initialActiveDescendant = props.initialActiveDescendant, isOpen = props.isOpen; var _c = useState(null), mountNode = _c[0], setMountNode = _c[1]; var _d = useState(null), dialogElement = _d[0], setDialogElement = _d[1]; var _e = useState(-1), activeChild = _e[0], setActiveChild = _e[1]; var _f = useState(false), preventScroll = _f[0], setPreventScroll = _f[1]; var menuRef = useRef(null); useEnhancedEffect(function () { setMountNode(window.document.body); }, []); useEffect(function () { if (isOpen) { document.addEventListener('keydown', globalKeyDownHandler, { capture: true }); if (!preventScroll) { scrollItemList("".concat(parentId, "-list-item-").concat(activeChild), menuRef); } return function () { document.removeEventListener('keydown', globalKeyDownHandler, { capture: true }); }; } }, [activeChild]); useEffect(function () { if (isOpen) { document.addEventListener('click', globalClickHandler, { capture: true }); return function () { document.removeEventListener('click', globalClickHandler, { capture: true }); }; } }, [isOpen]); useEffect(function () { var isMounted = true; setTimeout(function () { if (isMounted) { if (initialActiveDescendant === 'first') { setActiveChild(0); } else if (initialActiveDescendant === 'last') { setActiveChild(React.Children.count(children) - 1); } } }, 0); return function () { setActiveChild(-1); isMounted = false; }; }, [isOpen]); var globalClickHandler = function globalClickHandler(nativeEvent) { var _a, _b; if (!((_a = menuRef.current) === null || _a === void 0 ? void 0 : _a.contains(nativeEvent.target)) && !((_b = openButtonRef.current) === null || _b === void 0 ? void 0 : _b.contains(nativeEvent.target))) { handleClose(false); } }; var globalKeyDownHandler = function globalKeyDownHandler(event) { setPreventScroll(false); if (event.key === 'Escape') { handleClose(true); event.preventDefault(); } if (event.key === 'Tab') { handleClose(true); } var popoverItemsLength = React.Children.count(children); var getNextIndex = function getNextIndex() { return activeChild < popoverItemsLength - 1 ? activeChild + 1 : 0; }; var getPreviousIndex = function getPreviousIndex() { return activeChild !== 0 ? activeChild - 1 : popoverItemsLength - 1; }; if (event.key === 'ArrowDown') { event.preventDefault(); setActiveChild(getNextIndex()); } if (event.key === 'ArrowUp') { event.preventDefault(); setActiveChild(getPreviousIndex()); } }; var defaultModifiers = [{ name: 'eventListeners', enabled: isOpen }, { name: 'offset', options: { offset: [0, 15] } }, { name: 'flip', options: { fallbackPlacements: ['top-end'] } }, { name: 'preventOverflow', options: { padding: 5 } }]; var _g = usePopper(openButtonRef.current, dialogElement, { strategy: 'fixed', modifiers: defaultModifiers, placement: 'bottom-end' }), styles = _g.styles, attributes = _g.attributes; var handleClose = function handleClose(moveFocus) { onClose(moveFocus); }; if (React.Children.count(children) < 1) { getLogger().warn("LanguageMenu ".concat(menuId, " does not contain items")); return null; } var itemMouseOver = function itemMouseOver(value) { setActiveChild(value); }; if (!mountNode) { return null; } var menuItems = function menuItems(childs) { return React.Children.map(childs, function (child, index) { if ( /*#__PURE__*/React.isValidElement(child)) { return /*#__PURE__*/React.cloneElement(child, { itemIndex: index }); } return child; }); }; return /*#__PURE__*/React.createElement(HtmlDivWithRef, { className: classnames(className, baseClassName, (_a = {}, _a[languageMenuPopoverClassNames.hidden] = !isOpen, _a)), style: styles.popper, forwardedRef: setDialogElement }, /*#__PURE__*/React.createElement(LanguageMenuProvider, { value: { onItemClick: function onItemClick() { return handleClose(true); }, onItemMouseOver: function onItemMouseOver(itemIndex) { setPreventScroll(true); itemMouseOver(itemIndex); }, activeDescendantIndex: activeChild, parentId: parentId || '' } }, /*#__PURE__*/React.createElement(HtmlDivWithRef, { role: "menu", id: menuId, tabIndex: -1, className: languageMenuPopoverClassNames.list, forwardedRef: menuRef }, menuItems(children))), /*#__PURE__*/React.createElement(HtmlDiv, { className: languageMenuPopoverClassNames.popperArrow, style: styles.arrow, "data-popper-arrow": true, "data-popper-placement": (_b = attributes.popper) === null || _b === void 0 ? void 0 : _b['data-popper-placement'] })); }; var StyledLanguageMenuPopover = styled(function (_a) { _a.theme; var passProps = __rest(_a, ["theme"]); return /*#__PURE__*/React.createElement(BaseLanguageMenuPopover, __assign({}, passProps)); }).withConfig({ componentId: "sc-1xc0eyf-0" })(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n ", "\n"], ["\n ", "\n"])), function (_a) { var theme = _a.theme; return baseStyles(theme); }); var LanguageMenuPopover = function LanguageMenuPopover(props) { return /*#__PURE__*/React.createElement(SuomifiThemeConsumer, null, function (_a) { var suomifiTheme = _a.suomifiTheme; return /*#__PURE__*/React.createElement(StyledLanguageMenuPopover, __assign({ theme: suomifiTheme }, props)); }); }; LanguageMenuPopover.displayName = 'LanguageMenuPopover'; var templateObject_1; export { BaseLanguageMenuPopover, LanguageMenuConsumer, LanguageMenuPopover, LanguageMenuProvider, languageMenuPopoverClassNames }; //# sourceMappingURL=LanguageMenuPopover.js.map