UNPKG

@guardian/threads

Version:
177 lines 7.8 kB
import { __assign, __extends } from "tslib"; import React, { Component, createRef } from 'react'; import _range from 'lodash.range'; import { QueryElementHelpers, } from '../StructuredQuery'; import { ChipWrapper } from './Chip/ChipWrapper'; import { InlineInput } from './InlineInput'; import styles from './InputSupper.module.css'; var InputSupper = /** @class */ (function (_super) { __extends(InputSupper, _super); function InputSupper() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.deleteExpiryInterval = undefined; _this.elementRefs = []; _this.state = {}; _this.focusElement = function (index, focusEnd) { if (index >= 0 && index < _this.elementRefs.length) { var current = _this.elementRefs[index].current; if (current) { current.focus(focusEnd); } } }; _this.focusElementAt = function (index, offset) { if (index >= 0 && index < _this.elementRefs.length) { var current = _this.elementRefs[index].current; if (current) { current.focusAt(offset); } } }; _this.selectElement = function (index) { if (index >= 0 && index < _this.elementRefs.length) { var current = _this.elementRefs[index].current; if (current) { current.select(); } } }; _this.inputUpdated = function (index, value, label) { _this.props.onChange(QueryElementHelpers.updateElementValue(_this.props.elements, index, value, label)); }; _this.spawnChip = function (index, chipPosition, filter) { var elements = _this.props.elements; var sourceElement = elements[index]; // Should ONLY spawn a chip inside a text element if (sourceElement.type == 'text') { var value = sourceElement.value; var startIndex = chipPosition.startIndex, cursorIndex = chipPosition.cursorIndex; var elementsToInsert = [ QueryElementHelpers.textElementFromValue(value.substring(0, startIndex).trim()), QueryElementHelpers.filterElementFromFilter(filter, value[startIndex] === '-'), QueryElementHelpers.textElementFromValue(value.substring(cursorIndex, value.length).trim()), ]; _this.props.onChange(QueryElementHelpers.replaceElement(elements, index, elementsToInsert)); _this.setState({ focusElementIndex: index + 1, }); } }; _this.onNegateClicked = function (index) { var elements = _this.props.elements; var target = _this.props.elements[index]; if (QueryElementHelpers.isFilter(target)) { var newElement = __assign(__assign({}, target), { negate: !target.negate }); _this.props.onChange(QueryElementHelpers.replaceElement(elements, index, [newElement])); } }; _this.onDeleteClicked = function (index) { var elements = _this.props.elements; var left = elements[index - 1]; var right = elements[index + 1]; if (QueryElementHelpers.isText(left) && QueryElementHelpers.isText(right)) { var mergedText = { type: 'text', value: left.value.trim() + ' ' + right.value.trim(), }; _this.props.onChange(QueryElementHelpers.replaceElements(elements, index - 1, index + 2, [ mergedText, ])); _this.setState({ focusElementIndex: index - 1, }); } }; _this.deleteChip = function (index) { if (index < 0 || index > _this.props.elements.length - 1) { return; } if (_this.state.deleteStagedIndex === index) { // Confirm deleting chip _this.onDeleteClicked(index); _this.setState({ deleteStagedIndex: undefined, }); } else { // Stage the chip for deletion _this.setState({ deleteStagedIndex: index, deleteExpiry: 2, }); _this.deleteExpiryInterval = setInterval(_this.deleteExpiryTick, 1000); } }; _this.deleteExpiryTick = function () { var deleteExpiry = _this.state.deleteExpiry; if (_this.deleteExpiryInterval && deleteExpiry && deleteExpiry > 0) { var countdown = deleteExpiry - 1; if (countdown <= 0) { clearInterval(_this.deleteExpiryInterval); _this.setState({ deleteStagedIndex: undefined, deleteExpiry: undefined, }); } else { _this.setState({ deleteExpiry: countdown, }); } } }; _this.renderElement = function (e, index) { var sharedProps = { ref: _this.elementRefs[index], key: index, index: index, value: e.value, onUpdate: _this.inputUpdated, focusElement: _this.focusElement, deleteChip: _this.deleteChip, }; if (QueryElementHelpers.isFilter(e)) { return (React.createElement(ChipWrapper, __assign({}, sharedProps, { negate: e.negate, filter: e.filter, label: e.label, stagedForDeletion: _this.state.deleteStagedIndex === index, onDeleteClicked: _this.onDeleteClicked, onNegateClicked: _this.onNegateClicked }))); } else { return (React.createElement(InlineInput, __assign({}, sharedProps, { availableFilters: _this.props.availableFilters, spawnChip: _this.spawnChip, isLastInput: index === _this.props.elements.length - 1 }))); } }; return _this; } InputSupper.prototype.componentDidMount = function () { if (this.props.elements.length === 0) { this.props.onChange([ { type: 'text', value: '', }, ]); } }; InputSupper.prototype.componentDidUpdate = function (prevProps) { var focusElementIndex = this.state.focusElementIndex; if (focusElementIndex !== undefined) { if (prevProps.elements > this.props.elements) { // We've deleted a chip so we need to focus at the correct offset var offset = prevProps.elements[focusElementIndex].value.length; this.focusElementAt(focusElementIndex, offset); } else { this.focusElement(focusElementIndex, false); } this.setState({ focusElementIndex: undefined, }); } }; InputSupper.prototype.render = function () { var _this = this; var elements = this.props.elements; this.elementRefs = _range(elements.length).map(function () { return createRef(); }); return (React.createElement("div", { className: styles.root }, elements.map(function (e, index) { return _this.renderElement(e, index); }))); }; return InputSupper; }(Component)); export { InputSupper }; //# sourceMappingURL=InputSupper.js.map