UNPKG

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.

227 lines 7.87 kB
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; }; import { arrow, autoUpdate, computePosition, flip, inline, limitShift, offset, shift, size, } from '@floating-ui/dom'; import { LitElement, html } from 'lit'; import { property, query, queryAssignedElements } from 'lit/decorators.js'; import { watch } from '../common/decorators/watch.js'; import { registerComponent } from '../common/definitions/register.js'; import { first, getElementByIdFromRoot, isEmpty, isString, roundByDPR, } from '../common/util.js'; import { styles } from './themes/light/popover.base.css.js'; class IgcPopoverComponent extends LitElement { constructor() { super(...arguments); this.arrow = null; this.arrowOffset = 0; this.inline = false; this.flip = false; this.offset = 0; this.open = false; this.placement = 'bottom-start'; this.sameWidth = false; this.shift = false; this.shiftPadding = 0; } static register() { registerComponent(IgcPopoverComponent); } anchorChange() { const newTarget = isString(this.anchor) ? getElementByIdFromRoot(this, this.anchor) : this.anchor; if (newTarget) { this.target = newTarget; this._updateState(); } } openChange() { this.open ? this.show() : this.hide(); } floatingPropChange() { this._updateState(); } async connectedCallback() { super.connectedCallback(); await this.updateComplete; if (this.open) { this.show(); } } disconnectedCallback() { this.hide(); super.disconnectedCallback(); } show() { if (!this.target) { return; } this._showPopover(); this.dispose = autoUpdate(this.target, this._container, this._updatePosition.bind(this)); } async hide() { this._hidePopover(); return new Promise((resolve) => { this.dispose?.(); this.dispose = undefined; resolve(); }); } _showPopover() { this._container?.showPopover(); } _hidePopover() { this._container?.hidePopover(); } _createMiddleware() { const middleware = []; const styles = this._container.style; if (this.offset) { middleware.push(offset(this.offset)); } if (this.inline) { middleware.push(inline()); } if (this.shift) { middleware.push(shift({ padding: this.shiftPadding, limiter: limitShift(), })); } if (this.arrow) { middleware.push(arrow({ element: this.arrow })); } if (this.flip) { middleware.push(flip()); } if (this.sameWidth) { middleware.push(size({ apply: ({ rects }) => { Object.assign(styles, { width: `${rects.reference.width}px` }); }, })); } else { Object.assign(styles, { width: '' }); } return middleware; } async _updateState() { if (this.open) { await this.hide(); this.show(); } } async _updatePosition() { if (!(this.open && this.target)) { return; } const { x, y, middlewareData, placement } = await computePosition(this.target, this._container, { placement: this.placement ?? 'bottom-start', middleware: this._createMiddleware(), strategy: 'absolute', }); Object.assign(this._container.style, { left: 0, top: 0, transform: `translate(${roundByDPR(x)}px,${roundByDPR(y)}px)`, }); this._positionArrow(placement, middlewareData); } _positionArrow(placement, data) { if (!(data.arrow && this.arrow)) { return; } const { x, y } = data.arrow; const currentPlacement = first(placement.split('-')); const staticSide = { top: 'bottom', right: 'left', bottom: 'top', left: 'right', }[currentPlacement]; this.arrow.part = currentPlacement; Object.assign(this.arrow.style, { left: x != null ? `${roundByDPR(x + this.arrowOffset)}px` : '', top: y != null ? `${roundByDPR(y + this.arrowOffset)}px` : '', [staticSide]: '-4px', }); } _anchorSlotChange() { if (this.anchor || isEmpty(this._anchors)) { return; } this.target = this._anchors[0]; this._updateState(); } render() { return html ` <slot name="anchor" @slotchange=${this._anchorSlotChange}></slot> <div id="container" part="container" popover="manual"> <slot></slot> </div> `; } } IgcPopoverComponent.tagName = 'igc-popover'; IgcPopoverComponent.styles = styles; export default IgcPopoverComponent; __decorate([ query('#container') ], IgcPopoverComponent.prototype, "_container", void 0); __decorate([ queryAssignedElements({ slot: 'anchor', flatten: true }) ], IgcPopoverComponent.prototype, "_anchors", void 0); __decorate([ property() ], IgcPopoverComponent.prototype, "anchor", void 0); __decorate([ property({ attribute: false }) ], IgcPopoverComponent.prototype, "arrow", void 0); __decorate([ property({ type: Number, attribute: 'arrow-offset' }) ], IgcPopoverComponent.prototype, "arrowOffset", void 0); __decorate([ property({ type: Boolean, reflect: true }) ], IgcPopoverComponent.prototype, "inline", void 0); __decorate([ property({ type: Boolean, reflect: true }) ], IgcPopoverComponent.prototype, "flip", void 0); __decorate([ property({ type: Number }) ], IgcPopoverComponent.prototype, "offset", void 0); __decorate([ property({ type: Boolean, reflect: true }) ], IgcPopoverComponent.prototype, "open", void 0); __decorate([ property() ], IgcPopoverComponent.prototype, "placement", void 0); __decorate([ property({ type: Boolean, reflect: true, attribute: 'same-width' }) ], IgcPopoverComponent.prototype, "sameWidth", void 0); __decorate([ property({ type: Boolean, reflect: true }) ], IgcPopoverComponent.prototype, "shift", void 0); __decorate([ property({ type: Number, attribute: 'shift-padding' }) ], IgcPopoverComponent.prototype, "shiftPadding", void 0); __decorate([ watch('anchor') ], IgcPopoverComponent.prototype, "anchorChange", null); __decorate([ watch('open', { waitUntilFirstUpdate: true }) ], IgcPopoverComponent.prototype, "openChange", null); __decorate([ watch('arrow', { waitUntilFirstUpdate: true }), watch('arrowOffset', { waitUntilFirstUpdate: true }), watch('flip', { waitUntilFirstUpdate: true }), watch('inline', { waitUntilFirstUpdate: true }), watch('offset', { waitUntilFirstUpdate: true }), watch('placement', { waitUntilFirstUpdate: true }), watch('sameWidth', { waitUntilFirstUpdate: true }), watch('shift', { waitUntilFirstUpdate: true }), watch('shiftPadding', { waitUntilFirstUpdate: true }) ], IgcPopoverComponent.prototype, "floatingPropChange", null); //# sourceMappingURL=popover.js.map