igniteui-webcomponents
Version:
Ignite UI for Web Components is a complete library of UI components, giving you the ability to build modern web applications using encapsulation and the concept of reusable components in a dependency-free approach.
176 lines • 5.54 kB
JavaScript
import { addKeybindings, altKey, arrowDown, arrowUp, endKey, enterKey, escapeKey, homeKey, shiftKey, spaceBar, tabKey, } from '../../common/controllers/key-bindings.js';
export class ComboNavigationController {
get active() {
return this._active;
}
set active(value) {
this._active = value;
this.combo.requestUpdate();
}
get input() {
return this._config.input.value;
}
get searchInput() {
return this._config.search.value;
}
get list() {
return this._config.list.value;
}
get _firstItem() {
return this.state.dataState.findIndex((rec) => !rec.header);
}
get _lastItem() {
return this.state.dataState.length - 1;
}
async _hide() {
return await this.combo._hide(true);
}
async _show() {
return await this.combo._show(true);
}
_toggleSelection(index) {
this.combo.toggleSelect(index);
}
_select(index) {
this.combo.selectByIndex(index);
}
_scrollToActive(behavior) {
this.list.element(this.active)?.scrollIntoView({
block: 'center',
behavior: behavior ?? 'auto',
});
this.list.requestUpdate();
}
_getNearestItem(start, delta) {
let index = start;
const items = this.state.dataState;
while (items[index + delta]?.header) {
index += delta;
}
index += delta;
return index >= 0 && index < items.length ? index : -1;
}
_getNextItem(delta) {
const next = this._getNearestItem(this._active, delta);
if (next === -1 && this.active === this._firstItem) {
this.searchInput.checkVisibility()
? this.searchInput.focus()
: this._onEscape();
}
this.active = next;
}
constructor(combo, state, config) {
this.combo = combo;
this.state = state;
this._active = -1;
this._onSpace = () => {
if (this._active === -1) {
return;
}
const item = this.state.dataState[this._active];
if (!item.header) {
this._toggleSelection(this._active);
}
};
this._onEnter = async () => {
if (this._active === -1) {
return;
}
const item = this.state.dataState[this._active];
if (!item.header && this.combo.singleSelect) {
this._select(this.active);
}
if (await this._hide()) {
this.input.select();
this.combo.focus();
}
};
this._onTab = async ({ shiftKey }) => {
if (this.combo.open) {
if (shiftKey) {
this.combo.focus();
}
await this._hide();
}
};
this._onEscape = async () => {
if (!this.combo.open) {
this.combo.clearSelection();
}
if (await this._hide()) {
this.input.focus();
}
};
this._onMainInputArrowDown = async () => {
if (!this.combo.open && !(await this._show())) {
return;
}
if (this.combo.singleSelect) {
this._onSearchArrowDown();
}
};
this._onSearchArrowDown = () => {
this.list.focus();
this._onArrowDown();
};
this._onHome = () => {
this.active = this._firstItem;
this._scrollToActive();
};
this._onEnd = () => {
this.active = this._lastItem;
this._scrollToActive();
};
this._onArrowUp = () => {
this._getNextItem(-1);
this._scrollToActive();
};
this._onArrowDown = () => {
this._getNextItem(1);
this._scrollToActive();
};
this.combo.addController(this);
this._config = config;
const bindingDefaults = {
triggers: ['keydownRepeat'],
};
const skip = () => this.combo.disabled;
addKeybindings(this.combo, { skip, bindingDefaults })
.set(tabKey, this._onTab, { preventDefault: false })
.set([shiftKey, tabKey], this._onTab, {
preventDefault: false,
})
.set(escapeKey, this._onEscape);
addKeybindings(this.combo, {
skip,
ref: this._config.input,
bindingDefaults,
})
.set(arrowUp, async () => await this._hide())
.set([altKey, arrowDown], this._onMainInputArrowDown)
.set(arrowDown, this._onMainInputArrowDown)
.set(enterKey, this._onEnter);
addKeybindings(this.combo, {
skip,
ref: this._config.search,
bindingDefaults,
})
.set(arrowUp, this._onEscape)
.set(arrowDown, this._onSearchArrowDown);
addKeybindings(this.combo, {
skip,
ref: this._config.list,
bindingDefaults,
})
.set(arrowUp, this._onArrowUp)
.set(arrowDown, this._onArrowDown)
.set(homeKey, this._onHome)
.set(endKey, this._onEnd)
.set(spaceBar, this._onSpace)
.set(enterKey, this._onEnter);
}
hostDisconnected() {
this._active = -1;
}
}
//# sourceMappingURL=navigation.js.map