chayns-components
Version:
A set of beautiful React components for developing chayns® applications.
387 lines (385 loc) • 13.1 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _clsx = _interopRequireDefault(require("clsx"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _react = _interopRequireWildcard(require("react"));
var _InputBox = _interopRequireDefault(require("../../react-chayns-input_box/component/InputBox"));
var _isServer = require("../../utils/isServer");
var _getListLength = _interopRequireDefault(require("../utils/getListLength"));
var _getSelectedListItem = _interopRequireDefault(require("../utils/getSelectedListItem"));
var _PersonFinderResults = _interopRequireDefault(require("./PersonFinderResults"));
var _WaitCursor = _interopRequireDefault(require("./WaitCursor"));
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; }
const LAZY_LOADING_SPACE = 100;
class PersonFinderView extends _react.Component {
constructor(props) {
super(props);
this.updateIndex = index => {
const {
data,
value,
orm
} = this.props;
let focusIndex = index;
if (focusIndex !== null) {
const listLength = (0, _getListLength.default)(data, orm, value);
if (focusIndex >= listLength) {
focusIndex = listLength - 1;
}
if (focusIndex < 0) {
focusIndex = 0;
}
if (this.animationFrameId) {
window.cancelAnimationFrame(this.animationFrameId);
}
this.animationFrameId = window.requestAnimationFrame(() => {
if (this.resultList) {
this.resultList.scrollTo(0, 63 * (focusIndex - 1));
}
this.animationFrameId = null;
});
}
this.setState({
focusIndex
});
};
this.handleOnBlur = () => {
const {
autoSelectFirst
} = this.props;
this.updateIndex(autoSelectFirst ? 0 : null);
};
this.handleKeyDown = ev => {
const {
focusIndex
} = this.state;
const {
onSelect,
data,
orm,
value,
onKeyDown,
autoSelectFirst
} = this.props;
if (onKeyDown) {
onKeyDown(ev);
}
if (!this.resultList) return;
switch (ev.keyCode) {
case 40:
// Arrow down
ev.preventDefault();
if (focusIndex === null) {
this.updateIndex(0);
} else {
this.updateIndex(focusIndex + 1);
}
break;
case 38:
// Arrow up
ev.preventDefault();
if (focusIndex === null) {
this.updateIndex(0);
} else {
this.updateIndex(focusIndex - 1);
}
break;
case 27:
// Esc
this.updateIndex(autoSelectFirst ? 0 : null);
this.boxRef.blur();
break;
case 13:
// Enter
if (focusIndex !== null) {
const item = (0, _getSelectedListItem.default)(data, focusIndex, orm, value);
if (item !== undefined) {
onSelect(undefined, item);
}
this.updateIndex(autoSelectFirst ? 0 : null);
if (this.resultList) {
this.resultList.scrollTo(0, 0);
}
}
break;
default:
// letters, numbers (including numpad) and space
if ((ev.keyCode === 32 || ev.keyCode >= 48 && ev.keyCode <= 106) && this.boxRef.getHiddenState()) {
this.boxRef.focus();
}
break;
}
};
this.handleLazyLoad = async () => {
if (!this.resultList) return;
const {
lazyLoading
} = this.state;
const {
value,
autoLoading,
onLoadMore,
hasMore,
data
} = this.props;
const {
scrollTop,
offsetHeight,
scrollHeight
} = this.resultList;
if (onLoadMore && autoLoading && !lazyLoading && scrollHeight - scrollTop - offsetHeight <= LAZY_LOADING_SPACE && Object.keys(hasMore).some(key => {
if (data[key].length === 0) {
return false;
}
return hasMore[key] === true;
})) {
this.setState({
lazyLoading: true
});
await onLoadMore('default', value);
this.setState({
lazyLoading: false
});
}
};
this.hasEntries = () => {
const {
data,
orm,
value,
tags,
filterSelected,
inputValue
} = this.props;
const filterValues = _ref => {
let {
type,
id
} = _ref;
return tags.every(_ref2 => {
let {
value: tagValue
} = _ref2;
return type !== tagValue.type || id !== tagValue.id;
});
};
return Array.isArray(orm.groups) ? orm.groups.some(_ref3 => {
let {
key: group,
show,
filter
} = _ref3;
if (typeof show === 'function' && !show(value)) {
return false;
}
if (!Array.isArray(data[group])) {
return false;
}
let items = data[group];
if (typeof filter === 'function') {
items = items.filter(filter(inputValue));
}
if (filterSelected) {
items = items.filter(filterValues);
}
return items.length;
}) : !!(Array.isArray(data) && data.length || Object.values(data).some(d => Array.isArray(d) && d.length));
};
this.state = {
lazyLoading: false,
focusIndex: props.autoSelectFirst ? 0 : null
};
}
renderChildren() {
const {
onSelect,
onRemoveTag,
selectedValue,
data,
tags,
orm,
value,
hasMore,
onLoadMore,
showWaitCursor: waitCursor,
noBackground,
filterSelected,
hideFriendsIcon,
renderInline,
inputValue,
showCheckbox,
hideVerifiedIcon,
minCharCount
} = this.props;
const {
focusIndex
} = this.state;
const hasEntries = this.hasEntries();
if (typeof minCharCount === 'number' && inputValue.length < minCharCount) {
return null;
}
const showResults = !selectedValue && hasEntries;
const showWaitCursor = waitCursor === true || Object.entries(waitCursor).some(_ref4 => {
var _data$k$length, _data$k;
let [k, v] = _ref4;
if (!v) {
return false;
}
// prevent show global wait cursor when handling load more for one type
return ((_data$k$length = (_data$k = data[k]) === null || _data$k === void 0 ? void 0 : _data$k.length) !== null && _data$k$length !== void 0 ? _data$k$length : 0) <= 0;
});
if (showResults || showWaitCursor) {
return [showResults && /*#__PURE__*/_react.default.createElement(_PersonFinderResults.default, {
key: "results",
onSelect: onSelect,
onRemoveTag: onRemoveTag,
data: data,
tags: tags,
orm: orm,
value: value,
onLoadMore: async type => {
if (!onLoadMore) return;
await onLoadMore(type, value);
},
showWaitCursor: waitCursor,
hasMore: hasMore,
focusIndex: focusIndex,
noBackground: noBackground,
filterSelected: filterSelected,
hideFriendsIcon: hideFriendsIcon,
showCheckbox: showCheckbox,
hideVerifiedIcon: hideVerifiedIcon
}), showWaitCursor && /*#__PURE__*/_react.default.createElement(_WaitCursor.default, {
key: "wait-cursor"
})];
}
if (!selectedValue && renderInline) {
return inputValue ? /*#__PURE__*/_react.default.createElement("div", {
className: "cc__person-finder__no-results"
}, `Für Deine Suche "${inputValue}" gab es keine Ergebnisse`) : undefined;
}
return null;
}
render() {
var _this = this;
const {
onSelect,
selectedValue,
value,
inputComponent,
boxClassName,
parent,
orm,
boxRef,
onChange,
onKeyDown,
autoSelectFirst,
...props
} = this.props;
return /*#__PURE__*/_react.default.createElement(_InputBox.default, (0, _extends2.default)({
onBlur: this.handleOnBlur,
parent: parent || ((0, _isServer.isServer)() ? null : document.querySelector('.tapp')),
key: "single",
ref: ref => {
if (boxRef) {
boxRef(ref);
}
this.boxRef = ref;
},
inputComponent: inputComponent,
onKeyDown: this.handleKeyDown,
onAddTag: data => {
if (data.text !== undefined) {
return onSelect(undefined, {
[orm.identifier]: data.text,
[orm.showName]: data.text
});
}
return null;
},
value: value,
boxClassName: (0, _clsx.default)('cc__person-finder__overlay', boxClassName),
overlayProps: {
ref: ref => {
this.resultList = ref;
},
onScroll: this.handleLazyLoad
},
onChange: function () {
onChange(...arguments);
_this.updateIndex(autoSelectFirst ? 0 : null);
}
}, props), this.renderChildren());
}
}
PersonFinderView.propTypes = {
orm: _propTypes.default.shape({
identifier: _propTypes.default.string,
showName: _propTypes.default.string,
search: _propTypes.default.arrayOf(_propTypes.default.string),
imageUrl: _propTypes.default.string,
groups: _propTypes.default.arrayOf(_propTypes.default.shape({
key: _propTypes.default.string.isRequired,
show: _propTypes.default.func
}))
}).isRequired,
data: _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.object), _propTypes.default.objectOf(_propTypes.default.arrayOf(_propTypes.default.object))]),
tags: _propTypes.default.arrayOf(_propTypes.default.shape({
value: _propTypes.default.shape({})
})),
autoLoading: _propTypes.default.bool,
hasMore: _propTypes.default.oneOfType([_propTypes.default.objectOf(_propTypes.default.bool), _propTypes.default.bool]),
onSelect: _propTypes.default.func.isRequired,
onLoadMore: _propTypes.default.func,
value: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.string]),
selectedValue: _propTypes.default.bool,
inputComponent: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.node]).isRequired,
boxClassName: _propTypes.default.string,
parent: typeof Element !== 'undefined' ? _propTypes.default.instanceOf(Element) : () => {},
boxRef: _propTypes.default.func,
showWaitCursor: _propTypes.default.oneOfType([_propTypes.default.objectOf(_propTypes.default.bool), _propTypes.default.bool]),
onChange: _propTypes.default.func,
autoSelectFirst: _propTypes.default.bool,
onKeyDown: _propTypes.default.func,
noBackground: _propTypes.default.bool,
filterSelected: _propTypes.default.bool,
hideFriendsIcon: _propTypes.default.bool,
inputValue: _propTypes.default.string,
renderInline: _propTypes.default.bool,
showCheckbox: _propTypes.default.bool,
onRemoveTag: _propTypes.default.func.isRequired,
hideVerifiedIcon: _propTypes.default.bool,
minCharCount: _propTypes.default.number
};
PersonFinderView.defaultProps = {
value: '',
data: [],
tags: [],
autoLoading: false,
hasMore: false,
onLoadMore: null,
selectedValue: false,
boxClassName: null,
parent: null,
boxRef: null,
showWaitCursor: false,
onChange: null,
autoSelectFirst: false,
onKeyDown: null,
noBackground: false,
filterSelected: false,
hideFriendsIcon: false,
inputValue: '',
renderInline: false,
showCheckbox: false,
hideVerifiedIcon: false,
minCharCount: null
};
PersonFinderView.displayName = 'PersonFinderView';
var _default = PersonFinderView;
exports.default = _default;
//# sourceMappingURL=PersonFinderView.js.map