Fixed #1354 - Responsive Toast

pull/1361/head
Tuğçe Küçükoğlu 2021-06-16 13:00:57 +03:00
parent cbc0b98846
commit 71e93a1bf8
4 changed files with 69 additions and 2 deletions

View File

@ -22,6 +22,12 @@ const ToastProps = [
type: "number", type: "number",
default: "0", default: "0",
description: "Base zIndex value to use in layering." description: "Base zIndex value to use in layering."
},
{
name: "breakpoints",
type: "object",
default: "null",
description: "Object literal to define widths per screen size."
} }
]; ];

View File

@ -3,6 +3,7 @@ interface ToastProps {
position?: string; position?: string;
autoZIndex?: boolean; autoZIndex?: boolean;
baseZIndex?: number; baseZIndex?: number;
breakpoints?: {[key: string]: string};
} }
declare class Toast { declare class Toast {

View File

@ -1,7 +1,7 @@
<template> <template>
<Teleport to="body"> <Teleport to="body">
<div ref="container" :class="containerClass" v-bind="$attrs"> <div ref="container" :class="containerClass" v-bind="$attrs">
<transition-group name="p-toast-message" tag="div"> <transition-group name="p-toast-message" tag="div" @enter="onEnter">
<ToastMessage v-for="msg of messages" :key="msg.id" :message="msg" @close="remove($event)"/> <ToastMessage v-for="msg of messages" :key="msg.id" :message="msg" @close="remove($event)"/>
</transition-group> </transition-group>
</div> </div>
@ -11,7 +11,7 @@
<script> <script>
import ToastEventBus from 'primevue/toasteventbus'; import ToastEventBus from 'primevue/toasteventbus';
import ToastMessage from './ToastMessage.vue'; import ToastMessage from './ToastMessage.vue';
import {ZIndexUtils} from 'primevue/utils'; import {ZIndexUtils,UniqueComponentId} from 'primevue/utils';
var messageIdx = 0; var messageIdx = 0;
@ -34,6 +34,10 @@ export default {
baseZIndex: { baseZIndex: {
type: Number, type: Number,
default: 0 default: 0
},
breakpoints: {
type: Object,
default: null
} }
}, },
data() { data() {
@ -41,6 +45,7 @@ export default {
messages: [] messages: []
} }
}, },
styleElement: null,
mounted() { mounted() {
ToastEventBus.on('add', this.onAdd); ToastEventBus.on('add', this.onAdd);
ToastEventBus.on('remove-group', this.onRemoveGroup); ToastEventBus.on('remove-group', this.onRemoveGroup);
@ -49,8 +54,14 @@ export default {
if (this.autoZIndex) { if (this.autoZIndex) {
ZIndexUtils.set('modal', this.$refs.container, this.baseZIndex || this.$primevue.config.zIndex.modal); ZIndexUtils.set('modal', this.$refs.container, this.baseZIndex || this.$primevue.config.zIndex.modal);
} }
if (this.breakpoints) {
this.createStyle();
}
}, },
beforeUnmount() { beforeUnmount() {
this.destroyStyle();
if (this.$refs.container && this.autoZIndex) { if (this.$refs.container && this.autoZIndex) {
ZIndexUtils.clear(this.$refs.container); ZIndexUtils.clear(this.$refs.container);
} }
@ -90,6 +101,39 @@ export default {
}, },
onRemoveAllGroups() { onRemoveAllGroups() {
this.messages = []; this.messages = [];
},
onEnter() {
this.$refs.container.setAttribute(this.attributeSelector, '');
},
createStyle() {
if (!this.styleElement) {
this.styleElement = document.createElement('style');
this.styleElement.type = 'text/css';
document.head.appendChild(this.styleElement);
let innerHTML = '';
for (let breakpoint in this.breakpoints) {
let breakpointStyle = '';
for (let styleProp in this.breakpoints[breakpoint]) {
breakpointStyle += styleProp + ':' + this.breakpoints[breakpoint][styleProp] + '!important;';
}
innerHTML += `
@media screen and (max-width: ${breakpoint}) {
.p-toast[${this.attributeSelector}] {
${breakpointStyle}
}
}
`;
}
this.styleElement.innerHTML = innerHTML;
}
},
destroyStyle() {
if (this.styleElement) {
document.head.removeChild(this.styleElement);
this.styleElement = null;
}
} }
}, },
components: { components: {
@ -101,6 +145,9 @@ export default {
'p-input-filled': this.$primevue.config.inputStyle === 'filled', 'p-input-filled': this.$primevue.config.inputStyle === 'filled',
'p-ripple-disabled': this.$primevue.config.ripple === false 'p-ripple-disabled': this.$primevue.config.ripple === false
}]; }];
},
attributeSelector() {
return UniqueComponentId();
} }
} }
} }

View File

@ -176,6 +176,13 @@ this.$toast.add({severity:'success', summary: 'Specific Message', group: 'mykey'
<h5>Clearing Messages</h5> <h5>Clearing Messages</h5>
<p><i>removeGroup(group)</i> clears the messages for a specific Toast whereas <i>removeAllGroups()</i> method clears all messages.</p> <p><i>removeGroup(group)</i> clears the messages for a specific Toast whereas <i>removeAllGroups()</i> method clears all messages.</p>
<h5>Responsive</h5>
<p>Toast styling can be adjusted per screen size with the <i>breakpoints</i> option. The value of <i>breakpoints</i> should be an object literal whose keys are the maximum screen sizes and values are the styles per screen. In example below, width of the toast messages cover the whole page on screens whose widths is smaller than 921px.</p>
<pre v-code><code>
&lt;Toast :breakpoints="&#123;'920px': &#123;width: '100%', right: '0', left: '0'&#125;&#125;"&gt;&lt;/Toast&gt;
</code></pre>
<h5>Properties</h5> <h5>Properties</h5>
<div class="doc-tablewrapper"> <div class="doc-tablewrapper">
<table class="doc-table"> <table class="doc-table">
@ -211,6 +218,12 @@ this.$toast.add({severity:'success', summary: 'Specific Message', group: 'mykey'
<td>number</td> <td>number</td>
<td>0</td> <td>0</td>
<td>Base zIndex value to use in layering.</td> <td>Base zIndex value to use in layering.</td>
</tr>
<tr>
<td>breakpoints</td>
<td>object</td>
<td>null</td>
<td>Object literal to define styles per screen size.</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>