Skip to content

Commit

Permalink
#2: Add keyboard support.
Browse files Browse the repository at this point in the history
  • Loading branch information
eakoriakin committed Jul 16, 2016
1 parent 65040fb commit ccf33af
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 17 deletions.
88 changes: 79 additions & 9 deletions eqwad-combo-box.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import { EqwadComboBoxFilter } from './eqwad-combo-box-filter.pipe';
pipes: [EqwadComboBoxFilter],
template: `
<div class="eq-combo-box" #comboBoxElement
tabindex="0"
[ngClass]="{
'eq-combo-box_is-opened': _isOpened,
'eq-combo-box_is-focused': _isFocused,
'eq-combo-box_has-items': _hasItems
}"
(keydown)="_keydown($event)"
(mouseenter)="_mouseenter()"
(mouseleave)="_mouseleave()">
<div class="eq-combo-box__wrapper">
Expand All @@ -20,7 +22,8 @@ import { EqwadComboBoxFilter } from './eqwad-combo-box-filter.pipe';
[ngModel]="_text"
(ngModelChange)="_textChange($event)"
[placeholder]="placeholder"/>
<div class="eq-combo-box__open" (click)="_open()">
<div class="eq-combo-box__open"
(click)="_open()">
<i class="fa fa-caret-down"></i>
</div>
</div>
Expand All @@ -34,8 +37,12 @@ import { EqwadComboBoxFilter } from './eqwad-combo-box-filter.pipe';
(mouseenter)="_mouseenter()"
(mouseleave)="_mouseleave()">
<div class="eq-combo-box-list__item"
*ngFor="let item of (items | eqwadComboBoxFilter:itemTextField:_text)"
(click)="_select(item, $event)">
*ngFor="let item of (items | eqwadComboBoxFilter:itemTextField:_text); let i = index"
[ngClass]="{
'eq-combo-box-list__item_is-selected': _isItemSelected(i),
'eq-combo-box-list__item_is-highlighted': _isItemHighlighted(i)
}"
(click)="_select(i, $event)">
{{item[itemTextField]}}
</div>
</div>
Expand Down Expand Up @@ -64,6 +71,14 @@ export class EqwadComboBox implements OnDestroy {
private _isHovered = false;
private _documentClickListener: Function;
private _hasItems: boolean;
private _keyCode = {
down: 40,
escape: 27,
tab: 9,
up: 38
};
private _highlightedItemIndex = -1;
private _selectedItemIndex = -1;

constructor(renderer: Renderer) {
this._documentClickListener = renderer.listenGlobal('document', 'click', (event: any) => {
Expand Down Expand Up @@ -111,6 +126,7 @@ export class EqwadComboBox implements OnDestroy {
return;
}

this._highlightedItemIndex = -1;
this._isOpened = false;
this.onClose.emit(null);
}
Expand All @@ -123,12 +139,9 @@ export class EqwadComboBox implements OnDestroy {
this._isHovered = false;
}

private _select(item: Object, event: any) {
for (let i = 0; i < this.listElement.nativeElement.children.length; i++) {
this.listElement.nativeElement.children[i].className = 'eq-combo-box-list__item';
}

event.target.className = event.target.className + ' eq-combo-box-list__item_is-selected';
private _select(itemIndex: number, event: any) {
let item = this.items[itemIndex];
this._selectedItemIndex = itemIndex;
this.value = [item];
this.textElement.nativeElement.value = item[this.itemTextField];
this.onSelect.emit(item);
Expand All @@ -143,9 +156,66 @@ export class EqwadComboBox implements OnDestroy {
private _textChange(text: string) {
this._text = text;
this._checkItems();

if (!this._isOpened) {
this.open();
}
}

private _checkItems() {
this._hasItems = new EqwadComboBoxFilter().transform(this.items, this.itemTextField, this._text).length > 0;
}

private _isItemSelected(itemIndex) {
return itemIndex === this._selectedItemIndex;
}

private _isItemHighlighted(itemIndex) {
return itemIndex === this._highlightedItemIndex;
}

private _keydown(event) {
// Down key.
if (event.which === this._keyCode.down) {
if (!this._isOpened) {
this.open();
return;
}

if (this._highlightedItemIndex === -1) {
this._highlightedItemIndex = 0;
} else {
if (this._highlightedItemIndex < this.items.length - 1) {
this._highlightedItemIndex++;
}
}
}

// Up key.
if (event.which === this._keyCode.up) {
if (!this._isOpened) {
return;
}

if (this._highlightedItemIndex > 0) {
this._highlightedItemIndex--;
}
}

// Tab key.
if (event.which === this._keyCode.tab) {
if (this._highlightedItemIndex === -1) {
return;
}

this._select(this._highlightedItemIndex);
}

// Esc key.
if (event.which === this._keyCode.escape) {
if (this._isOpened) {
this._close();
}
}
}
}
13 changes: 6 additions & 7 deletions eqwad-combo-box.less
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,9 @@
right: 0;
height: 100%;
width: 30px;
border-left: 1px solid #ccc;
box-sizing: border-box;
text-align: center;

&:hover {
background-color: #e6e6e6;
cursor: pointer;
}
cursor: pointer;

.fa {
color: #333;
Expand Down Expand Up @@ -88,11 +83,15 @@
padding: 7px 10px;
cursor: pointer;

&:hover {
&:not(&_is-selected):hover {
background-color: #f5f5f5;
}

&_is-selected {
background-color: #e6e6e6;
}

&_is-highlighted:not(&_is-selected) {
background-color: #f5f5f5;
}
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.1.8",
"version": "0.2.0",
"name": "eqwad-combo-box",
"title": "Eqwad ComboBox",
"description": "Eqwad ComboBox is a customizable select box for Angular2.",
Expand Down

0 comments on commit ccf33af

Please sign in to comment.