pull/1047/head
Cagatay Civici 2021-03-01 23:54:17 +03:00
parent c3afd88435
commit ec15e94718
28 changed files with 434 additions and 611 deletions

View File

@ -14,29 +14,31 @@
</ul>
<i class="p-autocomplete-loader pi pi-spinner pi-spin" v-if="searching"></i>
<Button ref="dropdownButton" type="button" icon="pi pi-chevron-down" class="p-autocomplete-dropdown" :disabled="$attrs.disabled" @click="onDropdownClick" v-if="dropdown"/>
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave">
<div :ref="overlayRef" class="p-autocomplete-panel p-component" :style="{'max-height': scrollHeight}" v-if="overlayVisible">
<slot name="header" :value="modelValue" :suggestions="suggestions"></slot>
<ul :id="listId" class="p-autocomplete-items" role="listbox">
<template v-if="!optionGroupLabel">
<li v-for="(item, i) of suggestions" class="p-autocomplete-item" :key="i" @click="selectItem($event, item)" role="option" v-ripple>
<slot name="item" :item="item" :index="i">{{getItemContent(item)}}</slot>
</li>
</template>
<template v-else>
<template v-for="(optionGroup, i) of suggestions" :key="getOptionGroupRenderKey(optionGroup)">
<li class="p-autocomplete-item-group">
<slot name="optiongroup" :item="optionGroup" :index="i">{{getOptionGroupLabel(optionGroup)}}</slot>
</li>
<li v-for="(item, j) of getOptionGroupChildren(optionGroup)" class="p-autocomplete-item" :key="j" @click="selectItem($event, item)" role="option" v-ripple :data-group="i" :data-index="j">
<slot name="item" :item="item" :index="j">{{getItemContent(item)}}</slot>
<Teleport :to="appendTo">
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave">
<div :ref="overlayRef" class="p-autocomplete-panel p-component" :style="{'max-height': scrollHeight}" v-if="overlayVisible">
<slot name="header" :value="modelValue" :suggestions="suggestions"></slot>
<ul :id="listId" class="p-autocomplete-items" role="listbox">
<template v-if="!optionGroupLabel">
<li v-for="(item, i) of suggestions" class="p-autocomplete-item" :key="i" @click="selectItem($event, item)" role="option" v-ripple>
<slot name="item" :item="item" :index="i">{{getItemContent(item)}}</slot>
</li>
</template>
</template>
</ul>
<slot name="footer" :value="modelValue" :suggestions="suggestions"></slot>
</div>
</transition>
<template v-else>
<template v-for="(optionGroup, i) of suggestions" :key="getOptionGroupRenderKey(optionGroup)">
<li class="p-autocomplete-item-group">
<slot name="optiongroup" :item="optionGroup" :index="i">{{getOptionGroupLabel(optionGroup)}}</slot>
</li>
<li v-for="(item, j) of getOptionGroupChildren(optionGroup)" class="p-autocomplete-item" :key="j" @click="selectItem($event, item)" role="option" v-ripple :data-group="i" :data-index="j">
<slot name="item" :item="item" :index="j">{{getItemContent(item)}}</slot>
</li>
</template>
</template>
</ul>
<slot name="footer" :value="modelValue" :suggestions="suggestions"></slot>
</div>
</transition>
</Teleport>
</span>
</template>
@ -89,7 +91,7 @@ export default {
},
appendTo: {
type: String,
default: null
default: 'body'
},
forceSelection: {
type: Boolean,
@ -127,7 +129,6 @@ export default {
}
},
beforeUnmount() {
this.restoreAppend();
this.unbindOutsideClickListener();
this.unbindResizeListener();
@ -154,7 +155,6 @@ export default {
},
onOverlayEnter() {
this.overlay.style.zIndex = String(DomHandler.generateZIndex());
this.appendContainer();
this.alignOverlay();
this.bindOutsideClickListener();
this.bindScrollListener();
@ -168,10 +168,8 @@ export default {
},
alignOverlay() {
let target = this.multiple ? this.$refs.multiContainer : this.$refs.input;
if (this.appendTo)
DomHandler.absolutePosition(this.overlay, target);
else
DomHandler.relativePosition(this.overlay, target);
this.overlay.style.minWidth = DomHandler.getOuterWidth(target) + 'px';
DomHandler.absolutePosition(this.overlay, target);
},
bindOutsideClickListener() {
if (!this.outsideClickListener) {
@ -499,22 +497,6 @@ export default {
return selected;
},
appendContainer() {
if (this.appendTo) {
if (this.appendTo === 'body')
document.body.appendChild(this.overlay);
else
document.getElementById(this.appendTo).appendChild(this.overlay);
}
},
restoreAppend() {
if (this.overlay && this.appendTo) {
if (this.appendTo === 'body')
document.body.removeChild(this.overlay);
else
document.getElementById(this.appendTo).removeChild(this.overlay);
}
},
overlayRef(el) {
this.overlay = el;
}

View File

@ -3,130 +3,132 @@
<CalendarInputText ref="input" v-if="!inline" type="text" v-bind="$attrs" :value="inputFieldValue" @input="onInput" @focus="onFocus" @blur="onBlur" @keydown="onKeyDown" :readonly="!manualInput" inputmode="none"
:class="inputClass" :style="inputStyle" />
<CalendarButton v-if="showIcon" :icon="icon" tabindex="-1" class="p-datepicker-trigger" :disabled="$attrs.disabled" @click="onButtonClick" type="button" :aria-label="inputFieldValue"/>
<transition name="p-connected-overlay" @enter="onOverlayEnter($event)" @after-enter="onOverlayEnterComplete" @leave="onOverlayLeave">
<div :ref="overlayRef" :class="panelStyleClass" v-if="inline ? true : overlayVisible" :role="inline ? null : 'dialog'">
<template v-if="!timeOnly">
<div class="p-datepicker-group-container">
<div class="p-datepicker-group" v-for="(month,groupIndex) of months" :key="month.month + month.year">
<div class="p-datepicker-header">
<slot name="header"></slot>
<button class="p-datepicker-prev p-link" v-if="groupIndex === 0" @click="onPrevButtonClick" type="button" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled">
<span class="p-datepicker-prev-icon pi pi-chevron-left"></span>
</button>
<div class="p-datepicker-title">
<span class="p-datepicker-month" v-if="!monthNavigator && (view !== 'month')">{{getMonthName(month.month)}}</span>
<select class="p-datepicker-month" v-if="monthNavigator && (view !== 'month') && numberOfMonths === 1" @change="onMonthDropdownChange($event.target.value)">
<option :value="index" v-for="(monthName, index) of monthNames" :key="monthName" :selected="index === month.month">{{monthName}}</option>
</select>
<span class="p-datepicker-year" v-if="!yearNavigator">{{view === 'month' ? currentYear : month.year}}</span>
<select class="p-datepicker-year" v-if="yearNavigator && numberOfMonths === 1" @change="onYearDropdownChange($event.target.value)">
<option :value="year" v-for="year of yearOptions" :key="year" :selected="year === currentYear">{{year}}</option>
</select>
<Teleport :to="appendTo">
<transition name="p-connected-overlay" @enter="onOverlayEnter($event)" @after-enter="onOverlayEnterComplete" @leave="onOverlayLeave">
<div :ref="overlayRef" :class="panelStyleClass" v-if="inline ? true : overlayVisible" :role="inline ? null : 'dialog'">
<template v-if="!timeOnly">
<div class="p-datepicker-group-container">
<div class="p-datepicker-group" v-for="(month,groupIndex) of months" :key="month.month + month.year">
<div class="p-datepicker-header">
<slot name="header"></slot>
<button class="p-datepicker-prev p-link" v-if="groupIndex === 0" @click="onPrevButtonClick" type="button" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled">
<span class="p-datepicker-prev-icon pi pi-chevron-left"></span>
</button>
<div class="p-datepicker-title">
<span class="p-datepicker-month" v-if="!monthNavigator && (view !== 'month')">{{getMonthName(month.month)}}</span>
<select class="p-datepicker-month" v-if="monthNavigator && (view !== 'month') && numberOfMonths === 1" @change="onMonthDropdownChange($event.target.value)">
<option :value="index" v-for="(monthName, index) of monthNames" :key="monthName" :selected="index === month.month">{{monthName}}</option>
</select>
<span class="p-datepicker-year" v-if="!yearNavigator">{{view === 'month' ? currentYear : month.year}}</span>
<select class="p-datepicker-year" v-if="yearNavigator && numberOfMonths === 1" @change="onYearDropdownChange($event.target.value)">
<option :value="year" v-for="year of yearOptions" :key="year" :selected="year === currentYear">{{year}}</option>
</select>
</div>
<button class="p-datepicker-next p-link" v-if="numberOfMonths === 1 ? true : (groupIndex === numberOfMonths - 1)"
@click="onNextButtonClick" type="button" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled">
<span class="p-datepicker-next-icon pi pi-chevron-right"></span>
</button>
</div>
<div class="p-datepicker-calendar-container" v-if="view ==='date'">
<table class="p-datepicker-calendar">
<thead>
<tr>
<th scope="col" v-if="showWeek" class="p-datepicker-weekheader p-disabled">
<span>{{weekHeaderLabel}}</span>
</th>
<th scope="col" v-for="weekDay of weekDays" :key="weekDay">
<span>{{weekDay}}</span>
</th>
</tr>
</thead>
<tbody>
<tr v-for="(week,i) of month.dates" :key="week[0].day + '' + week[0].month">
<td v-if="showWeek" class="p-datepicker-weeknumber">
<span class="p-disabled">
<span style="visibility:hidden" v-if="month.weekNumbers[i] < 10">0</span>
{{month.weekNumbers[i]}}
</span>
</td>
<td v-for="date of week" :key="date.day + '' + date.month" :class="{'p-datepicker-other-month': date.otherMonth, 'p-datepicker-today': date.today}">
<span :class="{'p-highlight': isSelected(date), 'p-disabled': !date.selectable}" @click="onDateSelect($event, date)"
draggable="false" @keydown="onDateCellKeydown($event,date,groupIndex)" v-ripple>
<slot name="date" :date="date">{{date.day}}</slot>
</span>
</td>
</tr>
</tbody>
</table>
</div>
<button class="p-datepicker-next p-link" v-if="numberOfMonths === 1 ? true : (groupIndex === numberOfMonths - 1)"
@click="onNextButtonClick" type="button" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled">
<span class="p-datepicker-next-icon pi pi-chevron-right"></span>
</button>
</div>
<div class="p-datepicker-calendar-container" v-if="view ==='date'">
<table class="p-datepicker-calendar">
<thead>
<tr>
<th scope="col" v-if="showWeek" class="p-datepicker-weekheader p-disabled">
<span>{{weekHeaderLabel}}</span>
</th>
<th scope="col" v-for="weekDay of weekDays" :key="weekDay">
<span>{{weekDay}}</span>
</th>
</tr>
</thead>
<tbody>
<tr v-for="(week,i) of month.dates" :key="week[0].day + '' + week[0].month">
<td v-if="showWeek" class="p-datepicker-weeknumber">
<span class="p-disabled">
<span style="visibility:hidden" v-if="month.weekNumbers[i] < 10">0</span>
{{month.weekNumbers[i]}}
</span>
</td>
<td v-for="date of week" :key="date.day + '' + date.month" :class="{'p-datepicker-other-month': date.otherMonth, 'p-datepicker-today': date.today}">
<span :class="{'p-highlight': isSelected(date), 'p-disabled': !date.selectable}" @click="onDateSelect($event, date)"
draggable="false" @keydown="onDateCellKeydown($event,date,groupIndex)" v-ripple>
<slot name="date" :date="date">{{date.day}}</slot>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="p-monthpicker" v-if="view === 'month'">
<span v-for="(m,i) of monthPickerValues" :key="m" @click="onMonthSelect($event, i)" @keydown="onMonthCellKeydown($event,i)"
class="p-monthpicker-month" :class="{'p-highlight': isMonthSelected(i)}" v-ripple>
{{m}}
</span>
</div>
</template>
<div class="p-timepicker" v-if="showTime||timeOnly">
<div class="p-hour-picker">
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 0, 1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 0, 1)" @keyup.enter="onTimePickerElementMouseUp($event)" type="button">
<span class="pi pi-chevron-up"></span>
</button>
<span>{{formattedCurrentHour}}</span>
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 0, -1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 0, -1)" @keyup.enter="onTimePickerElementMouseUp($event)" type="button">
<span class="pi pi-chevron-down"></span>
</button>
</div>
<div class="p-separator">
<span>{{timeSeparator}}</span>
</div>
<div class="p-minute-picker">
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 1, 1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled"
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 1, 1)" @keyup.enter="onTimePickerElementMouseUp($event)" type="button">
<span class="pi pi-chevron-up"></span>
</button>
<span>{{formattedCurrentMinute}}</span>
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 1, -1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled"
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 1, -1)" @keyup.enter="onTimePickerElementMouseUp($event)" type="button">
<span class="pi pi-chevron-down"></span>
</button>
</div>
<div class="p-separator" v-if="showSeconds">
<span>{{timeSeparator}}</span>
</div>
<div class="p-second-picker" v-if="showSeconds">
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 2, 1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled"
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 2, 1)" @keyup.enter="onTimePickerElementMouseUp($event)" type="button">
<span class="pi pi-chevron-up"></span>
</button>
<span>{{formattedCurrentSecond}}</span>
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 2, -1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled"
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 2, -1)" @keyup.enter="onTimePickerElementMouseUp($event)" type="button">
<span class="pi pi-chevron-down"></span>
</button>
</div>
<div class="p-separator" v-if="hourFormat=='12'">
<span>{{timeSeparator}}</span>
</div>
<div class="p-ampm-picker" v-if="hourFormat=='12'">
<button class="p-link" @click="toggleAMPM($event)" type="button" v-ripple :disabled="$attrs.disabled">
<span class="pi pi-chevron-up"></span>
</button>
<span>{{pm ? 'PM' : 'AM'}}</span>
<button class="p-link" @click="toggleAMPM($event)" type="button" v-ripple :disabled="$attrs.disabled">
<span class="pi pi-chevron-down"></span>
</button>
</div>
</div>
<div class="p-monthpicker" v-if="view === 'month'">
<span v-for="(m,i) of monthPickerValues" :key="m" @click="onMonthSelect($event, i)" @keydown="onMonthCellKeydown($event,i)"
class="p-monthpicker-month" :class="{'p-highlight': isMonthSelected(i)}" v-ripple>
{{m}}
</span>
</div>
</template>
<div class="p-timepicker" v-if="showTime||timeOnly">
<div class="p-hour-picker">
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 0, 1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 0, 1)" @keyup.enter="onTimePickerElementMouseUp($event)" type="button">
<span class="pi pi-chevron-up"></span>
</button>
<span>{{formattedCurrentHour}}</span>
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 0, -1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 0, -1)" @keyup.enter="onTimePickerElementMouseUp($event)" type="button">
<span class="pi pi-chevron-down"></span>
</button>
</div>
<div class="p-separator">
<span>{{timeSeparator}}</span>
</div>
<div class="p-minute-picker">
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 1, 1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled"
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 1, 1)" @keyup.enter="onTimePickerElementMouseUp($event)" type="button">
<span class="pi pi-chevron-up"></span>
</button>
<span>{{formattedCurrentMinute}}</span>
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 1, -1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled"
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 1, -1)" @keyup.enter="onTimePickerElementMouseUp($event)" type="button">
<span class="pi pi-chevron-down"></span>
</button>
</div>
<div class="p-separator" v-if="showSeconds">
<span>{{timeSeparator}}</span>
</div>
<div class="p-second-picker" v-if="showSeconds">
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 2, 1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled"
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 2, 1)" @keyup.enter="onTimePickerElementMouseUp($event)" type="button">
<span class="pi pi-chevron-up"></span>
</button>
<span>{{formattedCurrentSecond}}</span>
<button class="p-link" @mousedown="onTimePickerElementMouseDown($event, 2, -1)" @mouseup="onTimePickerElementMouseUp($event)" @keydown="onContainerButtonKeydown" v-ripple :disabled="$attrs.disabled"
@mouseleave="onTimePickerElementMouseLeave()" @keydown.enter="onTimePickerElementMouseDown($event, 2, -1)" @keyup.enter="onTimePickerElementMouseUp($event)" type="button">
<span class="pi pi-chevron-down"></span>
</button>
</div>
<div class="p-separator" v-if="hourFormat=='12'">
<span>{{timeSeparator}}</span>
</div>
<div class="p-ampm-picker" v-if="hourFormat=='12'">
<button class="p-link" @click="toggleAMPM($event)" type="button" v-ripple :disabled="$attrs.disabled">
<span class="pi pi-chevron-up"></span>
</button>
<span>{{pm ? 'PM' : 'AM'}}</span>
<button class="p-link" @click="toggleAMPM($event)" type="button" v-ripple :disabled="$attrs.disabled">
<span class="pi pi-chevron-down"></span>
</button>
<div class="p-datepicker-buttonbar" v-if="showButtonBar">
<CalendarButton type="button" :label="todayLabel" @click="onTodayButtonClick($event)" class="p-button-text" @keydown="onContainerButtonKeydown"/>
<CalendarButton type="button" :label="clearLabel" @click="onClearButtonClick($event)" class="p-button-text" @keydown="onContainerButtonKeydown"/>
</div>
<slot name="footer"></slot>
</div>
<div class="p-datepicker-buttonbar" v-if="showButtonBar">
<CalendarButton type="button" :label="todayLabel" @click="onTodayButtonClick($event)" class="p-button-text" @keydown="onContainerButtonKeydown"/>
<CalendarButton type="button" :label="clearLabel" @click="onClearButtonClick($event)" class="p-button-text" @keydown="onContainerButtonKeydown"/>
</div>
<slot name="footer"></slot>
</div>
</transition>
</transition>
</Teleport>
</span>
</template>
@ -288,7 +290,7 @@ export default {
},
appendTo: {
type: String,
default: null
default: 'body'
},
inputClass: null,
inputStyle: null,
@ -333,7 +335,6 @@ export default {
this.destroyMask();
}
this.restoreAppend();
this.unbindOutsideClickListener();
this.unbindResizeListener();
@ -526,7 +527,6 @@ export default {
if (this.autoZIndex) {
this.overlay.style.zIndex = String(this.baseZIndex + DomHandler.generateZIndex());
}
this.appendContainer();
this.alignOverlay();
this.$emit('show');
},
@ -687,10 +687,8 @@ export default {
this.enableModality();
}
else if (this.overlay) {
if (this.appendTo)
DomHandler.absolutePosition(this.overlay, this.$el);
else
DomHandler.relativePosition(this.overlay, this.$el);
this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$el) + 'px';
DomHandler.absolutePosition(this.overlay, this.$el);
}
},
onButtonClick() {
@ -1922,22 +1920,6 @@ export default {
this.updateModel(event.target.value);
}
},
appendContainer() {
if (this.appendTo) {
if (this.appendTo === 'body')
document.body.appendChild(this.overlay);
else
document.getElementById(this.appendTo).appendChild(this.overlay);
}
},
restoreAppend() {
if (this.overlay && this.appendTo) {
if (this.appendTo === 'body')
document.body.removeChild(this.overlay);
else
document.getElementById(this.appendTo).removeChild(this.overlay);
}
},
onFocus() {
if (this.showOnFocus && this.isEnabled()) {
this.overlayVisible = true;

View File

@ -12,16 +12,18 @@
<div class="p-cascadeselect-trigger" role="button" aria-haspopup="listbox" :aria-expanded="overlayVisible">
<span class="p-cascadeselect-trigger-icon pi pi-chevron-down"></span>
</div>
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave">
<div :ref="overlayRef" class="p-cascadeselect-panel p-component" v-if="overlayVisible">
<div class="p-cascadeselect-items-wrapper">
<CascadeSelectSub :options="options" :selectionPath="selectionPath"
:optionLabel="optionLabel" :optionValue="optionValue" :level="0" :templates="$slots"
:optionGroupLabel="optionGroupLabel" :optionGroupChildren="optionGroupChildren"
@option-select="onOptionSelect" @optiongroup-select="onOptionGroupSelect" :dirty="dirty" :root="true" />
<Teleport :to="appendTo">
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave">
<div :ref="overlayRef" class="p-cascadeselect-panel p-component" v-if="overlayVisible">
<div class="p-cascadeselect-items-wrapper">
<CascadeSelectSub :options="options" :selectionPath="selectionPath"
:optionLabel="optionLabel" :optionValue="optionValue" :level="0" :templates="$slots"
:optionGroupLabel="optionGroupLabel" :optionGroupChildren="optionGroupChildren"
@option-select="onOptionSelect" @optiongroup-select="onOptionGroupSelect" :dirty="dirty" :root="true" />
</div>
</div>
</div>
</transition>
</transition>
</Teleport>
</div>
</template>
@ -56,7 +58,7 @@ export default {
ariaLabelledBy: null,
appendTo: {
type: String,
default: null
default: 'body'
}
},
outsideClickListener: null,
@ -64,7 +66,6 @@ export default {
resizeListener: null,
overlay: null,
beforeUnmount() {
this.restoreAppend();
this.unbindOutsideClickListener();
this.unbindResizeListener();
@ -165,7 +166,6 @@ export default {
},
onOverlayEnter() {
this.overlay.style.zIndex = String(DomHandler.generateZIndex());
this.appendContainer();
this.alignOverlay();
this.bindOutsideClickListener();
this.bindScrollListener();
@ -181,12 +181,8 @@ export default {
this.dirty = false;
},
alignOverlay() {
if (this.appendTo) {
DomHandler.absolutePosition(this.overlay, this.$el);
this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$el) + 'px';
} else {
DomHandler.relativePosition(this.overlay, this.$el);
}
DomHandler.absolutePosition(this.overlay, this.$el);
this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$el) + 'px';
},
bindOutsideClickListener() {
if (!this.outsideClickListener) {
@ -239,22 +235,6 @@ export default {
overlayRef(el) {
this.overlay = el;
},
appendContainer() {
if (this.appendTo) {
if (this.appendTo === 'body')
document.body.appendChild(this.overlay);
else
document.getElementById(this.appendTo).appendChild(this.overlay);
}
},
restoreAppend() {
if (this.overlay && this.appendTo) {
if (this.appendTo === 'body')
document.body.removeChild(this.overlay);
else
document.getElementById(this.appendTo).removeChild(this.overlay);
}
},
onKeyDown(event) {
switch(event.key) {
case 'Down':
@ -374,6 +354,7 @@ export default {
margin: 0;
padding: 0;
list-style-type: none;
min-width: 100%;
}
.p-fluid .p-cascadeselect {

View File

@ -2,22 +2,24 @@
<div ref="container" :class="containerClass">
<input ref="input" type="text" :class="inputClass" readonly="readonly" :tabindex="tabindex" :disabled="disabled"
@click="onInputClick" @keydown="onInputKeydown" v-if="!inline" :aria-labelledby="ariaLabelledBy"/>
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave">
<div :ref="pickerRef" :class="pickerClass" v-if="inline ? true : overlayVisible">
<div class="p-colorpicker-content">
<div :ref="colorSelectorRef" class="p-colorpicker-color-selector" @mousedown="onColorMousedown($event)"
@touchstart="onColorDragStart($event)" @touchmove="onDrag($event)" @touchend="onDragEnd()">
<div class="p-colorpicker-color">
<div :ref="colorHandleRef" class="p-colorpicker-color-handle"></div>
<Teleport to="body" :disabled="inline">
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave">
<div :ref="pickerRef" :class="pickerClass" v-if="inline ? true : overlayVisible">
<div class="p-colorpicker-content">
<div :ref="colorSelectorRef" class="p-colorpicker-color-selector" @mousedown="onColorMousedown($event)"
@touchstart="onColorDragStart($event)" @touchmove="onDrag($event)" @touchend="onDragEnd()">
<div class="p-colorpicker-color">
<div :ref="colorHandleRef" class="p-colorpicker-color-handle"></div>
</div>
</div>
<div :ref="hueViewRef" class="p-colorpicker-hue" @mousedown="onHueMousedown($event)"
@touchstart="onHueDragStart($event)" @touchmove="onDrag($event)" @touchend="onDragEnd()">
<div :ref="hueHandleRef" class="p-colorpicker-hue-handle"></div>
</div>
</div>
<div :ref="hueViewRef" class="p-colorpicker-hue" @mousedown="onHueMousedown($event)"
@touchstart="onHueDragStart($event)" @touchmove="onDrag($event)" @touchend="onDragEnd()">
<div :ref="hueHandleRef" class="p-colorpicker-hue-handle"></div>
</div>
</div>
</div>
</transition>
</transition>
</Teleport>
</div>
</template>
@ -349,7 +351,7 @@ export default {
this.clearRefs();
},
alignOverlay() {
DomHandler.relativePosition(this.picker, this.$refs.input);
DomHandler.absolutePosition(this.picker, this.$refs.input);
},
onInputClick() {
if (this.disabled) {

View File

@ -1,16 +1,18 @@
<template>
<transition name="p-confirm-popup" @enter="onEnter" @leave="onLeave">
<div class="p-confirm-popup p-component" v-if="visible" :ref="containerRef">
<div class="p-confirm-popup-content">
<i :class="iconClass" />
<span class="p-confirm-popup-message">{{confirmation.message}}</span>
<Teleport to="body">
<transition name="p-confirm-popup" @enter="onEnter" @leave="onLeave">
<div class="p-confirm-popup p-component" v-if="visible" :ref="containerRef" v-bind="$attrs">
<div class="p-confirm-popup-content">
<i :class="iconClass" />
<span class="p-confirm-popup-message">{{confirmation.message}}</span>
</div>
<div class="p-confirm-popup-footer">
<CPButton :label="rejectLabel" :icon="rejectIcon" :class="rejectClass" @click="reject()"/>
<CPButton :label="acceptLabel" :icon="acceptIcon" :class="acceptClass" @click="accept()" autofocus />
</div>
</div>
<div class="p-confirm-popup-footer">
<CPButton :label="rejectLabel" :icon="rejectIcon" :class="rejectClass" @click="reject()"/>
<CPButton :label="acceptLabel" :icon="acceptIcon" :class="acceptClass" @click="accept()" autofocus />
</div>
</div>
</transition>
</transition>
</Teleport>
</template>
<script>
@ -20,6 +22,7 @@ import {DomHandler} from 'primevue/utils';
import Button from 'primevue/button';
export default {
inheritAttrs: false,
props: {
group: String
},
@ -56,7 +59,6 @@ export default {
ConfirmationEventBus.off('confirm');
ConfirmationEventBus.off('close');
this.restoreAppend();
this.unbindOutsideClickListener();
if (this.scrollHandler) {
this.scrollHandler.destroy();
@ -83,7 +85,6 @@ export default {
this.visible = false;
},
onEnter() {
this.appendContainer();
this.alignOverlay();
this.bindOutsideClickListener();
this.bindScrollListener();
@ -162,14 +163,6 @@ export default {
isTargetClicked() {
return this.target && (this.target === event.target || this.target.contains(event.target));
},
appendContainer() {
document.body.appendChild(this.container);
},
restoreAppend() {
if (this.container) {
document.body.removeChild(this.container);
}
},
containerRef(el) {
this.container = el;
}

View File

@ -1,9 +1,11 @@
<template>
<transition name="p-contextmenu" @enter="onEnter" @leave="onLeave">
<div :ref="containerRef" class="p-contextmenu p-component" v-if="visible">
<ContextMenuSub :model="model" :root="true" @leaf-click="onLeafClick" />
</div>
</transition>
<Teleport :to="appendTo">
<transition name="p-contextmenu" @enter="onEnter" @leave="onLeave">
<div :ref="containerRef" class="p-contextmenu p-component" v-if="visible" v-bind="$attrs">
<ContextMenuSub :model="model" :root="true" @leaf-click="onLeafClick" />
</div>
</transition>
</Teleport>
</template>
<script>
@ -11,6 +13,7 @@ import {DomHandler} from 'primevue/utils';
import ContextMenuSub from './ContextMenuSub.vue';
export default {
inheritAttrs: false,
props: {
model: {
type: Array,
@ -18,7 +21,7 @@ export default {
},
appendTo: {
type: String,
default: null
default: 'body'
},
autoZIndex: {
type: Boolean,
@ -46,7 +49,6 @@ export default {
};
},
beforeUnmount() {
this.restoreAppend();
this.unbindResizeListener();
this.unbindOutsideClickListener();
this.unbindDocumentContextMenuListener();
@ -91,7 +93,6 @@ export default {
this.visible = false;
},
onEnter() {
this.appendContainer();
this.position();
this.bindOutsideClickListener();
this.bindResizeListener();
@ -166,22 +167,6 @@ export default {
this.resizeListener = null;
}
},
appendContainer() {
if (this.appendTo) {
if (this.appendTo === 'body')
document.body.appendChild(this.container);
else
document.getElementById(this.appendTo).appendChild(this.container);
}
},
restoreAppend() {
if (this.container && this.appendTo) {
if (this.appendTo === 'body')
document.body.removeChild(this.container);
else
document.getElementById(this.appendTo).removeChild(this.container);
}
},
bindDocumentContextMenuListener() {
if (!this.documentContextMenuListener) {
this.documentContextMenuListener = (event) => {

View File

@ -1,30 +1,33 @@
<template>
<div :ref="maskRef" :class="maskClass" v-if="containerVisible" @click="onMaskClick">
<transition name="p-dialog" @before-enter="onBeforeEnter" @enter="onEnter" @before-leave="onBeforeLeave" @leave="onLeave" @after-leave="onAfterLeave" appear>
<div :ref="containerRef" :class="dialogClass" v-if="visible" v-bind="$attrs" role="dialog" :aria-labelledby="ariaLabelledById" :aria-modal="modal">
<div class="p-dialog-header" v-if="showHeader">
<slot name="header">
<span :id="ariaLabelledById" class="p-dialog-title" v-if="header">{{header}}</span>
</slot>
<div class="p-dialog-header-icons">
<button class="p-dialog-header-icon p-dialog-header-maximize p-link" @click="maximize" v-if="maximizable" type="button" tabindex="-1" v-ripple>
<span :class="maximizeIconClass"></span>
</button>
<button class="p-dialog-header-icon p-dialog-header-close p-link" @click="close" v-if="closable" :aria-label="ariaCloseLabel" type="button" tabindex="-1" v-ripple>
<span class="p-dialog-header-close-icon pi pi-times"></span>
</button>
<Teleport to="body">
<div :ref="maskRef" :class="maskClass" v-if="containerVisible" @click="onMaskClick">
<transition name="p-dialog" @before-enter="onBeforeEnter" @enter="onEnter" @before-leave="onBeforeLeave" @leave="onLeave" @after-leave="onAfterLeave" appear>
<div :ref="containerRef" :class="dialogClass" v-if="visible" v-bind="$attrs" role="dialog" :aria-labelledby="ariaLabelledById" :aria-modal="modal">
<div class="p-dialog-header" v-if="showHeader">
<slot name="header">
<span :id="ariaLabelledById" class="p-dialog-title" v-if="header">{{header}}</span>
</slot>
<div class="p-dialog-header-icons">
<button class="p-dialog-header-icon p-dialog-header-maximize p-link" @click="maximize" v-if="maximizable" type="button" tabindex="-1" v-ripple>
<span :class="maximizeIconClass"></span>
</button>
<button class="p-dialog-header-icon p-dialog-header-close p-link" @click="close" v-if="closable" :aria-label="ariaCloseLabel" type="button" tabindex="-1" v-ripple>
<span class="p-dialog-header-close-icon pi pi-times"></span>
</button>
</div>
</div>
<div class="p-dialog-content" :style="contentStyle">
<slot></slot>
</div>
<div class="p-dialog-footer" v-if="footer || $slots.footer">
<slot name="footer">{{footer}}</slot>
</div>
</div>
<div class="p-dialog-content" :style="contentStyle">
<slot></slot>
</div>
<div class="p-dialog-footer" v-if="footer || $slots.footer">
<slot name="footer">{{footer}}</slot>
</div>
</div>
</transition>
</div>
</transition>
</div>
</Teleport>
</template>
<script>
import {UniqueComponentId,DomHandler} from 'primevue/utils';
import Ripple from 'primevue/ripple';

View File

@ -13,45 +13,47 @@
<div class="p-dropdown-trigger" role="button" aria-haspopup="listbox" :aria-expanded="overlayVisible">
<span class="p-dropdown-trigger-icon pi pi-chevron-down"></span>
</div>
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave">
<div :ref="overlayRef" class="p-dropdown-panel p-component" v-if="overlayVisible">
<slot name="header" :value="modelValue" :options="visibleOptions"></slot>
<div class="p-dropdown-header" v-if="filter">
<div class="p-dropdown-filter-container">
<input type="text" ref="filterInput" v-model="filterValue" autoComplete="off" class="p-dropdown-filter p-inputtext p-component" :placeholder="filterPlaceholder" @keydown="onFilterKeyDown" @input="onFilterChange"/>
<span class="p-dropdown-filter-icon pi pi-search"></span>
<Teleport :to="appendTo">
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave">
<div :ref="overlayRef" class="p-dropdown-panel p-component" v-if="overlayVisible">
<slot name="header" :value="modelValue" :options="visibleOptions"></slot>
<div class="p-dropdown-header" v-if="filter">
<div class="p-dropdown-filter-container">
<input type="text" ref="filterInput" v-model="filterValue" autoComplete="off" class="p-dropdown-filter p-inputtext p-component" :placeholder="filterPlaceholder" @keydown="onFilterKeyDown" @input="onFilterChange"/>
<span class="p-dropdown-filter-icon pi pi-search"></span>
</div>
</div>
</div>
<div :ref="itemsWrapperRef" class="p-dropdown-items-wrapper" :style="{'max-height': scrollHeight}">
<ul class="p-dropdown-items" role="listbox">
<template v-if="!optionGroupLabel">
<li v-for="(option, i) of visibleOptions" :class="['p-dropdown-item', {'p-highlight': isSelected(option), 'p-disabled': isOptionDisabled(option)}]" v-ripple
:key="getOptionRenderKey(option)" @click="onOptionSelect($event, option)" role="option" :aria-label="getOptionLabel(option)" :aria-selected="isSelected(option)">
<slot name="option" :option="option" :index="i">{{getOptionLabel(option)}}</slot>
</li>
</template>
<template v-else>
<template v-for="(optionGroup, i) of visibleOptions" :key="getOptionGroupRenderKey(optionGroup)">
<li class="p-dropdown-item-group" >
<slot name="optiongroup" :option="optionGroup" :index="i">{{getOptionGroupLabel(optionGroup)}}</slot>
</li>
<li v-for="(option, i) of getOptionGroupChildren(optionGroup)" :class="['p-dropdown-item', {'p-highlight': isSelected(option), 'p-disabled': isOptionDisabled(option)}]" v-ripple
<div :ref="itemsWrapperRef" class="p-dropdown-items-wrapper" :style="{'max-height': scrollHeight}">
<ul class="p-dropdown-items" role="listbox">
<template v-if="!optionGroupLabel">
<li v-for="(option, i) of visibleOptions" :class="['p-dropdown-item', {'p-highlight': isSelected(option), 'p-disabled': isOptionDisabled(option)}]" v-ripple
:key="getOptionRenderKey(option)" @click="onOptionSelect($event, option)" role="option" :aria-label="getOptionLabel(option)" :aria-selected="isSelected(option)">
<slot name="option" :option="option" :index="i">{{getOptionLabel(option)}}</slot>
</li>
</template>
</template>
<li v-if="filterValue && (!visibleOptions || (visibleOptions && visibleOptions.length === 0))" class="p-dropdown-empty-message">
<slot name="emptyfilter">{{emptyFilterMessageText}}</slot>
</li>
<li v-else-if="(!options || (options && options.length === 0))" class="p-dropdown-empty-message">
<slot name="empty">{{emptyMessageText}}</slot>
</li>
</ul>
<template v-else>
<template v-for="(optionGroup, i) of visibleOptions" :key="getOptionGroupRenderKey(optionGroup)">
<li class="p-dropdown-item-group" >
<slot name="optiongroup" :option="optionGroup" :index="i">{{getOptionGroupLabel(optionGroup)}}</slot>
</li>
<li v-for="(option, i) of getOptionGroupChildren(optionGroup)" :class="['p-dropdown-item', {'p-highlight': isSelected(option), 'p-disabled': isOptionDisabled(option)}]" v-ripple
:key="getOptionRenderKey(option)" @click="onOptionSelect($event, option)" role="option" :aria-label="getOptionLabel(option)" :aria-selected="isSelected(option)">
<slot name="option" :option="option" :index="i">{{getOptionLabel(option)}}</slot>
</li>
</template>
</template>
<li v-if="filterValue && (!visibleOptions || (visibleOptions && visibleOptions.length === 0))" class="p-dropdown-empty-message">
<slot name="emptyfilter">{{emptyFilterMessageText}}</slot>
</li>
<li v-else-if="(!options || (options && options.length === 0))" class="p-dropdown-empty-message">
<slot name="empty">{{emptyMessageText}}</slot>
</li>
</ul>
</div>
<slot name="footer" :value="modelValue" :options="visibleOptions"></slot>
</div>
<slot name="footer" :value="modelValue" :options="visibleOptions"></slot>
</div>
</transition>
</transition>
</Teleport>
</div>
</template>
@ -97,7 +99,7 @@ export default {
ariaLabelledBy: null,
appendTo: {
type: String,
default: null
default: 'body'
},
emptyFilterMessage: {
type: String,
@ -125,7 +127,6 @@ export default {
overlay: null,
itemsWrapper: null,
beforeUnmount() {
this.restoreAppend();
this.unbindOutsideClickListener();
this.unbindResizeListener();
@ -389,7 +390,6 @@ export default {
onOverlayEnter() {
this.overlay.style.zIndex = String(DomHandler.generateZIndex());
this.scrollValueInView();
this.appendContainer();
this.alignOverlay();
this.bindOutsideClickListener();
this.bindScrollListener();
@ -410,12 +410,8 @@ export default {
this.overlay = null;
},
alignOverlay() {
if (this.appendTo) {
DomHandler.absolutePosition(this.overlay, this.$el);
this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$el) + 'px';
} else {
DomHandler.relativePosition(this.overlay, this.$el);
}
this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$el) + 'px';
DomHandler.absolutePosition(this.overlay, this.$el);
},
updateModel(event, value) {
this.$emit('update:modelValue', value);
@ -549,22 +545,6 @@ export default {
let label = this.getOptionLabel(option).toLocaleLowerCase(this.filterLocale);
return label.startsWith(this.searchValue.toLocaleLowerCase(this.filterLocale));
},
appendContainer() {
if (this.appendTo) {
if (this.appendTo === 'body')
document.body.appendChild(this.overlay);
else
document.getElementById(this.appendTo).appendChild(this.overlay);
}
},
restoreAppend() {
if (this.overlay && this.appendTo) {
if (this.appendTo === 'body')
document.body.removeChild(this.overlay);
else
document.getElementById(this.appendTo).removeChild(this.overlay);
}
},
onFilterChange(event) {
this.$emit('filter', {originalEvent: event, value: event.target.value});
if (this.overlayVisible) {

View File

@ -1,11 +1,12 @@
<template>
<div v-if="fullScreen && containerVisible" :ref="maskRef" :class="maskContentClass">
<transition name="p-galleria" @before-enter="onBeforeEnter" @enter="onEnter" @before-leave="onBeforeLeave" @after-leave="onAfterLeave" appear>
<GalleriaContent :ref="containerRef" v-if="visible" v-bind="$props" @mask-hide="maskHide" :templates="$slots" @activeitem-change="onActiveItemChange" />
</transition>
</div>
<GalleriaContent v-else-if="!fullScreen" v-bind="$props" :templates="$slots" @activeitem-change="onActiveItemChange" />
<Teleport to="body" v-if="fullScreen">
<div v-if="containerVisible" :ref="maskRef" :class="maskContentClass">
<transition name="p-galleria" @before-enter="onBeforeEnter" @enter="onEnter" @before-leave="onBeforeLeave" @after-leave="onAfterLeave" appear>
<GalleriaContent :ref="containerRef" v-if="visible" v-bind="$props" @mask-hide="maskHide" :templates="$slots" @activeitem-change="onActiveItemChange" />
</transition>
</div>
</Teleport>
<GalleriaContent v-else v-bind="$props" :templates="$slots" @activeitem-change="onActiveItemChange" />
</template>
<script>

View File

@ -1,21 +1,23 @@
<template>
<transition name="p-connected-overlay" @enter="onEnter" @leave="onLeave">
<div :ref="containerRef" :class="containerClass" v-if="popup ? overlayVisible : true">
<ul class="p-menu-list p-reset" role="menu">
<template v-for="(item, i) of model" :key="item.label + i.toString()">
<template v-if="item.items && visible(item) && !item.separator">
<li class="p-submenu-header" v-if="item.items">{{item.label}}</li>
<template v-for="(child, j) of item.items" :key="child.label + i + j">
<Menuitem v-if="visible(child) && !child.separator" :item="child" @click="itemClick" />
<li v-else-if="visible(child) && child.separator" :class="['p-menu-separator', child.class]" :style="child.style" :key="'separator' + i + j" role="separator"></li>
<Teleport :to="appendTo" :disabled="!popup">
<transition name="p-connected-overlay" @enter="onEnter" @leave="onLeave">
<div :ref="containerRef" :class="containerClass" v-if="popup ? overlayVisible : true" v-bind="$attrs">
<ul class="p-menu-list p-reset" role="menu">
<template v-for="(item, i) of model" :key="item.label + i.toString()">
<template v-if="item.items && visible(item) && !item.separator">
<li class="p-submenu-header" v-if="item.items">{{item.label}}</li>
<template v-for="(child, j) of item.items" :key="child.label + i + j">
<Menuitem v-if="visible(child) && !child.separator" :item="child" @click="itemClick" />
<li v-else-if="visible(child) && child.separator" :class="['p-menu-separator', child.class]" :style="child.style" :key="'separator' + i + j" role="separator"></li>
</template>
</template>
<li v-else-if="visible(item) && item.separator" :class="['p-menu-separator', item.class]" :style="item.style" :key="'separator' + i.toString()" role="separator"></li>
<Menuitem v-else :key="item.label + i.toString()" :item="item" @click="itemClick" />
</template>
<li v-else-if="visible(item) && item.separator" :class="['p-menu-separator', item.class]" :style="item.style" :key="'separator' + i.toString()" role="separator"></li>
<Menuitem v-else :key="item.label + i.toString()" :item="item" @click="itemClick" />
</template>
</ul>
</div>
</transition>
</ul>
</div>
</transition>
</Teleport>
</template>
<script>
@ -24,6 +26,7 @@ import {DomHandler} from 'primevue/utils';
import Menuitem from './Menuitem.vue';
export default {
inheritAttrs: false,
props: {
popup: {
type: Boolean,
@ -35,7 +38,7 @@ export default {
},
appendTo: {
type: String,
default: null
default: 'body'
},
autoZIndex: {
type: Boolean,
@ -55,10 +58,8 @@ export default {
outsideClickListener: null,
scrollHandler: null,
resizeListener: null,
relativeAlign: false,
container: null,
beforeUnmount() {
this.restoreAppend();
this.unbindResizeListener();
this.unbindOutsideClickListener();
@ -94,16 +95,13 @@ export default {
},
show(event) {
this.overlayVisible = true;
this.relativeAlign = event.relativeAlign;
this.target = event.currentTarget;
},
hide() {
this.overlayVisible = false;
this.target = null;
this.relativeAlign = false;
},
onEnter() {
this.appendContainer();
this.alignOverlay();
this.bindOutsideClickListener();
this.bindResizeListener();
@ -119,11 +117,8 @@ export default {
this.unbindScrollListener();
},
alignOverlay() {
if (this.relativeAlign)
DomHandler.relativePosition(this.container, this.target);
else
DomHandler.absolutePosition(this.container, this.target);
DomHandler.absolutePosition(this.container, this.target);
this.container.style.minWidth = DomHandler.getOuterWidth(this.target) + 'px';
},
bindOutsideClickListener() {
if (!this.outsideClickListener) {
@ -176,22 +171,6 @@ export default {
isTargetClicked() {
return this.target && (this.target === event.target || this.target.contains(event.target));
},
appendContainer() {
if (this.appendTo) {
if (this.appendTo === 'body')
document.body.appendChild(this.container);
else
document.getElementById(this.appendTo).appendChild(this.container);
}
},
restoreAppend() {
if (this.container && this.appendTo) {
if (this.appendTo === 'body')
document.body.removeChild(this.container);
else
document.getElementById(this.appendTo).removeChild(this.container);
}
},
visible(item) {
return (typeof item.visible === 'function' ? item.visible() : item.visible !== false);
},

View File

@ -23,47 +23,31 @@
<div class="p-multiselect-trigger">
<span class="p-multiselect-trigger-icon pi pi-chevron-down"></span>
</div>
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave">
<div :ref="overlayRef" class="p-multiselect-panel p-component" v-if="overlayVisible">
<slot name="header" :value="modelValue" :options="visibleOptions"></slot>
<div class="p-multiselect-header">
<div class="p-checkbox p-component" @click="onToggleAll" role="checkbox" :aria-checked="allSelected">
<div class="p-hidden-accessible">
<input type="checkbox" readonly @focus="onHeaderCheckboxFocus" @blur="onHeaderCheckboxBlur">
<Teleport :to="appendTo">
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave">
<div :ref="overlayRef" class="p-multiselect-panel p-component" v-if="overlayVisible">
<slot name="header" :value="modelValue" :options="visibleOptions"></slot>
<div class="p-multiselect-header">
<div class="p-checkbox p-component" @click="onToggleAll" role="checkbox" :aria-checked="allSelected">
<div class="p-hidden-accessible">
<input type="checkbox" readonly @focus="onHeaderCheckboxFocus" @blur="onHeaderCheckboxBlur">
</div>
<div :class="['p-checkbox-box', {'p-highlight': allSelected, 'p-focus': headerCheckboxFocused}]" role="checkbox" :aria-checked="allSelected">
<span :class="['p-checkbox-icon', {'pi pi-check': allSelected}]"></span>
</div>
</div>
<div :class="['p-checkbox-box', {'p-highlight': allSelected, 'p-focus': headerCheckboxFocused}]" role="checkbox" :aria-checked="allSelected">
<span :class="['p-checkbox-icon', {'pi pi-check': allSelected}]"></span>
<div v-if="filter" class="p-multiselect-filter-container">
<input type="text" v-model="filterValue" class="p-multiselect-filter p-inputtext p-component" :placeholder="filterPlaceholder" @input="onFilterChange">
<span class="p-multiselect-filter-icon pi pi-search"></span>
</div>
<button class="p-multiselect-close p-link" @click="onCloseClick" type="button" v-ripple>
<span class="p-multiselect-close-icon pi pi-times" />
</button>
</div>
<div v-if="filter" class="p-multiselect-filter-container">
<input type="text" v-model="filterValue" class="p-multiselect-filter p-inputtext p-component" :placeholder="filterPlaceholder" @input="onFilterChange">
<span class="p-multiselect-filter-icon pi pi-search"></span>
</div>
<button class="p-multiselect-close p-link" @click="onCloseClick" type="button" v-ripple>
<span class="p-multiselect-close-icon pi pi-times" />
</button>
</div>
<div class="p-multiselect-items-wrapper" :style="{'max-height': scrollHeight}">
<ul class="p-multiselect-items p-component" role="listbox" aria-multiselectable="true">
<template v-if="!optionGroupLabel">
<li v-for="(option, i) of visibleOptions" :class="['p-multiselect-item', {'p-highlight': isSelected(option), 'p-disabled': isOptionDisabled(option)}]" role="option" :aria-selected="isSelected(option)"
:key="getOptionRenderKey(option)" @click="onOptionSelect($event, option)" @keydown="onOptionKeyDown($event, option)" :tabindex="tabindex||'0'" :aria-label="getOptionLabel(option)" v-ripple>
<div class="p-checkbox p-component">
<div :class="['p-checkbox-box', {'p-highlight': isSelected(option)}]">
<span :class="['p-checkbox-icon', {'pi pi-check': isSelected(option)}]"></span>
</div>
</div>
<slot name="option" :option="option" :index="i">
<span>{{getOptionLabel(option)}}</span>
</slot>
</li>
</template>
<template v-else>
<template v-for="(optionGroup, i) of visibleOptions" :key="getOptionGroupRenderKey(optionGroup)">
<li class="p-multiselect-item-group">
<slot name="optiongroup" :option="optionGroup" :index="i">{{getOptionGroupLabel(optionGroup)}}</slot>
</li>
<li v-for="(option, i) of getOptionGroupChildren(optionGroup)" :class="['p-multiselect-item', {'p-highlight': isSelected(option), 'p-disabled': isOptionDisabled(option)}]" role="option" :aria-selected="isSelected(option)"
<div class="p-multiselect-items-wrapper" :style="{'max-height': scrollHeight}">
<ul class="p-multiselect-items p-component" role="listbox" aria-multiselectable="true">
<template v-if="!optionGroupLabel">
<li v-for="(option, i) of visibleOptions" :class="['p-multiselect-item', {'p-highlight': isSelected(option), 'p-disabled': isOptionDisabled(option)}]" role="option" :aria-selected="isSelected(option)"
:key="getOptionRenderKey(option)" @click="onOptionSelect($event, option)" @keydown="onOptionKeyDown($event, option)" :tabindex="tabindex||'0'" :aria-label="getOptionLabel(option)" v-ripple>
<div class="p-checkbox p-component">
<div :class="['p-checkbox-box', {'p-highlight': isSelected(option)}]">
@ -75,18 +59,36 @@
</slot>
</li>
</template>
</template>
<li v-if="filterValue && (!visibleOptions || (visibleOptions && visibleOptions.length === 0))" class="p-multiselect-empty-message">
<slot name="emptyfilter">{{emptyFilterMessageText}}</slot>
</li>
<li v-else-if="(!options || (options && options.length === 0))" class="p-multiselect-empty-message">
<slot name="empty">{{emptyMessageText}}</slot>
</li>
</ul>
<template v-else>
<template v-for="(optionGroup, i) of visibleOptions" :key="getOptionGroupRenderKey(optionGroup)">
<li class="p-multiselect-item-group">
<slot name="optiongroup" :option="optionGroup" :index="i">{{getOptionGroupLabel(optionGroup)}}</slot>
</li>
<li v-for="(option, i) of getOptionGroupChildren(optionGroup)" :class="['p-multiselect-item', {'p-highlight': isSelected(option), 'p-disabled': isOptionDisabled(option)}]" role="option" :aria-selected="isSelected(option)"
:key="getOptionRenderKey(option)" @click="onOptionSelect($event, option)" @keydown="onOptionKeyDown($event, option)" :tabindex="tabindex||'0'" :aria-label="getOptionLabel(option)" v-ripple>
<div class="p-checkbox p-component">
<div :class="['p-checkbox-box', {'p-highlight': isSelected(option)}]">
<span :class="['p-checkbox-icon', {'pi pi-check': isSelected(option)}]"></span>
</div>
</div>
<slot name="option" :option="option" :index="i">
<span>{{getOptionLabel(option)}}</span>
</slot>
</li>
</template>
</template>
<li v-if="filterValue && (!visibleOptions || (visibleOptions && visibleOptions.length === 0))" class="p-multiselect-empty-message">
<slot name="emptyfilter">{{emptyFilterMessageText}}</slot>
</li>
<li v-else-if="(!options || (options && options.length === 0))" class="p-multiselect-empty-message">
<slot name="empty">{{emptyMessageText}}</slot>
</li>
</ul>
</div>
<slot name="footer" :value="modelValue" :options="visibleOptions"></slot>
</div>
<slot name="footer" :value="modelValue" :options="visibleOptions"></slot>
</div>
</transition>
</transition>
</Teleport>
</div>
</template>
@ -130,7 +132,7 @@ export default {
ariaLabelledBy: null,
appendTo: {
type: String,
default: null
default: 'body'
},
emptyFilterMessage: {
type: String,
@ -158,7 +160,6 @@ export default {
scrollHandler: null,
overlay: null,
beforeUnmount() {
this.restoreAppend();
this.unbindOutsideClickListener();
this.unbindResizeListener();
@ -342,7 +343,6 @@ export default {
},
onOverlayEnter() {
this.overlay.style.zIndex = String(DomHandler.generateZIndex());
this.appendContainer();
this.alignOverlay();
this.bindOutsideClickListener();
this.bindScrollListener();
@ -357,13 +357,8 @@ export default {
this.overlay = null;
},
alignOverlay() {
if (this.appendTo) {
DomHandler.absolutePosition(this.overlay, this.$el);
this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$el) + 'px';
}
else {
DomHandler.relativePosition(this.overlay, this.$el);
}
this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$el) + 'px';
DomHandler.absolutePosition(this.overlay, this.$el);
},
bindOutsideClickListener() {
if (!this.outsideClickListener) {
@ -464,22 +459,6 @@ export default {
this.$emit('update:modelValue', value);
this.$emit('change', {originalEvent: event, value: value});
},
appendContainer() {
if (this.appendTo) {
if (this.appendTo === 'body')
document.body.appendChild(this.overlay);
else
document.getElementById(this.appendTo).appendChild(this.overlay);
}
},
restoreAppend() {
if (this.overlay && this.appendTo) {
if (this.appendTo === 'body')
document.body.removeChild(this.overlay);
else
document.getElementById(this.appendTo).removeChild(this.overlay);
}
},
onFilterChange(event) {
this.$emit('filter', {originalEvent: event, value: event.target.value});
if (this.overlayVisible) {

View File

@ -1,14 +1,16 @@
<template>
<transition name="p-overlaypanel" @enter="onEnter" @leave="onLeave">
<div class="p-overlaypanel p-component" v-if="visible" :ref="containerRef">
<div class="p-overlaypanel-content" @click="onContentClick">
<slot></slot>
<Teleport :to="appendTo">
<transition name="p-overlaypanel" @enter="onEnter" @leave="onLeave">
<div class="p-overlaypanel p-component" v-if="visible" :ref="containerRef" v-bind="$attrs">
<div class="p-overlaypanel-content" @click="onContentClick">
<slot></slot>
</div>
<button class="p-overlaypanel-close p-link" @click="hide" v-if="showCloseIcon" :aria-label="ariaCloseLabel" type="button" v-ripple>
<span class="p-overlaypanel-close-icon pi pi-times"></span>
</button>
</div>
<button class="p-overlaypanel-close p-link" @click="hide" v-if="showCloseIcon" :aria-label="ariaCloseLabel" type="button" v-ripple>
<span class="p-overlaypanel-close-icon pi pi-times"></span>
</button>
</div>
</transition>
</transition>
</Teleport>
</template>
<script>
@ -17,6 +19,7 @@ import {DomHandler} from 'primevue/utils';
import Ripple from 'primevue/ripple';
export default {
inheritAttrs: false,
props: {
dismissable: {
type: Boolean,
@ -28,7 +31,7 @@ export default {
},
appendTo: {
type: String,
default: null
default: 'body'
},
baseZIndex: {
type: Number,
@ -55,7 +58,6 @@ export default {
resizeListener: null,
container: null,
beforeUnmount() {
this.restoreAppend();
if (this.dismissable) {
this.unbindOutsideClickListener();
}
@ -86,7 +88,6 @@ export default {
this.selfClick = true;
},
onEnter() {
this.appendContainer();
this.alignOverlay();
if (this.dismissable) {
this.bindOutsideClickListener();
@ -173,22 +174,6 @@ export default {
isTargetClicked(event) {
return this.target && (this.target === event.target || this.target.contains(event.target));
},
appendContainer() {
if (this.appendTo) {
if (this.appendTo === 'body')
document.body.appendChild(this.container);
else
document.getElementById(this.appendTo).appendChild(this.container);
}
},
restoreAppend() {
if (this.container && this.appendTo) {
if (this.appendTo === 'body')
document.body.removeChild(this.container);
else
document.getElementById(this.appendTo).removeChild(this.container);
}
},
containerRef(el) {
this.container = el;
}

View File

@ -2,18 +2,20 @@
<div :class="containerClass" :style="style">
<PInputText ref="input" :class="inputFieldClass" :style="inputStyle" :type="inputType" :value="modelValue" @input="onInput" @focus="onFocus" @blur="onBlur" @keyup="onKeyUp" v-bind="$attrs" />
<i v-if="toggleMask" :class="toggleIconClass" @click="onMaskToggle" />
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave">
<div :ref="overlayRef" class="p-password-panel p-component" v-if="overlayVisible">
<slot name="header"></slot>
<slot name="content">
<div class="p-password-meter">
<div :class="strengthClass" :style="{'width': meter ? meter.width : ''}"></div>
</div>
<div className="p-password-info">{{infoText}}</div>
</slot>
<slot name="footer"></slot>
</div>
</transition>
<Teleport :to="appendTo">
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave">
<div :ref="overlayRef" class="p-password-panel p-component" v-if="overlayVisible">
<slot name="header"></slot>
<slot name="content">
<div class="p-password-meter">
<div :class="strengthClass" :style="{'width': meter ? meter.width : ''}"></div>
</div>
<div className="p-password-info">{{infoText}}</div>
</slot>
<slot name="footer"></slot>
</div>
</transition>
</Teleport>
</div>
</template>
@ -57,7 +59,7 @@ export default {
},
appendTo: {
type: String,
default: null
default: 'body'
},
toggleMask: {
type: Boolean,
@ -88,7 +90,6 @@ export default {
this.strongCheckRegExp = new RegExp(this.strongRegex);
},
beforeUnmount() {
this.restoreAppend();
this.unbindResizeListener();
if (this.scrollHandler) {
this.scrollHandler.destroy();
@ -98,7 +99,6 @@ export default {
methods: {
onOverlayEnter() {
this.overlay.style.zIndex = String(DomHandler.generateZIndex());
this.appendContainer();
this.alignOverlay();
this.bindScrollListener();
this.bindResizeListener();
@ -109,29 +109,8 @@ export default {
this.overlay = null;
},
alignOverlay() {
if (this.appendTo) {
this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$refs.input.$el) + 'px';
DomHandler.absolutePosition(this.overlay, this.$refs.input.$el);
}
else {
DomHandler.relativePosition(this.overlay, this.$refs.input.$el);
}
},
appendContainer() {
if (this.appendTo) {
if (this.appendTo === 'body')
document.body.appendChild(this.overlay);
else
document.getElementById(this.appendTo).appendChild(this.overlay);
}
},
restoreAppend() {
if (this.overlay && this.appendTo) {
if (this.appendTo === 'body')
document.body.removeChild(this.overlay);
else
document.getElementById(this.appendTo).removeChild(this.overlay);
}
this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$refs.input.$el) + 'px';
DomHandler.absolutePosition(this.overlay, this.$refs.input.$el);
},
testStrength(str) {
let level = 0;

View File

@ -1,14 +1,16 @@
<template>
<transition name="p-sidebar" @enter="onEnter" @leave="onLeave" appear>
<div :class="containerClass" v-if="visible" ref="container" role="complementary" :aria-modal="modal">
<div class="p-sidebar-content">
<button class="p-sidebar-close p-link" @click="hide" :aria-label="ariaCloseLabel" v-if="showCloseIcon" type="button" v-ripple>
<span class="p-sidebar-close-icon pi pi-times" />
</button>
<slot></slot>
<Teleport to="body">
<transition name="p-sidebar" @enter="onEnter" @leave="onLeave" appear>
<div :class="containerClass" v-if="visible" ref="container" role="complementary" :aria-modal="modal" v-bind="$attrs">
<div class="p-sidebar-content">
<button class="p-sidebar-close p-link" @click="hide" :aria-label="ariaCloseLabel" v-if="showCloseIcon" type="button" v-ripple>
<span class="p-sidebar-close-icon pi pi-times" />
</button>
<slot></slot>
</div>
</div>
</div>
</transition>
</transition>
</Teleport>
</template>
<script>
@ -17,6 +19,7 @@ import Ripple from 'primevue/ripple';
export default {
emits: ['update:visible', 'show', 'hide'],
inheritAttrs: false,
props: {
visible: {
type: Boolean,

View File

@ -38,14 +38,14 @@ export default {
},
appendTo: {
type: String,
default: null
default: 'body'
},
class: null,
style: null
},
methods: {
onDropdownButtonClick() {
this.$refs.menu.toggle({currentTarget: this.$el, relativeAlign: this.appendTo == null});
this.$refs.menu.toggle({currentTarget: this.$el});
},
onDefaultButtonClick() {
this.$refs.menu.hide();

View File

@ -1,9 +1,11 @@
<template>
<transition name="p-connected-overlay" @enter="onEnter" @leave="onLeave">
<div :ref="containerRef" :class="containerClass" v-if="popup ? visible : true">
<TieredMenuSub :model="model" :root="true" :popup="popup" @leaf-click="onLeafClick"/>
</div>
</transition>
<Teleport :to="appendTo" :disabled="!popup">
<transition name="p-connected-overlay" @enter="onEnter" @leave="onLeave">
<div :ref="containerRef" :class="containerClass" v-if="popup ? visible : true" v-bind="$attrs">
<TieredMenuSub :model="model" :root="true" :popup="popup" @leaf-click="onLeafClick"/>
</div>
</transition>
</Teleport>
</template>
<script>
@ -12,6 +14,7 @@ import {DomHandler} from 'primevue/utils';
import TieredMenuSub from './TieredMenuSub.vue';
export default {
inheritAttrs: false,
props: {
popup: {
type: Boolean,
@ -23,7 +26,7 @@ export default {
},
appendTo: {
type: String,
default: null
default: 'body'
},
autoZIndex: {
type: Boolean,
@ -45,7 +48,6 @@ export default {
};
},
beforeUnmount() {
this.restoreAppend();
this.unbindResizeListener();
this.unbindOutsideClickListener();
@ -79,7 +81,6 @@ export default {
this.visible = false;
},
onEnter() {
this.appendContainer();
this.alignOverlay();
this.bindOutsideClickListener();
this.bindResizeListener();
@ -96,6 +97,7 @@ export default {
},
alignOverlay() {
DomHandler.absolutePosition(this.container, this.target);
this.container.style.minWidth = DomHandler.getOuterWidth(this.target) + 'px';
},
bindOutsideClickListener() {
if (!this.outsideClickListener) {
@ -148,22 +150,6 @@ export default {
isTargetClicked() {
return this.target && (this.target === event.target || this.target.contains(event.target));
},
appendContainer() {
if (this.appendTo) {
if (this.appendTo === 'body')
document.body.appendChild(this.container);
else
document.getElementById(this.appendTo).appendChild(this.container);
}
},
restoreAppend() {
if (this.container && this.appendTo) {
if (this.appendTo === 'body')
document.body.removeChild(this.container);
else
document.getElementById(this.appendTo).removeChild(this.container);
}
},
onLeafClick() {
if (this.popup) {
this.hide();

View File

@ -1,9 +1,11 @@
<template>
<div ref="container" :class="containerClass">
<transition-group name="p-toast-message" tag="div">
<ToastMessage v-for="msg of messages" :key="msg.id" :message="msg" @close="remove($event)"/>
</transition-group>
</div>
<Teleport to="body">
<div ref="container" :class="containerClass" v-bind="$attrs">
<transition-group name="p-toast-message" tag="div">
<ToastMessage v-for="msg of messages" :key="msg.id" :message="msg" @close="remove($event)"/>
</transition-group>
</div>
</Teleport>
</template>
<script>
@ -14,6 +16,7 @@ import {DomHandler} from 'primevue/utils';
var messageIdx = 0;
export default {
inheritAttrs: false,
props: {
group: {
type: String,

View File

@ -210,8 +210,8 @@ export default {
<tr>
<td>appendTo</td>
<td>string</td>
<td>null</td>
<td>Id of the element or "body" for document where the overlay should be appended to.</td>
<td>body</td>
<td>A valid query selector or an HTMLElement to specify where the overlay gets attached.</td>
</tr>
<tr>
<td>inputStyle</td>

View File

@ -400,8 +400,8 @@ export default {
<tr>
<td>appendTo</td>
<td>string</td>
<td>null</td>
<td>Id of the element or "body" for document where the overlay should be appended to.</td>
<td>body</td>
<td>A valid query selector or an HTMLElement to specify where the overlay gets attached.</td>
</tr>
<tr>
<td>inputStyle</td>

View File

@ -212,8 +212,8 @@ data() {
<tr>
<td>appendTo</td>
<td>string</td>
<td>null</td>
<td>Id of the element or "body" for document where the overlay should be appended to.</td>
<td>body</td>
<td>A valid query selector or an HTMLElement to specify where the overlay gets attached.</td>
</tr>
</tbody>
</table>

View File

@ -209,8 +209,8 @@ export default {
<tr>
<td>appendTo</td>
<td>string</td>
<td>null</td>
<td>Id of the element or "body" for document where the overlay should be appended to.</td>
<td>body</td>
<td>A valid query selector or an HTMLElement to specify where the overlay gets attached.</td>
</tr>
<tr>
<td>baseZIndex</td>

View File

@ -256,8 +256,8 @@ export default {
<tr>
<td>appendTo</td>
<td>string</td>
<td>null</td>
<td>Id of the element or "body" for document where the overlay should be appended to.</td>
<td>body</td>
<td>A valid query selector or an HTMLElement to specify where the overlay gets attached.</td>
</tr>
<tr>
<td>emptyFilterMessage</td>

View File

@ -116,8 +116,8 @@ toggle(event) {
<tr>
<td>appendTo</td>
<td>string</td>
<td>null</td>
<td>Id of the element or "body" for document where the overlay should be appended to.</td>
<td>body</td>
<td>A valid query selector or an HTMLElement to specify where the overlay gets attached.</td>
</tr>
<tr>
<td>baseZIndex</td>

View File

@ -252,8 +252,8 @@ export default {
<tr>
<td>appendTo</td>
<td>string</td>
<td>null</td>
<td>Id of the element or "body" for document where the overlay should be appended to.</td>
<td>body</td>
<td>A valid query selector or an HTMLElement to specify where the overlay gets attached.</td>
</tr>
<tr>
<td>emptyFilterMessage</td>

View File

@ -63,8 +63,8 @@ toggle(event) {
<tr>
<td>appendTo</td>
<td>string</td>
<td>null</td>
<td>Id of the element or "body" for document where the overlay should be appended to.</td>
<td>body</td>
<td>A valid query selector or an HTMLElement to specify where the overlay gets attached.</td>
</tr>
<tr>
<td>baseZIndex</td>

View File

@ -128,8 +128,8 @@ import Password from 'primevue/password';
<tr>
<td>appendTo</td>
<td>string</td>
<td>null</td>
<td>Id of the element or "body" for document where the overlay should be appended to.</td>
<td>body</td>
<td>A valid query selector or an HTMLElement to specify where the overlay gets attached.</td>
</tr>
<tr>
<td>inputStyle</td>

View File

@ -125,8 +125,8 @@ export default {
<tr>
<td>appendTo</td>
<td>string</td>
<td>null</td>
<td>Id of the element or "body" for document where the overlay should be appended to.</td>
<td>body</td>
<td>A valid query selector or an HTMLElement to specify where the overlay gets attached.</td>
</tr>
</tbody>
</table>

View File

@ -203,8 +203,8 @@ toggle(event) {
<tr>
<td>appendTo</td>
<td>string</td>
<td>null</td>
<td>Id of the element or "body" for document where the overlay should be appended to.</td>
<td>body</td>
<td>A valid query selector or an HTMLElement to specify where the overlay gets attached.</td>
</tr>
<tr>
<td>baseZIndex</td>