Fixed #1039 - Breakpoints to OverlayPanel

pull/1047/head
Cagatay Civici 2021-03-02 10:52:56 +03:00
parent 71242c8fd9
commit 3748b2dcc7
5 changed files with 65 additions and 5 deletions

View File

@ -1598,7 +1598,7 @@ export default {
.p-datatable[${this.attributeSelector}] .p-datatable-tbody > tr > td { .p-datatable[${this.attributeSelector}] .p-datatable-tbody > tr > td {
display: flex; display: flex;
width: 100%; width: 100% !important;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
} }

View File

@ -7,6 +7,7 @@ interface OverlayPanelProps {
baseZIndex?: number; baseZIndex?: number;
autoZIndex?: boolean; autoZIndex?: boolean;
ariaCloseLabel?: string; ariaCloseLabel?: string;
breakpoints?: {[key: string]: string};
} }
declare class OverlayPanel { declare class OverlayPanel {

View File

@ -14,8 +14,7 @@
</template> </template>
<script> <script>
import {ConnectedOverlayScrollHandler} from 'primevue/utils'; import {UniqueComponentId,DomHandler,ConnectedOverlayScrollHandler} from 'primevue/utils';
import {DomHandler} from 'primevue/utils';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
export default { export default {
@ -44,6 +43,10 @@ export default {
ariaCloseLabel: { ariaCloseLabel: {
type: String, type: String,
default: 'close' default: 'close'
},
breakpoints: {
type: Object,
default: null
} }
}, },
data() { data() {
@ -57,6 +60,7 @@ export default {
scrollHandler: null, scrollHandler: null,
resizeListener: null, resizeListener: null,
container: null, container: null,
styleElement: null,
beforeUnmount() { beforeUnmount() {
if (this.dismissable) { if (this.dismissable) {
this.unbindOutsideClickListener(); this.unbindOutsideClickListener();
@ -66,10 +70,16 @@ export default {
this.scrollHandler.destroy(); this.scrollHandler.destroy();
this.scrollHandler = null; this.scrollHandler = null;
} }
this.destroyStyle();
this.unbindResizeListener(); this.unbindResizeListener();
this.target = null; this.target = null;
this.container = null; this.container = null;
}, },
mounted() {
if (this.breakpoints) {
this.createStyle();
}
},
methods: { methods: {
toggle(event) { toggle(event) {
if (this.visible) if (this.visible)
@ -88,6 +98,7 @@ export default {
this.selfClick = true; this.selfClick = true;
}, },
onEnter() { onEnter() {
this.container.setAttribute(this.attributeSelector, '');
this.alignOverlay(); this.alignOverlay();
if (this.dismissable) { if (this.dismissable) {
this.bindOutsideClickListener(); this.bindOutsideClickListener();
@ -176,6 +187,37 @@ export default {
}, },
containerRef(el) { containerRef(el) {
this.container = el; this.container = el;
},
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) {
innerHTML += `
@media screen and (max-width: ${breakpoint}) {
.p-overlaypanel[${this.attributeSelector}] {
width: ${this.breakpoints[breakpoint]} !important;
}
}
`
}
this.styleElement.innerHTML = innerHTML;
}
},
destroyStyle() {
if (this.styleElement) {
document.head.removeChild(this.styleElement);
this.styleElement = null;
}
}
},
computed: {
attributeSelector() {
return UniqueComponentId();
} }
}, },
directives: { directives: {

View File

@ -11,8 +11,8 @@
<div class="card"> <div class="card">
<Button type="button" icon="pi pi-search" :label="selectedProduct ? selectedProduct.name : 'Select a Product'" @click="toggle" aria:haspopup="true" aria-controls="overlay_panel" /> <Button type="button" icon="pi pi-search" :label="selectedProduct ? selectedProduct.name : 'Select a Product'" @click="toggle" aria:haspopup="true" aria-controls="overlay_panel" />
<OverlayPanel ref="op" appendTo="body" :showCloseIcon="true" id="overlay_panel" style="width: 450px"> <OverlayPanel ref="op" appendTo="body" :showCloseIcon="true" id="overlay_panel" style="width:450px" :breakpoints="{'960px': '75vw'}">
<DataTable :value="products" v-model:selection="selectedProduct" selectionMode="single" :paginator="true" :rows="5" @row-select="onProductSelect" responsiveLayout="scroll"> <DataTable :value="products" v-model:selection="selectedProduct" selectionMode="single" :paginator="true" :rows="5" @row-select="onProductSelect">
<Column field="name" header="Name" sortable style="width: 50%"></Column> <Column field="name" header="Name" sortable style="width: 50%"></Column>
<Column header="Image" style="width: 20%"> <Column header="Image" style="width: 20%">
<template #body="slotProps"> <template #body="slotProps">

View File

@ -34,6 +34,17 @@ toggle(event) {
&lt;img src="demo/images/nature/nature1.jpg" alt="Nature Image"&gt; &lt;img src="demo/images/nature/nature1.jpg" alt="Nature Image"&gt;
&lt;/OverlayPanel&gt; &lt;/OverlayPanel&gt;
</code></pre>
<h5>Responsive</h5>
<p>OverlayPanel width can be adjusted per screen size with the <i>breakpoints</i> option. In example below, default width is set to 450px and below 961px, width would be 75vw and finally below 641px width becomes
100%. The value of <i>breakpoints</i> should be an object literal whose keys are the maximum screen sizes and values are the widths per screen.</p>
<pre v-code><code>
&lt;OverlayPanel ref="op" :breakpoints="{'960px': '75vw', '640px': '100vw'}" :style="{width: '450px'}"&gt;
Content
&lt;/OverlayPanel&gt;
</code></pre> </code></pre>
<h5>Properties</h5> <h5>Properties</h5>
@ -83,6 +94,12 @@ toggle(event) {
<td>string</td> <td>string</td>
<td>close</td> <td>close</td>
<td>Aria label of the close icon.</td> <td>Aria label of the close icon.</td>
</tr>
<tr>
<td>breakpoints</td>
<td>object</td>
<td>null</td>
<td>Object literal to define widths per screen size.</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>