UNPKG

chayns-components

Version:

A set of beautiful React components for developing chayns® applications.

198 lines (195 loc) 8.96 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = void 0; var _clsx = _interopRequireDefault(require("clsx")); var _propTypes = _interopRequireDefault(require("prop-types")); var _react = _interopRequireWildcard(require("react")); var _server = require("react-dom/server"); var _reactTransitionGroup = require("react-transition-group"); var _Button = _interopRequireDefault(require("../../react-chayns-button/component/Button")); var _Icon = _interopRequireDefault(require("../../react-chayns-icon/component/Icon")); var _TappPortal = _interopRequireDefault(require("../../react-chayns-tapp_portal/component/TappPortal")); var _isDescendant = _interopRequireDefault(require("../../utils/isDescendant")); var _ComboBoxItem = _interopRequireDefault(require("./ComboBoxItem")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /* eslint-disable jsx-a11y/click-events-have-key-events,react/forbid-prop-types */ const DialogSelectComboBox = _ref => { var _getItem; let { className, label, list, disabled = false, listValue, listKey, stopPropagation = false, defaultValue, parent, onSelect, style, value = null } = _ref; const [position, setPosition] = (0, _react.useState)({ bottom: 0, left: 0, width: 0 }); const [showOverlay, setShowOverlay] = (0, _react.useState)(false); const [selected, setSelected] = (0, _react.useState)(defaultValue); const [width, setWidth] = (0, _react.useState)(null); const mounted = (0, _react.useRef)(false); const overlayRef = (0, _react.useRef)(null); const buttonRef = (0, _react.useRef)(null); const onHide = (0, _react.useCallback)(e => { if (!((0, _isDescendant.default)(overlayRef.current, e.target) || buttonRef.current === e.target)) { setShowOverlay(false); } }, []); const getItem = (0, _react.useCallback)(key => { if (key === null || key === undefined) { return list[0]; } return list.find(item => String(item[listKey]) === String(key)); }, [list, listKey]); (0, _react.useLayoutEffect)(() => { const resize = () => { let max = 0; const clonedButton = buttonRef.current.cloneNode(true); clonedButton.style.position = 'absolute'; clonedButton.style.visibility = 'hidden'; clonedButton.style.width = ''; clonedButton.style.maxWidth = ''; buttonRef.current.parentElement.insertBefore(clonedButton, buttonRef.current); max = Math.max(max, clonedButton.getBoundingClientRect().width); list.forEach(item => { clonedButton.children[0].innerHTML = /*#__PURE__*/_react.default.isValidElement(item[listValue]) ? (0, _server.renderToStaticMarkup)(item[listValue]) : item[listValue]; max = Math.max(max, clonedButton.getBoundingClientRect().width); }); buttonRef.current.parentElement.removeChild(clonedButton); setWidth(max); }; // check if font awesome is loaded and resize again // required cause calculated width might be wrong before font is loaded if (!document.fonts.check('15px "Font Awesome 6 Pro"')) { document.fonts.addEventListener('loadingdone', () => { resize(); }); } resize(); }, [list, listValue, selected, label]); (0, _react.useEffect)(() => { if (showOverlay) { window.addEventListener('click', onHide); window.addEventListener('blur', onHide); } return () => { window.removeEventListener('click', onHide); window.removeEventListener('blur', onHide); }; }, [showOverlay, onHide]); (0, _react.useEffect)(() => { if (!mounted.current) { mounted.current = true; } else { setSelected(value); } }, [value]); const select = (0, _react.useCallback)(selection => { setSelected(selection); if (onSelect && list && list.length > 0 && listKey && selection !== null && selection !== undefined) { onSelect(getItem(selection)); } }, [getItem, list, listKey, onSelect]); const onButtonClick = (0, _react.useCallback)(e => { if (stopPropagation) { e.stopPropagation(); } if (chayns.env.isMobile) { const items = list.map(item => ({ name: /*#__PURE__*/_react.default.isValidElement(item[listValue]) ? (0, _server.renderToStaticMarkup)(item[listValue]) : item[listValue], value: item[listKey], isSelected: item[listKey] === (value !== null ? value : selected) })); chayns.dialog.select({ list: items, buttons: [] }).then(result => { if (result.buttonType === 1 && result.selection && result.selection[0]) { select(result.selection[0].value); } }); } else { const parentElement = parent || document.querySelector('.tapp'); if (parentElement && ['absolute', 'relative'].includes(window.getComputedStyle(parentElement).position)) { const rect = e.target.getBoundingClientRect(); const parentRect = parentElement.getBoundingClientRect(); setPosition({ bottom: rect.bottom - parentRect.top, left: rect.left - parentRect.left, width: rect.width }); } else { setPosition(e.target.getBoundingClientRect()); } setShowOverlay(!showOverlay); } }, [setPosition, setShowOverlay, showOverlay, selected, stopPropagation, list, listKey, listValue, select, value, parent]); return [/*#__PURE__*/_react.default.createElement(_Button.default, { key: "combobox-button", secondary: true, ref: buttonRef, onClick: onButtonClick, className: (0, _clsx.default)('cc__combo-box', className, disabled && 'cc__combo-box--disabled'), style: { width, ...style } }, /*#__PURE__*/_react.default.createElement("div", { className: "cc__combo-box__label ellipsis" }, (selected === null || selected === undefined || !getItem(selected)) && value === null && label ? label : ((_getItem = getItem(value !== null ? value : selected)) !== null && _getItem !== void 0 ? _getItem : getItem(selected))[listValue]), /*#__PURE__*/_react.default.createElement(_Icon.default, { className: "cc__combo-box__icon", icon: "fa fa-chevron-down" })), /*#__PURE__*/_react.default.createElement(_TappPortal.default, { parent: parent, key: "combobox-portal" }, /*#__PURE__*/_react.default.createElement(_reactTransitionGroup.CSSTransition, { in: !!(position && showOverlay), timeout: 200, mountOnEnter: true, classNames: "fade" }, /*#__PURE__*/_react.default.createElement("div", { ref: overlayRef, className: (0, _clsx.default)('cc__combo-box__overlay scrollbar chayns__background-color--101 chayns__border-color--104', className), style: { top: position.bottom, left: position.left, width: position.width, ...style } }, list.map(item => /*#__PURE__*/_react.default.createElement(_ComboBoxItem.default, { key: item[listKey], id: item[listKey], value: item[listValue], setShowOverlay: setShowOverlay, onSelect: select })))))]; }; var _default = DialogSelectComboBox; exports.default = _default; DialogSelectComboBox.propTypes = { onSelect: _propTypes.default.func, disabled: _propTypes.default.bool, label: _propTypes.default.string, list: _propTypes.default.array.isRequired, listKey: _propTypes.default.string.isRequired, listValue: _propTypes.default.string.isRequired, className: _propTypes.default.string, defaultValue: _propTypes.default.string, stopPropagation: _propTypes.default.bool, parent: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.node]), style: _propTypes.default.object, value: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]) }; //# sourceMappingURL=DialogSelectComboBox.js.map