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.
276 lines • 10.3 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var IgcDropdownComponent_1;
import { html } from 'lit';
import { property, query, state } from 'lit/decorators.js';
import { themes } from '../../theming/theming-decorator.js';
import { addKeybindings, arrowDown, arrowLeft, arrowRight, arrowUp, endKey, enterKey, escapeKey, homeKey, tabKey, } from '../common/controllers/key-bindings.js';
import { addRootScrollHandler } from '../common/controllers/root-scroll.js';
import { blazorAdditionalDependencies } from '../common/decorators/blazorAdditionalDependencies.js';
import { watch } from '../common/decorators/watch.js';
import { registerComponent } from '../common/definitions/register.js';
import { IgcBaseComboBoxLikeComponent, getActiveItems, getItems, getNextActiveItem, getPreviousActiveItem, setInitialSelectionState, } from '../common/mixins/combo-box.js';
import { EventEmitterMixin } from '../common/mixins/event-emitter.js';
import { findElementFromEventPath, getElementByIdFromRoot, isString, } from '../common/util.js';
import IgcPopoverComponent from '../popover/popover.js';
import IgcDropdownGroupComponent from './dropdown-group.js';
import IgcDropdownHeaderComponent from './dropdown-header.js';
import IgcDropdownItemComponent from './dropdown-item.js';
import { all } from './themes/container.js';
import { styles } from './themes/dropdown.base.css.js';
import { styles as shared } from './themes/shared/dropdown.common.css.js';
let IgcDropdownComponent = IgcDropdownComponent_1 = class IgcDropdownComponent extends EventEmitterMixin(IgcBaseComboBoxLikeComponent) {
static register() {
registerComponent(IgcDropdownComponent_1, IgcDropdownGroupComponent, IgcDropdownHeaderComponent, IgcDropdownItemComponent, IgcPopoverComponent);
}
get _activeItems() {
return Array.from(getActiveItems(this, IgcDropdownItemComponent.tagName));
}
get items() {
return Array.from(getItems(this, IgcDropdownItemComponent.tagName));
}
get groups() {
return Array.from(getItems(this, IgcDropdownGroupComponent.tagName));
}
get selectedItem() {
return this._selectedItem;
}
scrollStrategyChanged() {
this._rootScrollController.update({ resetListeners: true });
}
openStateChange() {
this._updateAnchorAccessibility(this._target);
this._rootClickController.update();
this._rootScrollController.update();
if (!this.open) {
this._target = undefined;
this._targetListeners?.unsubscribe();
this._rootClickController.update({ target: undefined });
}
}
constructor() {
super();
this._rootScrollController = addRootScrollHandler(this, {
hideCallback: this.handleClosing,
});
this._selectedItem = null;
this.placement = 'bottom-start';
this.scrollStrategy = 'scroll';
this.flip = false;
this.distance = 0;
this.sameWidth = false;
this._rootClickController.update({ hideCallback: this.handleClosing });
this._keyBindings = addKeybindings(this, {
skip: () => !this.open,
bindingDefaults: { preventDefault: true, triggers: ['keydownRepeat'] },
})
.set(tabKey, this.onTabKey, {
preventDefault: false,
})
.set(escapeKey, this.onEscapeKey)
.set(arrowUp, this.onArrowUp)
.set(arrowLeft, this.onArrowUp)
.set(arrowDown, this.onArrowDown)
.set(arrowRight, this.onArrowDown)
.set(enterKey, this.onEnterKey)
.set(homeKey, this.onHomeKey)
.set(endKey, this.onEndKey);
}
async firstUpdated() {
await this.updateComplete;
const selected = setInitialSelectionState(this.items);
if (selected) {
this._selectItem(selected, false);
}
}
disconnectedCallback() {
this._targetListeners?.unsubscribe();
super.disconnectedCallback();
}
handleListBoxClick(event) {
const item = findElementFromEventPath(IgcDropdownItemComponent.tagName, event);
if (item && this._activeItems.includes(item)) {
this._selectItem(item);
}
}
handleChange(item) {
this.emitEvent('igcChange', { detail: item });
}
handleSlotChange() {
this._updateAnchorAccessibility();
}
onArrowUp() {
this._navigateToActiveItem(getPreviousActiveItem(this.items, this._activeItem));
}
onArrowDown() {
this._navigateToActiveItem(getNextActiveItem(this.items, this._activeItem));
}
onHomeKey() {
this._navigateToActiveItem(this._activeItems.at(0));
}
onEndKey() {
this._navigateToActiveItem(this._activeItems.at(-1));
}
onTabKey() {
if (this._activeItem) {
this._selectItem(this._activeItem);
}
if (this.open) {
this._hide(true);
}
}
onEscapeKey() {
this._hide(true);
}
onEnterKey() {
this._selectItem(this._activeItem);
}
handleClosing() {
this._hide(true);
}
activateItem(item) {
if (this._activeItem) {
this._activeItem.active = false;
}
this._activeItem = item;
this._activeItem.active = true;
}
_navigateToActiveItem(item) {
if (item) {
this.activateItem(item);
item.scrollIntoView({ behavior: 'auto', block: 'nearest' });
}
}
_selectItem(item, emit = true) {
if (this._selectedItem) {
this._selectedItem.selected = false;
}
this.activateItem(item);
this._selectedItem = item;
this._selectedItem.selected = true;
if (emit)
this.handleChange(this._selectedItem);
if (emit && !this.keepOpenOnSelect)
this._hide(true);
return this._selectedItem;
}
_updateAnchorAccessibility(anchor) {
const target = anchor ?? this.trigger.assignedElements({ flatten: true }).at(0);
if (target) {
target.setAttribute('aria-haspopup', 'true');
target.setAttribute('aria-expanded', this.open ? 'true' : 'false');
}
}
getItem(value) {
return this.items.find((item) => item.value === value);
}
_setTarget(anchor) {
const target = isString(anchor)
? getElementByIdFromRoot(this, anchor)
: anchor;
this._target = target;
this._targetListeners = this._keyBindings.observeElement(target);
this._rootClickController.update({ target });
}
async show(target) {
if (target) {
this._setTarget(target);
}
return super.show();
}
async toggle(target) {
return this.open ? this.hide() : this.show(target);
}
navigateTo(value) {
const item = isString(value) ? this.getItem(value) : this.items[value];
if (item) {
this._navigateToActiveItem(item);
}
return item ?? null;
}
select(value) {
const item = isString(value) ? this.getItem(value) : this.items[value];
return item ? this._selectItem(item, false) : null;
}
clearSelection() {
if (this._selectedItem) {
this._selectedItem.selected = false;
}
this._selectedItem = null;
}
render() {
return html `<igc-popover
?open=${this.open}
?flip=${this.flip}
?same-width=${this.sameWidth}
.anchor=${this._target}
.offset=${this.distance}
.placement=${this.placement}
shift
>
<slot
id="dropdown-target"
name="target"
slot="anchor"
=${this.handleAnchorClick}
=${this.handleSlotChange}
></slot>
<div part="base" =${this.handleListBoxClick} .inert=${!this.open}>
<div
id="dropdown-list"
role="listbox"
part="list"
aria-labelledby="dropdown-target"
>
<slot></slot>
</div>
</div>
</igc-popover>`;
}
};
IgcDropdownComponent.tagName = 'igc-dropdown';
IgcDropdownComponent.styles = [styles, shared];
__decorate([
state()
], IgcDropdownComponent.prototype, "_selectedItem", void 0);
__decorate([
state()
], IgcDropdownComponent.prototype, "_activeItem", void 0);
__decorate([
state()
], IgcDropdownComponent.prototype, "_target", void 0);
__decorate([
query('slot[name="target"]', true)
], IgcDropdownComponent.prototype, "trigger", void 0);
__decorate([
property()
], IgcDropdownComponent.prototype, "placement", void 0);
__decorate([
property({ attribute: 'scroll-strategy' })
], IgcDropdownComponent.prototype, "scrollStrategy", void 0);
__decorate([
property({ type: Boolean })
], IgcDropdownComponent.prototype, "flip", void 0);
__decorate([
property({ type: Number })
], IgcDropdownComponent.prototype, "distance", void 0);
__decorate([
property({ type: Boolean, attribute: 'same-width' })
], IgcDropdownComponent.prototype, "sameWidth", void 0);
__decorate([
watch('scrollStrategy', { waitUntilFirstUpdate: true })
], IgcDropdownComponent.prototype, "scrollStrategyChanged", null);
__decorate([
watch('open', { waitUntilFirstUpdate: true }),
watch('keepOpenOnOutsideClick', { waitUntilFirstUpdate: true })
], IgcDropdownComponent.prototype, "openStateChange", null);
IgcDropdownComponent = IgcDropdownComponent_1 = __decorate([
themes(all),
blazorAdditionalDependencies('IgcDropdownItemComponent, IgcDropdownHeaderComponent, IgcDropdownGroupComponent')
], IgcDropdownComponent);
export default IgcDropdownComponent;
//# sourceMappingURL=dropdown.js.map