Skip to content

Commit

Permalink
Fix #791 - ConfirmPopup Component
Browse files Browse the repository at this point in the history
  • Loading branch information
tugcekucukoglu committed Dec 16, 2020
1 parent 9616579 commit a41dc49
Show file tree
Hide file tree
Showing 9 changed files with 612 additions and 0 deletions.
1 change: 1 addition & 0 deletions exports/confirmpopup.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './components/confirmpopup/ConfirmPopup';
2 changes: 2 additions & 0 deletions exports/confirmpopup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
'use strict';
module.exports = require('./components/confirmpopup/ConfirmPopup.vue');
1 change: 1 addition & 0 deletions src/AppMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@
<div class="menu-category">Overlay</div>
<div class="menu-items">
<router-link to="/confirmdialog">ConfirmDialog <Tag value="New"></Tag></router-link>
<router-link to="/confirmpopup">ConfirmPopup <Tag value="New"></Tag></router-link>
<router-link to="/dialog">Dialog</router-link>
<router-link to="/overlaypanel">OverlayPanel</router-link>
<router-link to="/sidebar">Sidebar</router-link>
Expand Down
7 changes: 7 additions & 0 deletions src/components/confirmpopup/ConfirmPopup.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Vue from 'vue';

declare class ConfirmPopup extends Vue {
group?: string;
}

export default ConfirmPopup;
272 changes: 272 additions & 0 deletions src/components/confirmpopup/ConfirmPopup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
<template>
<transition name="p-confirm-popup" @enter="onEnter" @leave="onLeave">
<div class="p-confirm-popup p-component" v-if="visible" ref="container">
<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>
</transition>
</template>

<script>
import ConfirmationEventBus from '../confirmation/ConfirmationEventBus';
import ConnectedOverlayScrollHandler from '../utils/ConnectedOverlayScrollHandler';
import DomHandler from '../utils/DomHandler';
import Button from '../button/Button';
export default {
props: {
group: String
},
data() {
return {
visible: false,
confirmation: null
}
},
target: null,
outsideClickListener: null,
scrollHandler: null,
resizeListener: null,
container: null,
mounted() {
ConfirmationEventBus.on('confirm', (options) => {
if (!options) {
return;
}
if (options.group === this.group) {
this.confirmation = options;
this.target = options.target;
this.visible = true;
}
});
ConfirmationEventBus.on('close', () => {
this.visible = false;
this.confirmation = null;
});
},
beforeDestroy() {
ConfirmationEventBus.off('confirm');
ConfirmationEventBus.off('close');
this.restoreAppend();
this.unbindOutsideClickListener();
if (this.scrollHandler) {
this.scrollHandler.destroy();
this.scrollHandler = null;
}
this.unbindResizeListener();
this.target = null;
this.container = null;
this.confirmation = null;
},
methods: {
accept() {
if (this.confirmation.accept) {
this.confirmation.accept();
}
this.visible = false;
},
reject() {
if (this.confirmation.reject) {
this.confirmation.reject();
}
this.visible = false;
},
onEnter() {
this.appendContainer();
this.alignOverlay();
this.bindOutsideClickListener();
this.bindScrollListener();
this.bindResizeListener();
this.$refs.container.style.zIndex = String(this.baseZIndex + DomHandler.generateZIndex());
},
onLeave() {
this.unbindOutsideClickListener();
this.unbindScrollListener();
this.unbindResizeListener();
},
alignOverlay() {
DomHandler.absolutePosition(this.$refs.container, this.target);
const containerOffset = DomHandler.getOffset(this.$refs.container);
const targetOffset = DomHandler.getOffset(this.target);
let arrowLeft = 0;
if (containerOffset.left < targetOffset.left) {
arrowLeft = targetOffset.left - containerOffset.left;
}
this.$refs.container.style.setProperty('--overlayArrowLeft', `${arrowLeft}px`);
if (containerOffset.top < targetOffset.top) {
DomHandler.addClass(this.$refs.container, 'p-confirm-popup-flipped');
}
},
bindOutsideClickListener() {
if (!this.outsideClickListener) {
this.outsideClickListener = (event) => {
if (this.visible && this.$refs.container && !this.$refs.container.contains(event.target) && !this.isTargetClicked(event)) {
this.visible = false;
}
};
document.addEventListener('click', this.outsideClickListener);
}
},
unbindOutsideClickListener() {
if (this.outsideClickListener) {
document.removeEventListener('click', this.outsideClickListener);
this.outsideClickListener = null;
}
},
bindScrollListener() {
if (!this.scrollHandler) {
this.scrollHandler = new ConnectedOverlayScrollHandler(this.target, () => {
if (this.visible) {
this.visible = false;
}
});
}
this.scrollHandler.bindScrollListener();
},
unbindScrollListener() {
if (this.scrollHandler) {
this.scrollHandler.unbindScrollListener();
}
},
bindResizeListener() {
if (!this.resizeListener) {
this.resizeListener = () => {
if (this.visible) {
this.visible = false;
}
};
window.addEventListener('resize', this.resizeListener);
}
},
unbindResizeListener() {
if (this.resizeListener) {
window.removeEventListener('resize', this.resizeListener);
this.resizeListener = null;
}
},
isTargetClicked() {
return this.target && (this.target === event.target || this.target.contains(event.target));
},
appendContainer() {
document.body.append(this.$refs.container);
},
restoreAppend() {
if (this.container) {
document.body.remove(this.$refs.container);
}
}
},
computed: {
message() {
return this.confirmation ? this.confirmation.message : null;
},
iconClass() {
return ['p-confirm-popup-icon', this.confirmation ? this.confirmation.icon : null];
},
acceptLabel() {
return this.confirmation ? (this.confirmation.acceptLabel || 'Yes') : null;
},
rejectLabel() {
return this.confirmation ? (this.confirmation.rejectLabel || 'No') : null;
},
acceptIcon() {
return this.confirmation ? this.confirmation.acceptIcon : null;
},
rejectIcon() {
return this.confirmation ? this.confirmation.rejectIcon : null;
},
acceptClass() {
return ['p-confirm-popup-accept p-button-sm', this.confirmation ? this.confirmation.acceptClass : null];
},
rejectClass() {
return ['p-confirm-popup-reject p-button-sm', this.confirmation ? (this.confirmation.rejectClass || 'p-button-text') : null];
}
},
components: {
'CPButton': Button
}
}
</script>

<style>
.p-confirm-popup {
position: absolute;
margin-top: 10px;
}
.p-confirm-popup-flipped {
margin-top: 0;
margin-bottom: 10px;
}
/* Animation */
.p-confirm-popup-enter-from {
opacity: 0;
transform: scaleY(0.8);
}
.p-confirm-popup-leave-to {
opacity: 0;
}
.p-confirm-popup-enter-active {
transition: transform .12s cubic-bezier(0, 0, 0.2, 1), opacity .12s cubic-bezier(0, 0, 0.2, 1);
}
.p-confirm-popup-leave-active {
transition: opacity .1s linear;
}
.p-confirm-popup:after, .p-confirm-popup:before {
bottom: 100%;
left: calc(var(--overlayArrowLeft, 0) + 1.25rem);
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.p-confirm-popup:after {
border-width: 8px;
margin-left: -8px;
}
.p-confirm-popup:before {
border-width: 10px;
margin-left: -10px;
}
.p-confirm-popup-flipped:after, .p-confirm-popup-flipped:before {
bottom: auto;
top: 100%;
}
.p-confirm-popup.p-confirm-popup-flipped:after {
border-bottom-color: transparent;
}
.p-confirm-popup.p-confirm-popup-flipped:before {
border-bottom-color: transparent
}
.p-confirm-popup .p-confirm-popup-content {
display: flex;
align-items: center;
}
</style>
2 changes: 2 additions & 0 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import ColorPicker from './components/colorpicker/ColorPicker';
import Column from './components/column/Column';
import ColumnGroup from './components/columngroup/ColumnGroup';
import ConfirmDialog from './components/confirmdialog/ConfirmDialog';
import ConfirmPopup from './components/confirmpopup/ConfirmPopup';
import ConfirmationService from './components/confirmation/ConfirmationService';
import ContextMenu from './components/contextmenu/ContextMenu';
import DataTable from './components/datatable/DataTable';
Expand Down Expand Up @@ -133,6 +134,7 @@ Vue.component('ColorPicker', ColorPicker);
Vue.component('Column', Column);
Vue.component('ColumnGroup', ColumnGroup);
Vue.component('ConfirmDialog', ConfirmDialog);
Vue.component('ConfirmPopup', ConfirmPopup);
Vue.component('ContextMenu', ContextMenu);
Vue.component('DataTable', DataTable);
Vue.component('DataView', DataView);
Expand Down
5 changes: 5 additions & 0 deletions src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ export default new Router({
name: 'confirmdialog',
component: () => import('./views/confirmdialog/ConfirmDialogDemo.vue')
},
{
path: '/confirmpopup',
name: 'confirmpopup',
component: () => import('./views/confirmpopup/ConfirmPopupDemo.vue')
},
{
path: '/contextmenu',
name: 'contextmenu',
Expand Down
59 changes: 59 additions & 0 deletions src/views/confirmpopup/ConfirmPopupDemo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<template>
<div>
<div class="content-section introduction">
<div class="feature-intro">
<h1>ConfirmPopup</h1>
<p>ConfirmPopup displays a confirmation overlay displayed relatively to its target.</p>
</div>
</div>

<div class="content-section implementation">
<ConfirmPopup></ConfirmPopup>

<div class="card">
<Button @click="confirm1($event)" icon="pi pi-check" label="Confirm" class="p-mr-2"></Button>
<Button @click="confirm2($event)" icon="pi pi-times" label="Delete" class="p-button-danger p-button-outlined"></Button>
</div>
</div>

<ConfirmPopupDoc />
</div>
</template>

<script>
import ConfirmPopupDoc from './ConfirmPopupDoc';
export default {
methods: {
confirm1(event) {
this.$confirm.require({
target: event.currentTarget,
message: 'Are you sure you want to proceed?',
icon: 'pi pi-exclamation-triangle',
accept: () => {
this.$toast.add({severity:'info', summary:'Confirmed', detail:'You have accepted', life: 3000});
},
reject: () => {
this.$toast.add({severity:'info', summary:'Rejected', detail:'You have rejected', life: 3000});
}
});
},
confirm2(event) {
this.$confirm.require({
target: event.currentTarget,
message: 'Do you want to delete this record?',
icon: 'pi pi-info-circle',
acceptClass: 'p-button-danger',
accept: () => {
this.$toast.add({severity:'info', summary:'Confirmed', detail:'Record deleted', life: 3000});
},
reject: () => {
this.$toast.add({severity:'info', summary:'Rejected', detail:'You have rejected', life: 3000});
}
});
}
},
components: {
'ConfirmPopupDoc': ConfirmPopupDoc
}
}
</script>
Loading

0 comments on commit a41dc49

Please sign in to comment.