diff --git a/src/components/editable-list.jsx b/src/components/editable-list.jsx index 12145a941..7034126e8 100644 --- a/src/components/editable-list.jsx +++ b/src/components/editable-list.jsx @@ -12,6 +12,7 @@ class EditableList extends Component { PropTypes.element, ])), className: PropTypes.string, + createPlaceholder: PropTypes.string, onCreateItem: PropTypes.func, onDeleteItem: PropTypes.func, onItemEdited: PropTypes.func, @@ -22,6 +23,8 @@ class EditableList extends Component { static defaultProps = { children: [], + className: '', + createPlaceholder: '', onDeleteItem: ()=> {}, onItemEdited: ()=> {}, onItemSelected: ()=> {}, @@ -30,7 +33,6 @@ class EditableList extends Component { constructor(props) { super(props); - this._items = this.props.children; this._doubleClickedItem = false; this.state = props.initialState || { editing: null, @@ -60,9 +62,15 @@ class EditableList extends Component { if (_.includes(['Enter', 'Return'], event.key)) { this.setState({creatingItem: false}); this.props.onItemCreated(event.target.value); + } else if (event.key === 'Escape') { + this.setState({creatingItem: false}); } } + _onCreateInputBlur = ()=> { + this.setState({creatingItem: false}); + } + _onItemClick = (event, item, idx)=> { this._selectItem(item, idx); } @@ -81,14 +89,14 @@ class EditableList extends Component { } _onListKeyDown = (event)=> { - const len = this._items.size; + const len = this.props.children.size; const handle = { 'ArrowUp': (sel)=> sel === 0 ? sel : sel - 1, 'ArrowDown': (sel)=> sel === len - 1 ? sel : sel + 1, 'Escape': ()=> null, }; const selected = (handle[event.key] || ((sel)=> sel))(this.state.selected); - this._selectItem(this._items[selected], selected); + this._selectItem(this.props.children[selected], selected); } _onCreateItem = ()=> { @@ -101,7 +109,7 @@ class EditableList extends Component { _onDeleteItem = ()=> { const idx = this.state.selected; - const item = this._items[idx]; + const item = this.props.children[idx]; if (item) { this.props.onDeleteItem(item, idx); } @@ -150,19 +158,21 @@ class EditableList extends Component { ); } - _renderCreateItem = (onCreateInputKeyDown = this._onCreateInputKeyDown)=> { + _renderCreateItem = ()=> { return ( -
+
+ placeholder={this.props.createPlaceholder} + onBlur={this._onCreateInputBlur} + onKeyDown={this._onCreateInputKeyDown} />
); } render() { - let items = this._items.map((item, idx)=> this._renderItem(item, idx)); + let items = this.props.children.map((item, idx)=> this._renderItem(item, idx)); if (this.state.creatingItem === true) { items = items.concat(this._renderCreateItem()); } diff --git a/static/components/editable-list.less b/static/components/editable-list.less index 9225dc71a..c63bd11c1 100644 --- a/static/components/editable-list.less +++ b/static/components/editable-list.less @@ -7,6 +7,7 @@ flex-direction: column; border: 1px solid @border-secondary-bg; background-color: @background-secondary; + min-height: 50px; font-size: 0.9em; .editable-item { @@ -32,14 +33,19 @@ } } - .create-item { - padding: @padding-small-vertical @padding-small-horizontal; + .editable-item+.create-item-input { border-top: 1px solid @border-color-divider; + } + + .create-item-input { input { + padding: 0 @padding-small-vertical; border: none; - padding: 0; font-size: inherit; } + ::-webkit-input-placeholder { + font-style: italic; + } } }