mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-10-09 20:58:12 +08:00
fix(editable-list): Prevent empty selection on esc pressed + other fixes
- When prop specified to not allow empty selection it should also prevent it from being cleared when pressing Esc while focusing the list - Adds a default value to the edit item input - Updates specs - Updates styles
This commit is contained in:
parent
643844c998
commit
f0cc7afb54
4 changed files with 41 additions and 3 deletions
|
@ -46,6 +46,7 @@ class PreferencesAccountDetails extends Component {
|
||||||
if (!name) {
|
if (!name) {
|
||||||
name = account.name || 'No name provided';
|
name = account.name || 'No name provided';
|
||||||
}
|
}
|
||||||
|
name = name.trim();
|
||||||
// TODO Sanitize the name string
|
// TODO Sanitize the name string
|
||||||
return `${name} <${email}>`;
|
return `${name} <${email}>`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ describe('EditableList', ()=> {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not enters editing mode when item is React Element', ()=> {
|
it('does not enters editing mode when item is React Element', ()=> {
|
||||||
const item = <div key='2'></div>;
|
const item = <div key="2"></div>;
|
||||||
const list = makeList(['1', item]);
|
const list = makeList(['1', item]);
|
||||||
spyOn(list, 'setState');
|
spyOn(list, 'setState');
|
||||||
list._onItemEdit({}, item, 1);
|
list._onItemEdit({}, item, 1);
|
||||||
|
@ -78,6 +78,17 @@ describe('EditableList', ()=> {
|
||||||
|
|
||||||
expect(list.setState).not.toHaveBeenCalled();
|
expect(list.setState).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not clear selection when prop does not allow it', ()=> {
|
||||||
|
const list = makeList(['1', '2'], {allowEmptySelection: false});
|
||||||
|
const innerList = findRenderedDOMComponentWithClass(list, 'items-wrapper');
|
||||||
|
list._beganEditing = false;
|
||||||
|
spyOn(list, 'setState');
|
||||||
|
|
||||||
|
Simulate.blur(innerList);
|
||||||
|
|
||||||
|
expect(list.setState).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('_onListKeyDown', ()=> {
|
describe('_onListKeyDown', ()=> {
|
||||||
|
@ -110,6 +121,26 @@ describe('EditableList', ()=> {
|
||||||
|
|
||||||
expect(onItemSelected).not.toHaveBeenCalled();
|
expect(onItemSelected).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('clears selection when esc pressed', ()=> {
|
||||||
|
const onItemSelected = jasmine.createSpy('onItemSelected');
|
||||||
|
const list = makeList(['1', '2'], {initialState: {selected: 0}, onItemSelected});
|
||||||
|
const innerList = findRenderedDOMComponentWithClass(list, 'items-wrapper');
|
||||||
|
|
||||||
|
Simulate.keyDown(innerList, {key: 'Escape'});
|
||||||
|
|
||||||
|
expect(onItemSelected).toHaveBeenCalledWith(undefined, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not clear the selection when esc pressed but prop does not allow it', ()=> {
|
||||||
|
const onItemSelected = jasmine.createSpy('onItemSelected');
|
||||||
|
const list = makeList(['1', '2'], {initialState: {selected: 0}, allowEmptySelection: false, onItemSelected});
|
||||||
|
const innerList = findRenderedDOMComponentWithClass(list, 'items-wrapper');
|
||||||
|
|
||||||
|
Simulate.keyDown(innerList, {key: 'Escape'});
|
||||||
|
|
||||||
|
expect(onItemSelected).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('_onCreateInputKeyDown', ()=> {
|
describe('_onCreateInputKeyDown', ()=> {
|
||||||
|
|
|
@ -170,11 +170,15 @@ class EditableList extends Component {
|
||||||
// Handlers
|
// Handlers
|
||||||
|
|
||||||
_onEditInputBlur = (event, item, idx)=> {
|
_onEditInputBlur = (event, item, idx)=> {
|
||||||
|
return;
|
||||||
this._updateItem(event.target.value, item, idx);
|
this._updateItem(event.target.value, item, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onEditInputFocus = ()=> {
|
_onEditInputFocus = (event)=> {
|
||||||
|
const input = event.target;
|
||||||
this._beganEditing = false;
|
this._beganEditing = false;
|
||||||
|
// Move cursor to the end of the input
|
||||||
|
input.selectionStart = input.selectionEnd = input.value.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
_onEditInputKeyDown = (event, item, idx)=> {
|
_onEditInputKeyDown = (event, item, idx)=> {
|
||||||
|
@ -221,7 +225,7 @@ class EditableList extends Component {
|
||||||
const handle = {
|
const handle = {
|
||||||
'ArrowUp': (sel)=> Math.max(0, sel - 1),
|
'ArrowUp': (sel)=> Math.max(0, sel - 1),
|
||||||
'ArrowDown': (sel)=> sel === len - 1 ? sel : sel + 1,
|
'ArrowDown': (sel)=> sel === len - 1 ? sel : sel + 1,
|
||||||
'Escape': ()=> null,
|
'Escape': (sel)=> this.props.allowEmptySelection ? null : sel,
|
||||||
};
|
};
|
||||||
const selected = (handle[event.key] || ((sel)=> sel))(this.state.selected);
|
const selected = (handle[event.key] || ((sel)=> sel))(this.state.selected);
|
||||||
this._scrollTo(selected);
|
this._scrollTo(selected);
|
||||||
|
@ -262,6 +266,7 @@ class EditableList extends Component {
|
||||||
autoFocus
|
autoFocus
|
||||||
type="text"
|
type="text"
|
||||||
placeholder={item}
|
placeholder={item}
|
||||||
|
defaultValue={item}
|
||||||
onBlur={_.partial(onInputBlur, _, item, idx)}
|
onBlur={_.partial(onInputBlur, _, item, idx)}
|
||||||
onFocus={onInputFocus}
|
onFocus={onInputFocus}
|
||||||
onKeyDown={_.partial(onInputKeyDown, _, item, idx)} />
|
onKeyDown={_.partial(onInputKeyDown, _, item, idx)} />
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
background-color: @component-active-color;
|
background-color: @component-active-color;
|
||||||
color: @component-active-bg;
|
color: @component-active-bg;
|
||||||
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
::-webkit-input-placeholder {
|
::-webkit-input-placeholder {
|
||||||
color: @text-color-inverse-very-subtle;
|
color: @text-color-inverse-very-subtle;
|
||||||
|
|
Loading…
Add table
Reference in a new issue