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.
162 lines • 5.55 kB
JavaScript
import { addKeybindings, altKey, arrowDown, arrowUp, endKey, enterKey, escapeKey, homeKey, shiftKey, spaceBar, tabKey, } from '../../common/controllers/key-bindings.js';
export class ComboNavigationController {
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;
}
constructor(host, state, config) {
this.active = -1;
this._onSpace = () => {
if (this.active > -1) {
this._config.interactions.toggleSelection(this.active);
}
};
this._onEnter = async () => {
if (this.active > -1) {
if (this._host.singleSelect) {
this._config.interactions.select(this.active);
}
if (await this._config.interactions.hide()) {
this._input?.select();
this._host.focus();
}
}
};
this._onTab = async ({ shiftKey }) => {
if (this._host.open) {
if (shiftKey) {
this._host.focus();
}
if (this._host.singleSelect && this.active > -1) {
this._config.interactions.select(this.active);
}
await this._config.interactions.hide();
}
};
this._onEscape = async () => {
if (!this._host.open) {
this._config.interactions.clearSelection();
}
if (await this._config.interactions.hide()) {
this._input?.focus();
}
};
this._onMainInputArrowDown = async () => {
if (!this._host.open && !(await this._config.interactions.show())) {
return;
}
if (this._host.singleSelect) {
this._onSearchArrowDown();
}
};
this._onSearchArrowDown = () => {
this._list?.focus();
this._onArrowDown();
};
this._onHome = () => {
const previous = this.active;
this.active = this._firstItem;
this._scrollToActive();
this._host.requestUpdate('_activeIndex', previous);
};
this._onEnd = () => {
const previous = this.active;
this.active = this._lastItem;
this._scrollToActive();
this._host.requestUpdate('_activeIndex', previous);
};
this._onArrowUp = () => {
this._getNextItem(-1);
this._scrollToActive();
};
this._onArrowDown = () => {
this._getNextItem(1);
this._scrollToActive();
};
this._host = host;
this._state = state;
this._config = config;
this._host.addController(this);
const bindingDefaults = { repeat: true };
const skip = () => this._host.disabled;
addKeybindings(this._host, { skip, bindingDefaults })
.set(tabKey, this._onTab, { preventDefault: false })
.set([shiftKey, tabKey], this._onTab, {
preventDefault: false,
})
.set(escapeKey, this._onEscape);
addKeybindings(this._host, {
skip,
ref: this._config.input,
bindingDefaults,
})
.set(arrowUp, this._config.interactions.hide)
.set([altKey, arrowDown], this._onMainInputArrowDown)
.set(arrowDown, this._onMainInputArrowDown)
.set(enterKey, this._onEnter);
addKeybindings(this._host, {
skip,
ref: this._config.search,
bindingDefaults,
})
.set(arrowUp, this._onEscape)
.set(arrowDown, this._onSearchArrowDown);
addKeybindings(this._host, {
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;
}
_scrollToActive(behavior) {
this._list?.element(this.active)?.scrollIntoView({
block: 'center',
behavior: behavior ?? 'auto',
});
this._list?.requestUpdate();
}
_getNearestItem(start, delta) {
const items = this._state.dataState;
const length = items.length;
for (let i = start + delta; i >= 0 && i < length; i += delta) {
if (!items[i].header) {
return i;
}
}
return -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();
return;
}
if (next !== -1) {
const previous = this.active;
this.active = next;
this._host.requestUpdate('_activeIndex', previous);
}
}
}
//# sourceMappingURL=navigation.js.map