chayns-components
Version:
A set of beautiful React components for developing chayns® applications.
198 lines (195 loc) • 8.96 kB
JavaScript
"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