UNPKG

primeng

Version:

PrimeNG is a premium UI library for Angular featuring a rich set of 90+ components, a theme designer, various theme alternatives such as Material, Bootstrap, Tailwind, premium templates and professional support. In addition, it integrates with PrimeBlock,

1,008 lines (1,006 loc) 71.4 kB
export * from 'primeng/types/dialog'; import { isPlatformBrowser, NgTemplateOutlet } from '@angular/common'; import * as i0 from '@angular/core'; import { Injectable, InjectionToken, input, inject, booleanAttribute, numberAttribute, computed, model, output, viewChild, contentChild, signal, effect, untracked, ViewEncapsulation, ChangeDetectionStrategy, Component, NgModule } from '@angular/core'; import { uuid, setAttribute, addStyle, getOuterWidth, getOuterHeight, getViewport, appendChild, removeClass, hasClass } from '@primeuix/utils'; import { OverlayService, TranslationKeys, SharedModule } from 'primeng/api'; import { BaseComponent, PARENT_INSTANCE } from 'primeng/basecomponent'; import * as i1 from 'primeng/bind'; import { Bind } from 'primeng/bind'; import { ButtonDirective } from 'primeng/button'; import { DomHandler, blockBodyScroll, unblockBodyScroll } from 'primeng/dom'; import { FocusTrap } from 'primeng/focustrap'; import { Times } from '@primeicons/angular/times'; import { WindowMaximize } from '@primeicons/angular/window-maximize'; import { WindowMinimize } from '@primeicons/angular/window-minimize'; import * as i2 from 'primeng/motion'; import { MotionModule } from 'primeng/motion'; import { ZIndexUtils } from 'primeng/utils'; import { style } from '@primeuix/styles/dialog'; import { BaseStyle } from 'primeng/base'; /* Position */ const inlineStyles = { mask: ({ instance }) => { const position = instance.position(); const modal = instance.modal(); const maskStyle = instance.maskStyle(); return { position: 'fixed', height: '100%', width: '100%', left: 0, top: 0, display: 'flex', justifyContent: position === 'left' || position === 'topleft' || position === 'bottomleft' ? 'flex-start' : position === 'right' || position === 'topright' || position === 'bottomright' ? 'flex-end' : 'center', alignItems: position === 'top' || position === 'topleft' || position === 'topright' ? 'flex-start' : position === 'bottom' || position === 'bottomleft' || position === 'bottomright' ? 'flex-end' : 'center', pointerEvents: modal ? 'auto' : 'none', ...maskStyle }; }, root: ({ instance }) => { const style = instance.style(); return { display: 'flex', flexDirection: 'column', pointerEvents: 'auto', ...style }; } }; const classes = { mask: ({ instance }) => { const positions = ['left', 'right', 'top', 'topleft', 'topright', 'bottom', 'bottomleft', 'bottomright']; const position = instance.position(); const pos = positions.find((item) => item === position); return ['p-dialog-mask', { 'p-overlay-mask': instance.modal() }, pos ? `p-dialog-${pos}` : '']; }, root: ({ instance }) => [ 'p-dialog p-component', { 'p-dialog-maximized': instance.maximizable() && instance.maximized() } ], header: 'p-dialog-header', title: 'p-dialog-title', resizeHandle: 'p-resizable-handle', headerActions: 'p-dialog-header-actions', pcMaximizeButton: 'p-dialog-maximize-button', pcCloseButton: 'p-dialog-close-button', content: () => ['p-dialog-content'], footer: 'p-dialog-footer' }; class DialogStyle extends BaseStyle { name = 'dialog'; style = style; classes = classes; inlineStyles = inlineStyles; static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: DialogStyle, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: DialogStyle }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: DialogStyle, decorators: [{ type: Injectable }] }); /** * * Dialog is a container to display content in an overlay window. * * [Live Demo](https://www.primeng.org/dialog) * * @module dialogstyle * */ var DialogClasses; (function (DialogClasses) { /** * Class name of the mask element */ DialogClasses["mask"] = "p-dialog-mask"; /** * Class name of the root element */ DialogClasses["root"] = "p-dialog"; /** * Class name of the header element */ DialogClasses["header"] = "p-dialog-header"; /** * Class name of the title element */ DialogClasses["title"] = "p-dialog-title"; /** * Class name of the header actions element */ DialogClasses["headerActions"] = "p-dialog-header-actions"; /** * Class name of the maximize button element */ DialogClasses["pcMaximizeButton"] = "p-dialog-maximize-button"; /** * Class name of the close button element */ DialogClasses["pcCloseButton"] = "p-dialog-close-button"; /** * Class name of the content element */ DialogClasses["content"] = "p-dialog-content"; /** * Class name of the footer element */ DialogClasses["footer"] = "p-dialog-footer"; })(DialogClasses || (DialogClasses = {})); const DIALOG_INSTANCE = new InjectionToken('DIALOG_INSTANCE'); /** * Dialog is a container to display content in an overlay window. * @group Components */ class Dialog extends BaseComponent { componentName = 'Dialog'; hostName = input('', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "hostName" }] : /* istanbul ignore next */ [])); $pcDialog = inject(DIALOG_INSTANCE, { optional: true, skipSelf: true }) ?? undefined; bindDirectiveInstance = inject(Bind, { self: true }); onAfterViewChecked() { this.bindDirectiveInstance.setAttrs(this.ptm('host')); } /** * Title text of the dialog. * @group Props */ header = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "header" }] : /* istanbul ignore next */ [])); /** * Enables dragging to change the position using header. * @group Props */ draggable = input(true, { ...(ngDevMode ? { debugName: "draggable" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Enables resizing of the content. * @group Props */ resizable = input(true, { ...(ngDevMode ? { debugName: "resizable" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Style of the content section. * @group Props */ contentStyle = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "contentStyle" }] : /* istanbul ignore next */ [])); /** * Style class of the content. * @group Props */ contentStyleClass = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "contentStyleClass" }] : /* istanbul ignore next */ [])); /** * Defines if background should be blocked when dialog is displayed. * @group Props */ modal = input(false, { ...(ngDevMode ? { debugName: "modal" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Specifies if pressing escape key should hide the dialog. * @group Props */ closeOnEscape = input(true, { ...(ngDevMode ? { debugName: "closeOnEscape" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Specifies if clicking the modal background should hide the dialog. * @group Props */ dismissableMask = input(false, { ...(ngDevMode ? { debugName: "dismissableMask" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * When enabled dialog is displayed in RTL direction. * @group Props */ rtl = input(false, { ...(ngDevMode ? { debugName: "rtl" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Adds a close icon to the header to hide the dialog. * @group Props */ closable = input(true, { ...(ngDevMode ? { debugName: "closable" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Object literal to define widths per screen size. * @group Props */ breakpoints = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "breakpoints" }] : /* istanbul ignore next */ [])); /** * Style class of the component. * @group Props */ styleClass = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "styleClass" }] : /* istanbul ignore next */ [])); /** * Style class of the mask. * @group Props */ maskStyleClass = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "maskStyleClass" }] : /* istanbul ignore next */ [])); /** * Style of the mask. * @group Props */ maskStyle = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "maskStyle" }] : /* istanbul ignore next */ [])); /** * Whether to show the header or not. * @group Props */ showHeader = input(true, { ...(ngDevMode ? { debugName: "showHeader" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Whether background scroll should be blocked when dialog is visible. * @group Props */ blockScroll = input(false, { ...(ngDevMode ? { debugName: "blockScroll" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Whether to automatically manage layering. * @group Props */ autoZIndex = input(true, { ...(ngDevMode ? { debugName: "autoZIndex" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Base zIndex value to use in layering. * @group Props */ baseZIndex = input(0, { ...(ngDevMode ? { debugName: "baseZIndex" } : /* istanbul ignore next */ {}), transform: numberAttribute }); /** * Minimum value for the left coordinate of dialog in dragging. * @group Props */ minX = input(0, { ...(ngDevMode ? { debugName: "minX" } : /* istanbul ignore next */ {}), transform: numberAttribute }); /** * Minimum value for the top coordinate of dialog in dragging. * @group Props */ minY = input(0, { ...(ngDevMode ? { debugName: "minY" } : /* istanbul ignore next */ {}), transform: numberAttribute }); /** * When enabled, first focusable element receives focus on show. * @group Props */ focusOnShow = input(true, { ...(ngDevMode ? { debugName: "focusOnShow" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Whether the dialog can be displayed full screen. * @group Props */ maximizable = input(false, { ...(ngDevMode ? { debugName: "maximizable" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Keeps dialog in the viewport. * @group Props */ keepInViewport = input(true, { ...(ngDevMode ? { debugName: "keepInViewport" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * When enabled, can only focus on elements inside the dialog. * @group Props */ focusTrap = input(true, { ...(ngDevMode ? { debugName: "focusTrap" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * The motion options for the mask. * @group Props */ maskMotionOptions = input(undefined, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "maskMotionOptions" }] : /* istanbul ignore next */ [])); computedMaskMotionOptions = computed(() => { return { ...this.ptm('maskMotion'), ...this.maskMotionOptions() }; }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "computedMaskMotionOptions" }] : /* istanbul ignore next */ [])); maskEnterActiveClass = computed(() => (this.modal() ? 'p-overlay-mask-enter-active' : ''), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "maskEnterActiveClass" }] : /* istanbul ignore next */ [])); maskLeaveActiveClass = computed(() => (this.modal() ? 'p-overlay-mask-leave-active' : ''), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "maskLeaveActiveClass" }] : /* istanbul ignore next */ [])); /** * The motion options. * @group Props */ motionOptions = input(undefined, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "motionOptions" }] : /* istanbul ignore next */ [])); computedMotionOptions = computed(() => { return { ...this.ptm('motion'), ...this.motionOptions() }; }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "computedMotionOptions" }] : /* istanbul ignore next */ [])); /** * Name of the close icon. * @group Props */ closeIcon = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "closeIcon" }] : /* istanbul ignore next */ [])); /** * Defines a string that labels the close button for accessibility. * @group Props */ closeAriaLabel = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "closeAriaLabel" }] : /* istanbul ignore next */ [])); /** * Index of the close button in tabbing order. * @group Props */ closeTabindex = input('0', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "closeTabindex" }] : /* istanbul ignore next */ [])); /** * Name of the minimize icon. * @group Props */ minimizeIcon = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "minimizeIcon" }] : /* istanbul ignore next */ [])); /** * Name of the maximize icon. * @group Props */ maximizeIcon = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "maximizeIcon" }] : /* istanbul ignore next */ [])); /** * Configuration object forwarded to the underlying button. * @group Props */ closeButtonProps = input({ severity: 'secondary', variant: 'text', rounded: true }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "closeButtonProps" }] : /* istanbul ignore next */ [])); /** * Configuration object forwarded to the underlying button. * @group Props */ maximizeButtonProps = input({ severity: 'secondary', variant: 'text', rounded: true }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "maximizeButtonProps" }] : /* istanbul ignore next */ [])); /** * Specifies the visibility of the dialog. * @group Props */ visible = model(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ [])); /** * Inline style of the component. * @group Props */ style = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "style" }] : /* istanbul ignore next */ [])); /** * Position of the dialog, options are "center", "top", "bottom", "left", "right", "topleft", "topright", "bottomleft" or "bottomright". * @group Props */ position = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "position" }] : /* istanbul ignore next */ [])); /** * Role attribute of html element. * @group Emits */ role = input('dialog', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ [])); /** * Target element to attach the overlay, valid values are "body" or a local ng-template variable of another element (note: use binding with brackets for template variables, e.g. [appendTo]="mydiv" for a div element having #mydiv as variable name). * @defaultValue 'self' * @group Props */ appendTo = input(undefined, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "appendTo" }] : /* istanbul ignore next */ [])); /** * Callback to invoke when dialog is shown. * @group Emits */ onShow = output(); /** * Callback to invoke when dialog is hidden. * @group Emits */ onHide = output(); /** * Callback to invoke when dialog resizing is initiated. * @param {MouseEvent} event - Mouse event. * @group Emits */ onResizeInit = output(); /** * Callback to invoke when dialog resizing is completed. * @param {MouseEvent} event - Mouse event. * @group Emits */ onResizeEnd = output(); /** * Callback to invoke when dialog dragging is initiated. * @param {MouseEvent} event - Mouse event. * @group Emits */ onDragStart = output(); /** * Callback to invoke when dialog dragging is completed. * @param {DragEvent} event - Drag event. * @group Emits */ onDragEnd = output(); /** * Callback to invoke when dialog maximized or unmaximized. * @group Emits */ onMaximize = output(); headerViewChild = viewChild('titlebar', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "headerViewChild" }] : /* istanbul ignore next */ [])); contentViewChild = viewChild('content', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "contentViewChild" }] : /* istanbul ignore next */ [])); footerViewChild = viewChild('footer', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "footerViewChild" }] : /* istanbul ignore next */ [])); /** * Custom header template. * @group Templates */ headerTemplate = contentChild('header', { ...(ngDevMode ? { debugName: "headerTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom content template. * @group Templates */ contentTemplate = contentChild('content', { ...(ngDevMode ? { debugName: "contentTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom footer template. * @group Templates */ footerTemplate = contentChild('footer', { ...(ngDevMode ? { debugName: "footerTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom close icon template. * @group Templates */ closeIconTemplate = contentChild('closeicon', { ...(ngDevMode ? { debugName: "closeIconTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom maximize icon template. * @group Templates */ maximizeIconTemplate = contentChild('maximizeicon', { ...(ngDevMode ? { debugName: "maximizeIconTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom minimize icon template. * @group Templates */ minimizeIconTemplate = contentChild('minimizeicon', { ...(ngDevMode ? { debugName: "minimizeIconTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom headless template. * @group Templates */ headlessTemplate = contentChild('headless', { ...(ngDevMode ? { debugName: "headlessTemplate" } : /* istanbul ignore next */ {}), descendants: false }); $appendTo = computed(() => this.appendTo() || this.config.overlayAppendTo(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "$appendTo" }] : /* istanbul ignore next */ [])); renderMask = signal(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "renderMask" }] : /* istanbul ignore next */ [])); renderDialog = signal(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "renderDialog" }] : /* istanbul ignore next */ [])); maskVisible; container = signal(null, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "container" }] : /* istanbul ignore next */ [])); wrapper; dragging; ariaId = uuid('pn_id_') + '_header'; ariaLabelledBy = computed(() => (this.header() !== null ? this.ariaId : null), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "ariaLabelledBy" }] : /* istanbul ignore next */ [])); headerTemplateContext = computed(() => ({ ariaLabelledBy: this.ariaLabelledBy() }), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "headerTemplateContext" }] : /* istanbul ignore next */ [])); documentDragListener; documentDragEndListener; resizing; documentResizeListener; documentResizeEndListener; documentEscapeListener; maskClickListener; lastPageX; lastPageY; preventVisibleChangePropagation; maximized = signal(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "maximized" }] : /* istanbul ignore next */ [])); preMaximizeContentHeight; preMaximizeContainerWidth; preMaximizeContainerHeight; preMaximizePageX; preMaximizePageY; id = uuid('pn_id_'); _style = {}; originalStyle; styleElement = null; _componentStyle = inject(DialogStyle); overlayService = inject(OverlayService); zIndexForLayering; get maximizeLabel() { return this.translate(TranslationKeys.ARIA, 'maximizeLabel'); } get minimizeLabel() { return this.translate(TranslationKeys.ARIA, 'minimizeLabel'); } maximizeButtonAriaLabel = computed(() => (this.maximized() ? this.minimizeLabel : this.maximizeLabel), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "maximizeButtonAriaLabel" }] : /* istanbul ignore next */ [])); maximizeButtonTabindex = computed(() => (this.maximizable() ? '0' : '-1'), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "maximizeButtonTabindex" }] : /* istanbul ignore next */ [])); toggleIcon = computed(() => (this.maximized() ? this.minimizeIcon() : this.maximizeIcon()), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "toggleIcon" }] : /* istanbul ignore next */ [])); showToggleIcon = computed(() => !!this.maximizeIcon() && !this.maximizeIconTemplate() && !this.minimizeIconTemplate(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showToggleIcon" }] : /* istanbul ignore next */ [])); showDefaultMaximizeIcon = computed(() => !this.maximizeIcon(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showDefaultMaximizeIcon" }] : /* istanbul ignore next */ [])); showMaximizeSvg = computed(() => !this.maximized() && !this.maximizeIconTemplate(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showMaximizeSvg" }] : /* istanbul ignore next */ [])); showMinimizeSvg = computed(() => this.maximized() && !this.minimizeIconTemplate(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showMinimizeSvg" }] : /* istanbul ignore next */ [])); showMaximizeIconTemplate = computed(() => !this.maximized() && !!this.maximizeIconTemplate(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showMaximizeIconTemplate" }] : /* istanbul ignore next */ [])); showMinimizeIconTemplate = computed(() => this.maximized() && !!this.minimizeIconTemplate(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showMinimizeIconTemplate" }] : /* istanbul ignore next */ [])); showDefaultCloseIcon = computed(() => !this.closeIconTemplate(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showDefaultCloseIcon" }] : /* istanbul ignore next */ [])); scrollBlockerActive = computed(() => this.modal() || this.blockScroll(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "scrollBlockerActive" }] : /* istanbul ignore next */ [])); focusTrapDisabled = computed(() => this.focusTrap() === false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "focusTrapDisabled" }] : /* istanbul ignore next */ [])); constructor() { super(); effect(() => { const isVisible = this.visible(); untracked(() => { if (isVisible && !this.maskVisible) { this.maskVisible = true; this.renderMask.set(true); this.renderDialog.set(true); } }); }); } onInit() { if (this.breakpoints()) { this.createStyle(); } } _focus(focusParentElement) { if (focusParentElement) { let _focusableElements = DomHandler.getFocusableElements(focusParentElement); if (_focusableElements && _focusableElements.length > 0) { _focusableElements[0].focus(); return true; } } return false; } focus(focusParentElement) { const element = focusParentElement ?? this.contentViewChild()?.nativeElement; let focused = this._focus(element); if (!focused) { focused = this._focus(this.footerViewChild()?.nativeElement); if (!focused) { focused = this._focus(this.headerViewChild()?.nativeElement); if (!focused) { this._focus(this.contentViewChild()?.nativeElement); } } } } close(event) { this.visible.set(false); event.preventDefault(); } enableModality() { this.maskClickListener = this.renderer.listen(this.wrapper, 'mousedown', (event) => { if (this.wrapper && this.wrapper.isSameNode(event.target)) { if (this.closable() && this.dismissableMask()) { this.close(event); } else if (this.focusTrap()) { // keep focus within the dialog so the trap is not defeated by a mask click event.preventDefault(); } } }); if (this.modal()) { blockBodyScroll(); } } disableModality() { if (this.wrapper) { this.unbindMaskClickListener(); // for nested dialogs w/modal const scrollBlockers = document.querySelectorAll('[data-p-scrollblocker-active="true"]'); if (this.modal() && scrollBlockers && scrollBlockers.length == 1) { unblockBodyScroll(); } if (!this.cd.destroyed) { this.cd.detectChanges(); } } } maximize() { this.maximized.update((v) => !v); if (!this.modal() && !this.blockScroll()) { if (this.maximized()) { blockBodyScroll(); } else { unblockBodyScroll(); } } this.onMaximize.emit({ maximized: this.maximized() }); } unbindMaskClickListener() { if (this.maskClickListener) { this.maskClickListener(); this.maskClickListener = null; } } moveOnTop() { if (this.autoZIndex()) { ZIndexUtils.set('modal', this.container(), this.baseZIndex() + this.config.zIndex.modal); this.wrapper.style.zIndex = String(parseInt(this.container().style.zIndex, 10) - 1); } else { this.zIndexForLayering = ZIndexUtils.generateZIndex('modal', (this.baseZIndex() ?? 0) + this.config.zIndex.modal); } } createStyle() { if (isPlatformBrowser(this.platformId)) { if (!this.styleElement && !this.$unstyled()) { const styleElement = this.renderer.createElement('style'); setAttribute(styleElement, 'nonce', this.config?.csp()?.nonce); this.renderer.appendChild(this.document.head, styleElement); let innerHTML = ''; for (let breakpoint in this.breakpoints()) { innerHTML += ` @media screen and (max-width: ${breakpoint}) { .p-dialog[${this.id}]:not(.p-dialog-maximized) { width: ${this.breakpoints()[breakpoint]} !important; } } `; } this.renderer.setProperty(styleElement, 'innerHTML', innerHTML); setAttribute(styleElement, 'nonce', this.config?.csp()?.nonce); this.styleElement = styleElement; } } } initDrag(event) { const target = event.target; const closestDiv = target.closest('div'); if (closestDiv?.getAttribute('data-pc-section') === 'headeractions') { return; } if (this.draggable()) { this.dragging = true; this.lastPageX = event.pageX; this.lastPageY = event.pageY; this.container().style.margin = '0'; this.document.body.setAttribute('data-p-unselectable-text', 'true'); !this.$unstyled() && addStyle(this.document.body, { 'user-select': 'none' }); this.onDragStart.emit(event); } } onDrag(event) { if (this.dragging && this.container()) { const containerWidth = getOuterWidth(this.container()); const containerHeight = getOuterHeight(this.container()); const deltaX = event.pageX - this.lastPageX; const deltaY = event.pageY - this.lastPageY; const offset = this.container().getBoundingClientRect(); const containerComputedStyle = getComputedStyle(this.container()); const leftMargin = parseFloat(containerComputedStyle.marginLeft); const topMargin = parseFloat(containerComputedStyle.marginTop); const leftPos = offset.left + deltaX - leftMargin; const topPos = offset.top + deltaY - topMargin; const viewport = getViewport(); this.container().style.position = 'fixed'; if (this.keepInViewport()) { if (leftPos >= this.minX() && leftPos + containerWidth < viewport.width) { this._style.left = `${leftPos}px`; this.lastPageX = event.pageX; this.container().style.left = `${leftPos}px`; } if (topPos >= this.minY() && topPos + containerHeight < viewport.height) { this._style.top = `${topPos}px`; this.lastPageY = event.pageY; this.container().style.top = `${topPos}px`; } } else { this.lastPageX = event.pageX; this.container().style.left = `${leftPos}px`; this.lastPageY = event.pageY; this.container().style.top = `${topPos}px`; } this.overlayService.emitParentDrag(this.container()); } } endDrag(event) { if (this.dragging) { this.dragging = false; this.document.body.removeAttribute('data-p-unselectable-text'); !this.$unstyled() && (this.document.body.style['user-select'] = ''); this.cd.detectChanges(); this.onDragEnd.emit(event); } } resetPosition() { this.container().style.position = ''; this.container().style.left = ''; this.container().style.top = ''; this.container().style.margin = ''; } //backward compatibility center() { this.resetPosition(); } initResize(event) { if (this.resizable()) { this.resizing = true; this.lastPageX = event.pageX; this.lastPageY = event.pageY; this.document.body.setAttribute('data-p-unselectable-text', 'true'); !this.$unstyled() && addStyle(this.document.body, { 'user-select': 'none' }); this.onResizeInit.emit(event); } } onResize(event) { if (this.resizing) { let deltaX = event.pageX - this.lastPageX; let deltaY = event.pageY - this.lastPageY; let containerWidth = getOuterWidth(this.container()); let containerHeight = getOuterHeight(this.container()); let contentHeight = getOuterHeight(this.contentViewChild()?.nativeElement); let newWidth = containerWidth + deltaX; let newHeight = containerHeight + deltaY; let minWidth = this.container().style.minWidth; let minHeight = this.container().style.minHeight; let offset = this.container().getBoundingClientRect(); let viewport = getViewport(); let hasBeenDragged = !parseInt(this.container().style.top) || !parseInt(this.container().style.left); if (hasBeenDragged) { newWidth += deltaX; newHeight += deltaY; } if ((!minWidth || newWidth > parseInt(minWidth)) && offset.left + newWidth < viewport.width) { this._style.width = newWidth + 'px'; this.container().style.width = this._style.width; } if ((!minHeight || newHeight > parseInt(minHeight)) && offset.top + newHeight < viewport.height) { this.contentViewChild().nativeElement.style.height = contentHeight + newHeight - containerHeight + 'px'; if (this._style.height) { this._style.height = newHeight + 'px'; this.container().style.height = this._style.height; } } this.lastPageX = event.pageX; this.lastPageY = event.pageY; } } resizeEnd(event) { if (this.resizing) { this.resizing = false; this.document.body.removeAttribute('data-p-unselectable-text'); !this.$unstyled() && (this.document.body.style['user-select'] = ''); this.onResizeEnd.emit(event); } } bindGlobalListeners() { if (this.draggable()) { this.bindDocumentDragListener(); this.bindDocumentDragEndListener(); } if (this.resizable()) { this.bindDocumentResizeListeners(); } if (this.closeOnEscape() && this.closable()) { this.bindDocumentEscapeListener(); } } unbindGlobalListeners() { this.unbindDocumentDragListener(); this.unbindDocumentDragEndListener(); this.unbindDocumentResizeListeners(); this.unbindDocumentEscapeListener(); } bindDocumentDragListener() { if (!this.documentDragListener) { this.documentDragListener = this.renderer.listen(this.document.defaultView, 'mousemove', this.onDrag.bind(this)); } } unbindDocumentDragListener() { if (this.documentDragListener) { this.documentDragListener(); this.documentDragListener = null; } } bindDocumentDragEndListener() { if (!this.documentDragEndListener) { this.documentDragEndListener = this.renderer.listen(this.document.defaultView, 'mouseup', this.endDrag.bind(this)); } } unbindDocumentDragEndListener() { if (this.documentDragEndListener) { this.documentDragEndListener(); this.documentDragEndListener = null; } } bindDocumentResizeListeners() { if (!this.documentResizeListener && !this.documentResizeEndListener) { this.documentResizeListener = this.renderer.listen(this.document.defaultView, 'mousemove', this.onResize.bind(this)); this.documentResizeEndListener = this.renderer.listen(this.document.defaultView, 'mouseup', this.resizeEnd.bind(this)); } } unbindDocumentResizeListeners() { if (this.documentResizeListener && this.documentResizeEndListener) { this.documentResizeListener(); this.documentResizeEndListener(); this.documentResizeListener = null; this.documentResizeEndListener = null; } } bindDocumentEscapeListener() { const documentTarget = this.el ? this.el.nativeElement.ownerDocument : this.document; this.documentEscapeListener = this.renderer.listen(documentTarget, 'keydown', (event) => { if (event.key == 'Escape') { const container = this.container(); if (!container) { return; } const currentZIndex = ZIndexUtils.getCurrent(); if (parseInt(container.style.zIndex) == currentZIndex || this.zIndexForLayering == currentZIndex) { this.close(event); } } }); } unbindDocumentEscapeListener() { if (this.documentEscapeListener) { this.documentEscapeListener(); this.documentEscapeListener = null; } } appendContainer() { if (this.$appendTo() !== 'self') { appendChild(this.document.body, this.wrapper); } } restoreAppend() { if (this.container() && this.$appendTo() !== 'self') { this.renderer.appendChild(this.el.nativeElement, this.wrapper); } } onBeforeEnter(event) { this.container.set(event.element); this.wrapper = this.container()?.parentElement; this.$attrSelector && this.container()?.setAttribute(this.$attrSelector, ''); this.appendContainer(); this.moveOnTop(); this.bindGlobalListeners(); this.container()?.setAttribute(this.id, ''); if (this.modal()) { this.enableModality(); } } onAfterEnter() { if (this.focusOnShow()) { this.focus(); } this.onShow.emit({}); } onBeforeLeave() { if (this.modal()) { this.maskVisible = false; } } onAfterLeave() { this.onContainerDestroy(); this.renderDialog.set(false); if (this.modal()) { this.renderMask.set(false); } else { this.maskVisible = false; } this.onHide.emit({}); } onMaskAfterLeave() { if (!this.renderDialog()) { this.renderMask.set(false); } } onContainerDestroy() { this.unbindGlobalListeners(); this.dragging = false; if (this.maximized()) { removeClass(this.document.body, 'p-overflow-hidden'); this.document.body.style.removeProperty('--px-scrollbar-width'); this.maximized.set(false); } if (this.modal()) { this.disableModality(); } const remainingScrollBlockers = this.document.querySelectorAll('[data-p-scrollblocker-active="true"]'); if (remainingScrollBlockers.length <= 1 && hasClass(this.document.body, 'p-overflow-hidden')) { removeClass(this.document.body, 'p-overflow-hidden'); } if (this.container() && this.autoZIndex()) { ZIndexUtils.clear(this.container()); } if (this.zIndexForLayering) { ZIndexUtils.revertZIndex(this.zIndexForLayering); } this.container.set(null); this.wrapper = null; this._style = this.originalStyle ? { ...this.originalStyle } : {}; } destroyStyle() { if (this.styleElement) { this.renderer.removeChild(this.document.head, this.styleElement); this.styleElement = null; } } onDestroy() { if (this.container()) { this.restoreAppend(); this.onContainerDestroy(); } this.destroyStyle(); } dataP = computed(() => this.cn({ maximized: this.maximized(), modal: this.modal() }), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "dataP" }] : /* istanbul ignore next */ [])); static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: Dialog, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: Dialog, isStandalone: true, selector: "p-dialog", inputs: { hostName: { classPropertyName: "hostName", publicName: "hostName", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, contentStyle: { classPropertyName: "contentStyle", publicName: "contentStyle", isSignal: true, isRequired: false, transformFunction: null }, contentStyleClass: { classPropertyName: "contentStyleClass", publicName: "contentStyleClass", isSignal: true, isRequired: false, transformFunction: null }, modal: { classPropertyName: "modal", publicName: "modal", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, dismissableMask: { classPropertyName: "dismissableMask", publicName: "dismissableMask", isSignal: true, isRequired: false, transformFunction: null }, rtl: { classPropertyName: "rtl", publicName: "rtl", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, breakpoints: { classPropertyName: "breakpoints", publicName: "breakpoints", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null }, maskStyleClass: { classPropertyName: "maskStyleClass", publicName: "maskStyleClass", isSignal: true, isRequired: false, transformFunction: null }, maskStyle: { classPropertyName: "maskStyle", publicName: "maskStyle", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, blockScroll: { classPropertyName: "blockScroll", publicName: "blockScroll", isSignal: true, isRequired: false, transformFunction: null }, autoZIndex: { classPropertyName: "autoZIndex", publicName: "autoZIndex", isSignal: true, isRequired: false, transformFunction: null }, baseZIndex: { classPropertyName: "baseZIndex", publicName: "baseZIndex", isSignal: true, isRequired: false, transformFunction: null }, minX: { classPropertyName: "minX", publicName: "minX", isSignal: true, isRequired: false, transformFunction: null }, minY: { classPropertyName: "minY", publicName: "minY", isSignal: true, isRequired: false, transformFunction: null }, focusOnShow: { classPropertyName: "focusOnShow", publicName: "focusOnShow", isSignal: true, isRequired: false, transformFunction: null }, maximizable: { classPropertyName: "maximizable", publicName: "maximizable", isSignal: true, isRequired: false, transformFunction: null }, keepInViewport: { classPropertyName: "keepInViewport", publicName: "keepInViewport", isSignal: true, isRequired: false, transformFunction: null }, focusTrap: { classPropertyName: "focusTrap", publicName: "focusTrap", isSignal: true, isRequired: false, transformFunction: null }, maskMotionOptions: { classPropertyName: "maskMotionOptions", publicName: "maskMotionOptions", isSignal: true, isRequired: false, transformFunction: null }, motionOptions: { classPropertyName: "motionOptions", publicName: "motionOptions", isSignal: true, isRequired: false, transformFunction: null }, closeIcon: { classPropertyName: "closeIcon", publicName: "closeIcon", isSignal: true, isRequired: false, transformFunction: null }, closeAriaLabel: { classPropertyName: "closeAriaLabel", publicName: "closeAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, closeTabindex: { classPropertyName: "closeTabindex", publicName: "closeTabindex", isSignal: true, isRequired: false, transformFunction: null }, minimizeIcon: { classPropertyName: "minimizeIcon", publicName: "minimizeIcon", isSignal: true, isRequired: false, transformFunction: null }, maximizeIcon: { classPropertyName: "maximizeIcon", publicName: "maximizeIcon", isSignal: true, isRequired: false, transformFunction: null }, closeButtonProps: { classPropertyName: "closeButtonProps", publicName: "closeButtonProps", isSignal: true, isRequired: false, transformFunction: null }, maximizeButtonProps: { classPropertyName: "maximizeButtonProps", publicName: "maximizeButtonProps", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, appendTo: { classPropertyName: "appendTo", publicName: "appendTo", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange", onShow: "onShow", onHide: "onHide", onResizeInit: "onResizeInit", onResizeEnd: "onResizeEnd", onDragStart: "onDragStart", onDragEnd: "onDragEnd", onMaximize: "onMaximize" }, providers: [DialogStyle, { provide: DIALOG_INSTANCE, useExisting: Dialog }, { provide: PARENT_INSTANCE, useExisting: Dialog }], queries: [{ propertyName: "headerTemplate", first: true, predicate: ["header"], isSignal: true }, { propertyName: "contentTemplate", first: true, predicate: ["content"], isSignal: true }, { propertyName: "footerTemplate", first: true, predicate: ["footer"], isSignal: true }, { propertyName: "closeIconTemplate", first: true, predicate: ["closeicon"], isSignal: true }, { propertyName: "maximizeIconTemplate", first: true, predicate: ["maximizeicon"], isSignal: true }, { propertyName: "minimizeIconTemplate", first: true, predicate: ["minimizeicon"], isSignal: true }, { propertyName: "headlessTemplate", first: true, predicate: ["headless"], isSignal: true }], viewQueries: [{ propertyName: "headerViewChild", first: true, predicate: ["titlebar"], descendants: true, isSignal: true }, { propertyName: "contentViewChild", first: true, predicate: ["content"], descendants: true, isSignal: true }, { propertyName: "footerViewChild", first: true, predicate: ["footer"], descendants: true, isSignal: true }], usesInheritance: true, hostDirectives: [{ directive: i1.Bind }], ngImport: i0, template: ` @if (renderMask()) { <div [class]="cn(cx('mask'), maskStyleClass())" [style]="sx('mask')" [pBind]="ptm('mask')" [pMotion]="maskVisible" [pMotionAppear]="true" [pMotionEnterActiveClass]="maskEnterActiveClass()" [pMotionLeaveActiveClass]="maskLeaveActiveClass()" [pMotionOptions]="computedMaskMotionOptions()" (pMotionOnAfterLeave)="onMaskAfterLeave()" [attr.data-p-scrollblocker-active]="scrollBlockerActive()" [attr.data-p]="dataP()" > @if (renderDialog()) { <div #container [class]="cn(cx('root'), styleClass())" [style]="sx('root')" [pBind]="ptm('root')" pFocusTrap [pFocusTrapDisabled]="focusTrapDisabled()" [pMotion]="visible()" [pMotionAppear]="true" [pMotionName]="'p-dialog'" [pMotionOptions]="computedMotionOptions()" (pMotionOnBeforeEnter)="onBeforeEnter($event)" (pMotionOnAfterEnter)="onAfterEnter($event)" (pMotionOnBeforeLeave)="onBeforeLeave($event)" (pMotionOnAfterLeave)="onAfterLeave($event)" [attr.role]="role()" [attr.aria-labelledby]="ariaLabelledBy()" [attr.aria-modal]="true" [attr.data-p]="dataP()" > @if (headlessTemplate()) { <ng-container *ngTemplateOutlet="headlessTemplate()"></ng-container> } @else { @if (resizable()) { <div [class]="cx('resizeHandle')" [pBind]="ptm('resizeHandle')" [style.z-index]="90" (mousedown)="initResize($event)"></div> } @if (showHeader()) { <div #titlebar [class]="cx('header')" [pBind]="ptm('header')" (mousedown)="initDrag($event)"> @if (!headerTemplate()) { <span [id]="ariaLabelledBy()" [class]="cx('title')" [pBind]="ptm('title')">{{ header() }}</span> } <ng-container *ngTemplateOutlet="headerTemplate(); context: headerTemplateContext()"></ng-container> <div [class]="cx('headerActions')" [pBind]="ptm('headerActions')"> @if (maximizable()) { <button type="button" iconOnly [pButton]="maximizeButtonProps()" [class]="cx('pcMaximizeButton')" [tabindex]="maximizeButtonTabindex()" [attr.aria-label]="maximizeButtonAriaLabel()" [attr.data-pc-group-section]="'headericon'" [pButtonPT]="ptm('pcMaximizeButton')" [pButtonUnstyled]="unstyled()" (click)="maximize()" (keydown.enter)="m