browser source added data components

pull/1664/head
Tuğçe Küçükoğlu 2021-10-11 16:54:19 +03:00
parent f9ebbc4685
commit a1d1882e7b
9 changed files with 1304 additions and 0 deletions

View File

@ -920,6 +920,255 @@ export default {
}
}
</style>`
},
'browser-source': {
tabName: 'Browser Source',
imports: `<script src="https://unpkg.com/primevue@^3/dataview/dataview.min.js"><\\/script>
<script src="https://unpkg.com/primevue@^3/dataviewlayoutoptions/dataviewlayoutoptions.min.js"><\\/script>
<script src="https://unpkg.com/primevue@^3/dropdown/dropdown.min.js"><\\/script>
<script src="https://unpkg.com/primevue@^3/rating/rating.min.js"><\\/script>
<script src="./ProductService.js"><\\/script>`,
content: `
<div id="app">
<div class="card">
<p-dataview :value="products" :layout="layout" :paginator="true" :rows="9" :sort-order="sortOrder" :sort-field="sortField">
<template #header>
<div class="p-grid p-nogutter">
<div class="p-col-6" style="text-align: left">
<p-dropdown v-model="sortKey" :options="sortOptions" option-label="label" placeholder="Sort By Price" @change="onSortChange($event)"></p-dropdown>
</div>
<div class="p-col-6" style="text-align: right">
<p-dataviewlayoutoptions v-model="layout"></p-dataviewlayoutoptions>
</div>
</div>
</template>
<template #list="slotProps">
<div class="p-col-12">
<div class="product-list-item">
<img src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" :alt="slotProps.data.name"/>
<div class="product-list-detail">
<div class="product-name">{{slotProps.data.name}}</div>
<div class="product-description">{{slotProps.data.description}}</div>
<p-rating :model-value="slotProps.data.rating" :readonly="true" :cancel="false"></p-rating>
<i class="pi pi-tag product-category-icon"></i><span class="product-category">{{slotProps.data.category}}</span>
</div>
<div class="product-list-action">
<span class="product-price">\${{slotProps.data.price}}</span>
<p-button icon="pi pi-shopping-cart" label="Add to Cart" :disabled="slotProps.data.inventoryStatus === 'OUTOFSTOCK'"></p-button>
<span :class="'product-badge status-'+slotProps.data.inventoryStatus.toLowerCase()">{{slotProps.data.inventoryStatus}}</span>
</div>
</div>
</div>
</template>
<template #grid="slotProps">
<div class="p-col-12 p-md-4">
<div class="product-grid-item card">
<div class="product-grid-item-top">
<div>
<i class="pi pi-tag product-category-icon"></i>
<span class="product-category">{{slotProps.data.category}}</span>
</div>
<span :class="'product-badge status-'+slotProps.data.inventoryStatus.toLowerCase()">{{slotProps.data.inventoryStatus}}</span>
</div>
<div class="product-grid-item-content">
<img src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" :alt="slotProps.data.name"/>
<div class="product-name">{{slotProps.data.name}}</div>
<div class="product-description">{{slotProps.data.description}}</div>
<p-rating :model-value="slotProps.data.rating" :readonly="true" :cancel="false"></p-rating>
</div>
<div class="product-grid-item-bottom">
<span class="product-price">\${{slotProps.data.price}}</span>
<p-button icon="pi pi-shopping-cart" :disabled="slotProps.data.inventoryStatus === 'OUTOFSTOCK'"></p-button>
</div>
</div>
</div>
</template>
</p-dataview>
</div>
</template>
<script type="module">
const { createApp, ref, onMounted } = Vue;
const App = {
setup() {
onMounted(() => {
productService.value.getProducts().then(data => products.value = data);
})
const products = ref();
const productService = ref(new ProductService());
const layout = ref('grid');
const sortKey = ref();
const sortOrder = ref();
const sortField = ref();
const sortOptions = ref([
{label: 'Price High to Low', value: '!price'},
{label: 'Price Low to High', value: 'price'},
]);
const onSortChange = (event) => {
const value = event.value.value;
const sortValue = event.value;
if (value.indexOf('!') === 0) {
sortOrder.value = -1;
sortField.value = value.substring(1, value.length);
sortKey.value = sortValue;
}
else {
sortOrder.value = 1;
sortField.value = value;
sortKey.value = sortValue;
}
};
return {
products, layout, sortKey, sortOrder, sortField, sortOptions, onSortChange
}
},
components: {
"p-dataview": primevue.dataview,
"p-dataviewlayoutoptions": primevue.dataviewlayoutoptions,
"p-dropdown": primevue.dropdown,
"p-rating": primevue.rating,
"p-button": primevue.button
}
};
createApp(App)
.use(primevue.config.default)
.mount("#app");
<\\/script>
<style>
.card {
background: #ffffff;
padding: 2rem;
box-shadow: 0 2px 1px -1px rgba(0,0,0,.2), 0 1px 1px 0 rgba(0,0,0,.14), 0 1px 3px 0 rgba(0,0,0,.12);
border-radius: 4px;
margin-bottom: 2rem;
}
.p-dropdown {
width: 14rem;
font-weight: normal;
}
.product-name {
font-size: 1.5rem;
font-weight: 700;
}
.product-description {
margin: 0 0 1rem 0;
}
.product-category-icon {
vertical-align: middle;
margin-right: .5rem;
}
.product-category {
font-weight: 600;
vertical-align: middle;
}
.product-list-item {
display: flex;
align-items: center;
padding: 1rem;
width: 100%;
}
.product-list-item img {
width: 50px;
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
margin-right: 2rem;
}
.product-list-item .product-list-detail {
flex: 1 1 0;
}
.product-list-item .p-rating {
margin: 0 0 .5rem 0;
}
.product-list-item .product-price {
font-size: 1.5rem;
font-weight: 600;
margin-bottom: .5rem;
align-self: flex-end;
}
.product-list-item .product-list-action {
display: flex;
flex-direction: column;
}
.product-list-item .p-button {
margin-bottom: .5rem;
}
.product-grid-item {
margin: .5rem;
border: 1px solid #dee2e6;
}
.product-grid-item .product-grid-item-top,
.product-grid-item .product-grid-item-bottom {
display: flex;
align-items: center;
justify-content: space-between;
}
.product-grid-item img {
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
margin: 2rem 0;
}
.product-grid-item .product-grid-item-content {
text-align: center;
}
.product-grid-item .product-price {
font-size: 1.5rem;
font-weight: 600;
}
@media screen and (max-width: 576px) {
.product-list-item {
flex-direction: column;
align-items: center;
}
.product-list-item .product-list-item img {
margin: 2rem 0;
}
.product-list-item .product-list-detail {
text-align: center;
}
.product-list-item .product-price {
align-self: center;
}
.product-list-item .product-list-action {
display: flex;
flex-direction: column;
}
.product-list-item .product-list-action {
margin-top: 2rem;
flex-direction: row;
justify-content: space-between;
align-items: center;
width: 100%;
}
}
</style>
`
}
}
}

View File

@ -363,6 +363,96 @@ export default {
}
}
<\\/script>
`
},
'browser-source': {
tabName: 'Browser Source',
imports: `<script src="https://unpkg.com/primevue@^3/datatable/datatable.min.js"><\\/script>
<script src="https://unpkg.com/primevue@^3/column/column.min.js"><\\/script>
<script src="./CustomerService.js"><\\/script>`,
content: `
<div id="app">
<div class="card">
<p-datatable :value="customers" :paginator="true" :rows="10" responsive-layout="scroll"
data-key="id" v-model:filters="filters" filter-display="row" :loading="loading">
<template #empty>
No customers found.
</template>
<template #loading>
Loading customers data. Please wait.
</template>
<p-column field="name" header="Name" :filter-match-mode-options="matchModeOptions">
<template #body="{data}">
{{data.name}}
</template>
<template #filter="{filterModel,filterCallback}">
<p-inputtext type="text" v-model="filterModel.value" @input="filterCallback()" class="p-column-filter" :placeholder="\`Search by name - \${filterModel.matchMode}\`"></p-inputtext>
</template>
</p-column>
<p-column header="Country" filter-field="country.name" :filter-match-mode-options="matchModeOptions">
<template #body="{data}">
<img src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" width="30" />
<span class="image-text">{{data.country.name}}</span>
</template>
<template #filter="{filterModel,filterCallback}">
<p-inputtext type="text" v-model="filterModel.value" @input="filterCallback()" class="p-column-filter" :placeholder="\`Search by country - \${filterModel.matchMode}\`"></p-inputtext>
</template>
</p-column>
</p-datatable>
</div>
</div>
<script type="module">
const { createApp, ref, onMounted } = Vue;
const { FilterMatchMode, FilterService } = primevue.api;
const App = {
setup() {
onMounted(() => {
customerService.value.getCustomersLarge().then(data => {
customers.value = data;
loading.value = false;
});
FilterService.register(YOUR_FILTER.value, (value, filter) => {
if (filter === undefined || filter === null || filter.trim() === '') {
return true;
}
if (value === undefined || value === null) {
return false;
}
return value.toString() === filter.toString();
});
})
const YOUR_FILTER = ref('YOUR FILTER');
const customers = ref();
const customerService = ref(new CustomerService());
const filters = ref({
'name': {value: null, matchMode: YOUR_FILTER.value},
'country.name': {value: null, matchMode: FilterMatchMode.STARTS_WITH}
});
const matchModeOptions = ref([
{label: 'Your Equals', value: YOUR_FILTER.value},
{label: 'Starts With', value: FilterMatchMode.STARTS_WITH}
]);
const loading = ref(true);
return { customers, customerService, filters, matchModeOptions, loading }
},
components: {
"p-datatable": primevue.datatable,
"p-column": primevue.column,
"p-inputtext": primevue.inputtext
}
};
createApp(App)
.use(primevue.config.default)
.mount("#app");
<\\/script>
`
}
}

View File

@ -117,6 +117,65 @@ export default {
}
}
</style>`
},
'browser-source': {
tabName: 'Browser Source',
imports: `<script src="https://unpkg.com/fullcalendar@5.7.2/main.min.js"><\\/script>
<link rel="stylesheet" href="https://unpkg.com/fullcalendar@5.7.2/main.min.css"><\\/link>
<script src="https://unpkg.com/primevue@^3/fullcalendar/fullcalendar.min.js"><\\/script>
<script src="./EventService.js"><\\/script>`,
content: `
<div id="app">
<p-fullcalendar :events="events" :options="options"></p-fullcalendar>
</div>
<script>
const { createApp, ref, onMounted } = Vue;
const { dayGridPlugin, timeGridPlugin, interactionPlugin } = FullCalendar.Calendar;
const App = {
setup() {
onMounted(() => {
eventService.value.getEvents().then(data => events.value = data);
})
const options = ref({
plugins:[dayGridPlugin, timeGridPlugin, interactionPlugin],
initialDate : '2017-02-01',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
editable: true,
selectable:true,
selectMirror: true,
dayMaxEvents: true
});
const events = ref(null);
const eventService = ref(new EventService());
return { options, events, eventService };
},
components: {
"p-fullcalendar": primevue.fullcalendar
}
};
createApp(App)
.use(primevue.config.default)
.mount("#app");
<\\/script>
<style scoped>
@media screen and (max-width: 960px) {
::v-deep(.fc-header-toolbar) {
display: flex;
flex-wrap: wrap;
}
}
</style>`
}
}
}

View File

@ -422,6 +422,121 @@ export default {
}
}
</style>`
},
'browser-source': {
tabName: 'Browser Source',
imports: `<script src="https://unpkg.com/primevue@^3/orderlist/orderlist.min.js"><\\/script>
<script src="./ProductService.js"><\\/script>`,
content: `
<div id="app">
<div class="card">
<p-orderlist v-model="products" listStyle="height:auto" dataKey="id">
<template #header>
List of Products
</template>
<template #item="slotProps">
<div class="product-item">
<div class="image-container">
<img src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" :alt="slotProps.item.name" />
</div>
<div class="product-list-detail">
<h6 class="p-mb-2">{{slotProps.item.name}}</h6>
<i class="pi pi-tag product-category-icon"></i>
<span class="product-category">{{slotProps.item.category}}</span>
</div>
<div class="product-list-action">
<h6 class="p-mb-2">\${{slotProps.item.price}}</h6>
<span :class="'product-badge status-'+slotProps.item.inventoryStatus.toLowerCase()">{{slotProps.item.inventoryStatus}}</span>
</div>
</div>
</template>
</p-orderlist>
</div>
</div>
<script type="module">
const { createApp, ref, onMounted } = Vue;
const App = {
setup() {
onMounted(() => {
productService.value.getProductsSmall().then(data => products.value = data);
})
const products = ref(null);
const productService = ref(new ProductService());
return { products, productService }
},
components: {
"p-orderlist": primevue.orderlist
}
};
createApp(App)
.use(primevue.config.default)
.mount("#app");
<\\/script>
<style>
.card {
background: #ffffff;
padding: 2rem;
box-shadow: 0 2px 1px -1px rgba(0,0,0,.2), 0 1px 1px 0 rgba(0,0,0,.14), 0 1px 3px 0 rgba(0,0,0,.12);
border-radius: 4px;
margin-bottom: 2rem;
}
.product-item {
display: flex;
align-items: center;
padding: .5rem;
width: 100%;
}
.product-item img {
width: 75px;
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
margin-right: 1rem;
}
.product-item .product-list-detail {
flex: 1 1 0;
}
.product-item .product-list-action {
display: flex;
flex-direction: column;
align-items: flex-end;
}
.product-item .product-category-icon {
vertical-align: middle;
margin-right: .5rem;
font-size: .875rem;
}
.product-item .product-category {
vertical-align: middle;
line-height: 1;
font-size: .875rem;
}
@media screen and (max-width: 576px) {
.product-item {
flex-wrap: wrap;
}
.product-item .image-container {
width: 100%;
text-align: center;
}
.product-item img {
margin: 0 0 1rem 0;
width: 100px;
}
}
</style>`
}
}
}

View File

@ -916,6 +916,232 @@ export default {
}
}
</style>`
},
'browser-source': {
tabName: 'Browser Source',
imports: `<script src="https://unpkg.com/primevue@^3/organizationchart/organizationchart.min.js"><\\/script>
<script src="https://unpkg.com/primevue@^3/toast/toast.min.js"><\\/script>
<script src="https://unpkg.com/primevue@^3/toastservice/toastservice.min.js"><\\/script>`,
content: `
<div id="app">
<p-toast></p-toast>
<div class="card">
<h5>Advanced</h5>
<p-organizationchart :value="data1" :collapsible="true" class="company" selection-mode="single" v-model:selection-keys="selection"
@node-select="onNodeSelect" @node-unselect="onNodeUnselect" @node-collapse="onNodeCollapse" @node-expand="onNodeExpand">
<template #person="slotProps">
<div class="node-header ui-corner-top">{{slotProps.node.data.label}}</div>
<div class="node-content">
<img src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" width="32">
<div>{{slotProps.node.data.name}}</div>
</div>
</template>
<template #default="slotProps">
<span>{{slotProps.node.data.label}}</span>
</template>
</p-organizationchart>
</div>
<div class="card">
<h5>Basic</h5>
<p-organizationchart :value="data2">
<template #default="slotProps">
<span>{{slotProps.node.data.label}}</span>
</template>
</p-organizationchart>
</div>
</div>
<script>
const { createApp, ref } = Vue;
const { useToast } = primevue.usetoast;
const App = {
setup() {
const toast = useToast();
const data1 = ref({
key: '0',
type: 'person',
styleClass: 'p-person',
data: {label: 'CEO', name: 'Walter White', avatar: 'walter.jpg'},
children: [
{
key: '0_0',
type: 'person',
styleClass: 'p-person',
data: {label: 'CFO', name:'Saul Goodman', avatar: 'saul.jpg'},
children:[{
key: '0_0_0',
data: {label: 'Tax'},
selectable: false,
styleClass: 'department-cfo'
},
{
key: '0_0_1',
data: {label: 'Legal'},
selectable: false,
styleClass: 'department-cfo'
}],
},
{
key: '0_1',
type: 'person',
styleClass: 'p-person',
data: {label: 'COO', name:'Mike E.', avatar: 'mike.jpg'},
children:[{
key: '0_1_0',
data: {label: 'Operations'},
selectable: false,
styleClass: 'department-coo'
}]
},
{
key: '0_2',
type: 'person',
styleClass: 'p-person',
data: {label: 'CTO', name:'Jesse Pinkman', avatar: 'jesse.jpg'},
children:[{
key: '0_2_0',
data: {label: 'Development'},
selectable: false,
styleClass: 'department-cto',
children:[{
key: '0_2_0_0',
data: {label: 'Analysis'},
selectable: false,
styleClass: 'department-cto'
},
{
key: '0_2_0_1',
data: {label: 'Front End'},
selectable: false,
styleClass: 'department-cto'
},
{
key: '0_2_0_2',
data: {label: 'Back End'},
selectable: false,
styleClass: 'department-cto'
}]
},
{
key: '0_2_1',
data: {label: 'QA'},
selectable: false,
styleClass: 'department-cto'
},
{
key: '0_2_2',
data: {label: 'R&D'},
selectable: false,
styleClass: 'department-cto'
}]
}
]
});
const data2 = ref({
key: '0',
data: {label: 'F.C. Barcelona'},
children: [
{
key: '0_0',
data: {label: 'F.C. Barcelona'},
children: [
{
key: '0_0_0',
data: {label: 'Chelsea F.C.'}
},
{
key: '0_0_1',
data: {label: 'F.C. Barcelona'}
}
]
},
{
key: '0_1',
data: {label: 'Real Madrid'},
children: [
{
key: '0_1_0',
data: {label: 'Bayern Munich'}
},
{
key: '0_1_1',
data: {label: 'Real Madrid'}
}
]
}
]
});
const selection = ref({});
const onNodeSelect = (node) => {
toast.add({severity:'success', summary: 'Node Selected', detail: node.data.label, life: 3000});
};
const onNodeUnselect = (node) => {
toast.add({severity:'success', summary: 'Node Unselected', detail: node.data.label, life: 3000});
};
const onNodeExpand = (node) => {
toast.add({severity:'success', summary: 'Node Expanded', detail: node.data.label, life: 3000});
};
const onNodeCollapse = (node) => {
toast.add({severity:'success', summary: 'Node Collapsed', detail: node.data.label, life: 3000});
};
return { data1, data2, selection, onNodeSelect, onNodeUnselect, onNodeExpand, onNodeCollapse }
},
components: {
"p-organizationchart": primevue.organizationchart,
"p-toast": primevue.toast
}
};
createApp(App)
.use(primevue.config.default)
.use(primevue.toastservice)
.mount("#app");
<\\/script>
<style>
.p-organizationchart .p-person {
padding: 0;
border: 0 none;
}
.p-organizationchart .node-header, .p-organizationchart .node-content {
padding: .5em .7rem;
}
.p-organizationchart .node-header {
background-color: #495ebb;
color: #ffffff;
}
.p-organizationchart .node-content {
text-align: center;
border: 1px solid #495ebb;
}
.p-organizationchart .node-content img {
border-radius: 50%;
}
.p-organizationchart .department-cfo {
background-color: #7247bc;
color: #ffffff;
}
.p-organizationchart .department-coo {
background-color: #a534b6;
color: #ffffff;
}
.p-organizationchart .department-cto {
background-color: #e9286f;
color: #ffffff;
}
</style>`
}
}
}

View File

@ -380,6 +380,66 @@ export default {
padding: 1rem;
}
</style>`
},
'browser-source': {
tabName: 'Browser Source',
imports: `<script src="https://unpkg.com/primevue@^3/paginator/paginator.min.js"><\\/script>`,
content: `
<div id="app">
<h5>Basic</h5>
<p-paginator :rows="10" :total-records="totalRecords" :rows-per-page-options="[10,20,30]"></p-paginator>
<h5>Custom</h5>
<p-paginator v-model:first="first" :rows="1" :total-records="totalRecords2"
template="FirstPageLink PrevPageLink CurrentPageReport NextPageLink LastPageLink">
<template #left>
<p-button type="button" icon="pi pi-refresh" @click="reset()"></p-button>
</template>
<template #right>
<p-button type="button" icon="pi pi-search"></p-button>
</template>
</p-paginator>
<div class="image-gallery">
<img src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" />
</div>
</div>
<script type="module">
const { createApp, ref } = Vue;
const App = {
setup() {
const first = ref(0);
const totalRecords = ref(120);
const totalRecords2 = ref(12);
const reset = () => {
first.value = 0;
}
return { first, totalRecords, totalRecords2, reset }
},
components: {
"p-paginator": primevue.paginator,
"p-button": primevue.button
}
};
createApp(App)
.use(primevue.config.default)
.mount("#app");
<\\/script>
<style scoped>
.p-button.p-button-icon-only {
border-radius: 0;
}
.image-gallery {
text-align: center;
padding: 1rem;
}
</style>`
}
}
}

View File

@ -479,6 +479,113 @@ export default {
}
}
}
</style>`
},
'browser-source': {
tabName: 'Browser Source',
imports: `<script src="https://unpkg.com/primevue@^3/picklist/picklist.min.js"><\\/script>
<script src="./ProductService.js"><\\/script>`,
content: `
<div id="app">
<p-picklist v-model="products" list-style="height:342px" data-key="id">
<template #sourceHeader>
Available
</template>
<template #targetHeader>
Selected
</template>
<template #item="slotProps">
<div class="product-item">
<div class="image-container">
<img src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" />
</div>
<div class="product-list-detail">
<h6 class="p-mb-2">{{slotProps.item.name}}</h6>
<i class="pi pi-tag product-category-icon"></i>
<span class="product-category">{{slotProps.item.category}}</span>
</div>
<div class="product-list-action">
<h6 class="p-mb-2">\${{slotProps.item.price}}</h6>
<span :class="'product-badge status-'+slotProps.item.inventoryStatus.toLowerCase()">{{slotProps.item.inventoryStatus}}</span>
</div>
</div>
</template>
</p-picklist>
</div>
<script type="module">
const { createApp, ref, onMounted } = Vue;
const App = {
setup() {
onMounted(() => {
productService.value.getProductsSmall().then(data => products.value = [data, []]);
})
const products = ref(null);
const productService = ref(new ProductService());
return { products, productService }
},
components: {
"p-picklist": primevue.picklist
}
};
createApp(App).use(primevue.config.default).mount("#app")
<\\/script>
<style>
.product-item {
display: flex;
align-items: center;
padding: .5rem;
width: 100%;
}
.product-item img {
width: 75px;
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
margin-right: 1rem;
}
.product-item .product-list-detail {
flex: 1 1 0;
}
.product-item .product-list-action {
display: flex;
flex-direction: column;
align-items: flex-end;
}
.product-item .product-category-icon {
vertical-align: middle;
margin-right: .5rem;
font-size: .875rem;
}
.product-item .product-category {
vertical-align: middle;
line-height: 1;
font-size: .875rem;
}
@media screen and (max-width: 576px) {
.product-item {
flex-wrap: wrap;
}
.product-item .image-container {
width: 100%;
text-align: center;
}
.product-item img {
margin: 0 0 1rem 0;
width: 100px;
}
}
</style>`
}
}

View File

@ -595,6 +595,171 @@ export default {
}
}
</style>`
},
'browser-source': {
tabName: 'Browser Source',
imports: `<script src="https://unpkg.com/primevue@^3/timeline/timeline.min.js"><\\/script>
<script src="https://unpkg.com/primevue@^3/card/card.min.js"><\\/script>`,
content: `
<div id="app">
<div class="card">
<h5>Left Align</h5>
<p-timeline :value="events1">
<template #content="slotProps">
{{slotProps.item.status}}
</template>
</p-timeline>
</div>
<div class="card">
<h5>Right Align</h5>
<p-timeline :value="events1" align="right">
<template #content="slotProps">
{{slotProps.item.status}}
</template>
</p-timeline>
</div>
<div class="card">
<h5>Alternate Align</h5>
<p-timeline :value="events1" align="alternate">
<template #content="slotProps">
{{slotProps.item.status}}
</template>
</p-timeline>
</div>
<div class="card">
<h5>Opposite Content</h5>
<p-timeline :value="events1">
<template #opposite="slotProps">
<small class="p-text-secondary">{{slotProps.item.date}}</small>
</template>
<template #content="slotProps">
{{slotProps.item.status}}
</template>
</p-timeline>
</div>
<div class="card">
<h5>Customized</h5>
<p-timeline :value="events1" align="alternate" class="customized-timeline">
<template #marker="slotProps">
<span class="custom-marker p-shadow-2" :style="{backgroundColor: slotProps.item.color}">
<i :class="slotProps.item.icon"></i>
</span>
</template>
<template #content="slotProps">
<p-card>
<template #title>
{{slotProps.item.status}}
</template>
<template #subtitle>
{{slotProps.item.date}}
</template>
<template #content>
<img v-if="slotProps.item.image" src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" :alt="slotProps.item.name" width="200" class="p-shadow-2" />
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore sed consequuntur error repudiandae numquam deserunt
quisquam repellat libero asperiores earum nam nobis, culpa ratione quam perferendis esse, cupiditate neque quas!</p>
<p-button label="Read more" class="p-button-text"></p-button>
</template>
</p-card>
</template>
</p-timeline>
</div>
<div class="card">
<h5>Horizontal</h5>
<h6>Top Align</h6>
<p-timeline :value="events2" layout="horizontal" align="top">
<template #content="slotProps">
{{slotProps.item}}
</template>
</p-timeline>
<h6>Bottom Align</h6>
<p-timeline :value="events2" layout="horizontal" align="bottom">
<template #content="slotProps">
{{slotProps.item}}
</template>
</p-timeline>
<h6>Alternate Align</h6>
<p-timeline :value="events2" layout="horizontal" align="alternate">
<template #opposite>
&nbsp;
</template>
<template #content="slotProps">
{{slotProps.item}}
</template>
</p-timeline>
</div>
</div>
<script type="module">
const { createApp, ref } = Vue;
const App = {
setup() {
const events1 = ref([
{status: 'Ordered', date: '15/10/2020 10:30', icon: 'pi pi-shopping-cart', color: '#9C27B0', image: 'game-controller.jpg'},
{status: 'Processing', date: '15/10/2020 14:00', icon: 'pi pi-cog', color: '#673AB7'},
{status: 'Shipped', date: '15/10/2020 16:15', icon: 'pi pi-shopping-cart', color: '#FF9800'},
{status: 'Delivered', date: '16/10/2020 10:00', icon: 'pi pi-check', color: '#607D8B'}
]);
const events2 = ref([
"2020", "2021", "2022", "2023"
]);
return { events1, events2 }
},
components: {
"p-timeline": primevue.timeline,
"p-card": primevue.card,
"p-button": primevue.button
}
};
createApp(App)
.use(primevue.config.default)
.mount("#app");
<\\/script>
<style>
.custom-marker {
display: flex;
width: 2rem;
height: 2rem;
align-items: center;
justify-content: center;
color: #ffffff;
border-radius: 50%;
z-index: 1;
}
.p-timeline-event-content,
.p-timeline-event-opposite, {
line-height: 1;
}
@media screen and (max-width: 960px) {
.customized-timeline .p-timeline-event:nth-child(even) {
flex-direction: row !important;
}
.customized-timeline .p-timeline-event:nth-child(even) .p-timeline-event-content {
text-align: left !important;
}
.customized-timeline .p-timeline-event-opposite {
flex: 0;
}
.customized-timeline .p-card {
margin-top: 1rem;
}
}
</style>`
}
}
}

View File

@ -796,6 +796,239 @@ export default {
}
}
</style>
`
},
'browser-source': {
tabName: 'Browser Source',
imports: `<script src="https://unpkg.com/primevue@^3/skeleton/skeleton.min.js"><\\/script>`,
content: `
<div id="app">
<div class="virtualscroller-demo">
<div class="card">
<h5 class="p-mb-0">Basic</h5>
<div class="p-d-flex p-ai-center p-flex-wrap">
<div class="p-d-flex p-dir-col p-mr-3 p-mt-3">
<h6>Vertical</h6>
<p-virtualscroller :items="basicItems" :item-size="50">
<template v-slot:item="{ item, options }">
<div :class="['scroll-item p-p-2', {'odd': options.odd}]" style="height: 50px">{{ item }}</div>
</template>
</p-virtualscroller>
</div>
<div class="p-d-flex p-dir-col p-mr-3 p-mt-3">
<h6>Horizontal</h6>
<p-virtualscroller :items="basicItems" :item-size="50" orientation="horizontal">
<template v-slot:item="{ item, options }">
<div :class="['scroll-item p-p-2', {'odd': options.odd}]" style="width: 50px">{{ item }}</div>
</template>
</p-virtualscroller>
</div>
<div class="p-d-flex p-dir-col p-mr-3 p-mt-3">
<h6>Both</h6>
<p-virtualscroller :items="multiItems" :item-size="[50, 100]" orientation="both">
<template v-slot:item="{ item, options }">
<div :class="['scroll-item p-p-2', {'odd': options.odd}]" style="height: 50px" >
<template v-for="(el, index) of item" :key="index">
<div style="width: 100px">{{ el }}</div>
</template>
</div>
</template>
</p-virtualscroller>
</div>
</div>
</div>
<div class="card">
<h5 class="p-mb-0">Scroll Delay</h5>
<div class="p-d-flex p-ai-center p-flex-wrap">
<div class="p-d-flex p-dir-col p-mr-3 p-mt-3">
<h6>0ms Delay</h6>
<p-virtualscroller :items="basicItems" :item-size="50">
<template v-slot:item="{ item, options }">
<div :class="['scroll-item p-p-2', {'odd': options.odd}]" style="height: 50px">{{ item }}</div>
</template>
</p-virtualscroller>
</div>
<div class="p-d-flex p-dir-col p-mr-3 p-mt-3">
<h6>150ms Delay</h6>
<p-virtualscroller :items="basicItems" :item-size="50" :delay="150">
<template v-slot:item="{ item, options }">
<div :class="['scroll-item p-p-2', {'odd': options.odd}]" style="height: 50px">{{ item }}</div>
</template>
</p-virtualscroller>
</div>
<div class="p-d-flex p-dir-col p-mr-3 p-mt-3">
<h6>250ms Delay</h6>
<p-virtualscroller :items="basicItems" :item-size="50" :delay="250">
<template v-slot:item="{ item, options }">
<div :class="['scroll-item p-p-2', {'odd': options.odd}]" style="height: 50px">{{ item }}</div>
</template>
</p-virtualscroller>
</div>
</div>
</div>
<div class="card">
<h5 class="p-mb-0">Loading</h5>
<div class="p-d-flex p-ai-center p-flex-wrap">
<div class="p-d-flex p-dir-col p-mr-3 p-mt-3">
<h6>Basic</h6>
<p-virtualscroller :items="basicItems" :item-size="50" show-loader :delay="250">
<template v-slot:item="{ item, options }">
<div :class="['scroll-item p-p-2', {'odd': options.odd}]" style="height: 50px">{{ item }}</div>
</template>
</p-virtualscroller>
</div>
<div class="p-d-flex p-dir-col p-mr-3 p-mt-3">
<h6>Templating</h6>
<p-virtualscroller class="custom-loading" :items="basicItems" :item-size="50" show-loader :delay="250">
<template v-slot:item="{ item, options }">
<div :class="['scroll-item p-p-2', {'odd': options.odd}]" style="height: 50px">{{ item }}</div>
</template>
<template v-slot:loader="{ options }">
<div :class="['scroll-item p-p-2', {'odd': options.odd}]" style="height: 50px" >
<p-skeleton :width="options.even ? '60%' : '50%'" height="1.3rem"></p-skeleton>
</div>
</template>
</p-virtualscroller>
</div>
</div>
</div>
<div class="card">
<h5 class="p-mb-0">Lazy</h5>
<div class="p-d-flex p-ai-center p-flex-wrap">
<div class="p-d-flex p-dir-col p-mr-3 p-mt-3">
<p-virtualscroller :items="lazyItems" :item-size="50" show-loader :delay="250" :loading="lazyLoading" :lazy=true @lazy-load="onLazyLoad">
<template v-slot:item="{ item, options }">
<div :class="['scroll-item p-p-2', {'odd': options.odd}]" style="height: 50px">{{ item }}</div>
</template>
</p-virtualscroller>
</div>
</div>
</div>
<div class="card">
<h5 class="p-mb-0">Template</h5>
<div class="p-d-flex p-ai-center p-flex-wrap">
<div class="p-d-flex p-dir-col p-mr-3 p-mt-3">
<p-virtualscroller class="custom-loading" :items="basicItems" :item-size="25 * 7" show-loader :delay="250">
<template v-slot:item="{ item, options }">
<div :class="['custom-scroll-item scroll-item', {'odd': options.odd}]">
<div class="p-d-flex p-ai-center p-px-2" style="height: 25px">{{\`Item: \${item}\`}}</div>
<div class="p-d-flex p-ai-center p-px-2" style="height: 25px">{{\`Index: \${options.index}\`}}</div>
<div class="p-d-flex p-ai-center p-px-2" style="height: 25px">{{\`Count: \${options.count}\`}}</div>
<div class="p-d-flex p-ai-center p-px-2" style="height: 25px">{{\`First: \${options.first}\`}}</div>
<div class="p-d-flex p-ai-center p-px-2" style="height: 25px">{{\`Last: \${options.last}\`}}</div>
<div class="p-d-flex p-ai-center p-px-2" style="height: 25px">{{\`Even: \${options.even}\`}}</div>
<div class="p-d-flex p-ai-center p-px-2" style="height: 25px">{{\`Odd: \${options.odd}\`}}</div>
</div>
</template>
<template v-slot:loader="{ options }">
<div :class="['custom-scroll-item scroll-item', {'odd': options.odd}]">
<div class="p-d-flex p-ai-center p-px-2" style="height: 25px"><p-skeleton width="60%" height="1.2rem"></p-skeleton></div>
<div class="p-d-flex p-ai-center p-px-2" style="height: 25px"><p-skeleton width="50%" height="1.2rem"></p-skeleton></div>
<div class="p-d-flex p-ai-center p-px-2" style="height: 25px"><p-skeleton width="60%" height="1.2rem"></p-skeleton></div>
<div class="p-d-flex p-ai-center p-px-2" style="height: 25px"><p-skeleton width="50%" height="1.2rem"></p-skeleton></div>
<div class="p-d-flex p-ai-center p-px-2" style="height: 25px"><p-skeleton width="60%" height="1.2rem"></p-skeleton></div>
<div class="p-d-flex p-ai-center p-px-2" style="height: 25px"><p-skeleton width="50%" height="1.2rem"></p-skeleton></div>
<div class="p-d-flex p-ai-center p-px-2" style="height: 25px"><p-skeleton width="60%" height="1.2rem"></p-skeleton></div>
</div>
</template>
</p-virtualscroller>
</div>
</div>
</div>
</div>
</div>
<script type="module">
const { createApp, ref, onMounted } = Vue;
const App = {
setup() {
const basicItems = ref(Array.from({ length: 100000 }).map((_, i) => \`Item #\${i}\`));
const multiItems = ref(Array.from({ length: 1000 }).map((_, i) => Array.from({ length: 1000 }).map((_j, j) => \`Item #\${i}_\${j}\`)));
const lazyItems = ref(Array.from({ length: 10000 }));
const lazyLoading = ref(false);
const loadLazyTimeout = ref(null);
const onLazyLoad = (event) => {
lazyLoading.value = true;
if (loadLazyTimeout.value) {
clearTimeout(loadLazyTimeout.value);
}
//imitate delay of a backend call
loadLazyTimeout.value = setTimeout(() => {
const { first, last } = event;
const _lazyItems = [...lazyItems.value];
for (let i = first; i < last; i++) {
_lazyItems[i] = \`Item #\${i}\`;
}
lazyItems.value = _lazyItems;
lazyLoading.value = false;
}, Math.random() * 1000 + 250);
}
return { basicItems, multiItems, lazyItems, lazyLoading, onLazyLoad }
},
components: {
"p-virtualscroller": primevue.virtualscroller,
"p-skeleton": primevue.skeleton
}
};
createApp(App)
.use(primevue.config.default)
.mount("#app");
<\\/script>
<style>
.virtualscroller-demo .p-virtualscroller {
height: 200px;
width: 200px;
border: 1px solid var(--surface-d);
}
.virtualscroller-demo .p-virtualscroller .scroll-item {
background-color: var(--surface-a);
display: flex;
align-items: center;
}
.virtualscroller-demo .p-virtualscroller .custom-scroll-item {
flex-direction: column;
align-items: stretch;
}
.virtualscroller-demo .p-virtualscroller .odd {
background-color: var(--surface-b);
}
.virtualscroller-demo .p-horizontal-scroll .p-virtualscroller-content {
display: flex;
flex-direction: row;
}
.virtualscroller-demo .p-horizontal-scroll .scroll-item {
writing-mode: vertical-lr;
}
.virtualscroller-demo .custom-loading > .p-virtualscroller-loader {
display: block;
}
</style>
`
}
}