import React, {PureComponent, PropTypes} from 'react'; import ReactDOM from 'react-dom'; import {DragSource, DropTarget} from 'react-dnd'; import classnames from 'classnames'; import FileInputButton from '../base/FileInputButton'; import {Dropdown, DropdownItem, DropdownButton} from '../base/dropdown/index'; import PromptButton from '../base/PromptButton'; import Button from '../base/Button'; import OneLineEditor from '../codemirror/OneLineEditor'; import {preventDefault} from '../../../common/misc'; class KeyValueEditorRow extends PureComponent { _nameInput = null; _valueInput = null; state = { dragDirection: 0 }; focusName () { this._nameInput.focus(); } focusValue () { this._valueInput.focus(); } setDragDirection (dragDirection) { if (dragDirection !== this.state.dragDirection) { this.setState({dragDirection}) } } _setNameInputRef = n => this._nameInput = n; _setValueInputRef = n => this._valueInput = n; _sendChange = patch => { const pair = Object.assign({}, this.props.pair, patch); this.props.onChange && this.props.onChange(pair); }; _handleNameChange = name => this._sendChange({name}); _handleValueChange = value => this._sendChange({value}); _handleFileNameChange = filename => this._sendChange({fileName}); _handleTypeChange = type => this._sendChange({type}); _handleDisableChange = disabled => this._sendChange({disabled}); _handleFocusName = e => this.props.onFocusName(this.props.pair, e); _handleFocusValue = e => this.props.onFocusValue(this.props.pair, e); _handleDelete = () => { if (this.props.onDelete) { this.props.onDelete(this.props.pair); } }; _handleKeyDown = (e, value) => { if (this.props.onKeyDown) { this.props.onKeyDown(this.props.pair, e, value); } }; render () { const { pair, namePlaceholder, valuePlaceholder, handleRender, valueInputType, multipart, sortable, noDropZone, hideButtons, readOnly, className, isDragging, isDraggingOver, connectDragSource, connectDropTarget, } = this.props; const {dragDirection} = this.state; const classes = classnames(className, { 'key-value-editor__row-wrapper': true, 'key-value-editor__row-wrapper--dragging': isDragging, 'key-value-editor__row-wrapper--dragging-above': isDraggingOver && dragDirection > 0, 'key-value-editor__row-wrapper--dragging-below': isDraggingOver && dragDirection < 0, 'key-value-editor__row-wrapper--disabled': pair.disabled, }); const row = (
  • {sortable ? (
    ) : null }
    {pair.type === 'file' ? ( ) : ( )}
    {multipart ? ( !hideButtons ? ( Text File ) : ( ) ) : null } {!hideButtons ? ( ) : ( )} {!hideButtons ? ( ) : ( )}
  • ); if (noDropZone || !sortable) { return row; } else { return connectDragSource(connectDropTarget(row)); } } } KeyValueEditorRow.propTypes = { // Required onChange: PropTypes.func.isRequired, onDelete: PropTypes.func.isRequired, onFocusName: PropTypes.func.isRequired, onFocusValue: PropTypes.func.isRequired, index: PropTypes.number.isRequired, pair: PropTypes.shape({ name: PropTypes.string.isRequired, value: PropTypes.string, fileName: PropTypes.string, type: PropTypes.string, disabled: PropTypes.bool, }).isRequired, // Optional readOnly: PropTypes.bool, onMove: PropTypes.func, onKeyDown: PropTypes.func, handleRender: PropTypes.func, namePlaceholder: PropTypes.string, valuePlaceholder: PropTypes.string, valueInputType: PropTypes.string, multipart: PropTypes.bool, sortable: PropTypes.bool, noDropZone: PropTypes.bool, hideButtons: PropTypes.bool, // For drag-n-drop connectDragSource: PropTypes.func, connectDropTarget: PropTypes.func, isDragging: PropTypes.bool, isDraggingOver: PropTypes.bool, }; const dragSource = { beginDrag(props) { return {pair: props.pair}; } }; function isAbove (monitor, component) { const hoveredNode = ReactDOM.findDOMNode(component); const hoveredTop = hoveredNode.getBoundingClientRect().top; const draggedTop = monitor.getSourceClientOffset().y; return hoveredTop > draggedTop; } const dragTarget = { drop (props, monitor, component) { if (isAbove(monitor, component)) { props.onMove(monitor.getItem().pair, props.pair, 1); } else { props.onMove(monitor.getItem().pair, props.pair, -1); } }, hover (props, monitor, component) { if (isAbove(monitor, component)) { component.decoratedComponentInstance.setDragDirection(1); } else { component.decoratedComponentInstance.setDragDirection(-1); } } }; function sourceCollect (connect, monitor) { return { connectDragSource: connect.dragSource(), isDragging: monitor.isDragging(), }; } function targetCollect (connect, monitor) { return { connectDropTarget: connect.dropTarget(), isDraggingOver: monitor.isOver(), }; } const source = DragSource('KEY_VALUE_EDITOR', dragSource, sourceCollect)(KeyValueEditorRow); const target = DropTarget('KEY_VALUE_EDITOR', dragTarget, targetCollect)(source); target.prototype.focusName = function () { this.handler.component.decoratedComponentInstance.focusName(); }; target.prototype.focusValue = function () { this.handler.component.decoratedComponentInstance.focusValue(); }; export default target;