UNPKG

chayns-components

Version:

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

287 lines (283 loc) 8.53 kB
"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 _Input = _interopRequireDefault(require("../../react-chayns-input/component/Input")); var _getInputSize = _interopRequireDefault(require("../utils/getInputSize")); var _Tag = _interopRequireDefault(require("./Tag")); 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; } /** * @component */ const KEY_BACKSPACE = 8; const KEY_ENTER = 13; const KEY_COMMA = 188; const BIGGEST_LETTER = 'm'; /** * A text input that allows values to be grouped as tags. */ class TagInput extends _react.Component { constructor(props) { super(props); this.handleKeyDown = event => { const { onKeyDown } = this.props; if (onKeyDown) { onKeyDown(event); } if (event.keyCode === KEY_COMMA) { event.preventDefault(); } }; this.setInputRef = this.setInputRef.bind(this); this.handleKeyUp = this.handleKeyUp.bind(this); this.handleTagRemove = this.handleTagRemove.bind(this); this.handleChange = this.handleChange.bind(this); this.handleBlur = this.handleBlur.bind(this); this.handleClick = this.handleClick.bind(this); this.state = { selectedIndex: null }; } componentDidUpdate(prevProps) { const { value, triggerEventOnValueChange } = this.props; if (triggerEventOnValueChange && value !== prevProps.value) { this.handleChange(value); } } handleChange() { const { onChange } = this.props; this.setState({ selectedIndex: null }); if (onChange) { onChange(...arguments); } } handleKeyUp(event) { const { value, disableRemove } = this.props; if (event.keyCode === KEY_BACKSPACE && !value && !disableRemove) { this.handleRemoveLast(); return; } if (![KEY_ENTER, KEY_COMMA].includes(event.keyCode) || !value) { return; } const tag = { text: value }; this.handleTagAdd(tag); } handleTagAdd(tag) { const { onAddTag } = this.props; if (onAddTag) { onAddTag(tag); } } handleTagRemove(tag, ev) { const { onRemoveTag } = this.props; if (onRemoveTag) { onRemoveTag(tag, ev); } } handleRemoveLast() { const { tags } = this.props; const { selectedIndex } = this.state; const lastTagIndex = tags.length - 1; if (selectedIndex !== lastTagIndex) { this.setState({ selectedIndex: lastTagIndex }); return; } this.setState({ selectedIndex: null }); this.handleTagRemove(tags[lastTagIndex]); } handleClick() { if (this.input) { this.input.focus(); } } handleBlur() { const { value } = this.props; if (value) { const tag = { text: value }; this.handleTagAdd(tag); } } setInputRef(ref) { this.input = ref; } focus() { if (!this.input) { return false; } this.input.focus(); return true; } render() { const { tags, placeholder, value, className, style, disableRemove, design, max, addTagOnBlur, left, ...props } = this.props; const { selectedIndex } = this.state; const { width } = (0, _getInputSize.default)(`${value || tags.length > 0 ? value : placeholder}${BIGGEST_LETTER}`); const inputStyle = { width: `${width + 20}px`, minWidth: '20px' }; return /*#__PURE__*/_react.default.createElement("div", { onClick: this.handleClick, className: (0, _clsx.default)(className, 'cc__tag-input input', design === _Input.default.BORDER_DESIGN && 'cc__tag-input--border-design'), style: style }, left, tags && tags.map((tag, index) => /*#__PURE__*/_react.default.createElement(_Tag.default, { key: tag.id || index, value: tag, onDelete: this.handleTagRemove, selected: selectedIndex === index, disableRemove: disableRemove }, tag.text)), max && tags && max === (tags === null || tags === void 0 ? void 0 : tags.length) ? false : /*#__PURE__*/_react.default.createElement("div", { className: "cc__tag-input__input" }, /*#__PURE__*/_react.default.createElement(_Input.default, (0, _extends2.default)({}, props, { inputRef: this.setInputRef, value: value, onChange: this.handleChange, onKeyUp: this.handleKeyUp, onKeyDown: this.handleKeyDown, placeholder: !tags || !tags.length ? placeholder : null, style: inputStyle, onBlur: addTagOnBlur ? this.handleBlur : undefined })))); } } exports.default = TagInput; TagInput.DEFAULT_DESIGN = 0; TagInput.BORDER_DESIGN = 1; TagInput.propTypes = { /** * An array of the current tags. */ tags: _propTypes.default.arrayOf(_propTypes.default.shape({ text: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.node]) })), /** * The text value of the tag input. */ value: _propTypes.default.string, /** * A callback that is invoked when the user adds a new tag (hits the * `enter`-key). */ onAddTag: _propTypes.default.func, /** * A callback that is invoked when the user removes a tag. */ onRemoveTag: _propTypes.default.func, /** * A callback that is invoked when the user changes the text inside the tag * input. */ onChange: _propTypes.default.func, /** * A placeholder that is shown when the tag input is empty (does neither * container a tag or text). */ placeholder: _propTypes.default.string, /** * A classname string that will be applied to the outer-most wrapper of the * input. */ className: _propTypes.default.string, /** * A React style object that will be applied to the outer-most wrapper of * the input. */ style: _propTypes.default.objectOf(_propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number])), triggerEventOnValueChange: _propTypes.default.bool, /** * Prevents removal of selected users and hides remove icon. */ disableRemove: _propTypes.default.bool, /** * The design of the input. Use either `TagInput.DEFAULT_DESIGN` or * `TagInput.BORDER_DESIGN`. */ design: _propTypes.default.number, /** * The maximum number of tags selected at once. */ max: _propTypes.default.number, /** * Adds a tag on blur */ addTagOnBlur: _propTypes.default.bool, /** * A string or `ReactNode` that will be rendered on the left side of the * tag input. */ left: _propTypes.default.node, /** * A callback for the `keydown`-event. */ onKeyDown: _propTypes.default.func }; TagInput.defaultProps = { tags: null, onAddTag: null, onRemoveTag: null, placeholder: null, onChange: null, value: '', className: null, style: null, triggerEventOnValueChange: false, disableRemove: false, design: TagInput.DEFAULT_DESIGN, max: null, addTagOnBlur: false, left: null, onKeyDown: null }; TagInput.displayName = 'TagInput'; //# sourceMappingURL=TagInput.js.map