Skip to content

Commit

Permalink
feat: Added the Arrow key navigation in the Select fields
Browse files Browse the repository at this point in the history
  • Loading branch information
Mayur committed Nov 23, 2024
1 parent e923a24 commit 0392f86
Showing 1 changed file with 101 additions and 7 deletions.
108 changes: 101 additions & 7 deletions apps/widget/src/hooks/Phase3/SelectEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@ import { CellProperties } from 'handsontable/settings';
export class SelectEditor extends BaseEditor {
[x: string]: any;
timer: any;

focus() {
this.selectInput.focus();
}
close() {
this._opened = false;
this.selectInput.value = '';
this.listDiv.classList.remove('open');
const highlighted = this.selectUl.querySelector('li.highlighted');
if (highlighted) {
highlighted.classList.remove('highlighted');
}
}
getValue() {
return this.selectInput.value;
Expand All @@ -32,6 +37,10 @@ export class SelectEditor extends BaseEditor {
selectStyle.minWidth = `${width}px`;
selectStyle[this.hot.isRtl() ? 'right' : 'left'] = `${start}px`;
selectStyle.margin = '0px';
const firstOption = this.selectUl.querySelector('li.option');
if (firstOption) {
firstOption.classList.add('highlighted');
}
}
prepare(
row: number,
Expand All @@ -52,11 +61,12 @@ export class SelectEditor extends BaseEditor {

if (!options || !options.length) return;

let filteredOptions = options;
if (search) {
options = options.filter((key) => key.toLowerCase().includes(search.toLowerCase()));
filteredOptions = options.filter((key) => key.toLowerCase().includes(search.toLowerCase()));
}

options.forEach((key) => {
filteredOptions.forEach((key) => {
const liElement = this.hot.rootDocument.createElement('li');
liElement.classList.add('option');
liElement.dataset.value = key;
Expand All @@ -68,10 +78,17 @@ export class SelectEditor extends BaseEditor {
};
this.selectUl.appendChild(liElement);
});
const firstOption = this.selectUl.querySelector('li.option');
if (firstOption) {
firstOption.classList.add('highlighted');
}
}
search() {
const text = this.selectInput.value;
if (this.timer) {
clearTimeout(this.timer);
}

const text = this.selectInput.value;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
this.prepareOptions(this.cellProperties.selectOptions, text);
Expand All @@ -83,10 +100,35 @@ export class SelectEditor extends BaseEditor {
const input = this.hot.rootDocument.createElement('input');
input.classList.add('dd-searchbox');
input.type = 'search';
input.onkeydown = () => {
this.timer = setTimeout(() => {
this.search();
}, 200);

input.onkeydown = (e) => {
e.stopPropagation();

switch (e.key) {
case 'ArrowDown':
e.preventDefault();
this.highlightNextOption();
break;
case 'ArrowUp':
e.preventDefault();
this.highlightPreviousOption();
break;
case 'Enter':
e.preventDefault();
this.selectHighlightedOption();
break;
case 'Escape':
e.preventDefault();
this.close();
break;
default:
if (this.timer) {
clearTimeout(this.timer);
}
this.timer = setTimeout(() => {
this.search();
}, 200);
}
};

listDiv.appendChild(input);
Expand All @@ -102,4 +144,56 @@ export class SelectEditor extends BaseEditor {

this.hot.rootElement.appendChild(this.listDiv);
}

highlightNextOption() {
const options = Array.from(this.selectUl.querySelectorAll('li.option'));
if (!options.length) return;

const currentIndex = options.findIndex((option) => {
const liOption = option as HTMLLIElement;

return liOption.classList.contains('highlighted');
});

const nextIndex = currentIndex >= options.length - 1 ? 0 : currentIndex + 1;
this.updateHighlight(options, currentIndex, nextIndex);
}

highlightPreviousOption() {
const options = Array.from(this.selectUl.querySelectorAll('li.option'));
if (!options.length) return;

const currentIndex = options.findIndex((option) => {
const liOption = option as HTMLLIElement;

return liOption.classList.contains('highlighted');
});
const previousIndex = currentIndex <= 0 ? options.length - 1 : currentIndex - 1;
this.updateHighlight(options, currentIndex, previousIndex);
}

updateHighlight(options, currentIndex, newIndex) {
if (currentIndex >= 0) {
options[currentIndex].classList.remove('highlighted');
}
if (newIndex >= 0 && newIndex < options.length) {
options[newIndex].classList.add('highlighted');
options[newIndex].scrollIntoView({ block: 'nearest', behavior: 'smooth' });
}
}

selectHighlightedOption() {
const highlighted = this.selectUl.querySelector('li.highlighted');
if (highlighted) {
this.selectInput.value = highlighted.dataset.value;
this.finishEditing();
} else {
// If no option is highlighted, select the first option
const firstOption = this.selectUl.querySelector('li.option');
if (firstOption) {
this.selectInput.value = firstOption.dataset.value;
this.finishEditing();
}
}
}
}

0 comments on commit 0392f86

Please sign in to comment.