Pages updated v3.21.0

pull/3420/head
Bahadır Sofuoğlu 2022-12-08 15:26:57 +03:00
parent defd6ff6e2
commit edc9695de0
246 changed files with 33769 additions and 28188 deletions

View File

@ -39,8 +39,10 @@ export default {
this.$appState.announcement = data;
const itemString = localStorage.getItem(this.storageKey);
if (itemString) {
const item = JSON.parse(itemString);
if (item.hiddenNews && item.hiddenNews !== data.id) {
this.$appState.newsActive = true;
} else this.$appState.newsActive = false;

View File

@ -1,7 +1,7 @@
<template>
<div :class="['layout-sidebar', { active: active }]">
<nuxt-link to="/" class="logo">
<img :src="'demo/images/primevue-logo-' + `${$appState.darkTheme ? 'light' : 'dark'}` + '.svg'" alt="primevue logo" />
<img :src="'/demo/images/primevue-logo-' + `${$appState.darkTheme ? 'light' : 'dark'}` + '.svg'" alt="primevue logo" />
</nuxt-link>
<div class="layout-sidebar-filter p-fluid">
<AutoComplete

View File

@ -1,20 +1,18 @@
<template>
<ClientOnly>
<div class="layout-news" :style="$appState?.announcement?.backgroundStyle">
<div class="layout-news" :style="$appState.announcement.backgroundStyle">
<i></i>
<div class="layout-news-content">
<span class="layout-news-text" :style="$appState?.announcement?.textStyle">{{ $appState?.announcement?.content }}</span>
<a class="layout-news-link" :href="$appState?.announcement?.linkHref">{{ $appState?.announcement?.linkText }}</a>
<span class="layout-news-text" :style="$appState.announcement.textStyle">{{ $appState.announcement.content }}</span>
<a class="layout-news-link" :href="$appState.announcement.linkHref">{{ $appState.announcement.linkText }}</a>
</div>
<a class="layout-news-close" :style="$appState?.announcement?.textStyle" @click="onClose">
<a class="layout-news-close" :style="$appState.announcement.textStyle" @click="onClose">
<span class="pi pi-times"></span>
</a>
</div>
</ClientOnly>
</template>
<script>
import EventBus from './AppEventBus';
import EventBus from '@/layouts/AppEventBus';
export default {
data() {
@ -33,6 +31,7 @@ export default {
const item = {
hiddenNews: this.$appState.announcement.id
};
localStorage.setItem(this.storageKey, JSON.stringify(item));
}
}

View File

@ -200,7 +200,7 @@
<div class="flex align-items-center">
<label for="binary" class="mr-2">Remember Me</label>
<Checkbox id="binary" binary v-model="checked" />
<Checkbox id="binary" v-model="checked" binary />
</div>
<h5>Colors</h5>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="AccordionDemo" :sources="sources" github="accordion/AccordionDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -136,7 +135,7 @@ import AccordionTab from 'primevue/accordiontab';
&lt;Button @click="active = 1" class="p-button-text" label="Activate 2nd" /&gt;
&lt;Button @click="active = 2" class="p-button-text" label="Activate 3rd" /&gt;
&lt;Accordion :multiple="true" :activeIdex="active"&gt;
&lt;Accordion :multiple="true" :activeIndex="active"&gt;
&lt;AccordionTab header="Header I"&gt;
Content
&lt;/AccordionTab&gt;
@ -377,7 +376,7 @@ export default {
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -406,14 +405,14 @@ export default {
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
Accordion header elements have a <i>button</i> role and use <i>aria-controls</i> to define the id of the content section along with <i>aria-expanded</i> for the visibility state. The value to read a header element defaults to the
value of the <i>header</i> property and can be customized by defining an <i>aria-label</i> or <i>aria-labelledby</i> via the <i>headerActionProps</i> property.
Accordion header elements have a <i>button</i> role and use <i>aria-controls</i> to define the id of the content section along with <i>aria-expanded</i> for the visibility state. The value to read a header element defaults to the value of
the <i>header</i> property and can be customized by defining an <i>aria-label</i> or <i>aria-labelledby</i> via the <i>headerActionProps</i> property.
</p>
<p>The content uses <i>region</i> role, defines an id that matches the <i>aria-controls</i> of the header and <i>aria-labelledby</i> referring to the id of the header.</p>
<h6>Header Keyboard Support</h6>
<div className="doc-tablewrapper">
<table className="doc-table">
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Key</th>
@ -425,11 +424,11 @@ export default {
<td>
<i>tab</i>
</td>
<td>Moves focus to the next the focusable element in the page tab sequence.</td>
<td>Moves focus to the next focusable element in the page tab sequence.</td>
</tr>
<tr>
<td><i>shift</i> + <i>tab</i></td>
<td>Moves focus to the previous the focusable element in the page tab sequence.</td>
<td>Moves focus to the previous focusable element in the page tab sequence.</td>
</tr>
<tr>
<td>
@ -474,7 +473,6 @@ export default {
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="AutoCompleteDemo" :sources="sources" :service="['CountryService']" :data="['countries']" github="autocomplete/AutoCompleteDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -46,8 +45,8 @@ export default {
<h5>Dropdown</h5>
<p>
Enabling <i>dropdown</i> property displays a button next to the input field where click behavior of the button is defined using dropdownMode property that takes "blank" or "current" as possible values. "blank" is the default mode to
send a query with an empty string whereas "current" setting sends a query with the current value of the input.
Enabling <i>dropdown</i> property displays a button next to the input field where click behavior of the button is defined using dropdownMode property that takes "blank" or "current" as possible values. "blank" is the default mode to send
a query with an empty string whereas "current" setting sends a query with the current value of the input.
</p>
<pre v-code><code>
&lt;AutoComplete v-model="brand" :dropdown="true" :suggestions="filteredBrands" @complete="searchBrand($event)" placeholder="Hint: type 'v' or 'f'" /&gt;
@ -63,8 +62,8 @@ export default {
<h5>Objects</h5>
<p>
AutoComplete can also work with objects using the <i>optionLabel</i> property that defines the label to display as a suggestion. The value passed to the model would still be the object instance of a suggestion. Here is an example with
a Country object that has name and code fields such as &#123;name:"United States",code:"USA"&#125;.
AutoComplete can also work with objects using the <i>optionLabel</i> property that defines the label to display as a suggestion. The value passed to the model would still be the object instance of a suggestion. Here is an example with a
Country object that has name and code fields such as &#123;name:"United States",code:"USA"&#125;.
</p>
<pre v-code><code>
&lt;AutoComplete optionLabel="label" v-model="selectedCountry" :suggestions="filteredCountriesBasic" @complete="searchCountryBasic($event)" /&gt;
@ -134,7 +133,7 @@ export default {
<pre v-code><code><template v-pre>
&lt;AutoComplete v-model="brand" :suggestions="filteredBrands" @complete="searchBrand($event)" placeholder="Hint: type 'v' or 'f'" :dropdown="true"&gt;
&lt;template #item="slotProps"&gt;
&lt;img :alt="slotProps.item" :src="'/demo/images/car/' + slotProps.item + '.png'" /&gt;
&lt;img :alt="slotProps.item" :src="'demo/images/car/' + slotProps.item + '.png'" /&gt;
&lt;div&gt;{{slotProps.item}}&lt;/div&gt;
&lt;/template&gt;
&lt;/AutoComplete&gt;
@ -316,17 +315,35 @@ export default {
<td>null</td>
<td>Uses to pass all properties of the HTMLDivElement to the overlay panel.</td>
</tr>
<tr>
<td>dropdownIcon</td>
<td>string</td>
<td>pi pi-chevron-down</td>
<td>Icon to display in dropdown</td>
</tr>
<tr>
<td>dropdownClass</td>
<td>string</td>
<td>null</td>
<td>Style class of the dropdown button.</td>
</tr>
<tr>
<td>loadingIcon</td>
<td>string</td>
<td>pi pi-spinner</td>
<td>Icon class used when loading</td>
</tr>
<tr>
<td>removeTokenIcon</td>
<td>string</td>
<td>pi pi-times-circle</td>
<td>Icon to display in chip remove action</td>
</tr>
<tr>
<td>virtualScrollerOptions</td>
<td>object</td>
<td>null</td>
<td>Whether to use the virtualScroller feature. The properties of <nuxt-link to="/virtualscroller">VirtualScroller</nuxt-link> component can be used like an object in it.</td>
<td>Whether to use the virtualScroller feature. The properties of <router-link to="/virtualscroller">VirtualScroller</router-link> component can be used like an object in it.</td>
</tr>
<tr>
<td>autoOptionFocus</td>
@ -600,13 +617,13 @@ export default {
<h6>Screen Reader</h6>
<p>
Value to describe the component can either be provided via <i>label</i> tag combined with <i>inputId</i> prop or using <i>aria-labelledby</i>, <i>aria-label</i> props. The input element has <i>combobox</i> role in addition to
<i>aria-autocomplete</i>, <i>aria-haspopup</i> and <i>aria-expanded</i> attributes. The relation between the input and the popup is created with <i>aria-controls</i> and <i>aria-activedescendant</i> attribute is used to instruct
screen reader which option to read during keyboard navigation within the popup list.
<i>aria-autocomplete</i>, <i>aria-haspopup</i> and <i>aria-expanded</i> attributes. The relation between the input and the popup is created with <i>aria-controls</i> and <i>aria-activedescendant</i> attribute is used to instruct screen
reader which option to read during keyboard navigation within the popup list.
</p>
<p>In multiple mode, chip list uses <i>listbox</i> role with <i>aria-orientation</i> set to horizontal whereas each chip has the <i>option</i> role with <i>aria-label</i> set to the label of the chip.</p>
<p>
The popup list has an id that refers to the <i>aria-controls</i> attribute of the input element and uses <i>listbox</i> as the role. Each list item has <i>option</i> role and an id to match the <i>aria-activedescendant</i> of the
input element.
The popup list has an id that refers to the <i>aria-controls</i> attribute of the input element and uses <i>listbox</i> as the role. Each list item has <i>option</i> role and an id to match the <i>aria-activedescendant</i> of the input
element.
</p>
<pre v-code><code>
@ -763,7 +780,6 @@ export default {
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -38,7 +38,7 @@
<h5>Multiple</h5>
<span class="p-fluid">
<AutoComplete :multiple="true" v-model="selectedCountries" :suggestions="filteredCountries" @complete="searchCountry($event)" optionLabel="name" />
<AutoComplete v-model="selectedCountries" :multiple="true" :suggestions="filteredCountries" @complete="searchCountry($event)" optionLabel="name" />
</span>
</div>
</div>
@ -48,9 +48,9 @@
</template>
<script>
import { FilterMatchMode, FilterService } from 'primevue/api';
import CountryService from '../../service/CountryService';
import AutoCompleteDoc from './AutoCompleteDoc';
import { FilterService, FilterMatchMode } from 'primevue/api';
export default {
data() {
@ -124,6 +124,7 @@ export default {
for (let country of this.groupedCities) {
let filteredItems = FilterService.filter(country.items, ['label'], query, FilterMatchMode.CONTAINS);
if (filteredItems && filteredItems.length) {
filteredCities.push({ ...country, ...{ items: filteredItems } });
}
@ -138,6 +139,7 @@ export default {
for (let i = 0; i < this.items.length; i++) {
let item = this.items[i];
if (item.label.toLowerCase().indexOf(query.toLowerCase()) === 0) {
filteredItems.push(item);
}

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="AvatarDemo" :sources="sources" github="avatar/AvatarDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -52,7 +51,7 @@ import AvatarGroup from 'primevue/avatargroup';
</code></pre>
<h5>Badge</h5>
<p>A badge can be added to an Avatar with the <nuxt-link to="/badge">Badge</nuxt-link> directive.</p>
<p>A badge can be added to an Avatar with the <router-link to="/badge">Badge</router-link> directive.</p>
<pre v-code><code>
&lt;Avatar image="user.png" size="xlarge" v-badge.danger="4" /&gt;
@ -110,6 +109,18 @@ import AvatarGroup from 'primevue/avatargroup';
<td>square</td>
<td>Shape of the element, valid options are "square" and "circle".</td>
</tr>
<tr>
<td>aria-label</td>
<td>string</td>
<td>null</td>
<td>Defines a string value that labels an interactive element.</td>
</tr>
<tr>
<td>aria-labelledby</td>
<td>string</td>
<td>null</td>
<td>Establishes relationships between the component and label(s) where its value should be one or more element IDs.</td>
</tr>
</tbody>
</table>
</div>
@ -138,7 +149,7 @@ import AvatarGroup from 'primevue/avatargroup';
</div>
<h5>Styling of Avatar</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -198,10 +209,19 @@ import AvatarGroup from 'primevue/avatargroup';
</table>
</div>
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
Avatar does not include any roles and attributes by default. Any attribute is passed to the root element so you may add a role like <i>img</i> along with <i>aria-labelledby</i> or <i>aria-label</i> to describe the component. In case
avatars need to be tabbable, <i>tabindex</i> can be added as well to implement custom key handlers.
</p>
<h5>Keyboard Support</h5>
<p>Component does not include any interactive elements.</p>
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -31,7 +31,7 @@
<div class="col-12 md:col-4">
<div class="card">
<h5>Label - Badge</h5>
<Avatar label="U" size="xlarge" style="background-color: #4caf4f; color: #ffffff" v-badge="4" />
<Avatar v-badge="4" label="U" size="xlarge" style="background-color: #4caf4f; color: #ffffff" />
</div>
</div>
</div>
@ -58,7 +58,7 @@
<div class="col-12 md:col-4">
<div class="card">
<h5>Icon - Badge</h5>
<Avatar icon="pi pi-user" size="xlarge" v-badge="4" />
<Avatar v-badge="4" icon="pi pi-user" size="xlarge" />
</div>
</div>
</div>
@ -67,9 +67,9 @@
<div class="col-12 md:col-4">
<div class="card">
<h5>Image</h5>
<Avatar image="/demo/images/avatar/amyelsner.png" class="mr-2" size="xlarge" shape="circle" />
<Avatar image="/demo/images/avatar/asiyajavayant.png" class="mr-2" size="large" shape="circle" />
<Avatar image="/demo/images/avatar/onyamalimba.png" class="mr-2" shape="circle" />
<Avatar image="demo/images/avatar/amyelsner.png" class="mr-2" size="xlarge" shape="circle" />
<Avatar image="demo/images/avatar/asiyajavayant.png" class="mr-2" size="large" shape="circle" />
<Avatar image="demo/images/avatar/onyamalimba.png" class="mr-2" shape="circle" />
</div>
</div>
@ -77,11 +77,11 @@
<div class="card">
<h5>Avatar Group</h5>
<AvatarGroup class="mb-3">
<Avatar image="/demo/images/avatar/amyelsner.png" size="large" shape="circle" />
<Avatar image="/demo/images/avatar/asiyajavayant.png" size="large" shape="circle" />
<Avatar image="/demo/images/avatar/onyamalimba.png" size="large" shape="circle" />
<Avatar image="/demo/images/avatar/ionibowcher.png" size="large" shape="circle" />
<Avatar image="/demo/images/avatar/xuxuefeng.png" size="large" shape="circle" />
<Avatar image="demo/images/avatar/amyelsner.png" size="large" shape="circle" />
<Avatar image="demo/images/avatar/asiyajavayant.png" size="large" shape="circle" />
<Avatar image="demo/images/avatar/onyamalimba.png" size="large" shape="circle" />
<Avatar image="demo/images/avatar/ionibowcher.png" size="large" shape="circle" />
<Avatar image="demo/images/avatar/xuxuefeng.png" size="large" shape="circle" />
<Avatar label="+2" shape="circle" size="large" style="background-color: #9c27b0; color: #ffffff" />
</AvatarGroup>
</div>
@ -90,7 +90,7 @@
<div class="col-12 md:col-4">
<div class="card">
<h5>Image - Badge</h5>
<Avatar image="/demo/images/organization/walter.jpg" size="xlarge" v-badge.danger="4" />
<Avatar v-badge.danger="4" image="demo/images/organization/walter.jpg" size="xlarge" />
</div>
</div>
</div>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="BadgeDemo" :sources="sources" github="badge/BadgeDemo.vue">
<h5>Getting Started</h5>
<p>Badge can either be used as a standalone component or as a directive.</p>
@ -139,7 +138,7 @@ app.directive('badge', BadgeDirective);
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -189,10 +188,19 @@ app.directive('badge', BadgeDirective);
</table>
</div>
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
Badge does not include any roles and attributes by default, any attribute is passed to the root element so aria roles and attributes can be added if required. If the badges are dynamic,
<i>aria-live</i> may be utilized as well. In case badges need to be tabbable, <i>tabindex</i> can be added to implement custom key handlers.
</p>
<h5>Keyboard Support</h5>
<p>Component does not include any interactive elements.</p>
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>
@ -206,7 +214,7 @@ export default {
<template>
<div>
<h5>Numbers</h5>
<Badge value="2" class="mr-2"></Badge>
<Badge value="2" class="mr-2" aria-label="Tabable Primary Badge" tabindex="0"></Badge>
<Badge value="8" severity="success" class="mr-2"></Badge>
<Badge value="4" severity="info" class="mr-2"></Badge>
<Badge value="12" severity="warning" class="mr-2"></Badge>
@ -240,7 +248,7 @@ export default {
<template>
<div>
<h5>Numbers</h5>
<Badge value="2" class="mr-2"></Badge>
<Badge value="2" class="mr-2" aria-label="Tabable Primary Badge" tabindex="0"></Badge>
<Badge value="8" severity="success" class="mr-2"></Badge>
<Badge value="4" severity="info" class="mr-2"></Badge>
<Badge value="12" severity="warning" class="mr-2"></Badge>
@ -273,7 +281,7 @@ export default {
<script src="https://unpkg.com/primevue@^3/badgedirective/badgedirective.min.js"><\\/script>`,
content: `<div id="app">
<h5>Numbers</h5>
<p-badge value="2" class="mr-2"></p-badge>
<p-badge value="2" class="mr-2" aria-label="Tabable Primary Badge" tabindex="0"></p-badge>
<p-badge value="8" severity="success" class="mr-2"></p-badge>
<p-badge value="4" severity="info" class="mr-2"></p-badge>
<p-badge value="12" severity="warning" class="mr-2"></p-badge>

View File

@ -11,16 +11,16 @@
<div class="content-section implementation">
<div class="card">
<h5>Numbers</h5>
<Badge value="2" class="mr-2"></Badge>
<Badge value="2" class="mr-2" aria-label="Tabable Primary Badge" tabindex="0"></Badge>
<Badge value="8" severity="success" class="mr-2"></Badge>
<Badge value="4" severity="info" class="mr-2"></Badge>
<Badge value="12" severity="warning" class="mr-2"></Badge>
<Badge value="3" severity="danger"></Badge>
<h5 class="mb-4">Positioned Badge</h5>
<i class="pi pi-bell mr-4 p-text-secondary" style="font-size: 2rem" v-badge="2"></i>
<i class="pi pi-calendar mr-4 p-text-secondary" style="font-size: 2rem" v-badge.danger="'10+'"></i>
<i class="pi pi-envelope p-text-secondary" style="font-size: 2rem" v-badge.danger></i>
<i v-badge="2" class="pi pi-bell mr-4 p-text-secondary" style="font-size: 2rem"></i>
<i v-badge.danger="'10+'" class="pi pi-calendar mr-4 p-text-secondary" style="font-size: 2rem"></i>
<i v-badge.danger class="pi pi-envelope p-text-secondary" style="font-size: 2rem"></i>
<h5>Button Badge</h5>
<Button type="button" label="Emails" badge="8" class="mr-2" />

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="BlockUIDemo" :sources="sources" github="blockui/BlockUIDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -16,8 +15,8 @@ import BlockUI from 'primevue/blockui';
<h5>Getting Started</h5>
<p>
BlockUI is controlled using the <i>blocked</i> property, by default target element to block is the child component. In example below, panel gets blocked with a mask when blockedPanel is enabled and gets unblock when the bound variable
is set to false.
BlockUI is controlled using the <i>blocked</i> property, by default target element to block is the child component. In example below, panel gets blocked with a mask when blockedPanel is enabled and gets unblock when the bound variable is
set to false.
</p>
<pre v-code><code>
&lt;BlockUI :blocked="blockedPanel"&gt;
@ -122,7 +121,7 @@ export default {
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -144,10 +143,18 @@ export default {
</table>
</div>
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
BlockUI manages <i>aria-busy</i> state attribute when the UI gets blocked and unblocked. Any valid attribute is passed to the root element so additional attributes like <i>role</i> and <i>aria-live</i> can be used to define live regions.
</p>
<h5>Keyboard Support</h5>
<p>Component does not include any interactive elements.</p>
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="BreadcrumbDemo" :sources="sources" github="breadcrumb/BreadcrumbDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -15,7 +14,7 @@ import Breadcrumb from 'primevue/breadcrumb';
</code></pre>
<h5>MenuModel</h5>
<p>Breadcrumb uses the common MenuModel API to define the items, visit <nuxt-link to="/menumodel">MenuModel API</nuxt-link> for details.</p>
<p>Breadcrumb uses the common MenuModel API to define the items, visit <router-link to="/menumodel">MenuModel API</router-link> for details.</p>
<h5>Getting Started</h5>
<p>Breadcrumb requires a collection of menuitems as its model and a home item.</p>
@ -53,13 +52,13 @@ export default {
</template>
</code></pre>
<p><i>nuxt-link</i> with route configuration can also be used within templating for further customization.</p>
<p><i>router-link</i> with route configuration can also be used within templating for further customization.</p>
<pre v-code><code><template v-pre>
&lt;Breadcrumb :home="home" :model="items"&gt;
&lt;template #item="{item}"&gt;
&lt;nuxt-link :to="item.to" custom v-slot="{href, route, navigate, isActive, isExactActive}"&gt;
&lt;router-link :to="item.to" custom v-slot="{href, route, navigate, isActive, isExactActive}"&gt;
&lt;a :href="href" @click="navigate" :class="{'active-link': isActive, 'active-link-exact": isExactActive}&gt;{{route.fullPath}}&lt;/a&gt;
&lt;/nuxt-link&gt;
&lt;/router-link&gt;
&lt;/template&gt;
&lt;/Breadcrumb&gt;
</template>
@ -94,7 +93,19 @@ export default {
<td>exact</td>
<td>boolean</td>
<td>true</td>
<td>Whether to apply 'nuxt-link-active-exact' class if route exactly matches the item path.</td>
<td>Whether to apply 'router-link-active-exact' class if route exactly matches the item path.</td>
</tr>
<tr>
<td>aria-label</td>
<td>string</td>
<td>null</td>
<td>Defines a string value that labels an interactive element.</td>
</tr>
<tr>
<td>aria-labelledby</td>
<td>string</td>
<td>null</td>
<td>Establishes relationships between the component and label(s) where its value should be one or more element IDs.</td>
</tr>
</tbody>
</table>
@ -119,7 +130,7 @@ export default {
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -133,17 +144,29 @@ export default {
<td>p-breadcrumb</td>
<td>Container element.</td>
</tr>
<tr>
<td>p-breadcrumb-list</td>
<td>Ordered list element.</td>
</tr>
<tr>
<td>p-breadcrumb-home</td>
<td>First list element.</td>
</tr>
<tr>
<td>p-menuitem</td>
<td>Menuitem element.</td>
</tr>
<tr>
<td>p-menuitem-link</td>
<td>Link element of the menuitem.</td>
</tr>
<tr>
<td>p-menuitem-text</td>
<td>Label of a menuitem.</td>
</tr>
<tr>
<td>p-breadcrumb-chevron</td>
<td>Chevron element.</td>
<td>p-menuitem-icon</td>
<td>Icon of a menuitem.</td>
</tr>
</tbody>
</table>
@ -151,8 +174,20 @@ export default {
<h5>Dependencies</h5>
<p>None.</p>
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
Breadcrumb uses the <i>nav</i> element and since any attribute is passed to the root implicitly <i>aria-labelledby</i> or <i>aria-label</i> can be used to describe the component. Inside an ordered list is used where the list item
separators have <i>aria-hidden</i> to be able to ignored by the screen readers. If the last link represents the current route, <i>aria-current</i> is added with "page" as the value.
</p>
<h6>Keyboard Support</h6>
<p>No special keyboard interaction is needed, all menuitems are focusable based on the page tab sequence.</p>
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>
@ -165,7 +200,7 @@ export default {
content: `
<template>
<div>
<Breadcrumb :home="home" :model="items" />
<Breadcrumb :home="home" :model="items" aria-label="breadcrumb" />
</div>
</template>
@ -195,7 +230,7 @@ export default {
content: `
<template>
<div>
<Breadcrumb :home="home" :model="items" />
<Breadcrumb :home="home" :model="items" aria-label="breadcrumb" />
</div>
</template>
@ -227,7 +262,7 @@ export default {
imports: `<script src="https://unpkg.com/vue-router@4.0.0/dist/vue-router.global.js"><\\/script>
<script src="https://unpkg.com/primevue@^3/breadcrumb/breadcrumb.min.js"><\\/script>`,
content: `<div id="app">
<p-breadcrumb :home="home" :model="items"></p-breadcrumb>
<p-breadcrumb :home="home" :model="items" aria-label="breadcrumb"></p-breadcrumb>
</div>
<script type="module">

View File

@ -10,7 +10,7 @@
<div class="content-section implementation">
<div class="card">
<Breadcrumb :home="home" :model="items" />
<Breadcrumb :home="home" :model="items" aria-label="breadcrumb" />
</div>
</div>
@ -25,7 +25,7 @@ export default {
data() {
return {
home: { icon: 'pi pi-home', to: '/' },
items: [{ label: 'Computer' }, { label: 'Notebook' }, { label: 'Accessories' }, { label: 'Backpacks' }, { label: 'Item' }]
items: [{ label: 'Computer' }, { label: 'Notebook' }, { label: 'Accessories' }, { label: 'Backpacks' }, { label: 'Item', to: '/breadcrumb' }]
};
},
components: {

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="ButtonDemo" :sources="sources" github="button/ButtonDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -95,7 +94,7 @@ import Button from 'primevue/button';
</code></pre>
<h5>Badges</h5>
<p>Badge is a small status indicator for a button. Refer to the <nuxt-link to="/badge">badge</nuxt-link> documentation for available styling options.</p>
<p>Badge is a small status indicator for a button. Refer to the <router-link to="/badge">badge</router-link> documentation for available styling options.</p>
<pre v-code><code>
&lt;Button type="button" label="Emails" badge="8" /&gt;
@ -116,8 +115,8 @@ import Button from 'primevue/button';
<h5>Sizes</h5>
<p>
2 more sizes are available in addition to a regular button, for a smaller input add <i>p-button-sm</i> and for a larger one, use <i>p-button-lg</i>. Note that these classes available to change the size of a particular button, for
global scaling see the <nuxt-link to="/theming">theming</nuxt-link> page.
2 more sizes are available in addition to a regular button, for a smaller input add <i>p-button-sm</i> and for a larger one, use <i>p-button-lg</i>. Note that these classes available to change the size of a particular button, for global
scaling see the <router-link to="/theming">theming</router-link> page.
</p>
<pre v-code><code>
&lt;Button label="Small" icon="pi pi-check" class="p-button-sm" /&gt;
@ -213,7 +212,7 @@ import Button from 'primevue/button';
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -248,11 +247,10 @@ import Button from 'primevue/button';
</div>
<h5>Accessibility</h5>
<DevelopmentSection>
<h6>Screen Reader</h6>
<p>
Button component renders a native button element that implicitly includes any passed prop. Text to describe the button is defined with the <i>aria-label</i> prop, if not present <i>label</i> prop is used as the value. If the
button is icon only or custom templating is used, it is recommended to use <i>aria-label</i> so that screen readers would be able to read the element properly.
Button component renders a native button element that implicitly includes any passed prop. Text to describe the button is defined with the <i>aria-label</i> prop, if not present <i>label</i> prop is used as the value. If the button is
icon only or custom templating is used, it is recommended to use <i>aria-label</i> so that screen readers would be able to read the element properly.
</p>
<pre v-code><code>
@ -292,12 +290,10 @@ import Button from 'primevue/button';
</tbody>
</table>
</div>
</DevelopmentSection>
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>
@ -414,15 +410,6 @@ export default {
<Button type="button" icon="pi pi-search" :loading="loading[2]" @click="load(2)" />
<Button type="button" label="Search" :loading="loading[3]" @click="load(3)" />
<h5>Templating</h5>
<Button type="button" class="px-3">
<img alt="logo" src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" style="width: 1.5rem"/>
</Button>
<Button type="button" class="p-button-outlined p-button-success">
<img alt="logo" src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" style="width: 1.5rem" />
<span class="ml-2 font-bold">PrimeVue</span>
</Button>
<h5>Button Set</h5>
<span class="p-buttonset">
<Button label="Save" icon="pi pi-check" />
@ -436,6 +423,42 @@ export default {
<Button label="Normal" icon="pi pi-check" class="p-button" />
<Button label="Large" icon="pi pi-check" class="p-button-lg" />
</div>
<h5>Template</h5>
<div class="template">
<Button class="google p-0" aria-label="Google">
<i class="pi pi-google px-2"></i>
<span class="px-3">Google</span>
</Button>
<Button class="youtube p-0" aria-label="Youtube">
<i class="pi pi-youtube px-2"></i>
<span class="px-3">Youtube</span>
</Button>
<Button class="vimeo p-0" aria-label="Vimeo">
<i class="pi pi-vimeo px-2"></i>
<span class="px-3">Vimeo</span>
</Button>
<Button class="facebook p-0" aria-label="Facebook">
<i class="pi pi-facebook px-2"></i>
<span class="px-3">Facebook</span>
</Button>
<Button class="twitter p-0" aria-label="Twitter">
<i class="pi pi-twitter px-2"></i>
<span class="px-3">Twitter</span>
</Button>
<Button class="slack p-0" aria-label="Slack">
<i class="pi pi-slack px-2"></i>
<span class="px-3">Slack</span>
</Button>
<Button class="amazon p-0" aria-label="Amazon">
<i class="pi pi-amazon px-2"></i>
<span class="px-3">Amazon</span>
</Button>
<Button class="discord p-0" aria-label="Discord">
<i class="pi pi-discord px-2"></i>
<span class="px-3">Discord</span>
</Button>
</div>
</div>
</template>
@ -456,8 +479,8 @@ export default {
<\\/script>
<style lang="scss" scoped>
.p-button {
margin-right: .5rem;
.p-button {
margin-right: 0.5rem;
}
.p-buttonset {
@ -468,7 +491,7 @@ export default {
.sizes {
.button {
margin-bottom: .5rem;
margin-bottom: 0.5rem;
display: block;
&:last-child {
@ -477,9 +500,149 @@ export default {
}
}
.template .p-button i {
line-height: 2.25rem;
}
.template .p-button.google {
background: linear-gradient(to left, var(--purple-600) 50%, var(--purple-700) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--purple-700);
}
.template .p-button.google:hover {
background-position: left bottom;
}
.template .p-button.google i {
background-color: var(--purple-700);
}
.template .p-button.google:focus {
box-shadow: 0 0 0 1px var(--purple-400);
}
.template .p-button.youtube {
background: linear-gradient(to left, var(--pink-600) 50%, var(--pink-700) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--pink-700);
}
.template .p-button.youtube:hover {
background-position: left bottom;
}
.template .p-button.youtube i {
background-color: var(--pink-700);
}
.template .p-button.youtube:focus {
box-shadow: 0 0 0 1px var(--pink-400);
}
.template .p-button.vimeo {
background: linear-gradient(to left, var(--green-200) 50%, var(--green-300) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #000;
border-color: var(--green-300);
}
.template .p-button.vimeo:hover {
background-position: left bottom;
}
.template .p-button.vimeo i {
background-color: var(--green-300);
}
.template .p-button.vimeo:focus {
box-shadow: 0 0 0 1px var(--green-400);
}
.template .p-button.facebook {
background: linear-gradient(to left, var(--indigo-600) 50%, var(--indigo-700) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--indigo-700);
}
.template .p-button.facebook:hover {
background-position: left bottom;
}
.template .p-button.facebook i {
background-color: var(--indigo-700);
}
.template .p-button.facebook:focus {
box-shadow: 0 0 0 1px var(--indigo-400);
}
.template .p-button.twitter {
background: linear-gradient(to left, var(--blue-400) 50%, var(--blue-500) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--blue-500);
}
.template .p-button.twitter:hover {
background-position: left bottom;
}
.template .p-button.twitter i {
background-color: var(--blue-500);
}
.template .p-button.twitter:focus {
box-shadow: 0 0 0 1px var(--blue-200);
}
.template .p-button.slack {
background: linear-gradient(to left, var(--orange-400) 50%, var(--orange-500) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--orange-500);
}
.template .p-button.slack:hover {
background-position: left bottom;
}
.template .p-button.slack i {
background-color: var(--orange-500);
}
.template .p-button.slack:focus {
box-shadow: 0 0 0 1px var(--orange-200);
}
.template .p-button.amazon {
background: linear-gradient(to left, var(--yellow-400) 50%, var(--yellow-500) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #000;
border-color: var(--yellow-500);
}
.template .p-button.amazon:hover {
background-position: left bottom;
}
.template .p-button.amazon i {
background-color: var(--yellow-500);
}
.template .p-button.amazon:focus {
box-shadow: 0 0 0 1px var(--yellow-200);
}
.template .p-button.discord {
background: linear-gradient(to left, var(--bluegray-700) 50%, var(--bluegray-800) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--bluegray-800);
}
.template .p-button.discord:hover {
background-position: left bottom;
}
.template .p-button.discord i {
background-color: var(--bluegray-800);
}
.template .p-button.discord:focus {
box-shadow: 0 0 0 1px var(--bluegray-500);
}
@media screen and (max-width: 640px) {
.p-button {
margin-bottom: .5rem;
margin-bottom: 0.5rem;
&:not(.p-button-icon-only) {
display: flex;
@ -604,15 +767,6 @@ export default {
<Button type="button" icon="pi pi-search" :loading="loading[2]" @click="load(2)" />
<Button type="button" label="Search" :loading="loading[3]" @click="load(3)" />
<h5>Templating</h5>
<Button type="button" class="px-3">
<img alt="logo" src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" style="width: 1.5rem"/>
</Button>
<Button type="button" class="p-button-outlined p-button-success">
<img alt="logo" src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" style="width: 1.5rem" />
<span class="ml-2 font-bold">PrimeVue</span>
</Button>
<h5>Button Set</h5>
<span class="p-buttonset">
<Button label="Save" icon="pi pi-check" />
@ -626,6 +780,42 @@ export default {
<Button label="Normal" icon="pi pi-check" class="p-button" />
<Button label="Large" icon="pi pi-check" class="p-button-lg" />
</div>
<h5>Template</h5>
<div class="template">
<Button class="google p-0" aria-label="Google">
<i class="pi pi-google px-2"></i>
<span class="px-3">Google</span>
</Button>
<Button class="youtube p-0" aria-label="Youtube">
<i class="pi pi-youtube px-2"></i>
<span class="px-3">Youtube</span>
</Button>
<Button class="vimeo p-0" aria-label="Vimeo">
<i class="pi pi-vimeo px-2"></i>
<span class="px-3">Vimeo</span>
</Button>
<Button class="facebook p-0" aria-label="Facebook">
<i class="pi pi-facebook px-2"></i>
<span class="px-3">Facebook</span>
</Button>
<Button class="twitter p-0" aria-label="Twitter">
<i class="pi pi-twitter px-2"></i>
<span class="px-3">Twitter</span>
</Button>
<Button class="slack p-0" aria-label="Slack">
<i class="pi pi-slack px-2"></i>
<span class="px-3">Slack</span>
</Button>
<Button class="amazon p-0" aria-label="Amazon">
<i class="pi pi-amazon px-2"></i>
<span class="px-3">Amazon</span>
</Button>
<Button class="discord p-0" aria-label="Discord">
<i class="pi pi-discord px-2"></i>
<span class="px-3">Discord</span>
</Button>
</div>
</div>
</template>
@ -646,8 +836,8 @@ export default({
<\\/script>
<style lang="scss" scoped>
.p-button {
margin-right: .5rem;
.p-button {
margin-right: 0.5rem;
}
.p-buttonset {
@ -658,7 +848,7 @@ export default({
.sizes {
.button {
margin-bottom: .5rem;
margin-bottom: 0.5rem;
display: block;
&:last-child {
@ -667,9 +857,149 @@ export default({
}
}
.template .p-button i {
line-height: 2.25rem;
}
.template .p-button.google {
background: linear-gradient(to left, var(--purple-600) 50%, var(--purple-700) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--purple-700);
}
.template .p-button.google:hover {
background-position: left bottom;
}
.template .p-button.google i {
background-color: var(--purple-700);
}
.template .p-button.google:focus {
box-shadow: 0 0 0 1px var(--purple-400);
}
.template .p-button.youtube {
background: linear-gradient(to left, var(--pink-600) 50%, var(--pink-700) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--pink-700);
}
.template .p-button.youtube:hover {
background-position: left bottom;
}
.template .p-button.youtube i {
background-color: var(--pink-700);
}
.template .p-button.youtube:focus {
box-shadow: 0 0 0 1px var(--pink-400);
}
.template .p-button.vimeo {
background: linear-gradient(to left, var(--green-200) 50%, var(--green-300) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #000;
border-color: var(--green-300);
}
.template .p-button.vimeo:hover {
background-position: left bottom;
}
.template .p-button.vimeo i {
background-color: var(--green-300);
}
.template .p-button.vimeo:focus {
box-shadow: 0 0 0 1px var(--green-400);
}
.template .p-button.facebook {
background: linear-gradient(to left, var(--indigo-600) 50%, var(--indigo-700) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--indigo-700);
}
.template .p-button.facebook:hover {
background-position: left bottom;
}
.template .p-button.facebook i {
background-color: var(--indigo-700);
}
.template .p-button.facebook:focus {
box-shadow: 0 0 0 1px var(--indigo-400);
}
.template .p-button.twitter {
background: linear-gradient(to left, var(--blue-400) 50%, var(--blue-500) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--blue-500);
}
.template .p-button.twitter:hover {
background-position: left bottom;
}
.template .p-button.twitter i {
background-color: var(--blue-500);
}
.template .p-button.twitter:focus {
box-shadow: 0 0 0 1px var(--blue-200);
}
.template .p-button.slack {
background: linear-gradient(to left, var(--orange-400) 50%, var(--orange-500) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--orange-500);
}
.template .p-button.slack:hover {
background-position: left bottom;
}
.template .p-button.slack i {
background-color: var(--orange-500);
}
.template .p-button.slack:focus {
box-shadow: 0 0 0 1px var(--orange-200);
}
.template .p-button.amazon {
background: linear-gradient(to left, var(--yellow-400) 50%, var(--yellow-500) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #000;
border-color: var(--yellow-500);
}
.template .p-button.amazon:hover {
background-position: left bottom;
}
.template .p-button.amazon i {
background-color: var(--yellow-500);
}
.template .p-button.amazon:focus {
box-shadow: 0 0 0 1px var(--yellow-200);
}
.template .p-button.discord {
background: linear-gradient(to left, var(--bluegray-700) 50%, var(--bluegray-800) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--bluegray-800);
}
.template .p-button.discord:hover {
background-position: left bottom;
}
.template .p-button.discord i {
background-color: var(--bluegray-800);
}
.template .p-button.discord:focus {
box-shadow: 0 0 0 1px var(--bluegray-500);
}
@media screen and (max-width: 640px) {
.p-button {
margin-bottom: .5rem;
margin-bottom: 0.5rem;
&:not(.p-button-icon-only) {
display: flex;
@ -793,15 +1123,6 @@ export default({
<p-button type="button" icon="pi pi-search" :loading="loading[2]" @click="load(2)"></p-button>
<p-button type="button" label="Search" :loading="loading[3]" @click="load(3)"></p-button>
<h5>Templating</h5>
<p-button type="button" class="px-3">
<img alt="logo" src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" style="width: 1.5rem" />
</p-button>
<p-button type="button" class="p-button-outlined p-button-success">
<img alt="logo" src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" style="width: 1.5rem" />
<span class="ml-2 font-bold">PrimeVue</span>
</p-button>
<h5>Button Set</h5>
<span class="p-buttonset">
<p-button label="Save" icon="pi pi-check"></p-button>
@ -815,6 +1136,42 @@ export default({
<p-button label="Normal" icon="pi pi-check" class="p-button"></p-button>
<p-button label="Large" icon="pi pi-check" class="p-button-lg"></p-button>
</div>
<h5>Template</h5>
<div class="template">
<p-button class="google p-0" aria-label="Google">
<i class="pi pi-google px-2"></i>
<span class="px-3">Google</span>
</p-button>
<p-button class="youtube p-0" aria-label="Youtube">
<i class="pi pi-youtube px-2"></i>
<span class="px-3">Youtube</span>
</p-button>
<p-button class="vimeo p-0" aria-label="Vimeo">
<i class="pi pi-vimeo px-2"></i>
<span class="px-3">Vimeo</span>
</p-button>
<p-button class="facebook p-0" aria-label="Facebook">
<i class="pi pi-facebook px-2"></i>
<span class="px-3">Facebook</span>
</p-button>
<p-button class="twitter p-0" aria-label="Twitter">
<i class="pi pi-twitter px-2"></i>
<span class="px-3">Twitter</span>
</p-button>
<p-button class="slack p-0" aria-label="Slack">
<i class="pi pi-slack px-2"></i>
<span class="px-3">Slack</span>
</p-button>
<p-button class="amazon p-0" aria-label="Amazon">
<i class="pi pi-amazon px-2"></i>
<span class="px-3">Amazon</span>
</p-button>
<p-button class="discord p-0" aria-label="Discord">
<i class="pi pi-discord px-2"></i>
<span class="px-3">Discord</span>
</p-button>
</div>
</div>
</div>
@ -843,7 +1200,7 @@ export default({
<style>
.p-button {
margin-right: .5rem;
margin-right: 0.5rem;
}
.p-buttonset .p-button {
@ -855,13 +1212,149 @@ export default({
display: block;
}
.sizes .button:last-child {
margin-bottom: 0;
.template .p-button i {
line-height: 2.25rem;
}
.template .p-button.google {
background: linear-gradient(to left, var(--purple-600) 50%, var(--purple-700) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--purple-700);
}
.template .p-button.google:hover {
background-position: left bottom;
}
.template .p-button.google i {
background-color: var(--purple-700);
}
.template .p-button.google:focus {
box-shadow: 0 0 0 1px var(--purple-400);
}
.template .p-button.youtube {
background: linear-gradient(to left, var(--pink-600) 50%, var(--pink-700) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--pink-700);
}
.template .p-button.youtube:hover {
background-position: left bottom;
}
.template .p-button.youtube i {
background-color: var(--pink-700);
}
.template .p-button.youtube:focus {
box-shadow: 0 0 0 1px var(--pink-400);
}
.template .p-button.vimeo {
background: linear-gradient(to left, var(--green-200) 50%, var(--green-300) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #000;
border-color: var(--green-300);
}
.template .p-button.vimeo:hover {
background-position: left bottom;
}
.template .p-button.vimeo i {
background-color: var(--green-300);
}
.template .p-button.vimeo:focus {
box-shadow: 0 0 0 1px var(--green-400);
}
.template .p-button.facebook {
background: linear-gradient(to left, var(--indigo-600) 50%, var(--indigo-700) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--indigo-700);
}
.template .p-button.facebook:hover {
background-position: left bottom;
}
.template .p-button.facebook i {
background-color: var(--indigo-700);
}
.template .p-button.facebook:focus {
box-shadow: 0 0 0 1px var(--indigo-400);
}
.template .p-button.twitter {
background: linear-gradient(to left, var(--blue-400) 50%, var(--blue-500) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--blue-500);
}
.template .p-button.twitter:hover {
background-position: left bottom;
}
.template .p-button.twitter i {
background-color: var(--blue-500);
}
.template .p-button.twitter:focus {
box-shadow: 0 0 0 1px var(--blue-200);
}
.template .p-button.slack {
background: linear-gradient(to left, var(--orange-400) 50%, var(--orange-500) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--orange-500);
}
.template .p-button.slack:hover {
background-position: left bottom;
}
.template .p-button.slack i {
background-color: var(--orange-500);
}
.template .p-button.slack:focus {
box-shadow: 0 0 0 1px var(--orange-200);
}
.template .p-button.amazon {
background: linear-gradient(to left, var(--yellow-400) 50%, var(--yellow-500) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #000;
border-color: var(--yellow-500);
}
.template .p-button.amazon:hover {
background-position: left bottom;
}
.template .p-button.amazon i {
background-color: var(--yellow-500);
}
.template .p-button.amazon:focus {
box-shadow: 0 0 0 1px var(--yellow-200);
}
.template .p-button.discord {
background: linear-gradient(to left, var(--bluegray-700) 50%, var(--bluegray-800) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--bluegray-800);
}
.template .p-button.discord:hover {
background-position: left bottom;
}
.template .p-button.discord i {
background-color: var(--bluegray-800);
}
.template .p-button.discord:focus {
box-shadow: 0 0 0 1px var(--bluegray-500);
}
@media screen and (max-width: 640px) {
.p-button {
margin-bottom: .5rem;
margin-bottom: 0.5rem;
}
.p-button:not(.p-button-icon-only) {

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="CalendarDemo" :sources="sources" github="calendar/CalendarDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -42,8 +41,8 @@ export default {
<h5>Selection Mode</h5>
<p>
By default calendar allows selecting one date only whereas multiple dates can be selected by setting <i>selectionMode</i> to multiple. In this case calendar updates the value with an array of dates where optionally number of
selectable dates can be restricted with maxDateCount property. Third alternative is the range mode that allows selecting a range based on an array of two values where first value is the start date and second value is the end date.
By default calendar allows selecting one date only whereas multiple dates can be selected by setting <i>selectionMode</i> to multiple. In this case calendar updates the value with an array of dates where optionally number of selectable
dates can be restricted with maxDateCount property. Third alternative is the range mode that allows selecting a range based on an array of two values where first value is the start date and second value is the end date.
</p>
<pre v-code><code>
@ -52,7 +51,7 @@ export default {
</code></pre>
<h5>DateFormat</h5>
<p>Default date format is mm/dd/yy, to customize this use <i>dateFormat</i> property or define it at <nuxt-link to="/locale">PrimeVue Locale</nuxt-link> globally. Note that standalone property overrides the value in locale settings.</p>
<p>Default date format is mm/dd/yy, to customize this use <i>dateFormat</i> property or define it at <router-link to="/locale">PrimeVue Locale</router-link> globally. Note that standalone property overrides the value in locale settings.</p>
<pre v-code><code>
&lt;Calendar v-model="value" dateFormat="dd.mm.yy" /&gt;
@ -117,7 +116,7 @@ export default {
</code></pre>
<h5>Locale</h5>
<p>Locale for different languages and formats is defined globally, refer to the <nuxt-link to="/locale">PrimeVue Locale</nuxt-link> configuration for more information.</p>
<p>Locale for different languages and formats is defined globally, refer to the <router-link to="/locale">PrimeVue Locale</router-link> configuration for more information.</p>
<h5>Custom Content</h5>
<p>Calendar UI accepts custom content using header and footer templates.</p>
@ -202,7 +201,7 @@ export default {
<td>dateFormat</td>
<td>string</td>
<td>null</td>
<td>Format of the date. Defaults to PrimeVue <nuxt-link to="/locale">Locale</nuxt-link> configuration.</td>
<td>Format of the date. Defaults to PrimeVue <router-link to="/locale">Locale</router-link> configuration.</td>
</tr>
<tr>
<td>inline</td>
@ -246,6 +245,30 @@ export default {
<td>pi pi-calendar</td>
<td>Icon of the calendar button.</td>
</tr>
<tr>
<td>previousIcon</td>
<td>string</td>
<td>pi pi-chevron-left</td>
<td>Icon to show in the previous button.</td>
</tr>
<tr>
<td>nextIcon</td>
<td>string</td>
<td>pi pi-chevron-right</td>
<td>Icon to show in the next button.</td>
</tr>
<tr>
<td>incrementIcon</td>
<td>string</td>
<td>pi pi-chevron-up</td>
<td>Icon to show in each of the increment buttons.</td>
</tr>
<tr>
<td>decrementIcon</td>
<td>string</td>
<td>pi pi-chevron-down</td>
<td>Icon to show in each of the decrement buttons.</td>
</tr>
<tr>
<td>numberOfMonths</td>
<td>number</td>
@ -618,7 +641,7 @@ export default {
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -688,7 +711,7 @@ export default {
</p>
<p>
The optional calendar button requires includes <i>aria-haspopup</i>, <i>aria-expanded</i> for states along with <i>aria-controls</i> to define the relation between the popup and the button. The value to read is retrieved from the
<i>chooseDate</i> key of the aria property from the <nuxt-link to="/locale">locale</nuxt-link> API. This label is also used for the <i>aria-label</i> of the popup as well. When there is a value selected, it is formatted and appended
<i>chooseDate</i> key of the aria property from the <router-link to="/locale">locale</router-link> API. This label is also used for the <i>aria-label</i> of the popup as well. When there is a value selected, it is formatted and appended
to the label to be able to notify users about the current value.
</p>
@ -877,7 +900,6 @@ export default {
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -14,59 +14,59 @@
<div class="p-fluid grid formgrid">
<div class="field col-12 md:col-4">
<label for="basic">Basic</label>
<Calendar inputId="basic" v-model="date1" autocomplete="off" />
<Calendar v-model="date1" inputId="basic" autocomplete="off" />
</div>
<div class="field col-12 md:col-4">
<label for="dateformat">DateFormat</label>
<Calendar inputId="dateformat" v-model="date2" dateFormat="mm-dd-yy" />
<Calendar v-model="date2" inputId="dateformat" dateFormat="mm-dd-yy" />
</div>
<div class="field col-12 md:col-4">
<label for="icon">Icon</label>
<Calendar inputId="icon" v-model="date3" :showIcon="true" />
<Calendar v-model="date3" inputId="icon" :showIcon="true" />
</div>
<div class="field col-12 md:col-4">
<label for="minmax">MinMax</label>
<Calendar inputId="minmax" v-model="date4" :minDate="minDate" :maxDate="maxDate" :manualInput="false" />
<Calendar v-model="date4" inputId="minmax" :minDate="minDate" :maxDate="maxDate" :manualInput="false" />
</div>
<div class="field col-12 md:col-4">
<label for="disableddays">Disabled Days</label>
<Calendar inputId="disableddays" v-model="date5" :disabledDates="invalidDates" :disabledDays="[0, 6]" :manualInput="false" />
<Calendar v-model="date5" inputId="disableddays" :disabledDates="invalidDates" :disabledDays="[0, 6]" :manualInput="false" />
</div>
<div class="field col-12 md:col-4">
<label for="multiple">Multiple</label>
<Calendar inputId="multiple" v-model="dates1" selectionMode="multiple" :manualInput="false" />
<Calendar v-model="dates1" inputId="multiple" selectionMode="multiple" :manualInput="false" />
</div>
<div class="field col-12 md:col-4">
<label for="range">Range</label>
<Calendar inputId="range" v-model="dates2" selectionMode="range" :manualInput="false" />
<Calendar v-model="dates2" inputId="range" selectionMode="range" :manualInput="false" />
</div>
<div class="field col-12 md:col-4">
<label for="buttonbar">Button Bar</label>
<Calendar inputId="buttonbar" v-model="date6" :showButtonBar="true" />
<Calendar v-model="date6" inputId="buttonbar" :showButtonBar="true" />
</div>
<div class="field col-12 md:col-4">
<label for="time24">Time / 24h</label>
<Calendar inputId="time24" v-model="date7" :showTime="true" :showSeconds="true" />
<Calendar v-model="date7" inputId="time24" :showTime="true" :showSeconds="true" />
</div>
<div class="field col-12 md:col-4">
<label for="time12">Time / 12h</label>
<Calendar inputId="time12" v-model="date8" :timeOnly="true" hourFormat="12" />
<Calendar v-model="date8" inputId="time12" :timeOnly="true" hourFormat="12" />
</div>
<div class="field col-12 md:col-4">
<label for="monthpicker">Month Picker</label>
<Calendar inputId="monthpicker" v-model="date9" view="month" dateFormat="mm/yy" />
<Calendar v-model="date9" inputId="monthpicker" view="month" dateFormat="mm/yy" />
</div>
<div class="field col-12 md:col-4">
<label for="yearpicker">Year Picker</label>
<Calendar inputId="yearpicker" v-model="date10" view="year" dateFormat="yy" />
<Calendar v-model="date10" inputId="yearpicker" view="year" dateFormat="yy" />
</div>
<div class="field col-12 md:col-4">
<label for="multiplemonths">Multiple Months</label>
<Calendar inputId="multiplemonths" v-model="date11" :numberOfMonths="3" :responsiveOptions="responsiveOptions" />
<Calendar v-model="date11" inputId="multiplemonths" :numberOfMonths="3" :responsiveOptions="responsiveOptions" />
</div>
<div class="field col-12 md:col-4">
<label for="datetemplate">Date Template</label>
<Calendar inputId="datetemplate" v-model="date12">
<Calendar v-model="date12" inputId="datetemplate">
<template #date="slotProps">
<strong v-if="slotProps.date.day > 10 && slotProps.date.day < 15" class="special-day">{{ slotProps.date.day }}</strong>
<template v-else>{{ slotProps.date.day }}</template>
@ -75,7 +75,7 @@
</div>
<div class="field col-12 md:col-4">
<label for="touchUI">TouchUI</label>
<Calendar inputId="touchUI" v-model="date13" :touchUI="true" />
<Calendar v-model="date13" inputId="touchUI" :touchUI="true" />
</div>
</div>
@ -92,25 +92,6 @@
import CalendarDoc from './CalendarDoc';
export default {
created() {
let today = new Date();
let month = today.getMonth();
let year = today.getFullYear();
let prevMonth = month === 0 ? 11 : month - 1;
let prevYear = prevMonth === 11 ? year - 1 : year;
let nextMonth = month === 11 ? 0 : month + 1;
let nextYear = nextMonth === 0 ? year + 1 : year;
this.minDate = new Date();
this.minDate.setMonth(prevMonth);
this.minDate.setFullYear(prevYear);
this.maxDate = new Date();
this.maxDate.setMonth(nextMonth);
this.maxDate.setFullYear(nextYear);
let invalidDate = new Date();
invalidDate.setDate(today.getDate() - 1);
this.invalidDates = [today, invalidDate];
},
data() {
return {
date1: null,
@ -144,6 +125,27 @@ export default {
]
};
},
created() {
let today = new Date();
let month = today.getMonth();
let year = today.getFullYear();
let prevMonth = month === 0 ? 11 : month - 1;
let prevYear = prevMonth === 11 ? year - 1 : year;
let nextMonth = month === 11 ? 0 : month + 1;
let nextYear = nextMonth === 0 ? year + 1 : year;
this.minDate = new Date();
this.minDate.setMonth(prevMonth);
this.minDate.setFullYear(prevYear);
this.maxDate = new Date();
this.maxDate.setMonth(nextMonth);
this.maxDate.setFullYear(nextYear);
let invalidDate = new Date();
invalidDate.setDate(today.getDate() - 1);
this.invalidDates = [today, invalidDate];
},
components: {
CalendarDoc: CalendarDoc
}

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="CardDemo" :sources="sources" github="card/CardDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -19,7 +18,7 @@ import Card from 'primevue/card';
<pre v-code><code>
&lt;Card&gt;
&lt;template #header&gt;
&lt;img alt="user header" src="/demo/images/usercard.png"&gt;
&lt;img alt="user header" src="demo/images/usercard.png"&gt;
&lt;/template&gt;
&lt;template #title&gt;
Advanced Card
@ -71,7 +70,7 @@ import Card from 'primevue/card';
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -106,11 +105,11 @@ import Card from 'primevue/card';
</div>
<h5>Accessibility</h5>
<DevelopmentSection>
<h6>Screen Reader</h6>
<p>
A card can be utilized in many use cases as a result no role is enforced, in fact a role may not be necessary if the card is used for presentational purposes only. Any valid attribute is passed to the container element so if you
require to use one of the <a href="https://www.w3.org/TR/wai-aria/#landmark" alt="Landmark Roles">landmark</a> roles like <i>region</i>, you may use the <i>role</i> property.
A card can be utilized in many use cases as a result no role is enforced, in fact a role may not be necessary if the card is used for presentational purposes only. Any valid attribute is passed to the container element so if you require
to use one of the <a href="https://www.w3.org/TR/wai-aria/#landmark" alt="Landmark Roles">landmark</a> roles like <i>region</i>, you may use the <i>role</i> property.
</p>
<pre v-code><code>
@ -122,12 +121,10 @@ import Card from 'primevue/card';
<h5>Keyboard Support</h5>
<p>Component does not include any interactive elements.</p>
</DevelopmentSection>
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -21,7 +21,7 @@
<Card style="width: 25em">
<template #header>
<img alt="user header" src="/demo/images/usercard.png" />
<img alt="user header" src="demo/images/usercard.png" />
</template>
<template #title> Advanced Card </template>
<template #subtitle> Card subtitle </template>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="CarouselDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="carousel/CarouselDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -45,7 +44,7 @@ import Carousel from 'primevue/carousel';
&lt;div class="car-item"&gt;
&lt;div class="car-content"&gt;
&lt;div&gt;
&lt;img :src="'/demo/images/car/' + slotProps.data.brand + '.png'" :alt="slotProps.data.brand" /&gt;
&lt;img :src="'demo/images/car/' + slotProps.data.brand + '.png'" :alt="slotProps.data.brand" /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div class="car-title"&gt;{{slotProps.data.brand}}&lt;/div&gt;
@ -118,9 +117,7 @@ data() {
</code></pre>
<h5>AutoPlay and Circular</h5>
<p>
When <i>autoplayInterval</i> is defined in milliseconds, items are scrolled automatically. In addition, for infinite scrolling <i>circular</i> property needs to be enabled. Note that in autoplay mode, circular is enabled by default.
</p>
<p>When <i>autoplayInterval</i> is defined in milliseconds, items are scrolled automatically. In addition, for infinite scrolling <i>circular</i> property needs to be enabled. Note that in autoplay mode, circular is enabled by default.</p>
<pre v-code><code>
&lt;Carousel :value="cars" :numVisible="3" :numScroll="1" :circular="true" :autoplayInterval="3000"&gt;
&lt;template #header&gt;
@ -229,6 +226,18 @@ data() {
<td>true</td>
<td>Whether to display indicator container.</td>
</tr>
<tr>
<td>prevButtonProps</td>
<td>object</td>
<td>null</td>
<td>Uses to pass all properties of the HTMLButtonElement to the previous navigation button.</td>
</tr>
<tr>
<td>nextButtonProps</td>
<td>object</td>
<td>null</td>
<td>Uses to pass all properties of the HTMLButtonElement to the next navigation button.</td>
</tr>
</tbody>
</table>
</div>
@ -263,7 +272,7 @@ data() {
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -309,10 +318,116 @@ data() {
</table>
</div>
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
Carousel uses <i>region</i> role and since any attribute is passed to the main container element, attributes such as <i>aria-label</i> and <i>aria-roledescription</i> can be used as well. The slides container has
<i>aria-live</i> attribute set as "polite" if carousel is not in autoplay mode, otherwise "off" would be the value in autoplay.
</p>
<p>
A slide has a <i>group</i> role with an aria-label that refers to the <i>aria.slideNumber</i> property of the <router-link to="/locale">locale</router-link> API. Similarly <i>aria.slide</i> is used as the <i>aria-roledescription</i> of
the item. Inactive slides are hidden from the readers with <i>aria-hidden</i>.
</p>
<p>
Next and Previous navigators are button elements with <i>aria-label</i> attributes referring to the <i>aria.prevPageLabel</i> and <i>aria.nextPageLabel</i> properties of the <router-link to="/locale">locale</router-link> API by default
respectively, you may still use your own aria roles and attributes as any valid attribute is passed to the button elements implicitly by using <i>nextButtonProps</i> and <i>prevButtonProps</i>.
</p>
<p>Quick navigation elements are button elements with an <i>aria-label</i> attribute referring to the <i>aria.pageLabel</i> of the <router-link to="/locale">locale</router-link> API. Current page is marked with <i>aria-current</i>.</p>
<h6>Next/Prev Keyboard Support</h6>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<i>tab</i>
</td>
<td>Moves focus through interactive elements in the carousel.</td>
</tr>
<tr>
<td>
<i>enter</i>
</td>
<td>Activates navigation.</td>
</tr>
<tr>
<td>
<i>space</i>
</td>
<td>Activates navigation.</td>
</tr>
</tbody>
</table>
</div>
<h6>Quick Navigation Keyboard Support</h6>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<i>tab</i>
</td>
<td>Moves focus through the active slide link.</td>
</tr>
<tr>
<td>
<i>enter</i>
</td>
<td>Activates the focused slide link.</td>
</tr>
<tr>
<td>
<i>space</i>
</td>
<td>Activates the focused slide link.</td>
</tr>
<tr>
<td>
<i>right arrow</i>
</td>
<td>Moves focus to the next slide link.</td>
</tr>
<tr>
<td>
<i>left arrow</i>
</td>
<td>Moves focus to the previous slide link.</td>
</tr>
<tr>
<td>
<i>home</i>
</td>
<td>Moves focus to the first slide link.</td>
</tr>
<tr>
<td>
<i>end</i>
</td>
<td>Moves focus to the last slide link.</td>
</tr>
</tbody>
</table>
</div>
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -18,7 +18,7 @@
<div class="product-item">
<div class="product-item-content">
<div class="mb-3">
<img :src="'/demo/images/product/' + slotProps.data.image" :alt="slotProps.data.name" class="product-image" />
<img :src="'demo/images/product/' + slotProps.data.image" :alt="slotProps.data.name" class="product-image" />
</div>
<div>
<h4 class="mb-1">{{ slotProps.data.name }}</h4>
@ -45,7 +45,7 @@
<div class="product-item">
<div class="product-item-content">
<div class="mb-3">
<img :src="'/demo/images/product/' + slotProps.data.image" :alt="slotProps.data.name" class="product-image" />
<img :src="'demo/images/product/' + slotProps.data.image" :alt="slotProps.data.name" class="product-image" />
</div>
<div>
<h4 class="mb-1">{{ slotProps.data.name }}</h4>
@ -72,7 +72,7 @@
<div class="product-item">
<div class="product-item-content">
<div class="mb-3">
<img :src="'/demo/images/product/' + slotProps.data.image" :alt="slotProps.data.name" class="product-image" />
<img :src="'demo/images/product/' + slotProps.data.image" :alt="slotProps.data.name" class="product-image" />
</div>
<div>
<h4 class="mb-1">{{ slotProps.data.name }}</h4>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="CascadeSelectDemo" :sources="sources" github="cascadeselect/CascadeSelectDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -256,12 +255,24 @@ data() &#123;
<td>false</td>
<td>Whether the dropdown is in loading state.</td>
</tr>
<tr>
<td>dropdownIcon</td>
<td>string</td>
<td>pi pi-chevron-down</td>
<td>Icon to display in the dropdown.</td>
</tr>
<tr>
<td>loadingIcon</td>
<td>string</td>
<td>pi pi-spinner pi-spin</td>
<td>Icon to display in loading state.</td>
</tr>
<tr>
<td>optionGroupIcon</td>
<td>string</td>
<td>pi pi-angle-right</td>
<td>Icon to display in the option group.</td>
</tr>
<tr>
<td>autoOptionFocus</td>
<td>boolean</td>
@ -428,7 +439,7 @@ data() &#123;
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -477,13 +488,12 @@ data() &#123;
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
Value to describe the component can either be provided with <i>aria-labelledby</i> or <i>aria-label</i> props. The cascadeselect element has a <i>combobox</i> role in addition to <i>aria-haspopup</i> and
<i>aria-expanded</i> attributes. The relation between the combobox and the popup is created with <i>aria-controls</i> that refers to the id of the popup.
Value to describe the component can either be provided with <i>aria-labelledby</i> or <i>aria-label</i> props. The cascadeselect element has a <i>combobox</i> role in addition to <i>aria-haspopup</i> and <i>aria-expanded</i> attributes.
The relation between the combobox and the popup is created with <i>aria-controls</i> that refers to the id of the popup.
</p>
<p>
The popup list has an id that refers to the <i>aria-controls</i> attribute of the <i>combobox</i> element and uses <i>tree</i> as the role. Each list item has a <i>treeitem</i> role along with <i>aria-label</i>,
<i>aria-selected</i> and <i>aria-expanded</i> attributes. The container element of a treenode has the <i>group</i> role. The <i>aria-setsize</i>, <i>aria-posinset</i> and <i>aria-level</i> attributes are calculated implicitly and
added to each treeitem.
The popup list has an id that refers to the <i>aria-controls</i> attribute of the <i>combobox</i> element and uses <i>tree</i> as the role. Each list item has a <i>treeitem</i> role along with <i>aria-label</i>, <i>aria-selected</i> and
<i>aria-expanded</i> attributes. The container element of a treenode has the <i>group</i> role. The <i>aria-setsize</i>, <i>aria-posinset</i> and <i>aria-level</i> attributes are calculated implicitly and added to each treeitem.
</p>
<pre v-code><code>
@ -601,7 +611,6 @@ data() &#123;
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -11,22 +11,22 @@
<div class="content-section implementation">
<div class="card">
<h5>Basic</h5>
<CascadeSelect v-model="selectedCity1" :options="countries" optionLabel="cname" optionGroupLabel="name" :optionGroupChildren="['states', 'cities']" style="minwidth: 14rem" placeholder="Select a City" />
<CascadeSelect v-model="selectedCity1" :options="countries" optionLabel="cname" optionGroupLabel="name" :optionGroupChildren="['states', 'cities']" style="min-width: 14rem" placeholder="Select a City" />
<h5>Templating</h5>
<CascadeSelect v-model="selectedCity2" :options="countries" optionLabel="cname" optionGroupLabel="name" :optionGroupChildren="['states', 'cities']" style="minwidth: 14rem" placeholder="Select a City">
<CascadeSelect v-model="selectedCity2" :options="countries" optionLabel="cname" optionGroupLabel="name" :optionGroupChildren="['states', 'cities']" style="min-width: 14rem" placeholder="Select a City">
<template #option="slotProps">
<div class="country-item">
<img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + slotProps.option.code.toLowerCase()" v-if="slotProps.option.states" />
<i class="pi pi-compass mr-2" v-if="slotProps.option.cities"></i>
<i class="pi pi-map-marker mr-2" v-if="slotProps.option.cname"></i>
<img v-if="slotProps.option.states" src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + slotProps.option.code.toLowerCase()" />
<i v-if="slotProps.option.cities" class="pi pi-compass mr-2"></i>
<i v-if="slotProps.option.cname" class="pi pi-map-marker mr-2"></i>
<span>{{ slotProps.option.cname || slotProps.option.name }}</span>
</div>
</template>
</CascadeSelect>
<h5>Loading State</h5>
<CascadeSelect placeholder="Loading..." loading style="minwidth: 14rem"></CascadeSelect>
<CascadeSelect placeholder="Loading..." loading style="min-width: 14rem"></CascadeSelect>
</div>
</div>

View File

@ -35,27 +35,11 @@
</template>
<script>
import BarChartDoc from './BarChartDoc';
import EventBus from '@/layouts/AppEventBus';
import BarChartDoc from './BarChartDoc';
export default {
themeChangeListener: null,
mounted() {
this.themeChangeListener = (event) => {
if (event.dark) this.applyDarkTheme();
else this.applyLightTheme();
};
EventBus.on('theme-change', this.themeChangeListener);
if (this.isDarkTheme()) {
this.applyDarkTheme();
} else {
this.applyLightTheme();
}
},
beforeUnmount() {
EventBus.off('change-theme', this.themeChangeListener);
},
data() {
return {
basicData: {
@ -119,6 +103,23 @@ export default {
stackedOptions: null
};
},
mounted() {
this.themeChangeListener = (event) => {
if (event.dark) this.applyDarkTheme();
else this.applyLightTheme();
};
EventBus.on('theme-change', this.themeChangeListener);
if (this.isDarkTheme()) {
this.applyDarkTheme();
} else {
this.applyLightTheme();
}
},
beforeUnmount() {
EventBus.off('change-theme', this.themeChangeListener);
},
methods: {
isDarkTheme() {
return this.$appState.darkTheme === true;

View File

@ -1,7 +1,5 @@
<template>
<ClientOnly>
<AppDoc name="ChartDemo" :sources="sources" :dependencies="{ 'chart.js': '3.3.2' }" component="Chart" github="chart/BarChartDemo.vue" />
</ClientOnly>
</template>
<script>

View File

@ -149,6 +149,12 @@ options: {
<td>150</td>
<td>Height of the chart in non-responsive mode.</td>
</tr>
<tr>
<td>canvasProps</td>
<td>object</td>
<td>null</td>
<td>Uses to pass all properties of the CanvasHTMLAttributes to canvas element inside the component.</td>
</tr>
</tbody>
</table>
</div>
@ -231,5 +237,16 @@ options: {
</tbody>
</table>
</div>
<h5>Accessibility</h5>
<p>
Chart components internally use <i>canvas</i> element, refer to the <a href="https://www.chartjs.org/docs/latest/general/accessibility.html">Chart.js accessibility</a> guide for more information. The canvas element can be customized with
<i>canvasProps</i> property to define aria roles and properties, in addition any content inside the component is directly passed as a child of the canvas to be able to provide fallback content like a table.
</p>
<pre v-code><code>
&lt;Chart type="line" :data="data" :canvasProps="{'role': 'img', 'aria-label': 'Data'}" /&gt;
</code></pre>
</div>
</template>

View File

@ -19,25 +19,11 @@
</template>
<script>
import ComboChartDoc from './ComboChartDoc';
import EventBus from '@/layouts/AppEventBus';
import ComboChartDoc from './ComboChartDoc';
export default {
themeChangeListener: null,
mounted() {
this.themeChangeListener = (event) => {
if (event.dark) this.applyDarkTheme();
else this.applyLightTheme();
};
EventBus.on('theme-change', this.themeChangeListener);
if (this.isDarkTheme()) {
this.applyDarkTheme();
}
},
beforeUnmount() {
EventBus.off('change-theme', this.themeChangeListener);
},
data() {
return {
chartData: {
@ -70,6 +56,21 @@ export default {
chartOptions: this.isDarkTheme() ? this.applyDarkTheme() : this.applyLightTheme()
};
},
mounted() {
this.themeChangeListener = (event) => {
if (event.dark) this.applyDarkTheme();
else this.applyLightTheme();
};
EventBus.on('theme-change', this.themeChangeListener);
if (this.isDarkTheme()) {
this.applyDarkTheme();
}
},
beforeUnmount() {
EventBus.off('change-theme', this.themeChangeListener);
},
methods: {
isDarkTheme() {
return this.$appState.darkTheme === true;

View File

@ -1,7 +1,5 @@
<template>
<ClientOnly>
<AppDoc name="ChartDemo" :sources="sources" :dependencies="{ 'chart.js': '3.3.2' }" component="Chart" github="chart/ComboChartDemo.vue" />
</ClientOnly>
</template>
<script>

View File

@ -19,21 +19,11 @@
</template>
<script>
import DoughnutChartDoc from './DoughnutChartDoc';
import EventBus from '@/layouts/AppEventBus';
import DoughnutChartDoc from './DoughnutChartDoc';
export default {
themeChangeListener: null,
mounted() {
this.themeChangeListener = (event) => {
if (event.dark) this.chartOptions = this.getDarkTheme();
else this.chartOptions = this.getLightTheme();
};
EventBus.on('theme-change', this.themeChangeListener);
},
beforeUnmount() {
EventBus.off('change-theme', this.themeChangeListener);
},
data() {
return {
chartData: {
@ -49,6 +39,17 @@ export default {
chartOptions: this.isDarkTheme() ? this.getDarkTheme() : this.getLightTheme()
};
},
mounted() {
this.themeChangeListener = (event) => {
if (event.dark) this.chartOptions = this.getDarkTheme();
else this.chartOptions = this.getLightTheme();
};
EventBus.on('theme-change', this.themeChangeListener);
},
beforeUnmount() {
EventBus.off('change-theme', this.themeChangeListener);
},
methods: {
isDarkTheme() {
return this.$appState.darkTheme === true;

View File

@ -1,7 +1,5 @@
<template>
<ClientOnly>
<AppDoc name="ChartDemo" :sources="sources" :dependencies="{ 'chart.js': '3.3.2' }" component="Chart" github="chart/DoughnutChartDemo.vue" />
</ClientOnly>
</template>
<script>

View File

@ -30,27 +30,11 @@
</template>
<script>
import LineChartDoc from './LineChartDoc';
import EventBus from '@/layouts/AppEventBus';
import LineChartDoc from './LineChartDoc';
export default {
themeChangeListener: null,
mounted() {
this.themeChangeListener = (event) => {
if (event.dark) this.applyDarkTheme();
else this.applyLightTheme();
};
EventBus.on('theme-change', this.themeChangeListener);
if (this.isDarkTheme()) {
this.applyDarkTheme();
} else {
this.applyLightTheme();
}
},
beforeUnmount() {
EventBus.off('change-theme', this.themeChangeListener);
},
data() {
return {
basicData: {
@ -125,6 +109,23 @@ export default {
multiAxisOptions: null
};
},
mounted() {
this.themeChangeListener = (event) => {
if (event.dark) this.applyDarkTheme();
else this.applyLightTheme();
};
EventBus.on('theme-change', this.themeChangeListener);
if (this.isDarkTheme()) {
this.applyDarkTheme();
} else {
this.applyLightTheme();
}
},
beforeUnmount() {
EventBus.off('change-theme', this.themeChangeListener);
},
methods: {
isDarkTheme() {
return this.$appState.darkTheme === true;

View File

@ -1,7 +1,5 @@
<template>
<ClientOnly>
<AppDoc name="ChartDemo" :sources="sources" :dependencies="{ 'chart.js': '3.3.2' }" component="Chart" github="chart/LineChartDemo.vue" />
</ClientOnly>
</template>
<script>

View File

@ -19,21 +19,11 @@
</template>
<script>
import PieChartDoc from './PieChartDoc';
import EventBus from '@/layouts/AppEventBus';
import PieChartDoc from './PieChartDoc';
export default {
themeChangeListener: null,
mounted() {
this.themeChangeListener = (event) => {
if (event.dark) this.chartOptions = this.getDarkTheme();
else this.chartOptions = this.getLightTheme();
};
EventBus.on('theme-change', this.themeChangeListener);
},
beforeUnmount() {
EventBus.off('change-theme', this.themeChangeListener);
},
data() {
return {
chartData: {
@ -49,6 +39,17 @@ export default {
chartOptions: this.isDarkTheme() ? this.getDarkTheme() : this.getLightTheme()
};
},
mounted() {
this.themeChangeListener = (event) => {
if (event.dark) this.chartOptions = this.getDarkTheme();
else this.chartOptions = this.getLightTheme();
};
EventBus.on('theme-change', this.themeChangeListener);
},
beforeUnmount() {
EventBus.off('change-theme', this.themeChangeListener);
},
methods: {
isDarkTheme() {
return this.$appState.darkTheme === true;

View File

@ -1,7 +1,5 @@
<template>
<ClientOnly>
<AppDoc name="ChartDemo" :sources="sources" :dependencies="{ 'chart.js': '3.3.2' }" component="Chart" github="chart/PieChartDemo.vue" />
</ClientOnly>
</template>
<script>

View File

@ -19,21 +19,11 @@
</template>
<script>
import PolarAreaChartDoc from './PolarAreaChartDoc';
import EventBus from '@/layouts/AppEventBus';
import PolarAreaChartDoc from './PolarAreaChartDoc';
export default {
themeChangeListener: null,
mounted() {
this.themeChangeListener = (event) => {
if (event.dark) this.chartOptions = this.getDarkTheme();
else this.chartOptions = this.getLightTheme();
};
EventBus.on('theme-change', this.themeChangeListener);
},
beforeUnmount() {
EventBus.off('change-theme', this.themeChangeListener);
},
data() {
return {
chartData: {
@ -49,6 +39,17 @@ export default {
chartOptions: this.isDarkTheme() ? this.getDarkTheme() : this.getLightTheme()
};
},
mounted() {
this.themeChangeListener = (event) => {
if (event.dark) this.chartOptions = this.getDarkTheme();
else this.chartOptions = this.getLightTheme();
};
EventBus.on('theme-change', this.themeChangeListener);
},
beforeUnmount() {
EventBus.off('change-theme', this.themeChangeListener);
},
methods: {
isDarkTheme() {
return this.$appState.darkTheme === true;

View File

@ -1,7 +1,5 @@
<template>
<ClientOnly>
<AppDoc name="ChartDemo" :sources="sources" :dependencies="{ 'chart.js': '3.3.2' }" component="Chart" github="chart/PolarAreaChartDemo.vue" />
</ClientOnly>
</template>
<script>

View File

@ -19,21 +19,11 @@
</template>
<script>
import RadarChartDoc from './RadarChartDoc';
import EventBus from '@/layouts/AppEventBus';
import RadarChartDoc from './RadarChartDoc';
export default {
themeChangeListener: null,
mounted() {
this.themeChangeListener = (event) => {
if (event.dark) this.chartOptions = this.getDarkTheme();
else this.chartOptions = this.getLightTheme();
};
EventBus.on('theme-change', this.themeChangeListener);
},
beforeUnmount() {
EventBus.off('change-theme', this.themeChangeListener);
},
data() {
return {
chartData: {
@ -64,6 +54,17 @@ export default {
chartOptions: this.isDarkTheme() ? this.getDarkTheme() : this.getLightTheme()
};
},
mounted() {
this.themeChangeListener = (event) => {
if (event.dark) this.chartOptions = this.getDarkTheme();
else this.chartOptions = this.getLightTheme();
};
EventBus.on('theme-change', this.themeChangeListener);
},
beforeUnmount() {
EventBus.off('change-theme', this.themeChangeListener);
},
methods: {
isDarkTheme() {
return this.$appState.darkTheme === true;

View File

@ -1,7 +1,5 @@
<template>
<ClientOnly>
<AppDoc name="ChartDemo" :sources="sources" :dependencies="{ 'chart.js': '3.3.2' }" component="Chart" github="chart/RadarChartDemo.vue" />
</ClientOnly>
</template>
<script>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="CheckboxDemo" :sources="sources" github="checkbox/CheckboxDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -141,6 +140,18 @@ export default {
<td>null</td>
<td>Uses to pass all properties of the HTMLInputElement to the focusable input element inside the component.</td>
</tr>
<tr>
<td>aria-label</td>
<td>string</td>
<td>null</td>
<td>Defines a string value that labels an interactive element.</td>
</tr>
<tr>
<td>aria-labelledby</td>
<td>string</td>
<td>null</td>
<td>Establishes relationships between the component and label(s) where its value should be one or more element IDs.</td>
</tr>
</tbody>
</table>
</div>
@ -177,7 +188,7 @@ export default {
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -246,7 +257,6 @@ export default {
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -12,31 +12,31 @@
<div class="card">
<h5>Basic</h5>
<div class="field-checkbox">
<Checkbox inputId="binary" v-model="checked" :binary="true" />
<Checkbox v-model="checked" inputId="binary" :binary="true" />
<label for="binary">Remember Me</label>
</div>
<h5>Multiple</h5>
<div class="field-checkbox">
<Checkbox inputId="city1" name="city" value="Chicago" v-model="cities" />
<Checkbox v-model="cities" inputId="city1" name="city" value="Chicago" />
<label for="city1">Chicago</label>
</div>
<div class="field-checkbox">
<Checkbox inputId="city2" name="city" value="Los Angeles" v-model="cities" />
<Checkbox v-model="cities" inputId="city2" name="city" value="Los Angeles" />
<label for="city2">Los Angeles</label>
</div>
<div class="field-checkbox">
<Checkbox inputId="city3" name="city" value="New York" v-model="cities" />
<Checkbox v-model="cities" inputId="city3" name="city" value="New York" />
<label for="city3">New York</label>
</div>
<div class="field-checkbox">
<Checkbox inputId="city4" name="city" value="San Francisco" v-model="cities" />
<Checkbox v-model="cities" inputId="city4" name="city" value="San Francisco" />
<label for="city4">San Francisco</label>
</div>
<h5>Dynamic Values, Preselection, Value Binding and Disabled Option</h5>
<div v-for="category of categories" :key="category.key" class="field-checkbox">
<Checkbox :inputId="category.key" name="category" :value="category.name" v-model="selectedCategories" :disabled="category.key === 'R'" />
<Checkbox v-model="selectedCategories" :inputId="category.key" name="category" :value="category.name" :disabled="category.key === 'R'" />
<label :for="category.key">{{ category.name }}</label>
</div>
</div>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="ChipDemo" :sources="sources" github="chip/ChipDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -77,7 +76,7 @@ import Chip from 'primevue/chip';
<td>Whether to display a remove icon.</td>
</tr>
<tr>
<td>removeIconClass</td>
<td>removeIcon</td>
<td>string</td>
<td>pi pi-times-circle</td>
<td>Icon of the remove element.</td>
@ -107,7 +106,7 @@ import Chip from 'primevue/chip';
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -137,10 +136,42 @@ import Chip from 'primevue/chip';
</table>
</div>
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
Chip uses the <i>label</i> property as the default <i>aria-label</i>, since any attribute is passed to the root element <i>aria-labelledby</i> or <i>aria-label</i> can be used to override the default behavior. Removable chips have a
<i>tabindex</i> and focusable with the tab key.
</p>
<h6>Keyboard Support</h6>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<i>backspace</i>
</td>
<td>Hides removable.</td>
</tr>
<tr>
<td>
<i>enter</i>
</td>
<td>Hides removable.</td>
</tr>
</tbody>
</table>
</div>
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -28,18 +28,18 @@
<h5>Image</h5>
<div class="flex align-items-center">
<Chip label="Amy Elsner" image="/demo/images/avatar/amyelsner.png" class="mr-2" />
<Chip label="Asiya Javayant" image="/demo/images/avatar/asiyajavayant.png" class="mr-2" />
<Chip label="Onyama Limba" image="/demo/images/avatar/onyamalimba.png" class="mr-2" />
<Chip label="Xuxue Feng" image="/demo/images/avatar/xuxuefeng.png" removable />
<Chip label="Amy Elsner" image="demo/images/avatar/amyelsner.png" class="mr-2" />
<Chip label="Asiya Javayant" image="demo/images/avatar/asiyajavayant.png" class="mr-2" />
<Chip label="Onyama Limba" image="demo/images/avatar/onyamalimba.png" class="mr-2" />
<Chip label="Xuxue Feng" image="demo/images/avatar/xuxuefeng.png" removable />
</div>
<h5>Styling</h5>
<div class="flex align-items-center">
<Chip label="Action" class="mr-2 custom-chip" />
<Chip label="Apple" icon="pi pi-apple" class="mr-2 custom-chip" />
<Chip label="Onyama Limba" image="/demo/images/avatar/onyamalimba.png" class="mr-2 custom-chip" />
<Chip label="Xuxue Feng" image="/demo/images/avatar/xuxuefeng.png" class="custom-chip" removable />
<Chip label="Onyama Limba" image="demo/images/avatar/onyamalimba.png" class="mr-2 custom-chip" />
<Chip label="Xuxue Feng" image="demo/images/avatar/xuxuefeng.png" class="custom-chip" removable />
</div>
</div>
</div>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="ChipsDemo" :sources="sources" github="chips/ChipsDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -114,6 +113,12 @@ import Chips from 'primevue/chips';
<td>null</td>
<td>Uses to pass all properties of the HTMLInputElement to the focusable input element inside the component.</td>
</tr>
<tr>
<td>removeTokenIcon</td>
<td>string</td>
<td>pi pi-times-circle</td>
<td>Icon to display in chip remove action.</td>
</tr>
</tbody>
</table>
</div>
@ -169,7 +174,7 @@ import Chips from 'primevue/chips';
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -206,8 +211,8 @@ import Chips from 'primevue/chips';
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
Value to describe the component can either be provided via <i>label</i> tag combined with <i>inputId</i> prop or using <i>aria-labelledby</i>, <i>aria-label</i> props. Chip list uses <i>listbox</i> role with
<i>aria-orientation</i> set to horizontal whereas each chip has the <i>option</i> role with <i>aria-label</i> set to the label of the chip.
Value to describe the component can either be provided via <i>label</i> tag combined with <i>inputId</i> prop or using <i>aria-labelledby</i>, <i>aria-label</i> props. Chip list uses <i>listbox</i> role with <i>aria-orientation</i> set to
horizontal whereas each chip has the <i>option</i> role with <i>aria-label</i> set to the label of the chip.
</p>
<pre v-code><code>
@ -280,7 +285,6 @@ import Chips from 'primevue/chips';
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>
@ -300,8 +304,11 @@ export default {
<h5>Comma Separator</h5>
<Chips v-model="value2" separator="," />
<h5>RegExp Separator</h5>
<Chips v-model="value3" :separator="separatorExp" />
<h5>Template</h5>
<Chips v-model="value3">
<Chips v-model="value4">
<template #chip="slotProps">
<div>
<span>{{slotProps.value}} - (active) </span>
@ -319,7 +326,9 @@ export default {
return {
value1: null,
value2: null,
value3: null
value3: null,
value4: null,
separatorExp:/,| /
}
}
}
@ -338,8 +347,11 @@ export default {
<h5>Comma Separator</h5>
<Chips v-model="value2" separator="," />
<h5>RegExp Separator</h5>
<Chips v-model="value3" :separator="separatorExp" />
<h5>Template</h5>
<Chips v-model="value3">
<Chips v-model="value4">
<template #chip="slotProps">
<div>
<span>{{slotProps.value}} - (active) </span>
@ -359,6 +371,8 @@ export default {
const value1 = ref();
const value2 = ref();
const value3 = ref();
const value4 = ref();
const separatorExp = ref(/,| /);
return { value1, value2, value3 }
}
@ -379,6 +393,9 @@ export default {
<h5>Comma Separator</h5>
<p-chips v-model="value2" separator=","></p-chips>
<h5>RegExp Separator</h5>
<p-chips v-model="value3" :separator="separatorExp" />
<h5>Template</h5>
<p-chips v-model="value3">
<template #chip="slotProps">
@ -400,6 +417,8 @@ export default {
const value1 = ref();
const value2 = ref();
const value3 = ref();
const value4 = ref();
const separatorExp = ref(/,| /);
return { value1, value2, value3 }
},

View File

@ -16,8 +16,11 @@
<h5>Comma Separator</h5>
<Chips v-model="value2" separator="," />
<h5>RegExp Separator</h5>
<Chips v-model="value3" :separator="separatorExp" />
<h5>Template</h5>
<Chips v-model="value3">
<Chips v-model="value4">
<template #chip="slotProps">
<div>
<span>{{ slotProps.value }} - (active) </span>
@ -40,7 +43,9 @@ export default {
return {
value1: null,
value2: null,
value3: null
value3: null,
value4: null,
separatorExp: /,| /
};
},
components: {

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="ColorPickerDemo" :sources="sources" :extFiles="extFiles" github="colorpicker/ColorPickerDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -207,8 +206,8 @@ export default {
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
Specification does not cover a color picker <a href="https://github.com/w3c/aria/issues/930">yet</a> and using a semantic native color picker is not consistent across browsers so currently component is not compatible with screen
readers. In the upcoming versions, text fields will be introduced below the slider section to be able to pick a color using accessible text boxes in hsl, rgba and hex formats.
Specification does not cover a color picker <a href="https://github.com/w3c/aria/issues/930">yet</a> and using a semantic native color picker is not consistent across browsers so currently component is not compatible with screen readers.
In the upcoming versions, text fields will be introduced below the slider section to be able to pick a color using accessible text boxes in hsl, rgba and hex formats.
</p>
<h6>Closed State Keyboard Support of Popup ColorPicker</h6>
@ -303,7 +302,6 @@ export default {
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -22,7 +22,7 @@
<div class="flex flex-column align-items-center md:flex-row md:align-items-start">
<ColorPicker v-model="color3" :inline="true" />
<div :style="wallStyle" class="mt-5 md:mt-0 md:ml-5 inline-flex">
<img alt="room" src="/demo/images/interior.png" class="w-full md:auto" />
<img alt="room" src="demo/images/interior.png" class="w-full md:auto" />
</div>
</div>
</div>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="ConfirmDialogDemo" :sources="sources" github="confirmdialog/ConfirmDialogDemo.vue">
<h5>ConfirmationService</h5>
<p>ConfirmDialog is controlled via the <i>ConfirmationService</i> that needs to be installed globally before the application instance is created.</p>
@ -27,8 +26,8 @@ import ConfirmDialog from 'primevue/confirmdialog';
<h5>Getting Started</h5>
<p>
ConfirmDialog is displayed by calling the <i>require</i> method of the <i>$confirm</i> instance by passing the options to customize the Dialog. Suggested location of the Dialog is the main application component where it can be shared
by any component within the application.
ConfirmDialog is displayed by calling the <i>require</i> method of the <i>$confirm</i> instance by passing the options to customize the Dialog. Suggested location of the Dialog is the main application component where it can be shared by
any component within the application.
</p>
<pre v-code><code>
&lt;ConfirmDialog&gt;&lt;/ConfirmDialog&gt;
@ -50,6 +49,12 @@ export default {
},
reject: () => {
//callback to execute when user rejects the action
},
onShow: () => {
//callback to execute when dialog is shown
},
onHide: () => {
//callback to execute when dialog is hidden
}
});
},
@ -76,6 +81,12 @@ export default defineComponent({
},
reject: () => {
//callback to execute when user rejects the action
},
onShow: () => {
//callback to execute when dialog is shown
},
onHide: () => {
//callback to execute when dialog is hidden
}
});
}
@ -107,7 +118,6 @@ export default {
&lt;/div&gt;
&lt;/template&gt;
&lt;/ConfirmPopup&gt;
</template>
</code></pre>
@ -176,17 +186,29 @@ export default {
<td>null</td>
<td>Callback to execute when action is rejected.</td>
</tr>
<tr>
<td>onShow</td>
<td>Function</td>
<td>null</td>
<td>Callback to execute when dialog is shown.</td>
</tr>
<tr>
<td>onHide</td>
<td>Function</td>
<td>null</td>
<td>Callback to execute when dialog is hidden.</td>
</tr>
<tr>
<td>acceptLabel</td>
<td>string</td>
<td>null</td>
<td>Label of the accept button. Defaults to PrimeVue <nuxt-link to="/locale">Locale</nuxt-link> configuration.</td>
<td>Label of the accept button. Defaults to PrimeVue <router-link to="/locale">Locale</router-link> configuration.</td>
</tr>
<tr>
<td>rejectLabel</td>
<td>string</td>
<td>null</td>
<td>Label of the reject button. Defaults to PrimeVue <nuxt-link to="/locale">Locale</nuxt-link> configuration.</td>
<td>Label of the reject button. Defaults to PrimeVue <router-link to="/locale">Locale</router-link> configuration.</td>
</tr>
<tr>
<td>acceptIcon</td>
@ -301,7 +323,7 @@ export default {
</div>
<h5>Styling</h5>
<p>ConfirmDialog inherits all the classes from the Dialog component, visit <nuxt-link to="/dialog">dialog</nuxt-link> for more information.</p>
<p>ConfirmDialog inherits all the classes from the Dialog component, visit <router-link to="/dialog">dialog</router-link> for more information.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -315,6 +337,112 @@ export default {
<td>p-confirm-dialog</td>
<td>Container element.</td>
</tr>
<tr>
<td>p-confirm-dialog-message</td>
<td>Container of message.</td>
</tr>
<tr>
<td>p-confirm-dialog-icon</td>
<td>Icon container inside content.</td>
</tr>
</tbody>
</table>
</div>
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
ConfirmDialog component uses <i>alertdialog</i> role along with <i>aria-labelledby</i> referring to the header element however any attribute is passed to the root element so you may use <i>aria-labelledby</i> to override this default
behavior. In addition <i>aria-modal</i> is added since focus is kept within the popup.
</p>
<p>
When <i>require</i> method of the <i>$confirm</i> instance is used and a trigger is passed as a parameter, ConfirmDialog adds <i>aria-expanded</i> state attribute and <i>aria-controls</i> to the trigger so that the relation between the
trigger and the dialog is defined.
</p>
<pre v-code><code>
&lt;ConfirmDialog id="confirm" /&gt;
&lt;Button @click="openDialog()" label="Confirm" :aria-expanded="visible" :aria-controls="visible ? 'confirm' : null"&gt;&lt;/Button&gt;
</code></pre>
<pre v-code.script><code>
setup() {
const confirm = useConfirm();
const isVisible = ref(false);
const openDialog = () => {
confirm.require({
message: 'Are you sure you want to proceed?',
header: 'Confirmation',
onShow: () => {
isVisible.value = true;
},
onHide: () => {
isVisible.value = false;
}
});
};
return { isVisible, openDialog};
}
</code></pre>
<h6>Overlay Keyboard Support</h6>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<i>tab</i>
</td>
<td>Moves focus to the next the focusable element within the dialog.</td>
</tr>
<tr>
<td><i>shift</i> + <i>tab</i></td>
<td>Moves focus to the previous the focusable element within the dialog.</td>
</tr>
<tr>
<td>
<i>escape</i>
</td>
<td>Closes the dialog.</td>
</tr>
</tbody>
</table>
</div>
<h6>Buttons Keyboard Support</h6>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<i>enter</i>
</td>
<td>Closes the dialog.</td>
</tr>
<tr>
<td>
<i>space</i>
</td>
<td>Closes the dialog.</td>
</tr>
</tbody>
</table>
</div>
@ -322,7 +450,6 @@ export default {
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="ConfirmPopupDemo" :sources="sources" github="confirmpopup/ConfirmPopupDemo.vue">
<h5>ConfirmationService</h5>
<p>ConfirmPopup is controlled via the <i>ConfirmationService</i> that needs to be installed globally before the application instance is created.</p>
@ -47,6 +46,12 @@ export default {
},
reject: () => {
//callback to execute when user rejects the action
},
onShow: () => {
//callback to execute when popup is shown
},
onHide: () => {
//callback to execute when popup is hidden
}
});
},
@ -74,6 +79,12 @@ export default defineComponent({
},
reject: () => {
//callback to execute when user rejects the action
},
onShow: () => {
//callback to execute when popup is shown
},
onHide: () => {
//callback to execute when popup is hidden
}
});
}
@ -161,17 +172,29 @@ export default {
<td>null</td>
<td>Callback to execute when action is rejected.</td>
</tr>
<tr>
<td>onShow</td>
<td>Function</td>
<td>null</td>
<td>Callback to execute when popup is shown.</td>
</tr>
<tr>
<td>onHide</td>
<td>Function</td>
<td>null</td>
<td>Callback to execute when popup is hidden.</td>
</tr>
<tr>
<td>acceptLabel</td>
<td>string</td>
<td>null</td>
<td>Label of the accept button. Defaults to PrimeVue <nuxt-link to="/locale">Locale</nuxt-link> configuration.</td>
<td>Label of the accept button. Defaults to PrimeVue <router-link to="/locale">Locale</router-link> configuration.</td>
</tr>
<tr>
<td>rejectLabel</td>
<td>string</td>
<td>null</td>
<td>Label of the reject button. Defaults to PrimeVue <nuxt-link to="/locale">Locale</nuxt-link> configuration.</td>
<td>Label of the reject button. Defaults to PrimeVue <router-link to="/locale">Locale</router-link> configuration.</td>
</tr>
<tr>
<td>acceptIcon</td>
@ -197,6 +220,12 @@ export default {
<td>null</td>
<td>Style class of the reject button.</td>
</tr>
<tr>
<td>defaultFocus</td>
<td>string</td>
<td>accept</td>
<td>Element to receive the focus when the dialog gets visible, valid values are "accept" and "reject".</td>
</tr>
</tbody>
</table>
</div>
@ -268,7 +297,7 @@ export default {
</div>
<h5>Styling</h5>
<p>ConfirmDialog inherits all the classes from the Dialog component, visit <nuxt-link to="/dialog">dialog</nuxt-link> for more information.</p>
<p>ConfirmDialog inherits all the classes from the Dialog component, visit <router-link to="/dialog">dialog</router-link> for more information.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -302,10 +331,107 @@ export default {
</table>
</div>
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
ConfirmPopup component uses <i>alertdialog</i> role and since any attribute is passed to the root element you may define attributes like <i>aria-label</i> or <i>aria-labelledby</i> to describe the popup contents. In addition
<i>aria-modal</i> is added since focus is kept within the popup.
</p>
<p>
When <i>require</i> method of the <i>$confirm</i> instance is used and a trigger is passed as a parameter, ConfirmDialog adds <i>aria-expanded</i> state attribute and <i>aria-controls</i> to the trigger so that the relation between the
trigger and the dialog is defined.
</p>
<pre v-code><code>
&lt;ConfirmPopup id="confirm" aria-label="popup" /&gt;
&lt;Button @click="openPopup($event)" label="Confirm" id="confirmButton" :aria-expanded="isVisible" :aria-controls="isVisible ? 'confirm' : null" /&gt;
</code></pre>
<pre v-code.script><code>
setup() {
const confirm = useConfirm();
const isVisible = ref(false);
const openPopup = (event) => {
confirm.require({
target: event.currentTarget,
message: 'Are you sure you want to proceed?',
header: 'Confirmation',
onShow: () => {
isVisible.value = true;
},
onHide: () => {
isVisible.value = false;
}
});
}
return {isVisible, openPopup};
}
</code></pre>
<h6>Overlay Keyboard Support</h6>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<i>tab</i>
</td>
<td>Moves focus to the next the focusable element within the popup.</td>
</tr>
<tr>
<td><i>shift</i> + <i>tab</i></td>
<td>Moves focus to the previous the focusable element within the popup.</td>
</tr>
<tr>
<td>
<i>escape</i>
</td>
<td>Closes the popup and moves focus to the trigger.</td>
</tr>
</tbody>
</table>
</div>
<h6>Buttons Keyboard Support</h6>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<i>enter</i>
</td>
<td>Triggers the action, closes the popup and moves focus to the trigger.</td>
</tr>
<tr>
<td>
<i>space</i>
</td>
<td>Triggers the action, closes the popup and moves focus to the trigger.</td>
</tr>
</tbody>
</table>
</div>
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="ContextMenuDemo" :sources="sources" github="contextmenu/ContextMenuDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -15,7 +14,7 @@ import ContextMenu from 'primevue/contextmenu';
</code></pre>
<h5>MenuModel</h5>
<p>ContextMenu uses the common MenuModel API to define the items, visit <nuxt-link to="/menumodel">MenuModel API</nuxt-link> for details.</p>
<p>ContextMenu uses the common MenuModel API to define the items, visit <router-link to="/menumodel">MenuModel API</router-link> for details.</p>
<h5>Getting Started</h5>
<p>ContextMenu requires a collection of menuitems as its model.</p>
@ -171,7 +170,7 @@ export default {
<p>ContextMenu is attached to a custom element manually using the reference and calling the <i>show(event)</i> method.</p>
<pre v-code><code>
&lt;img alt="logo" src="/demo/images/nature/nature3.jpg" @contextmenu="onImageRightClick"&gt;
&lt;img alt="logo" src="demo/images/nature/nature3.jpg" @contextmenu="onImageRightClick"&gt;
&lt;ContextMenu ref="menu" :model="items" /&gt;
</code></pre>
@ -203,13 +202,13 @@ export default {
</template>
</code></pre>
<p><i>nuxt-link</i> with route configuration can also be used within templating for further customization.</p>
<p><i>router-link</i> with route configuration can also be used within templating for further customization.</p>
<pre v-code><code><template v-pre>
&lt;ContextMenu :model="items"&gt;
&lt;template #item="{item}"&gt;
&lt;nuxt-link :to="item.to" custom v-slot="{href, route, navigate, isActive, isExactActive}"&gt;
&lt;router-link :to="item.to" custom v-slot="{href, route, navigate, isActive, isExactActive}"&gt;
&lt;a :href="href" @click="navigate" :class="{'active-link': isActive, 'active-link-exact": isExactActive}&gt;{{route.fullPath}}&lt;/a&gt;
&lt;/nuxt-link&gt;
&lt;/router-link&gt;
&lt;/template&gt;
&lt;/ContextMenu&gt;
</template>
@ -262,7 +261,25 @@ export default {
<td>exact</td>
<td>boolean</td>
<td>true</td>
<td>Whether to apply 'nuxt-link-active-exact' class if route exactly matches the item path.</td>
<td>Whether to apply 'router-link-active-exact' class if route exactly matches the item path.</td>
</tr>
<tr>
<td>tabindex</td>
<td>number</td>
<td>0</td>
<td>Index of the element in tabbing order.</td>
</tr>
<tr>
<td>aria-label</td>
<td>string</td>
<td>null</td>
<td>Defines a string value that labels an interactive element.</td>
</tr>
<tr>
<td>aria-labelledby</td>
<td>string</td>
<td>null</td>
<td>Establishes relationships between the component and label(s) where its value should be one or more element IDs.</td>
</tr>
</tbody>
</table>
@ -298,6 +315,51 @@ export default {
</table>
</div>
<h5>Events</h5>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Name</th>
<th>Parameters</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>focus</td>
<td>event</td>
<td>Callback to invoke when the component receives focus.</td>
</tr>
<tr>
<td>blur</td>
<td>event</td>
<td>Callback to invoke when the component loses focus.</td>
</tr>
<tr>
<td>before-show</td>
<td>-</td>
<td>Callback to invoke before the popup is shown.</td>
</tr>
<tr>
<td>before-hide</td>
<td>-</td>
<td>Callback to invoke before the popup is hidden.</td>
</tr>
<tr>
<td>show</td>
<td>-</td>
<td>Callback to invoke when the popup is shown.</td>
</tr>
<tr>
<td>hide</td>
<td>-</td>
<td>Callback to invoke when the popup is hidden.</td>
</tr>
</tbody>
</table>
</div>
<h5>Slots</h5>
<div class="doc-tablewrapper">
<table class="doc-table">
@ -317,7 +379,7 @@ export default {
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -331,6 +393,10 @@ export default {
<td>p-contextmenu</td>
<td>Container element.</td>
</tr>
<tr>
<td>p-contextmenu-root-list</td>
<td>Root list element.</td>
</tr>
<tr>
<td>p-submenu-list</td>
<td>Submenu list element.</td>
@ -343,6 +409,14 @@ export default {
<td>p-menuitem-active</td>
<td>Active menuitem element.</td>
</tr>
<tr>
<td>p-menuitem-content</td>
<td>Content of menuitem.</td>
</tr>
<tr>
<td>p-menuitem-link</td>
<td>Link element of the menuitem.</td>
</tr>
<tr>
<td>p-menuitem-text</td>
<td>Label of a menuitem.</td>
@ -359,10 +433,95 @@ export default {
</table>
</div>
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
ContextMenu component uses the <i>menubar</i> role with <i>aria-orientation</i> set to "vertical" and the value to describe the menu can either be provided with <i>aria-labelledby</i> or <i>aria-label</i> props. Each list item has a
<i>menuitem</i> role with <i>aria-label</i> referring to the label of the item and <i>aria-disabled</i> defined if the item is disabled. A submenu within a ContextMenu uses the <i>menu</i> role with an <i>aria-labelledby</i> defined as
the id of the submenu root menuitem label. In addition, menuitems that open a submenu have <i>aria-haspopup</i>, <i>aria-expanded</i> and <i>aria-controls</i> to define the relation between the item and the submenu.
</p>
<h6>Keyboard Support</h6>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<i>tab</i>
</td>
<td>When focus is in the menu, closes the context menu and moves focus to the next focusable element in the page sequence.</td>
</tr>
<tr>
<td>
<i>enter</i>
</td>
<td>If menuitem has a submenu, toggles the visibility of the submenu otherwise activates the menuitem and closes all open overlays.</td>
</tr>
<tr>
<td>
<i>space</i>
</td>
<td>If menuitem has a submenu, toggles the visibility of the submenu otherwise activates the menuitem and closes all open overlays.</td>
</tr>
<tr>
<td>
<i>escape</i>
</td>
<td>Closes the context menu.</td>
</tr>
<tr>
<td>
<i>down arrow</i>
</td>
<td>If focus is not inside the menu and menu is open, add focus to the first item. If an item is already focused, moves focus to the next menuitem within the submenu.</td>
</tr>
<tr>
<td>
<i>up arrow</i>
</td>
<td>If focus is not inside the menu and menu is open, add focus to the last item. If an item is already focused, moves focus to the next menuitem within the submenu.</td>
</tr>
<tr>
<td>
<i>right arrow</i>
</td>
<td>Opens a submenu if there is one available and moves focus to the first item.</td>
</tr>
<tr>
<td>
<i>left arrow</i>
</td>
<td>Closes a submenu and moves focus to the root item of the closed submenu.</td>
</tr>
<tr>
<td>
<i>home</i>
</td>
<td>Moves focus to the first menuitem within the submenu.</td>
</tr>
<tr>
<td>
<i>end</i>
</td>
<td>Moves focus to the last menuitem within the submenu.</td>
</tr>
<tr>
<td><i>any printable character</i></td>
<td>Moves focus to the menuitem whose label starts with the characters being typed.</td>
</tr>
</tbody>
</table>
</div>
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>
@ -529,17 +688,17 @@ export default {
'composition-api': {
tabName: 'Composition API Source',
content: `
<template>
<div>
<template>
<div>
<img alt="logo" src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" @contextmenu="onImageRightClick" aria-haspopup="true">
<ContextMenu ref="menu" :model="items" />
</div>
</template>
</div>
</template>
<script>
import { ref } from 'vue';
<script>
import { ref } from 'vue';
export default {
export default {
setup() {
const menu = ref();
const items = ref([
@ -676,9 +835,9 @@ export default {
return { menu, items, onImageRightClick }
}
}
<\\/script>
`
}
<\\/script>
`
},
'browser-source': {
tabName: 'Browser Source',
@ -846,7 +1005,7 @@ export default {
.use(primevue.config.default)
.mount("#app");
<\\/script>
`
`
}
}
};

View File

@ -13,7 +13,7 @@
<div class="content-section implementation">
<div class="card">
<img alt="logo" src="/demo/images/nature/nature3.jpg" @contextmenu="onImageRightClick" aria-haspopup="true" />
<img alt="logo" src="demo/images/nature/nature3.jpg" @contextmenu="onImageRightClick" aria-haspopup="true" />
<ContextMenu ref="menu" :model="items" />
</div>
</div>

View File

@ -24,7 +24,7 @@
</template>
<script>
import ProductService from '@/service/ProductService';
import ProductService from '../../service/ProductService';
import DataTableBasicDoc from './DataTableBasicDoc';
export default {

View File

@ -1,6 +1,5 @@
<template>
<div>
<ClientOnly>
<div class="content-section introduction">
<div class="feature-intro">
<h1>DataTable <span>ColumnGroup</span></h1>
@ -57,7 +56,6 @@
</div>
<AppDoc name="DataTableColGroupDemo" :sources="sources" github="datatable/DataTableColGroupDemo.vue" />
</ClientOnly>
</div>
</template>
@ -401,6 +399,7 @@ export default {
computed: {
lastYearTotal() {
let total = 0;
for (let sale of this.sales) {
total += sale.lastYearProfit;
}
@ -409,6 +408,7 @@ export default {
},
thisYearTotal() {
let total = 0;
for (let sale of this.sales) {
total += sale.thisYearProfit;
}

View File

@ -33,9 +33,7 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableColResizeDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="datatable/DataTableColResizeDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -17,14 +17,12 @@
</div>
</template>
<Column field="code" header="Code" />
<Column v-for="(col, index) of selectedColumns" :field="col.field" :header="col.header" :key="col.field + '_' + index"></Column>
<Column v-for="(col, index) of selectedColumns" :key="col.field + '_' + index" :field="col.field" :header="col.header"></Column>
</DataTable>
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableColToggleDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="datatable/DataTableColToggleDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -10,7 +10,7 @@
<div class="content-section implementation">
<div class="card">
<DataTable :value="products" contextMenu v-model:contextMenuSelection="selectedProduct" @row-contextmenu="onRowContextMenu" responsiveLayout="scroll">
<DataTable v-model:contextMenuSelection="selectedProduct" :value="products" contextMenu @row-contextmenu="onRowContextMenu" responsiveLayout="scroll">
<Column field="code" header="Code"></Column>
<Column field="name" header="Name"></Column>
<Column field="category" header="Category"></Column>
@ -22,12 +22,10 @@
</DataTable>
</div>
<ContextMenu :model="menuModel" ref="cm" />
<ContextMenu ref="cm" :model="menuModel" />
</div>
<ClientOnly>
<AppDoc name="DataTableContextMenuDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="datatable/DataTableContextMenuDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -24,8 +24,8 @@
<DataTable
ref="dt"
:value="products"
v-model:selection="selectedProducts"
:value="products"
dataKey="id"
:paginator="true"
:rows="10"
@ -50,7 +50,7 @@
<Column field="name" header="Name" :sortable="true" style="min-width: 16rem"></Column>
<Column header="Image">
<template #body="slotProps">
<img :src="'/demo/images/product/' + slotProps.data.image" :alt="slotProps.data.image" class="product-image" />
<img :src="'demo/images/product/' + slotProps.data.image" :alt="slotProps.data.image" class="product-image" />
</template>
</Column>
<Column field="price" header="Price" :sortable="true" style="min-width: 8rem">
@ -79,11 +79,11 @@
</div>
<Dialog v-model:visible="productDialog" :style="{ width: '450px' }" header="Product Details" :modal="true" class="p-fluid">
<img :src="'/demo/images/product/' + product.image" :alt="product.image" class="product-image" v-if="product.image" />
<img v-if="product.image" :src="'demo/images/product/' + product.image" :alt="product.image" class="product-image" />
<div class="field">
<label for="name">Name</label>
<InputText id="name" v-model.trim="product.name" required="true" autofocus :class="{ 'p-invalid': submitted && !product.name }" />
<small class="p-error" v-if="submitted && !product.name">Name is required.</small>
<small v-if="submitted && !product.name" class="p-error">Name is required.</small>
</div>
<div class="field">
<label for="description">Description</label>
@ -111,19 +111,19 @@
<label class="mb-3">Category</label>
<div class="formgrid grid">
<div class="field-radiobutton col-6">
<RadioButton id="category1" name="category" value="Accessories" v-model="product.category" />
<RadioButton id="category1" v-model="product.category" name="category" value="Accessories" />
<label for="category1">Accessories</label>
</div>
<div class="field-radiobutton col-6">
<RadioButton id="category2" name="category" value="Clothing" v-model="product.category" />
<RadioButton id="category2" v-model="product.category" name="category" value="Clothing" />
<label for="category2">Clothing</label>
</div>
<div class="field-radiobutton col-6">
<RadioButton id="category3" name="category" value="Electronics" v-model="product.category" />
<RadioButton id="category3" v-model="product.category" name="category" value="Electronics" />
<label for="category3">Electronics</label>
</div>
<div class="field-radiobutton col-6">
<RadioButton id="category4" name="category" value="Fitness" v-model="product.category" />
<RadioButton id="category4" v-model="product.category" name="category" value="Fitness" />
<label for="category4">Fitness</label>
</div>
</div>
@ -171,9 +171,7 @@
</Dialog>
</div>
<ClientOnly>
<AppDoc name="DataTableCrudDemo" :sources="sources" :service="['ProductService']" :data="['products']" github="datatable/DataTableCrudDemo.vue" />
</ClientOnly>
</div>
</template>
@ -1186,6 +1184,7 @@ export default {
methods: {
formatCurrency(value) {
if (value) return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
return;
},
openNew() {
@ -1234,6 +1233,7 @@ export default {
},
findIndexById(id) {
let index = -1;
for (let i = 0; i < this.products.length; i++) {
if (this.products[i].id === id) {
index = i;
@ -1246,9 +1246,11 @@ export default {
createId() {
let id = '';
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (var i = 0; i < 5; i++) {
id += chars.charAt(Math.floor(Math.random() * chars.length));
}
return id;
},
exportCSV() {

View File

@ -1,7 +1,5 @@
<template>
<ClientOnly>
<AppDoc name="DataTableBasicDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="datatable/DataTableBasicDemo.vue" />
</ClientOnly>
</template>
<script>

View File

@ -1,6 +1,5 @@
<template>
<div class="content-section documentation">
<ClientOnly>
<AppDoc name="DataTableDemo" :sources="sources" :service="['CustomerService']" :data="['customers-large']" github="datatable/DataTableDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -504,15 +503,15 @@ export default {
<h5>Auto Layout</h5>
<p>
Default table-layout is fixed meaning the cell widths do not depend on their content. If you require cells to scale based on their contents set <i>autoLayout</i> property to true. Note that Scrollable and/or Resizable tables do
not support auto layout due to technical limitations.
Default table-layout is fixed meaning the cell widths do not depend on their content. If you require cells to scale based on their contents set <i>autoLayout</i> property to true. Note that Scrollable and/or Resizable tables do not
support auto layout due to technical limitations.
</p>
<h5>Templating</h5>
<p>
Field data of a corresponding row is displayed as the cell content by default, this can be customized using a <i>body</i> template where current row data and column properties are passed via the slot props. On the other hand,
<i>header</i> and <i>footer</i> sections of a column can either be defined with the properties or the templates. Similarly DataTable itself also provides header and footer properties along with the templates for the main header
and footer of the table.
<i>header</i> and <i>footer</i> sections of a column can either be defined with the properties or the templates. Similarly DataTable itself also provides header and footer properties along with the templates for the main header and
footer of the table.
</p>
<pre v-code><code><template v-pre>
@ -527,7 +526,7 @@ export default {
&lt;Column field="year" header="Year"&gt;&lt;/Column&gt;
&lt;Column field="brand" header="Brand"&gt;
&lt;template #body="slotProps"&gt;
&lt;img :src="'/demo/images/car/' + slotProps.data.brand + '.png'" :alt="slotProps.data.brand" width="48px"/&gt;
&lt;img :src="'demo/images/car/' + slotProps.data.brand + '.png'" :alt="slotProps.data.brand" width="48px"/&gt;
&lt;/template&gt;
&lt;/Column&gt;
&lt;Column field="color" header="Color"&gt;&lt;/Column&gt;
@ -621,7 +620,7 @@ export default {
<h5>Pagination</h5>
<p>
Pagination is enabled by setting <i>paginator</i> property to true and defining the <i>rows</i> property defines the number of rows per page. See the <nuxt-link to="/paginator">Paginator</nuxt-link> for the available customization
Pagination is enabled by setting <i>paginator</i> property to true and defining the <i>rows</i> property defines the number of rows per page. See the <router-link to="/paginator">Paginator</router-link> for the available customization
options such as paginator templates, page links, rows per page options and more which can be passed through the DataTable.
</p>
@ -653,8 +652,8 @@ export default {
</code></pre>
<p>
Paginator can also be programmed programmatically using a binding to the <i>first</i> property that defines the index of the first element to display. For example setting first to zero will reset the paginator to the very first
page. This property also supports v-model in case you'd like your binding to be updated whenever the user changes the page.
Paginator can also be programmed programmatically using a binding to the <i>first</i> property that defines the index of the first element to display. For example setting first to zero will reset the paginator to the very first page.
This property also supports v-model in case you'd like your binding to be updated whenever the user changes the page.
</p>
<pre v-code><code><template v-pre>
&lt;DataTable :value="cars" :paginator="true" :rows="10" :first="firstRecordIndex"&gt;
@ -691,8 +690,8 @@ export default {
</code></pre>
<p>
In case you'd like to display the table as sorted per a single column by default on mount or programmatically apply sort, use <i>sortField</i> and <i>sortOrder</i> properties. These two properties also support the v-model
directive to get updated when the user applies sort a column.
In case you'd like to display the table as sorted per a single column by default on mount or programmatically apply sort, use <i>sortField</i> and <i>sortOrder</i> properties. These two properties also support the v-model directive to
get updated when the user applies sort a column.
</p>
<pre v-code><code><template v-pre>
&lt;DataTable :value="cars" sortField="year" :sortOrder="1"&gt;
@ -736,10 +735,10 @@ data() {
<h5>Filtering</h5>
<p>
DataTable has advanced filtering capabilities that does the heavy lifting while providing flexible customization. Filtering has two layout alternatives defined with the <i>filterDisplay</i>. In <b>row</b> setting, filter elements
are displayed in a separate row at the header section whereas in <i>menu</i> mode filter elements are displayed inside an overlay. Filter metadata is specified using the <i>filters</i> as a v-model and UI elements for the
filtering are placed inside the filter template. The template filter gets a <i>filterModel</i> and <i>filterCallback</i>, use filterModel.value to populate the filter with your own form components and call the filterCallback with
the event of your choice like @input, @change, @click.
DataTable has advanced filtering capabilities that does the heavy lifting while providing flexible customization. Filtering has two layout alternatives defined with the <i>filterDisplay</i>. In <b>row</b> setting, filter elements are
displayed in a separate row at the header section whereas in <i>menu</i> mode filter elements are displayed inside an overlay. Filter metadata is specified using the <i>filters</i> as a v-model and UI elements for the filtering are
placed inside the filter template. The template filter gets a <i>filterModel</i> and <i>filterCallback</i>, use filterModel.value to populate the filter with your own form components and call the filterCallback with the event of your
choice like @input, @change, @click.
</p>
<pre v-code.script><code>
@ -917,8 +916,8 @@ matchModes: [
<h5>Selection</h5>
<p>
DataTable provides single and multiple selection modes on click of a row. Selected rows are bound to the <i>selection</i> property and updated using the v-model directive. Alternatively column based selection can be done using
radio buttons or checkboxes using <i>selectionMode</i> of a particular column. In addition row-select and row-unselect events are provided as optional callbacks.
DataTable provides single and multiple selection modes on click of a row. Selected rows are bound to the <i>selection</i> property and updated using the v-model directive. Alternatively column based selection can be done using radio
buttons or checkboxes using <i>selectionMode</i> of a particular column. In addition row-select and row-unselect events are provided as optional callbacks.
</p>
<p>The <i>dataKey</i> property identifies a unique value of a row in the dataset, it is not mandatory however being able to define it increases the performance of the table signifantly.</p>
@ -936,8 +935,8 @@ matchModes: [
</code></pre>
<p>
In multiple mode, selection binding should be an array and multiple items can either be selected using metaKey or toggled individually depending on the value of <i>metaKeySelection</i> property value which is true by default. On
touch enabled devices metaKeySelection is turned off automatically. Additionally ShiftKey is supported for range selection.
In multiple mode, selection binding should be an array and multiple items can either be selected using metaKey or toggled individually depending on the value of <i>metaKeySelection</i> property value which is true by default. On touch
enabled devices metaKeySelection is turned off automatically. Additionally ShiftKey is supported for range selection.
</p>
<pre v-code><code><template v-pre>
&lt;DataTable :value="cars" v-model:selection="selectedCars" selectionMode="multiple" dataKey="vin"&gt;
@ -950,8 +949,8 @@ matchModes: [
</code></pre>
<p>
If you prefer a radioButton or a checkbox instead of a row click, use the <i>selectionMode</i> of a column instead. Following datatable displays a checkbox at the first column of each row and automatically adds a header checkbox
to toggle selection of all rows.
If you prefer a radioButton or a checkbox instead of a row click, use the <i>selectionMode</i> of a column instead. Following datatable displays a checkbox at the first column of each row and automatically adds a header checkbox to
toggle selection of all rows.
</p>
<pre v-code><code><template v-pre>
&lt;DataTable :value="cars" v-model:selection="selectedCars" dataKey="vin"&gt;
@ -1012,7 +1011,7 @@ matchModes: [
</code></pre>
<h6>Full Page Scroll</h6>
<p>FlexScroll can also be used for cases where scrollable viewport should be responsive with respect to the window size. See the <nuxt-link to="/datatable/flexscroll">full page</nuxt-link> demo for an example.</p>
<p>FlexScroll can also be used for cases where scrollable viewport should be responsive with respect to the window size. See the <router-link to="/datatable/flexscroll">full page</router-link> demo for an example.</p>
<pre v-code><code><template v-pre>
&lt;div style="height: calc(100vh - 143px)"&gt;
&lt;DataTable :value="cars" :scrollable="true" scrollHeight="flex"&gt;
@ -1094,26 +1093,26 @@ matchModes: [
<h6>Scrollable RowGroup</h6>
<p>
Row groups with subheaders have exclusive support for filtering, when the table scrolls the subheaders stay fixed as long as their data are still displayed. No additional configuration is required to enable this feature. View the
<nuxt-link to="/datatable/rowgroup">Row Group</nuxt-link> demo for an example.
<router-link to="/datatable/rowgroup">Row Group</router-link> demo for an example.
</p>
<h5>Lazy Loading</h5>
<p>
Lazy mode is handy to deal with large datasets, instead of loading the entire data, small chunks of data is loaded by invoking corresponding callbacks such as paging and sorting. It is also important to assign the logical number
of rows to totalRecords by doing a projection query for paginator configuration so that paginator displays the UI accordingly.
Lazy mode is handy to deal with large datasets, instead of loading the entire data, small chunks of data is loaded by invoking corresponding callbacks such as paging and sorting. It is also important to assign the logical number of
rows to totalRecords by doing a projection query for paginator configuration so that paginator displays the UI accordingly.
</p>
<p>
Lazy loading is implemented by handling <i>page</i>, <i>sort</i>, <i>filter</i> events by making a remote query using the information passed to these events such as first offset, number of rows, sort field for ordering and
filters. Note that, in lazy filtering totalRecords should also be updated to align the data with the paginator.
Lazy loading is implemented by handling <i>page</i>, <i>sort</i>, <i>filter</i> events by making a remote query using the information passed to these events such as first offset, number of rows, sort field for ordering and filters.
Note that, in lazy filtering totalRecords should also be updated to align the data with the paginator.
</p>
<p>Visit the <nuxt-link to="/datatable/lazy">lazy loading</nuxt-link> demo for an example with a remote datasource.</p>
<p>Visit the <router-link to="/datatable/lazy">lazy loading</router-link> demo for an example with a remote datasource.</p>
<h5>Row Expansion</h5>
<p>
Rows can be expanded to display additional content using the <i>expandedRows</i> property with the v-model directive accompanied by a template named "expansion". <i>row-expand</i> and <i>row-collapse</i> are optional callbacks
that are invoked when a row is expanded or toggled.
Rows can be expanded to display additional content using the <i>expandedRows</i> property with the v-model directive accompanied by a template named "expansion". <i>row-expand</i> and <i>row-collapse</i> are optional callbacks that
are invoked when a row is expanded or toggled.
</p>
<p>The <i>dataKey</i> property identifies a unique value of a row in the dataset, it is not mandatory in row expansion functionality however being able to define it increases the performance of the table significantly.</p>
@ -1134,7 +1133,7 @@ matchModes: [
&lt;template #expansion="slotProps"&gt;
&lt;div class="car-details"&gt;
&lt;div&gt;
&lt;img :src="'/demo/images/car/' + slotProps.data.brand + '.png'" :alt="slotProps.data.brand"/&gt;
&lt;img :src="'demo/images/car/' + slotProps.data.brand + '.png'" :alt="slotProps.data.brand"/&gt;
&lt;div class="grid"&gt;
&lt;div class="col-12"&gt;Vin: &lt;b&gt;&#123;&#123;slotProps.data.vin&#125;&#125;&lt;/b&gt;&lt;/div&gt;
&lt;div class="col-12"&gt;Year: &lt;b&gt;&#123;&#123;slotProps.data.year&#125;&#125;&lt;/b&gt;&lt;/div&gt;
@ -1190,9 +1189,9 @@ export default {
<p>In cell editing provides a rapid and user friendly way to manipulate the data. The datatable provides a flexible API so that the editing behavior is implemented by the page author whether it utilizes v-model or vuex.</p>
<p>
Individual cell editing is configured by setting the <i>editMode</i> to <b>cell</b>, defining editors with the <b>editor</b> template along with the <i>@cell-edit-complete</i> event. The content of the editor defines how the
editing is implemented. The editor template receives a clone of the row data and using <i>@cell-edit-complete</i> event the new value can be updated to the model or cancelled. This also provides flexibility to apply conditional
logic such as implementing validations.
Individual cell editing is configured by setting the <i>editMode</i> to <b>cell</b>, defining editors with the <b>editor</b> template along with the <i>@cell-edit-complete</i> event. The content of the editor defines how the editing
is implemented. The editor template receives a clone of the row data and using <i>@cell-edit-complete</i> event the new value can be updated to the model or cancelled. This also provides flexibility to apply conditional logic such as
implementing validations.
</p>
<pre v-code><code><template v-pre>
@ -1213,7 +1212,7 @@ export default {
&lt;Dropdown v-model="slotProps.data['brand']" :options="brands" optionLabel="brand" optionValue="value" placeholder="Select a Brand"&gt;
&lt;template #option="optionProps"&gt;
&lt;div class="p-dropdown-car-option"&gt;
&lt;img :alt="optionProps.option.brand" :src="'/demo/images/car/' + optionProps.option.brand + '.png'" /&gt;
&lt;img :alt="optionProps.option.brand" :src="'demo/images/car/' + optionProps.option.brand + '.png'" /&gt;
&lt;span&gt;{{optionProps.option.brand}}&lt;/span&gt;
&lt;/div&gt;
&lt;/template&gt;
@ -1378,8 +1377,8 @@ export default {
<h5>Column Reorder</h5>
<p>
Columns can be reordered using drag drop by setting the <i>reorderableColumns</i> to true. <i>column-reorder</i> is a callback that is invoked when a column is reordered. DataTable keeps the column order state internally using
keys that identifies a column using the field property. If the column has no field, use columnKey instead as it is mandatory for columns to have unique keys when reordering is enabled.
Columns can be reordered using drag drop by setting the <i>reorderableColumns</i> to true. <i>column-reorder</i> is a callback that is invoked when a column is reordered. DataTable keeps the column order state internally using keys
that identifies a column using the field property. If the column has no field, use columnKey instead as it is mandatory for columns to have unique keys when reordering is enabled.
</p>
<pre v-code><code><template v-pre>
&lt;DataTable :value="cars" :reorderableColumns="true"&gt;
@ -1393,8 +1392,8 @@ export default {
<h5>Row Reorder</h5>
<p>
Data can be reordered using drag drop by adding a reorder column that will display an icon as a drag handle along with the <i>row-reorder</i> event which is <b>mandatory</b> to update the new order. Note that the reorder icon can
be customized using <i>rowReorderIcon</i> of the column component.
Data can be reordered using drag drop by adding a reorder column that will display an icon as a drag handle along with the <i>row-reorder</i> event which is <b>mandatory</b> to update the new order. Note that the reorder icon can be
customized using <i>rowReorderIcon</i> of the column component.
</p>
<pre v-code><code><template v-pre>
&lt;DataTable :value="cars" @row-reorder="onRowReorder"&gt;
@ -1582,9 +1581,9 @@ export default {
<h5>TableState</h5>
<p>
Stateful table allows keeping the state such as page, sort and filtering either at local storage or session storage so that when the page is visited again, table would render the data using its last settings. Enabling state is
easy as defining a unique <i>stateKey</i>, the storage to keep the state is defined with the <i>stateStorage</i> property that accepts session for sessionStorage and local for localStorage. Currently following features are
supported by TableState; paging, sorting, filtering, column resizing, column reordering, row expansion, row group expansion and row selection.
Stateful table allows keeping the state such as page, sort and filtering either at local storage or session storage so that when the page is visited again, table would render the data using its last settings. Enabling state is easy as
defining a unique <i>stateKey</i>, the storage to keep the state is defined with the <i>stateStorage</i> property that accepts session for sessionStorage and local for localStorage. Currently following features are supported by
TableState; paging, sorting, filtering, column resizing, column reordering, row expansion, row group expansion and row selection.
</p>
<pre v-code><code><template v-pre>
&lt;DataTable :value="cars" :paginator="true" :rows="10" v-model:filters="filters"
@ -1611,7 +1610,7 @@ export default {
&lt;Dropdown v-model="filters['brand']" :options="brands" optionLabel="brand" optionValue="value" placeholder="Select a Brand" class="p-column-filter" :showClear="true"&gt;
&lt;template #option="slotProps"&gt;
&lt;div class="p-dropdown-car-option"&gt;
&lt;img :alt="slotProps.option.brand" :src="'/demo/images/car/' + slotProps.option.brand + '.png'" /&gt;
&lt;img :alt="slotProps.option.brand" :src="'demo/images/car/' + slotProps.option.brand + '.png'" /&gt;
&lt;span&gt;&#123;&#123;slotProps.option.brand&#125;&#125;&lt;/span&gt;
&lt;/div&gt;
&lt;/template&gt;
@ -1743,8 +1742,8 @@ export default {
<h5>Loading</h5>
<p>
A loading status indicator can be displayed when the <i>loading</i> property is enabled. The icon is customized through <i>loadingIcon</i> property. Additionally an option loading template is available to render as the body until
the data is loaded.
A loading status indicator can be displayed when the <i>loading</i> property is enabled. The icon is customized through <i>loadingIcon</i> property. Additionally an option loading template is available to render as the body until the
data is loaded.
</p>
<pre v-code><code><template v-pre>
&lt;DataTable :value="cars" :loading="loading"&gt;
@ -1788,14 +1787,14 @@ export default {
<h5>Responsive</h5>
<p>
DataTable responsive layout can be achieved in two ways; first approach is displaying a horizontal scrollbar for smaller screens and second one is defining a breakpoint to display the cells of a row as stacked. Scrollable tables
use the scroll layout approach internally and do not require additional configuration.
DataTable responsive layout can be achieved in two ways; first approach is displaying a horizontal scrollbar for smaller screens and second one is defining a breakpoint to display the cells of a row as stacked. Scrollable tables use
the scroll layout approach internally and do not require additional configuration.
</p>
<h6>Scroll Layout</h6>
<p>
Set <i>responsiveLayout</i> to scroll to enabled this layout. Note that, when scroll mode is enabled table-layout automatically switches to auto from fixed as a result table widths are likely to differ and resizable columns are
not supported. Read more about <a href="https://www.w3schools.com/cssref/pr_tab_table-layout.asp">table-layout</a> for more details.
Set <i>responsiveLayout</i> to scroll to enabled this layout. Note that, when scroll mode is enabled table-layout automatically switches to auto from fixed as a result table widths are likely to differ and resizable columns are not
supported. Read more about <a href="https://www.w3schools.com/cssref/pr_tab_table-layout.asp">table-layout</a> for more details.
</p>
<pre v-code><code><template v-pre>
@ -1816,8 +1815,8 @@ export default {
<h5>Row and Cell Styling</h5>
<p>
Certain rows or cells can easily be styled based on conditions. Cell styling is implemented with templating whereas row styling utilizes the <i>rowClass</i> property which takes the row data as a parameter and returns the style
class as a string.
Certain rows or cells can easily be styled based on conditions. Cell styling is implemented with templating whereas row styling utilizes the <i>rowClass</i> property which takes the row data as a parameter and returns the style class
as a string.
</p>
<pre v-code><code><template v-pre>
&lt;DataTable :value="cars" :rowClass="rowClass"&gt;
@ -1947,7 +1946,7 @@ export default {
FirstPageLink PrevPageLink PageLinks <br />
NextPageLink LastPageLink RowsPerPageDropdown
</td>
<td>Template of the paginator. See the <nuxt-link to="/paginator">Paginator</nuxt-link> for all available options.</td>
<td>Template of the paginator. See the <router-link to="/paginator">Paginator</router-link> for all available options.</td>
</tr>
<tr>
<td>pageLinkSize</td>
@ -2234,7 +2233,7 @@ export default {
<td>object</td>
<td>null</td>
<td>
Whether to use the virtualScroller feature. The properties of <nuxt-link to="/virtualscroller">VirtualScroller</nuxt-link> component can be used like an object in it. <br /><b>Note:</b> Currently only vertical
Whether to use the virtualScroller feature. The properties of <router-link to="/virtualscroller">VirtualScroller</router-link> component can be used like an object in it. <br /><b>Note:</b> Currently only vertical
orientation mode is supported.
</td>
</tr>
@ -2280,6 +2279,18 @@ export default {
<td>null</td>
<td>Style class of the table element.</td>
</tr>
<tr>
<td>tableProps</td>
<td>object</td>
<td>null</td>
<td>Uses to pass all properties of the TableHTMLAttributes to table element inside the component.</td>
</tr>
<tr>
<td>filterInputProps</td>
<td>object</td>
<td>null</td>
<td>Uses to pass all properties of the HTMLInputElement to the focusable filter input element inside the component.</td>
</tr>
</tbody>
</table>
</div>
@ -2747,10 +2758,182 @@ export default {
</table>
</div>
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
DataTable uses a <i>table</i> element whose attributes can be extended with the <i>tableProps</i> option. This property allows passing aria roles and attributes like <i>aria-label</i> and <i>aria-describedby</i> to define the table
for readers. Default role of the table is <i>table</i>. Header, body and footer elements use <i>rowgroup</i>, rows use <i>row</i> role, header cells have <i>columnheader</i> and body cells use <i>cell</i> roles. Sortable headers
utilizer <i>aria-sort</i> attribute either set to "ascending" or "descending".
</p>
<p>
Built-in checkbox and radiobutton components for row selection use <i>checkbox</i> and <i>radiobutton</i>. The label to describe them is retrieved from the <i>aria.selectRow</i> and <i>aria.unselectRow</i> properties of the
<router-link to="/locale">locale</router-link> API. Similarly header checkbox uses <i>selectAll</i> and <i>unselectAll</i> keys. When a row is selected, <i>aria-selected</i> is set to true on a row.
</p>
<p>
The element to expand or collapse a row is a <i>button</i> with <i>aria-expanded</i> and <i>aria-controls</i> properties. Value to describe the buttons is derived from <i>aria.expandRow</i> and <i>aria.collapseRow</i> properties of
the <router-link to="/locale">locale</router-link> API.
</p>
<p>
The filter menu button use <i>aria.showFilterMenu</i> and <i>aria.hideFilterMenu</i> properties as <i>aria-label</i> in addition to the <i>aria-haspopup</i>, <i>aria-expanded</i> and <i>aria-controls</i> to define the relation between
the button and the overlay. Popop menu has <i>dialog</i> role with <i>aria-modal</i> as focus is kept within the overlay. The operator dropdown use <i>aria.filterOperator</i> and filter constraints dropdown use
<i>aria.filterConstraint</i> properties. Buttons to add rules on the other hand utilize <i>aria.addRule</i> and <i>aria.removeRule</i> properties. The footer buttons similarly use <i>aria.clear</i> and <i>aria.apply</i> properties.
<i>filterInputProps</i> of the Column component can be used to define aria labels for the built-in filter components, if a custom component is used with templating you also may define your own aria labels as well.
</p>
<p>
Editable cells use custom templating so you need to manage aria roles and attributes manually if required. The row editor controls are button elements with <i>aria.editRow</i>, <i>aria.cancelEdit</i> and <i>aria.saveEdit</i> used for
the <i>aria-label</i>.
</p>
<p>Paginator is a standalone component used inside the DataTable, refer to the <router-link to="/paginator">paginator</router-link> for more information about the accessibility features.</p>
<h6>Keyboard Support</h6>
<p>Any button element inside the DataTable used for cases like filter, row expansion, edit are tabbable and can be used with <i>space</i> and <i>enter</i> keys.</p>
<h6>Sortable Headers Keyboard Support</h6>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<i>tab</i>
</td>
<td>Moves through the headers.</td>
</tr>
<tr>
<td>
<i>enter</i>
</td>
<td>Sorts the column.</td>
</tr>
<tr>
<td>
<i>space</i>
</td>
<td>Sorts the column.</td>
</tr>
</tbody>
</table>
</div>
<h6>Filter Menu Keyboard Support</h6>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<i>tab</i>
</td>
<td>Moves through the elements inside the popup.</td>
</tr>
<tr>
<td>
<i>escape</i>
</td>
<td>Hides the popup.</td>
</tr>
</tbody>
</table>
</div>
<h6>Selection Keyboard Support</h6>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<i>tab</i>
</td>
<td>Moves focus to the first selected row, if there is none then first row receives the focus.</td>
</tr>
<tr>
<td>
<i>up arrow</i>
</td>
<td>Moves focus to the previous row.</td>
</tr>
<tr>
<td>
<i>down arrow</i>
</td>
<td>Moves focus to the next row.</td>
</tr>
<tr>
<td>
<i>enter</i>
</td>
<td>Toggles the selected state of the focused row depending on the metaKeySelection setting.</td>
</tr>
<tr>
<td>
<i>space</i>
</td>
<td>Toggles the selected state of the focused row depending on the metaKeySelection setting.</td>
</tr>
<tr>
<td>
<i>home</i>
</td>
<td>Moves focus to the first row.</td>
</tr>
<tr>
<td>
<i>end</i>
</td>
<td>Moves focus to the last row.</td>
</tr>
<tr>
<td><i>shift</i> + <i>down arrow</i></td>
<td>Moves focus to the next row and toggles the selection state.</td>
</tr>
<tr>
<td><i>shift</i> + <i>up arrow</i></td>
<td>Moves focus to the previous row and toggles the selection state.</td>
</tr>
<tr>
<td><i>shift</i> + <i>space</i></td>
<td>Selects the rows between the most recently selected row and the focused row.</td>
</tr>
<tr>
<td><i>control</i> + <i>shift</i> + <i>home</i></td>
<td>Selects the focused rows and all the options up to the first one.</td>
</tr>
<tr>
<td><i>control</i> + <i>shift</i> + <i>end</i></td>
<td>Selects the focused rows and all the options down to the last one.</td>
</tr>
<tr>
<td><i>control</i> + <i>a</i></td>
<td>Selects all rows.</td>
</tr>
</tbody>
</table>
</div>
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</div>
</template>

View File

@ -11,14 +11,12 @@
<div class="content-section implementation">
<div class="card">
<DataTable :value="products" responsiveLayout="scroll">
<Column v-for="col of columns" :field="col.field" :header="col.header" :key="col.field"></Column>
<Column v-for="col of columns" :key="col.field" :field="col.field" :header="col.header"></Column>
</DataTable>
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableDynamicColumnsDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="datatable/DataTableDynamicColumnsDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -13,7 +13,7 @@
<h5>Cell Editing</h5>
<p>Validations, dynamic columns and reverting values with the escape key.</p>
<DataTable :value="products1" editMode="cell" @cell-edit-complete="onCellEditComplete" class="editable-cells-table" responsiveLayout="scroll">
<Column v-for="col of columns" :field="col.field" :header="col.header" :key="col.field" style="width: 25%">
<Column v-for="col of columns" :key="col.field" :field="col.field" :header="col.header" style="width: 25%">
<template #editor="{ data, field }">
<InputText v-model="data[field]" autofocus />
</template>
@ -23,7 +23,7 @@
<div class="card">
<h5>Row Editing</h5>
<DataTable :value="products2" editMode="row" dataKey="id" v-model:editingRows="editingRows" @row-edit-save="onRowEditSave" responsiveLayout="scroll">
<DataTable v-model:editingRows="editingRows" :value="products2" editMode="row" dataKey="id" @row-edit-save="onRowEditSave" responsiveLayout="scroll">
<Column field="code" header="Code" style="width: 20%">
<template #editor="{ data, field }">
<InputText v-model="data[field]" autofocus />
@ -57,10 +57,10 @@
<div class="card">
<h5>Cell Editing with Sorting and Filter</h5>
<DataTable :value="products3" editMode="cell" @cell-edit-complete="onCellEditComplete" class="editable-cells-table" filterDisplay="row" v-model:filters="filters" responsiveLayout="scroll">
<Column v-for="col of columns" :field="col.field" :header="col.header" :key="col.field" style="width: 25%" sortable filter>
<DataTable v-model:filters="filters" :value="products3" editMode="cell" @cell-edit-complete="onCellEditComplete" class="editable-cells-table" filterDisplay="row" responsiveLayout="scroll">
<Column v-for="col of columns" :key="col.field" :field="col.field" :header="col.header" style="width: 25%" sortable filter>
<template #filter="{ filterModel, filterCallback }">
<InputText type="text" v-model="filterModel.value" @keydown.enter="filterCallback()" class="p-column-filter" v-tooltip.top.focus="'Hit enter key to filter'" />
<InputText v-model="filterModel.value" v-tooltip.top.focus="'Hit enter key to filter'" type="text" @keydown.enter="filterCallback()" class="p-column-filter" />
</template>
<template #editor="{ data, field }">
<InputText v-model="data[field]" autofocus />
@ -70,15 +70,13 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableEditDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="datatable/DataTableEditDemo.vue" />
</ClientOnly>
</div>
</template>
<script>
import ProductService from '../../service/ProductService';
import { FilterMatchMode } from 'primevue/api';
import ProductService from '../../service/ProductService';
export default {
data() {
@ -628,6 +626,11 @@ export default {
{ field: 'price', header: 'Price' }
];
},
mounted() {
this.productService.getProductsSmall().then((data) => (this.products1 = data));
this.productService.getProductsSmall().then((data) => (this.products2 = data));
this.productService.getProductsSmall().then((data) => (this.products3 = data));
},
methods: {
onCellEditComplete(event) {
let { data, newValue, field } = event;
@ -647,12 +650,16 @@ export default {
},
isPositiveInteger(val) {
let str = String(val);
str = str.trim();
if (!str) {
return false;
}
str = str.replace(/^0+/, '') || '0';
var n = Math.floor(Number(str));
return n !== Infinity && String(n) === str && n >= 0;
},
onRowEditSave(event) {
@ -675,11 +682,6 @@ export default {
return 'NA';
}
}
},
mounted() {
this.productService.getProductsSmall().then((data) => (this.products1 = data));
this.productService.getProductsSmall().then((data) => (this.products2 = data));
this.productService.getProductsSmall().then((data) => (this.products3 = data));
}
};
</script>

View File

@ -10,7 +10,7 @@
<div class="content-section implementation">
<div class="card">
<DataTable :value="products" ref="dt" responsiveLayout="scroll">
<DataTable ref="dt" :value="products" responsiveLayout="scroll">
<template #header>
<div style="text-align: left">
<Button icon="pi pi-external-link" label="Export" @click="exportCSV($event)" />
@ -24,9 +24,7 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableExportDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="datatable/DataTableExportDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -13,13 +13,13 @@
<h5>Filter Menu</h5>
<p>Filters are displayed in an overlay.</p>
<DataTable
v-model:filters="filters1"
:value="customers1"
:paginator="true"
class="p-datatable-customers"
showGridlines
:rows="10"
dataKey="id"
v-model:filters="filters1"
filterDisplay="menu"
:loading="loading1"
responsiveLayout="scroll"
@ -41,7 +41,7 @@
{{ data.name }}
</template>
<template #filter="{ filterModel }">
<InputText type="text" v-model="filterModel.value" class="p-column-filter" placeholder="Search by name" />
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by name" />
</template>
</Column>
<Column header="Country" filterField="country.name" style="min-width: 12rem">
@ -50,7 +50,7 @@
<span class="image-text">{{ data.country.name }}</span>
</template>
<template #filter="{ filterModel }">
<InputText type="text" v-model="filterModel.value" class="p-column-filter" placeholder="Search by country" />
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by country" />
</template>
<template #filterclear="{ filterCallback }">
<Button type="button" icon="pi pi-times" @click="filterCallback()" class="p-button-secondary"></Button>
@ -64,7 +64,7 @@
</Column>
<Column header="Agent" filterField="representative" :showFilterMatchModes="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 14rem">
<template #body="{ data }">
<img :alt="data.representative.name" :src="'/demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" />
<img :alt="data.representative.name" :src="'demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{ data.representative.name }}</span>
</template>
<template #filter="{ filterModel }">
@ -72,7 +72,7 @@
<MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter">
<template #option="slotProps">
<div class="p-multiselect-representative-option">
<img :alt="slotProps.option.name" :src="'/demo/images/avatar/' + slotProps.option.image" width="32" style="vertical-align: middle" />
<img :alt="slotProps.option.name" :src="'demo/images/avatar/' + slotProps.option.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{ slotProps.option.name }}</span>
</div>
</template>
@ -102,7 +102,7 @@
<template #filter="{ filterModel }">
<Dropdown v-model="filterModel.value" :options="statuses" placeholder="Any" class="p-column-filter" :showClear="true">
<template #value="slotProps">
<span :class="'customer-badge status-' + slotProps.value" v-if="slotProps.value">{{ slotProps.value }}</span>
<span v-if="slotProps.value" :class="'customer-badge status-' + slotProps.value">{{ slotProps.value }}</span>
<span v-else>{{ slotProps.placeholder }}</span>
</template>
<template #option="slotProps">
@ -117,7 +117,7 @@
</template>
<template #filter="{ filterModel }">
<Slider v-model="filterModel.value" range class="m-3"></Slider>
<div class="flex align-items-center justify-content-center px-2">
<div class="flex align-items-center justify-content-between px-2">
<span>{{ filterModel.value ? filterModel.value[0] : 0 }}</span>
<span>{{ filterModel.value ? filterModel.value[1] : 100 }}</span>
</div>
@ -138,12 +138,12 @@
<h5>Filter Row</h5>
<p>Filters are displayed inline within a separate row.</p>
<DataTable
v-model:filters="filters2"
:value="customers2"
:paginator="true"
class="p-datatable-customers"
:rows="10"
dataKey="id"
v-model:filters="filters2"
filterDisplay="row"
:loading="loading2"
responsiveLayout="scroll"
@ -164,7 +164,7 @@
{{ data.name }}
</template>
<template #filter="{ filterModel, filterCallback }">
<InputText type="text" v-model="filterModel.value" @keydown.enter="filterCallback()" class="p-column-filter" :placeholder="`Search by name - ${filterModel.matchMode}`" v-tooltip.top.focus="'Hit enter key to filter'" />
<InputText v-model="filterModel.value" v-tooltip.top.focus="'Hit enter key to filter'" type="text" @keydown.enter="filterCallback()" class="p-column-filter" :placeholder="`Search by name - ${filterModel.matchMode}`" />
</template>
</Column>
<Column header="Country" filterField="country.name" style="min-width: 12rem">
@ -173,19 +173,19 @@
<span class="image-text">{{ data.country.name }}</span>
</template>
<template #filter="{ filterModel, filterCallback }">
<InputText type="text" v-model="filterModel.value" @input="filterCallback()" class="p-column-filter" placeholder="Search by country" v-tooltip.top.focus="'Filter as you type'" />
<InputText v-model="filterModel.value" v-tooltip.top.focus="'Filter as you type'" type="text" @input="filterCallback()" class="p-column-filter" placeholder="Search by country" />
</template>
</Column>
<Column header="Agent" filterField="representative" :showFilterMenu="false" style="min-width: 14rem">
<template #body="{ data }">
<img :alt="data.representative.name" :src="'/demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" />
<img :alt="data.representative.name" :src="'demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{ data.representative.name }}</span>
</template>
<template #filter="{ filterModel, filterCallback }">
<MultiSelect v-model="filterModel.value" @change="filterCallback()" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter">
<template #option="slotProps">
<div class="p-multiselect-representative-option">
<img :alt="slotProps.option.name" :src="'/demo/images/avatar/' + slotProps.option.image" width="32" style="vertical-align: middle" />
<img :alt="slotProps.option.name" :src="'demo/images/avatar/' + slotProps.option.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{ slotProps.option.name }}</span>
</div>
</template>
@ -199,7 +199,7 @@
<template #filter="{ filterModel, filterCallback }">
<Dropdown v-model="filterModel.value" @change="filterCallback()" :options="statuses" placeholder="Any" class="p-column-filter" :showClear="true">
<template #value="slotProps">
<span :class="'customer-badge status-' + slotProps.value" v-if="slotProps.value">{{ slotProps.value }}</span>
<span v-if="slotProps.value" :class="'customer-badge status-' + slotProps.value">{{ slotProps.value }}</span>
<span v-else>{{ slotProps.placeholder }}</span>
</template>
<template #option="slotProps">
@ -220,15 +220,13 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableFilterDemo" :sources="sources" :service="['CustomerService']" :data="['customers-large']" github="datatable/DataTableFilterDemo.vue" />
</ClientOnly>
</div>
</template>
<script>
import CustomerService from '../../service/CustomerService';
import { FilterMatchMode, FilterOperator } from 'primevue/api';
import CustomerService from '../../service/CustomerService';
export default {
data() {
@ -367,7 +365,7 @@ export default {
</template>
<template #filter={filterModel}>
<Slider v-model="filterModel.value" range class="m-3"></Slider>
<div class="flex align-items-center justify-content-center px-2">
<div class="flex align-items-center justify-content-between px-2">
<span>{{filterModel.value ? filterModel.value[0] : 0}}</span>
<span>{{filterModel.value ? filterModel.value[1] : 100}}</span>
</div>
@ -708,7 +706,7 @@ export default {
</template>
<template #filter={filterModel}>
<Slider v-model="filterModel.value" range class="m-3"></Slider>
<div class="flex align-items-center justify-content-center px-2">
<div class="flex align-items-center justify-content-between px-2">
<span>{{filterModel.value ? filterModel.value[0] : 0}}</span>
<span>{{filterModel.value ? filterModel.value[1] : 100}}</span>
</div>
@ -1063,7 +1061,7 @@ export default {
</template>
<template #filter={filterModel}>
<p-slider v-model="filterModel.value" range class="m-3"></p-slider>
<div class="flex align-items-center justify-content-center px-2">
<div class="flex align-items-center justify-content-between px-2">
<span>{{filterModel.value ? filterModel.value[0] : 0}}</span>
<span>{{filterModel.value ? filterModel.value[1] : 100}}</span>
</div>

View File

@ -17,9 +17,7 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableFlexScrollDemo" :sources="sources" :service="['CustomerService']" :data="['customers-large']" github="datatable/DataTableFlexScrollDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -21,9 +21,7 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableGridLinesDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="datatable/DataTableGridLinesDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -16,12 +16,13 @@
<div class="content-section implementation">
<div class="card">
<DataTable
ref="dt"
v-model:filters="filters"
v-model:selection="selectedCustomers"
:value="customers"
:lazy="true"
:paginator="true"
:rows="10"
v-model:filters="filters"
ref="dt"
dataKey="id"
:totalRecords="totalRecords"
:loading="loading"
@ -31,40 +32,37 @@
filterDisplay="row"
:globalFilterFields="['name', 'country.name', 'company', 'representative.name']"
responsiveLayout="scroll"
v-model:selection="selectedCustomers"
:selectAll="selectAll"
@select-all-change="onSelectAllChange"
@row-select="onRowSelect"
@row-unselect="onRowUnselect"
>
<Column selectionMode="multiple" headerStyle="width: 3em"></Column>
<Column field="name" header="Name" filterMatchMode="startsWith" ref="name" :sortable="true">
<Column ref="name" field="name" header="Name" filterMatchMode="startsWith" :sortable="true">
<template #filter="{ filterModel, filterCallback }">
<InputText type="text" v-model="filterModel.value" @keydown.enter="filterCallback()" class="p-column-filter" placeholder="Search by name" />
<InputText v-model="filterModel.value" type="text" @keydown.enter="filterCallback()" class="p-column-filter" placeholder="Search by name" />
</template>
</Column>
<Column field="country.name" header="Country" filterField="country.name" filterMatchMode="contains" ref="country.name" :sortable="true">
<Column ref="country.name" field="country.name" header="Country" filterField="country.name" filterMatchMode="contains" :sortable="true">
<template #filter="{ filterModel, filterCallback }">
<InputText type="text" v-model="filterModel.value" @keydown.enter="filterCallback()" class="p-column-filter" placeholder="Search by country" />
<InputText v-model="filterModel.value" type="text" @keydown.enter="filterCallback()" class="p-column-filter" placeholder="Search by country" />
</template>
</Column>
<Column field="company" header="Company" filterMatchMode="contains" ref="company" :sortable="true">
<Column ref="company" field="company" header="Company" filterMatchMode="contains" :sortable="true">
<template #filter="{ filterModel, filterCallback }">
<InputText type="text" v-model="filterModel.value" @keydown.enter="filterCallback()" class="p-column-filter" placeholder="Search by company" />
<InputText v-model="filterModel.value" type="text" @keydown.enter="filterCallback()" class="p-column-filter" placeholder="Search by company" />
</template>
</Column>
<Column field="representative.name" header="Representative" filterField="representative.name" ref="representative.name" :sortable="true">
<Column ref="representative.name" field="representative.name" header="Representative" filterField="representative.name" :sortable="true">
<template #filter="{ filterModel, filterCallback }">
<InputText type="text" v-model="filterModel.value" @keydown.enter="filterCallback()" class="p-column-filter" placeholder="Search by representative" />
<InputText v-model="filterModel.value" type="text" @keydown.enter="filterCallback()" class="p-column-filter" placeholder="Search by representative" />
</template>
</Column>
</DataTable>
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableLazyDemo" :sources="sources" :service="['CustomerService']" github="datatable/DataTableLazyDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<div>
<div class="content-section introduction">
<div class="feature-intro">
@ -11,6 +10,7 @@
<div class="content-section implementation">
<div class="card">
<h5>Basic</h5>
<DataTable
:value="customers"
:paginator="true"
@ -32,10 +32,39 @@
</template>
</DataTable>
</div>
<div class="card">
<h5>Responsive Paginator</h5>
<DataTable
:value="customers"
:paginator="true"
:rows="10"
:paginatorTemplate="{
'640px': 'PrevPageLink CurrentPageReport NextPageLink',
'960px': 'FirstPageLink PrevPageLink CurrentPageReport NextPageLink LastPageLink',
'1300px': 'FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink',
default: 'FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink JumpToPageDropdown'
}"
:rowsPerPageOptions="[10, 20, 50]"
responsiveLayout="scroll"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords}"
>
<Column field="name" header="Name"></Column>
<Column field="country.name" header="Country"></Column>
<Column field="company" header="Company"></Column>
<Column field="representative.name" header="Representative"></Column>
<template #paginatorstart>
<Button type="button" icon="pi pi-refresh" class="p-button-text" />
</template>
<template #paginatorend>
<Button type="button" icon="pi pi-cloud" class="p-button-text" />
</template>
</DataTable>
</div>
</div>
<AppDoc name="DataTablePaginatorDemo" :sources="sources" :service="['CustomerService']" :data="['customers-large']" github="datatable/DataTablePaginatorDemo.vue" />
</div>
</ClientOnly>
</template>
<script>
@ -66,6 +95,31 @@ export default {
<Button type="button" icon="pi pi-cloud" class="p-button-text" />
</template>
</DataTable>
<DataTable
:value="customers"
:paginator="true"
:rows="10"
:paginatorTemplate="{
'640px': 'PrevPageLink CurrentPageReport NextPageLink',
'960px': 'FirstPageLink PrevPageLink CurrentPageReport NextPageLink LastPageLink',
'1300px': 'FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink',
default: 'FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink JumpToPageDropdown'
}"
responsiveLayout="scroll"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords}"
>
<Column field="name" header="Name"></Column>
<Column field="country.name" header="Country"></Column>
<Column field="company" header="Company"></Column>
<Column field="representative.name" header="Representative"></Column>
<template #paginatorstart>
<Button type="button" icon="pi pi-refresh" class="p-button-text" />
</template>
<template #paginatorend>
<Button type="button" icon="pi pi-cloud" class="p-button-text" />
</template>
</DataTable>
</div>
</template>
@ -109,6 +163,31 @@ export default {
<Button type="button" icon="pi pi-cloud" class="p-button-text" />
</template>
</DataTable>
<DataTable
:value="customers"
:paginator="true"
:rows="10"
:paginatorTemplate="{
'640px': 'PrevPageLink CurrentPageReport NextPageLink',
'960px': 'FirstPageLink PrevPageLink CurrentPageReport NextPageLink LastPageLink',
'1300px': 'FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink',
default: 'FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink JumpToPageDropdown'
}"
responsiveLayout="scroll"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords}"
>
<Column field="name" header="Name"></Column>
<Column field="country.name" header="Country"></Column>
<Column field="company" header="Company"></Column>
<Column field="representative.name" header="Representative"></Column>
<template #paginatorstart>
<Button type="button" icon="pi pi-refresh" class="p-button-text" />
</template>
<template #paginatorend>
<Button type="button" icon="pi pi-cloud" class="p-button-text" />
</template>
</DataTable>
</div>
</template>
@ -152,6 +231,31 @@ export default {
<p-button type="button" icon="pi pi-cloud" class="p-button-text"></p-button>
</template>
</p-datatable>
<p-datatable
:value="customers"
:paginator="true"
:rows="10"
:paginatorTemplate="{
'640px': 'PrevPageLink CurrentPageReport NextPageLink',
'960px': 'FirstPageLink PrevPageLink CurrentPageReport NextPageLink LastPageLink',
'1300px': 'FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink',
default: 'FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink JumpToPageDropdown'
}"
responsiveLayout="scroll"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords}"
>
<Column field="name" header="Name"></Column>
<Column field="country.name" header="Country"></Column>
<Column field="company" header="Company"></Column>
<Column field="representative.name" header="Representative"></Column>
<template #paginatorstart>
<Button type="button" icon="pi pi-refresh" class="p-button-text" />
</template>
<template #paginatorend>
<Button type="button" icon="pi pi-cloud" class="p-button-text" />
</template>
</p-datatable>
</div>
<script type="module">

View File

@ -12,14 +12,12 @@
<div class="card">
<DataTable :value="products" :reorderableColumns="true" @column-reorder="onColReorder" @row-reorder="onRowReorder" responsiveLayout="scroll">
<Column :rowReorder="true" headerStyle="width: 3rem" :reorderableColumn="false" />
<Column v-for="col of columns" :field="col.field" :header="col.header" :key="col.field"></Column>
<Column v-for="col of columns" :key="col.field" :field="col.field" :header="col.header"></Column>
</DataTable>
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableReorderDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="datatable/DataTableReorderDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -50,9 +50,7 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableResponsiveDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="datatable/DataTableResponsiveDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -10,7 +10,7 @@
<div class="content-section implementation">
<div class="card">
<DataTable :value="products" v-model:expandedRows="expandedRows" dataKey="id" @row-expand="onRowExpand" @row-collapse="onRowCollapse" responsiveLayout="scroll">
<DataTable v-model:expandedRows="expandedRows" :value="products" dataKey="id" @row-expand="onRowExpand" @row-collapse="onRowCollapse" responsiveLayout="scroll">
<template #header>
<div class="table-header-container">
<Button icon="pi pi-plus" label="Expand All" @click="expandAll" class="mr-2" />
@ -21,7 +21,7 @@
<Column field="name" header="Name" sortable></Column>
<Column header="Image">
<template #body="slotProps">
<img :src="'/demo/images/product/' + slotProps.data.image" :alt="slotProps.data.image" class="product-image" />
<img :src="'demo/images/product/' + slotProps.data.image" :alt="slotProps.data.image" class="product-image" />
</template>
</Column>
<Column field="price" header="Price" sortable>
@ -69,9 +69,7 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableRowExpandDemo" :sources="sources" :service="['ProductService']" :data="['products-orders-small']" github="datatable/DataTableRowExpandDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -29,7 +29,7 @@
</Column>
<Column field="date" header="Date" style="min-width: 200px"></Column>
<template #groupheader="slotProps">
<img :alt="slotProps.data.representative.name" :src="'/demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" />
<img :alt="slotProps.data.representative.name" :src="'demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{ slotProps.data.representative.name }}</span>
</template>
<template #groupfooter="slotProps">
@ -45,6 +45,7 @@
<h5>Expandable Row Groups</h5>
<p>Group customers by their representative.</p>
<DataTable
v-model:expandedRowGroups="expandedRowGroups"
:value="customers"
rowGroupMode="subheader"
groupRowsBy="representative.name"
@ -53,7 +54,6 @@
:sortOrder="1"
responsiveLayout="scroll"
:expandableRowGroups="true"
v-model:expandedRowGroups="expandedRowGroups"
@rowgroup-expand="onRowGroupExpand"
@rowgroup-collapse="onRowGroupCollapse"
>
@ -73,7 +73,7 @@
</Column>
<Column field="date" header="Date"></Column>
<template #groupheader="slotProps">
<img :alt="slotProps.data.representative.name" :src="'/demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" />
<img :alt="slotProps.data.representative.name" :src="'demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{ slotProps.data.representative.name }}</span>
</template>
<template #groupfooter="slotProps">
@ -93,7 +93,7 @@
</Column>
<Column field="representative.name" header="Representative">
<template #body="slotProps">
<img :alt="slotProps.data.representative.name" :src="'/demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" />
<img :alt="slotProps.data.representative.name" :src="'demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{ slotProps.data.representative.name }}</span>
</template>
</Column>
@ -115,9 +115,7 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableRowGroupDemo" :sources="sources" :service="['CustomerService']" :data="['customers-medium']" github="datatable/DataTableRowGroupDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -29,7 +29,7 @@
<Button label="Show" icon="pi pi-external-link" @click="openDialog" />
</div>
<Dialog header="Flex Scroll" v-model:visible="dialogVisible" :style="{ width: '75vw' }" :maximizable="true" :modal="true" :contentStyle="{ height: '300px' }">
<Dialog v-model:visible="dialogVisible" header="Flex Scroll" :style="{ width: '75vw' }" :maximizable="true" :modal="true" :contentStyle="{ height: '300px' }">
<DataTable :value="customers1" :scrollable="true" scrollHeight="flex">
<Column field="name" header="Name" style="min-width: 200px"></Column>
<Column field="country.name" header="Country" style="min-width: 200px"></Column>
@ -116,7 +116,7 @@
</Column>
<Column field="date" header="Date" style="min-width: 200px"></Column>
<template #groupheader="slotProps">
<img :alt="slotProps.data.representative.name" :src="'/demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" />
<img :alt="slotProps.data.representative.name" :src="'demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{ slotProps.data.representative.name }}</span>
</template>
<template #groupfooter="slotProps">
@ -126,9 +126,7 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableScrollDemo" :sources="sources" :service="['CustomerService']" :data="['customers-medium', 'customers-large']" github="datatable/DataTableScrollDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -12,7 +12,7 @@
<div class="card">
<h5>Single</h5>
<p>In single mode, a row is selected on click event of a row. If the row is already selected then the row gets unselected.</p>
<DataTable :value="products" v-model:selection="selectedProduct1" selectionMode="single" dataKey="id" responsiveLayout="scroll">
<DataTable v-model:selection="selectedProduct1" :value="products" selectionMode="single" dataKey="id" responsiveLayout="scroll">
<Column field="code" header="Code"></Column>
<Column field="name" header="Name"></Column>
<Column field="category" header="Category"></Column>
@ -26,7 +26,7 @@
In multiple mode, selection binding should be an array. For touch enabled devices, selection is managed by tapping and for other devices metakey or shiftkey are required. Setting metaKeySelection property as false enables multiple
selection without meta key.
</p>
<DataTable :value="products" v-model:selection="selectedProducts1" selectionMode="multiple" dataKey="id" responsiveLayout="scroll">
<DataTable v-model:selection="selectedProducts1" :value="products" selectionMode="multiple" dataKey="id" responsiveLayout="scroll">
<template #header> Multiple Selection with MetaKey </template>
<Column field="code" header="Code"></Column>
<Column field="name" header="Name"></Column>
@ -34,7 +34,7 @@
<Column field="quantity" header="Quantity"></Column>
</DataTable>
<DataTable :value="products" v-model:selection="selectedProducts2" selectionMode="multiple" dataKey="id" :metaKeySelection="false" style="margin-top: 2em" responsiveLayout="scroll">
<DataTable v-model:selection="selectedProducts2" :value="products" selectionMode="multiple" dataKey="id" :metaKeySelection="false" style="margin-top: 2em" responsiveLayout="scroll">
<template #header> Multiple Selection without MetaKey </template>
<Column field="code" header="Code"></Column>
<Column field="name" header="Name"></Column>
@ -46,7 +46,7 @@
<div class="card">
<h5>Events</h5>
<p>row-select and row-unselects are available as selection events.</p>
<DataTable :value="products" v-model:selection="selectedProduct2" selectionMode="single" dataKey="id" @row-select="onRowSelect" @row-unselect="onRowUnselect" responsiveLayout="scroll">
<DataTable v-model:selection="selectedProduct2" :value="products" selectionMode="single" dataKey="id" :metaKeySelection="false" @row-select="onRowSelect" @row-unselect="onRowUnselect" responsiveLayout="scroll">
<Column field="code" header="Code"></Column>
<Column field="name" header="Name"></Column>
<Column field="category" header="Category"></Column>
@ -57,7 +57,7 @@
<div class="card">
<h5>RadioButton</h5>
<p>Single selection can also be handled using radio buttons by enabling the selectionMode property of column as "single".</p>
<DataTable :value="products" v-model:selection="selectedProduct3" dataKey="id" responsiveLayout="scroll">
<DataTable v-model:selection="selectedProduct3" :value="products" dataKey="id" responsiveLayout="scroll">
<Column selectionMode="single" headerStyle="width: 3em"></Column>
<Column field="code" header="Code"></Column>
<Column field="name" header="Name"></Column>
@ -69,7 +69,7 @@
<div class="card">
<h5>Checkbox</h5>
<DataTable :value="products" v-model:selection="selectedProducts3" dataKey="id" responsiveLayout="scroll">
<DataTable v-model:selection="selectedProducts3" :value="products" dataKey="id" responsiveLayout="scroll">
<Column selectionMode="multiple" headerStyle="width: 3em"></Column>
<Column field="code" header="Code"></Column>
<Column field="name" header="Name"></Column>
@ -79,9 +79,7 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableSelectionDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="datatable/DataTableSelectionDemo.vue" />
</ClientOnly>
</div>
</template>
@ -141,7 +139,7 @@ export default {
<div class="card">
<h5>Events</h5>
<DataTable :value="products" v-model:selection="selectedProduct2" selectionMode="single" dataKey="id"
<DataTable :value="products" v-model:selection="selectedProduct2" selectionMode="single" dataKey="id" :metaKeySelection="false"
@rowSelect="onRowSelect" @rowUnselect="onRowUnselect" responsiveLayout="scroll">
<Column field="code" header="Code"></Column>
<Column field="name" header="Name"></Column>
@ -251,7 +249,7 @@ export default {
<div class="card">
<h5>Events</h5>
<DataTable :value="products" v-model:selection="selectedProduct2" selectionMode="single" dataKey="id"
<DataTable :value="products" v-model:selection="selectedProduct2" selectionMode="single" dataKey="id" :metaKeySelection="false"
@rowSelect="onRowSelect" @rowUnselect="onRowUnselect" responsiveLayout="scroll">
<Column field="code" header="Code"></Column>
<Column field="name" header="Name"></Column>
@ -365,7 +363,7 @@ export default {
<div class="card">
<h5>Events</h5>
<p-datatable :value="products" v-model:selection="selectedProduct2" selection-mode="single" dataKey="id"
<p-datatable :value="products" v-model:selection="selectedProduct2" selection-mode="single" data-key="id" :meta-key-selection="false"
@row-select="onRowSelect" @row-unselect="onRowUnselect" responsive-layout="scroll">
<p-column field="code" header="Code"></p-column>
<p-column field="name" header="Name"></p-column>

View File

@ -40,9 +40,7 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableSizeDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="datatable/DataTableSizeDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -71,9 +71,7 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableSortDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="datatable/DataTableSortDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -12,11 +12,11 @@
<div class="card">
<h5>Session Storage</h5>
<DataTable
v-model:filters="filters1"
v-model:selection="selectedCustomer1"
:value="customers"
:paginator="true"
:rows="10"
v-model:filters="filters1"
v-model:selection="selectedCustomer1"
selectionMode="single"
dataKey="id"
stateStorage="session"
@ -31,7 +31,7 @@
</template>
<Column field="name" header="Name" :sortable="true" style="width: 25%">
<template #filter>
<InputText type="text" v-model="filters1['name']" class="p-column-filter" placeholder="Search by name" />
<InputText v-model="filters1['name']" type="text" class="p-column-filter" placeholder="Search by name" />
</template>
</Column>
<Column header="Country" :sortable="true" sortField="country.name" filterField="country.name" filterMatchMode="contains" style="width: 25%">
@ -40,19 +40,19 @@
<span class="image-text">{{ slotProps.data.country.name }}</span>
</template>
<template #filter>
<InputText type="text" v-model="filters1['country.name']" class="p-column-filter" placeholder="Search by country" />
<InputText v-model="filters1['country.name']" type="text" class="p-column-filter" placeholder="Search by country" />
</template>
</Column>
<Column header="Representative" :sortable="true" sortField="representative.name" filterField="representative.name" filterMatchMode="in" style="width: 25%">
<template #body="slotProps">
<img :alt="slotProps.data.representative.name" :src="'/demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" />
<img :alt="slotProps.data.representative.name" :src="'demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{ slotProps.data.representative.name }}</span>
</template>
<template #filter>
<MultiSelect v-model="filters1['representative.name']" :options="representatives" optionLabel="name" optionValue="name" placeholder="All" class="p-column-filter">
<template #option="slotProps">
<div class="p-multiselect-representative-option">
<img :alt="slotProps.option.name" :src="'/demo/images/avatar/' + slotProps.option.image" width="32" style="vertical-align: middle" />
<img :alt="slotProps.option.name" :src="'demo/images/avatar/' + slotProps.option.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{ slotProps.option.name }}</span>
</div>
</template>
@ -78,11 +78,11 @@
<div class="card">
<h5>Local Storage</h5>
<DataTable
v-model:filters="filters2"
v-model:selection="selectedCustomer2"
:value="customers"
:paginator="true"
:rows="10"
v-model:filters="filters2"
v-model:selection="selectedCustomer2"
selectionMode="single"
dataKey="id"
stateStorage="local"
@ -97,7 +97,7 @@
</template>
<Column field="name" header="Name" :sortable="true" style="width: 25%">
<template #filter>
<InputText type="text" v-model="filters2['name']" class="p-column-filter" placeholder="Search by name" />
<InputText v-model="filters2['name']" type="text" class="p-column-filter" placeholder="Search by name" />
</template>
</Column>
<Column header="Country" :sortable="true" sortField="country.name" filterField="country.name" filterMatchMode="contains" style="width: 25%">
@ -106,19 +106,19 @@
<span class="image-text">{{ slotProps.data.country.name }}</span>
</template>
<template #filter>
<InputText type="text" v-model="filters2['country.name']" class="p-column-filter" placeholder="Search by country" />
<InputText v-model="filters2['country.name']" type="text" class="p-column-filter" placeholder="Search by country" />
</template>
</Column>
<Column header="Representative" :sortable="true" sortField="representative.name" filterField="representative.name" filterMatchMode="in" style="width: 25%">
<template #body="slotProps">
<img :alt="slotProps.data.representative.name" :src="'/demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" />
<img :alt="slotProps.data.representative.name" :src="'demo/images/avatar/' + slotProps.data.representative.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{ slotProps.data.representative.name }}</span>
</template>
<template #filter>
<MultiSelect v-model="filters2['representative.name']" :options="representatives" optionLabel="name" optionValue="name" placeholder="All" class="p-column-filter">
<template #option="slotProps">
<div class="p-multiselect-representative-option">
<img :alt="slotProps.option.name" :src="'/demo/images/avatar/' + slotProps.option.image" width="32" style="vertical-align: middle" />
<img :alt="slotProps.option.name" :src="'demo/images/avatar/' + slotProps.option.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{ slotProps.option.name }}</span>
</div>
</template>
@ -142,9 +142,7 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableStateDemo" :sources="sources" :service="['CustomerService']" :data="['customers-medium']" github="datatable/DataTableStateDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -19,9 +19,7 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableStripedDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="datatable/DataTableStripedDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -25,9 +25,7 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableStyleDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="datatable/DataTableStyleDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -20,7 +20,7 @@
<Column field="name" header="Name"></Column>
<Column header="Image">
<template #body="slotProps">
<img :src="'/demo/images/product/' + slotProps.data.image" :alt="slotProps.data.image" class="product-image" />
<img :src="'demo/images/product/' + slotProps.data.image" :alt="slotProps.data.image" class="product-image" />
</template>
</Column>
<Column field="price" header="Price">
@ -43,9 +43,7 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableTemplatingDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="datatable/DataTableTemplatingDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -61,9 +61,7 @@
</div>
</div>
<ClientOnly>
<AppDoc name="DataTableVirtualScrollDemo" :sources="sources" :service="['CarService']" github="datatable/DataTableVirtualScrollDemo.vue" />
</ClientOnly>
</div>
</template>

View File

@ -11,14 +11,14 @@
<div class="content-section implementation">
<div class="card">
<DataTable
v-model:selection="selectedCustomers"
v-model:filters="filters"
:value="customers"
:paginator="true"
class="p-datatable-customers"
:rows="10"
dataKey="id"
:rowHover="true"
v-model:selection="selectedCustomers"
v-model:filters="filters"
filterDisplay="menu"
:loading="loading"
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
@ -44,7 +44,7 @@
{{ data.name }}
</template>
<template #filter="{ filterModel }">
<InputText type="text" v-model="filterModel.value" class="p-column-filter" placeholder="Search by name" />
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by name" />
</template>
</Column>
<Column field="country.name" header="Country" sortable filterMatchMode="contains" style="min-width: 14rem">
@ -53,12 +53,12 @@
<span class="image-text">{{ data.country.name }}</span>
</template>
<template #filter="{ filterModel }">
<InputText type="text" v-model="filterModel.value" class="p-column-filter" placeholder="Search by country" />
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by country" />
</template>
</Column>
<Column header="Agent" sortable filterField="representative" sortField="representative.name" :showFilterMatchModes="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 14rem">
<template #body="{ data }">
<img :alt="data.representative.name" :src="'/demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" />
<img :alt="data.representative.name" :src="'demo/images/avatar/' + data.representative.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{ data.representative.name }}</span>
</template>
<template #filter="{ filterModel }">
@ -66,7 +66,7 @@
<MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter">
<template #option="slotProps">
<div class="p-multiselect-representative-option">
<img :alt="slotProps.option.name" :src="'/demo/images/avatar/' + slotProps.option.image" width="32" style="vertical-align: middle" />
<img :alt="slotProps.option.name" :src="'demo/images/avatar/' + slotProps.option.image" width="32" style="vertical-align: middle" />
<span class="image-text">{{ slotProps.option.name }}</span>
</div>
</template>
@ -130,8 +130,8 @@
</template>
<script>
import CustomerService from '../../service/CustomerService';
import { FilterMatchMode, FilterOperator } from 'primevue/api';
import CustomerService from '../../service/CustomerService';
import DataTableDoc from './DataTableDoc';
export default {

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="DataViewDemo" :sources="sources" :service="['ProductService']" :data="['products']" github="dataview/DataViewDemo.vue">
<h5>Import via Module</h5>
@ -49,7 +48,7 @@ export default {
&lt;div class="col-12"&gt;
&lt;div class="car-details"&gt;
&lt;div&gt;
&lt;img :src="'/demo/images/car/' + slotProps.data.brand + '.png'" :alt="slotProps.data.brand"/&gt;
&lt;img :src="'demo/images/car/' + slotProps.data.brand + '.png'" :alt="slotProps.data.brand"/&gt;
&lt;div class="grid"&gt;
&lt;div class="col-12"&gt;Vin: &lt;b&gt;&#123;&#123;slotProps.data.vin&#125;&#125;&lt;/b&gt;&lt;/div&gt;
&lt;div class="col-12"&gt;Year: &lt;b&gt;&#123;&#123;slotProps.data.year&#125;&#125;&lt;/b&gt;&lt;/div&gt;
@ -64,7 +63,7 @@ export default {
&lt;template #grid="slotProps"&gt;
&lt;div style="padding: .5em" class="col-12 md:col-3"&gt;
&lt;Panel :header="slotProps.data.vin" style="text-align: center"&gt;
&lt;img :src="'/demo/images/car/' + slotProps.data.brand + '.png'" :alt="slotProps.data.brand"/&gt;
&lt;img :src="'demo/images/car/' + slotProps.data.brand + '.png'" :alt="slotProps.data.brand"/&gt;
&lt;div class="car-detail"&gt;{{slotProps.data.year}} - {{slotProps.data.color}}&lt;/div&gt;
&lt;Button icon="pi pi-search"&gt;&lt;/Button&gt;
&lt;/Panel&gt;
@ -90,8 +89,8 @@ export default {
<h5>DataViewLayoutOptions</h5>
<p>
When both layout modes are enabled in DataView, a UI element would be necessary to let the user toggle between the view. DataViewLayoutOptions is a helper component to display a buttonset to choose the layout mode in DataView.
Location of the DataViewLayoutOptions should be inside the DataView component. If you prefer a different UI element you can create your own that updates the layout property of the DataView.
When both layout modes are enabled in DataView, a UI element would be necessary to let the user toggle between the view. DataViewLayoutOptions is a helper component to display a buttonset to choose the layout mode in DataView. Location of
the DataViewLayoutOptions should be inside the DataView component. If you prefer a different UI element you can create your own that updates the layout property of the DataView.
</p>
<pre v-code><code><template v-pre>
@ -205,8 +204,8 @@ export default {
<h5>Lazy Loading</h5>
<p>
Lazy loading is useful to deal with huge datasets, in order to implement lazy loading use the pagination and utilize the <i>page</i> callback to load your data from the backend. Pagination in this case needs to display the logical
number of records bound to the <i>totalRecords</i> property so that paginator can display itself according to the total records although you'd only need to load the data of the current page.
Lazy loading is useful to deal with huge datasets, in order to implement lazy loading use the pagination and utilize the <i>page</i> callback to load your data from the backend. Pagination in this case needs to display the logical number
of records bound to the <i>totalRecords</i> property so that paginator can display itself according to the total records although you'd only need to load the data of the current page.
</p>
<pre v-code><code><template v-pre>
&lt;DataView :value="cars" :layout="layout" :paginator="true" :rows="20" :lazy="true" @page="onPage($event)"&gt;
@ -305,7 +304,7 @@ export default {
<td>paginatorTemplate</td>
<td>string</td>
<td>FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdown</td>
<td>Template of the paginator. See the <nuxt-link to="/paginator">Paginator</nuxt-link> for all available options.</td>
<td>Template of the paginator. See the <router-link to="/paginator">Paginator</router-link> for all available options.</td>
</tr>
<tr>
<td>pageLinkSize</td>
@ -427,7 +426,7 @@ export default {
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -469,10 +468,44 @@ export default {
</table>
</div>
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
The container element that wraps the layout options buttons has a <i>group</i> role whereas each button element uses <i>button</i> role and <i>aria-pressed</i> is updated depending on selection state. Values to describe the buttons are
derived from the <i>aria.listView</i> and <i>aria.gridView</i> properties of the <router-link to="/locale">locale</router-link> API respectively.
</p>
<p>Refer to <router-link to="/paginator">paginator</router-link> accessibility documentation for the paginator of the component.</p>
<h6>Keyboard Support</h6>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<i>tab</i>
</td>
<td>Moves focus to the buttons.</td>
</tr>
<tr>
<td>
<i>space</i>
</td>
<td>Toggles the checked state of a button.</td>
</tr>
</tbody>
</table>
</div>
<h5>Dependencies</h5>
<p>PrimeFlex</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -25,7 +25,7 @@
<template #list="slotProps">
<div class="col-12">
<div class="product-list-item">
<img :src="'/demo/images/product/' + slotProps.data.image" :alt="slotProps.data.name" />
<img :src="'demo/images/product/' + slotProps.data.image" :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>
@ -52,7 +52,7 @@
<span :class="'product-badge status-' + slotProps.data.inventoryStatus.toLowerCase()">{{ slotProps.data.inventoryStatus }}</span>
</div>
<div class="product-grid-item-content">
<img :src="'/demo/images/product/' + slotProps.data.image" :alt="slotProps.data.name" />
<img :src="'demo/images/product/' + slotProps.data.image" :alt="slotProps.data.name" />
<div class="product-name">{{ slotProps.data.name }}</div>
<div class="product-description">{{ slotProps.data.description }}</div>
<Rating :modelValue="slotProps.data.rating" :readonly="true" :cancel="false"></Rating>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="DeferredContentDemo" :sources="sources" :service="['ProductService']" :data="['products-small']" github="deferredcontent/DeferredContentDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -69,11 +68,10 @@ import DeferredContent from 'primevue/deferredcontent';
<p>Component does not apply any styling.</p>
<h5>Accessibility</h5>
<DevelopmentSection>
<h6>Screen Reader</h6>
<p>
DeferredContent can be utilized in many use cases as a result no role is enforced, in fact a role may not be necessary if the card is used for presentational purposes only. Any valid attribute is passed to the container element so
you have full control over the roles like <a href="https://www.w3.org/TR/wai-aria/#landmark" alt="Landmark Roles">landmark</a> and attributes like <i>aria-live</i>.
DeferredContent can be utilized in many use cases as a result no role is enforced, in fact a role may not be necessary if the card is used for presentational purposes only. Any valid attribute is passed to the container element so you
have full control over the roles like <a href="https://www.w3.org/TR/wai-aria/#landmark" alt="Landmark Roles">landmark</a> and attributes like <i>aria-live</i>.
</p>
<pre v-code><code>
@ -85,12 +83,10 @@ import DeferredContent from 'primevue/deferredcontent';
<h5>Keyboard Support</h5>
<p>Component does not include any interactive elements.</p>
</DevelopmentSection>
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -13,7 +13,7 @@
<div style="height: 800px">Scroll down to lazy load an image and the DataTable which initiates a query that is not executed on initial page load to speed up load performance.</div>
<!-- <DeferredContent @load="onImageLoad">
<img src="/demo/images/nature/nature4.jpg" alt="Nature"/>
<img src="demo/images/nature/nature4.jpg" alt="Nature"/>
</DeferredContent> -->
<div style="height: 500px"></div>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="DialogDemo" :sources="sources" github="dialog/DialogDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -159,6 +158,12 @@ export default {
<td>null</td>
<td>Style class of the content section.</td>
</tr>
<tr>
<td>contentProps</td>
<td>null</td>
<td>null</td>
<td>Uses to pass all properties of the HTMLDivElement to the overlay panel inside the component.</td>
</tr>
<tr>
<td>rtl</td>
<td>boolean</td>
@ -190,10 +195,14 @@ export default {
<td>Whether to automatically manage layering.</td>
</tr>
<tr>
<td>ariaCloseLabel</td>
<td style="text-decoration: line-through">ariaCloseLabel</td>
<td>string</td>
<td>close</td>
<td>Aria label of the close icon.</td>
<td>
Aria label of the close icon.
<br />
<b> Deprecated: </b> <i>aria.close</i> can be used in defaults to PrimeVue <router-link to="/locale">Locale</router-link> configuration.
</td>
</tr>
<tr>
<td>maximizable</td>
@ -237,6 +246,24 @@ export default {
<td>body</td>
<td>A valid query selector or an HTMLElement to specify where the dialog gets attached. Special keywords are "body" for document body and "self" for the element itself.</td>
</tr>
<tr>
<td>closeIcon</td>
<td>string</td>
<td>pi pi-times</td>
<td>Icon to display in the dialog close button.</td>
</tr>
<tr>
<td>maximizeIcon</td>
<td>string</td>
<td>pi pi-window-maximize</td>
<td>Icon to display in the dialog maximize button when dialog is not maximized.</td>
</tr>
<tr>
<td>minimizeIcon</td>
<td>string</td>
<td>pi pi-window-minimize</td>
<td>Icon to display in the dialog maximize button when dialog is maximized.</td>
</tr>
</tbody>
</table>
</div>
@ -309,7 +336,7 @@ export default {
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -347,10 +374,86 @@ export default {
</table>
</div>
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
Dialog component uses <i>dialog</i> role along with <i>aria-labelledby</i> referring to the header element however any attribute is passed to the root element so you may use <i>aria-labelledby</i> to override this default behavior. In
addition <i>aria-modal</i> is added since focus is kept within the popup.
</p>
<p>Trigger element also requires <i>aria-expanded</i> and <i>aria-controls</i> to be handled explicitly.</p>
<p>
Close element is a <i>button</i> with an <i>aria-label</i> that refers to the <i>aria.close</i> property of the <router-link to="/locale">locale</router-link> API by default, you may use <i>closeButtonProps</i> to customize the element
and override the default <i>aria-label</i>.
</p>
<pre v-code><code>
&lt;Button label="Show" icon="pi pi-external-link" @click="visible = true" :aria-controls="visible ? 'dlg' : null" :aria-expanded="visible ? true : false" /&gt;
&lt;Dialog id="dlg" header="Header" v-model:visible="visible" :style="{ width: '50vw' }"&gt;
&lt;p&gt;Content&lt;/p&gt;
&lt;/Dialog&gt;
</code></pre>
<h6>Overlay Keyboard Support</h6>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<i>tab</i>
</td>
<td>Moves focus to the next the focusable element within the dialog if <i>modal</i> is true. Otherwise, the focusable element in the page tab sequence.</td>
</tr>
<tr>
<td><i>shift</i> + <i>tab</i></td>
<td>Moves focus to the previous the focusable element within the dialog if <i>modal</i> is true. Otherwise, the focusable element in the page tab sequence.</td>
</tr>
<tr>
<td>
<i>escape</i>
</td>
<td>Closes the dialog if <i>closeOnEscape</i> is true.</td>
</tr>
</tbody>
</table>
</div>
<h6>Close Button Keyboard Support</h6>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<i>enter</i>
</td>
<td>Closes the dialog.</td>
</tr>
<tr>
<td>
<i>space</i>
</td>
<td>Closes the dialog.</td>
</tr>
</tbody>
</table>
</div>
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>
@ -378,20 +481,28 @@ export default {
<Button label="Long Content" icon="pi pi-external-link" @click="openBasic2" />
<Dialog header="Header" v-model:visible="displayBasic2" :breakpoints="{'960px': '75vw', '640px': '90vw'}" :style="{width: '50vw'}">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.</p>
<p>"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae
dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,
qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam,
quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur,
vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?</p>
<p>At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident,
similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio
cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe
eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.</p>
<div v-for="i in 2" :key="i">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
</p>
<br />
<p>
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo
enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet,
consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam,
nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
</p>
<br />
<p>
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in
culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id
quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et
molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
</p>
<br />
</div>
<template #footer>
<Button label="No" icon="pi pi-times" @click="closeBasic2" class="p-button-text"/>
<Button label="Yes" icon="pi pi-check" @click="closeBasic2" autofocus />
@ -581,20 +692,28 @@ p {
<Button label="Long Content" icon="pi pi-external-link" @click="openBasic2" />
<Dialog header="Header" v-model:visible="displayBasic2" :breakpoints="{'960px': '75vw', '640px': '90vw'}" :style="{width: '50vw'}">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.</p>
<p>"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae
dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,
qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam,
quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur,
vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?</p>
<p>At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident,
similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio
cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe
eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.</p>
<div v-for="i in 2" :key="i">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
</p>
<br />
<p>
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo
enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet,
consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam,
nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
</p>
<br />
<p>
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in
culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id
quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et
molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
</p>
<br />
</div>
<template #footer>
<Button label="No" icon="pi pi-times" @click="closeBasic2" class="p-button-text"/>
<Button label="Yes" icon="pi pi-check" @click="closeBasic2" autofocus />
@ -785,20 +904,28 @@ p {
<p-button label="Long Content" icon="pi pi-external-link" @click="openBasic2"></p-button>
<p-dialog header="Header" v-model:visible="displayBasic2" :breakpoints="{'960px': '75vw', '640px': '90vw'}" :style="{width: '50vw'}">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.</p>
<p>"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae
dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,
qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam,
quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur,
vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?</p>
<p>At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident,
similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio
cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe
eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.</p>
<div v-for="i in 2" :key="i">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
</p>
<br />
<p>
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo
enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet,
consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam,
nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
</p>
<br />
<p>
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in
culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id
quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et
molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
</p>
<br />
</div>
<template #footer>
<p-button label="No" icon="pi pi-times" @click="closeBasic2" class="p-button-text"></p-button>
<p-button label="Yes" icon="pi pi-check" @click="closeBasic2" autofocus></p-button>

View File

@ -12,7 +12,7 @@
<div class="card">
<h5>Basic</h5>
<Button label="Show" icon="pi pi-external-link" @click="openBasic" />
<Dialog header="Header" v-model:visible="displayBasic" :breakpoints="{ '960px': '75vw', '640px': '90vw' }" :style="{ width: '50vw' }">
<Dialog v-model:visible="displayBasic" header="Header" :breakpoints="{ '960px': '75vw', '640px': '90vw' }" :style="{ width: '50vw' }">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@ -24,25 +24,29 @@
</Dialog>
<Button label="Long Content" icon="pi pi-external-link" @click="openBasic2" />
<Dialog header="Header" v-model:visible="displayBasic2" :breakpoints="{ '960px': '75vw', '640px': '90vw' }" :style="{ width: '50vw' }">
<Dialog v-model:visible="displayBasic2" header="Header" :breakpoints="{ '960px': '75vw', '640px': '90vw' }" :style="{ width: '50vw' }">
<div v-for="i in 2" :key="i">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
</p>
<br />
<p>
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim
ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur,
adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid
ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo
enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet,
consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam,
nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
</p>
<br />
<p>
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa
qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod
maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae
non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in
culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id
quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et
molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
</p>
<br />
</div>
<template #footer>
<Button label="No" icon="pi pi-times" @click="closeBasic2" class="p-button-text" />
<Button label="Yes" icon="pi pi-check" @click="closeBasic2" autofocus />
@ -51,7 +55,7 @@
<h5>Modal</h5>
<Button label="Show" icon="pi pi-external-link" @click="openModal" />
<Dialog header="Header" v-model:visible="displayModal" :breakpoints="{ '960px': '75vw', '640px': '90vw' }" :style="{ width: '50vw' }" :modal="true">
<Dialog v-model:visible="displayModal" header="Header" :breakpoints="{ '960px': '75vw', '640px': '90vw' }" :style="{ width: '50vw' }" :modal="true">
<p class="m-0">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@ -64,7 +68,7 @@
<h5>Responsive</h5>
<Button label="Show" icon="pi pi-external-link" @click="openResponsive" />
<Dialog header="Header" v-model:visible="displayResponsive" :breakpoints="{ '960px': '75vw', '640px': '90vw' }" :style="{ width: '50vw' }">
<Dialog v-model:visible="displayResponsive" header="Header" :breakpoints="{ '960px': '75vw', '640px': '90vw' }" :style="{ width: '50vw' }">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@ -77,7 +81,7 @@
<h5>Confirmation</h5>
<Button label="Confirm" icon="pi pi-external-link" @click="openConfirmation" />
<Dialog header="Confirmation" v-model:visible="displayConfirmation" :breakpoints="{ '960px': '75vw', '640px': '90vw' }" :style="{ width: '350px' }" :modal="true">
<Dialog v-model:visible="displayConfirmation" header="Confirmation" :breakpoints="{ '960px': '75vw', '640px': '90vw' }" :style="{ width: '350px' }" :modal="true">
<div class="confirmation-content">
<i class="pi pi-exclamation-triangle mr-3" style="font-size: 2rem" />
<span>Are you sure you want to proceed?</span>
@ -90,7 +94,7 @@
<h5>Maximizable</h5>
<Button label="Show" icon="pi pi-external-link" @click="openMaximizable" />
<Dialog header="Header" v-model:visible="displayMaximizable" :breakpoints="{ '960px': '75vw', '640px': '90vw' }" :style="{ width: '50vw' }" :maximizable="true" :modal="true">
<Dialog v-model:visible="displayMaximizable" header="Header" :breakpoints="{ '960px': '75vw', '640px': '90vw' }" :style="{ width: '50vw' }" :maximizable="true" :modal="true">
<p class="m-0">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
@ -119,7 +123,7 @@
</div>
</div>
<Dialog header="Header" v-model:visible="displayPosition" :breakpoints="{ '960px': '75vw', '640px': '90vw' }" :style="{ width: '50vw' }" :position="position" :modal="true">
<Dialog v-model:visible="displayPosition" header="Header" :breakpoints="{ '960px': '75vw', '640px': '90vw' }" :style="{ width: '50vw' }" :position="position" :modal="true">
<p class="m-0">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="DividerDemo" :sources="sources" github="divider/DividerDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -112,7 +111,7 @@ import Divider from 'primevue/divider';
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -171,18 +170,15 @@ import Divider from 'primevue/divider';
</div>
<h5>Accessibility</h5>
<DevelopmentSection>
<h6>Screen Reader</h6>
<p>Divider uses a <i>separator</i> role with <i>aria-orientation</i> set to either "horizontal" or "vertical".</p>
<h5>Keyboard Support</h5>
<p>Component does not include any interactive elements.</p>
</DevelopmentSection>
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="DockDemo" :sources="sources" github="dock/DockDemo.vue" :service="['NodeService', 'PhotoService']" :data="['treenodes', 'photos']">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -29,19 +28,19 @@ import Dock from 'primevue/dock';
items: [
{
label: "Finder",
icon: "/demo/images/dock/finder.svg"
icon: "demo/images/dock/finder.svg"
},
{
label: "App Store",
icon: "/demo/images/dock/appstore.svg"
icon: "demo/images/dock/appstore.svg"
},
{
label: "Photos",
icon: "/demo/images/dock/photos.svg"
icon: "demo/images/dock/photos.svg"
},
{
label: "Trash",
icon: "/demo/images/dock/trash.png"
icon: "demo/images/dock/trash.png"
}
]
}
@ -52,7 +51,7 @@ import Dock from 'primevue/dock';
</code></pre>
<h5>MenuModel API</h5>
<p>Dock uses the common MenuModel API to define the items, visit <nuxt-link to="/menumodel">MenuModel API</nuxt-link> for details.</p>
<p>Dock uses the common MenuModel API to define the items, visit <router-link to="/menumodel">MenuModel API</router-link> for details.</p>
<h5>Properties</h5>
<p>Any property as style and class are passed to the main container element. Following are the additional properties to configure the component.</p>
@ -95,20 +94,57 @@ import Dock from 'primevue/dock';
<td>exact</td>
<td>boolean</td>
<td>true</td>
<td>Whether to apply 'nuxt-link-active-exact' class if route exactly matches the item path.</td>
<td>Whether to apply 'router-link-active-exact' class if route exactly matches the item path.</td>
</tr>
<tr>
<td>tooltipOptions</td>
<td>object</td>
<td>null</td>
<td>Whether to display the tooltip on items. The modifiers of <nuxt-link to="/tooltip">Tooltip</nuxt-link> can be used like an object in it. Valid keys are 'event' and 'position'.</td>
<td>Whether to display the tooltip on items. The modifiers of <router-link to="/tooltip">Tooltip</router-link> can be used like an object in it. Valid keys are 'event' and 'position'.</td>
</tr>
<tr>
<td>menuId</td>
<td>string</td>
<td>null</td>
<td>Unique identifier of the menu.</td>
</tr>
<tr>
<td>tabindex</td>
<td>number</td>
<td>0</td>
<td>Index of the element in tabbing order.</td>
</tr>
</tbody>
</table>
</div>
<h5>Events</h5>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Name</th>
<th>Parameters</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>focus</td>
<td>event</td>
<td>Callback to invoke when the component receives focus.</td>
</tr>
<tr>
<td>blur</td>
<td>event</td>
<td>Callback to invoke when the component loses focus.</td>
</tr>
</tbody>
</table>
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -122,6 +158,10 @@ import Dock from 'primevue/dock';
<td>p-dock</td>
<td>Container element.</td>
</tr>
<tr>
<td>p-dock-list-container</td>
<td>Container of the list.</td>
</tr>
<tr>
<td>p-dock-list</td>
<td>List of items.</td>
@ -130,6 +170,18 @@ import Dock from 'primevue/dock';
<td>p-dock-item</td>
<td>Each items in list.</td>
</tr>
<tr>
<td>p-menuitem-content</td>
<td>Content of menuitem.</td>
</tr>
<tr>
<td>p-dock-link</td>
<td>Link of the menuitem.</td>
</tr>
<tr>
<td>p-dock-icon</td>
<td>Icon of a menuitem.</td>
</tr>
</tbody>
</table>
</div>
@ -146,7 +198,10 @@ import Dock from 'primevue/dock';
<tbody>
<tr>
<td>item</td>
<td>item: Custom content for item</td>
<td>
item: Custom content for menuitem<br />
index: Index of the menuitem
</td>
</tr>
<tr>
<td>icon</td>
@ -156,10 +211,84 @@ import Dock from 'primevue/dock';
</table>
</div>
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
Dock component uses the <i>menu</i> role with the <i>aria-orientation</i> and the value to describe the menu can either be provided with <i>aria-labelledby</i> or <i>aria-label</i> props. Each list item has a <i>menuitem</i> role with
<i>aria-label</i> referring to the label of the item and <i>aria-disabled</i> defined if the item is disabled.
</p>
<h6>Keyboard Support</h6>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<i>tab</i>
</td>
<td>Moves focus to the first menuitem.</td>
</tr>
<tr>
<td>
<i>enter</i>
</td>
<td>Activates the focused menuitem.</td>
</tr>
<tr>
<td>
<i>space</i>
</td>
<td>Activates the focused menuitem.</td>
</tr>
<tr>
<td>
<i>down arrow</i>
</td>
<td>Moves focus to the next menuitem in vertical layout.</td>
</tr>
<tr>
<td>
<i>up arrow</i>
</td>
<td>Moves focus to the previous menuitem in vertical layout.</td>
</tr>
<tr>
<td>
<i>right arrow</i>
</td>
<td>Moves focus to the next menuitem in horizontal layout.</td>
</tr>
<tr>
<td>
<i>left arrow</i>
</td>
<td>Moves focus to the previous menuitem in horizontal layout.</td>
</tr>
<tr>
<td>
<i>home</i>
</td>
<td>Moves focus to the first menuitem.</td>
</tr>
<tr>
<td>
<i>end</i>
</td>
<td>Moves focus to the last menuitem.</td>
</tr>
</tbody>
</table>
</div>
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>
@ -178,22 +307,22 @@ export default {
<h5>Basic</h5>
<div class="dock-window">
<Dock :model="dockBasicItems" position="bottom">
<template #icon="{ item }">
<img :alt="item.label" :src="item.icon" style="width: 100%" />
</template>
</Dock>
<Dock :model="dockBasicItems" position="top">
<template #icon="{ item }">
<img :alt="item.label" :src="item.icon" style="width: 100%" />
</template>
</Dock>
<Dock :model="dockBasicItems" position="left">
<Dock :model="dockBasicItems" position="right">
<template #icon="{ item }">
<img :alt="item.label" :src="item.icon" style="width: 100%" />
</template>
</Dock>
<Dock :model="dockBasicItems" position="right">
<Dock :model="dockBasicItems" position="bottom">
<template #icon="{ item }">
<img :alt="item.label" :src="item.icon" style="width: 100%" />
</template>
</Dock>
<Dock :model="dockBasicItems" position="left">
<template #icon="{ item }">
<img :alt="item.label" :src="item.icon" style="width: 100%" />
</template>
@ -218,7 +347,7 @@ export default {
<div class="dock-window dock-advanced">
<Dock :model="dockItems">
<template #item="{ item }">
<a href="#" class="p-dock-action" v-tooltip.top="item.label" @click="onDockItemClick($event, item)">
<a href="#" class="p-dock-link" v-tooltip.top="item.label" @click="onDockItemClick($event, item)">
<img :alt="item.label" src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" style="width: 100%">
</a>
</template>
@ -260,46 +389,46 @@ export default {
dockItems: [
{
label: 'Finder',
icon: "/demo/images/dock/finder.svg",
icon: "demo/images/dock/finder.svg",
command: () => {
this.displayFinder = true;
}
},
{
label: 'Terminal',
icon: "/demo/images/dock/terminal.svg",
icon: "demo/images/dock/terminal.svg",
command: () => {
this.displayTerminal = true;
}
},
{
label: 'App Store',
icon: "/demo/images/dock/appstore.svg",
icon: "demo/images/dock/appstore.svg",
command: () => {
this.$toast.add({ severity: 'error', summary: 'An unexpected error occurred while signing in.', detail: 'UNTRUSTED_CERT_TITLE', group: 'tc', life: 3000 });
}
},
{
label: 'Safari',
icon: "/demo/images/dock/safari.svg",
icon: "demo/images/dock/safari.svg",
command: () => {
this.$toast.add({ severity: 'warn', summary: 'Safari has stopped working', group: 'tc', life: 3000 });
}
},
{
label: 'Photos',
icon: "/demo/images/dock/photos.svg",
icon: "demo/images/dock/photos.svg",
command: () => {
this.displayPhotos = true;
}
},
{
label: 'GitHub',
icon: "/demo/images/dock/github.svg",
icon: "demo/images/dock/github.svg",
},
{
label: 'Trash',
icon: "/demo/images/dock/trash.png",
icon: "demo/images/dock/trash.png",
command: () => {
this.$toast.add({ severity: 'info', summary: 'Empty Trash', life: 3000 });
}
@ -308,19 +437,19 @@ export default {
dockBasicItems: [
{
label: "Finder",
icon: "/demo/images/dock/finder.svg"
icon: "demo/images/dock/finder.svg"
},
{
label: "App Store",
icon: "/demo/images/dock/appstore.svg"
icon: "demo/images/dock/appstore.svg"
},
{
label: "Photos",
icon: "/demo/images/dock/photos.svg"
icon: "demo/images/dock/photos.svg"
},
{
label: "Trash",
icon: "/demo/images/dock/trash.png"
icon: "demo/images/dock/trash.png"
}
],
menubarItems: [
@ -546,7 +675,7 @@ export default {
padding: 0.5rem .75rem;
}
.p-menubar-root-list > .p-menuitem > .p-menuitem-link {
.p-menubar-root-list > .p-menuitem > .p-menuitem-content > .p-menuitem-link {
padding: 0.5rem .75rem;
> .p-submenu-icon {
@ -579,22 +708,22 @@ export default {
<h5>Basic</h5>
<div class="dock-window">
<Dock :model="dockBasicItems" position="bottom">
<template #icon="{ item }">
<img :alt="item.label" :src="item.icon" style="width: 100%" />
</template>
</Dock>
<Dock :model="dockBasicItems" position="top">
<template #icon="{ item }">
<img :alt="item.label" :src="item.icon" style="width: 100%" />
</template>
</Dock>
<Dock :model="dockBasicItems" position="left">
<Dock :model="dockBasicItems" position="right">
<template #icon="{ item }">
<img :alt="item.label" :src="item.icon" style="width: 100%" />
</template>
</Dock>
<Dock :model="dockBasicItems" position="right">
<Dock :model="dockBasicItems" position="bottom">
<template #icon="{ item }">
<img :alt="item.label" :src="item.icon" style="width: 100%" />
</template>
</Dock>
<Dock :model="dockBasicItems" position="left">
<template #icon="{ item }">
<img :alt="item.label" :src="item.icon" style="width: 100%" />
</template>
@ -619,7 +748,7 @@ export default {
<div class="dock-window dock-advanced">
<Dock :model="dockItems">
<template #item="{ item }">
<a href="#" class="p-dock-action" v-tooltip.top="item.label" @click="onDockItemClick($event, item)">
<a href="#" class="p-dock-link" v-tooltip.top="item.label" @click="onDockItemClick($event, item)">
<img :alt="item.label" src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" style="width: 100%" />
</a>
</template>
@ -676,46 +805,46 @@ export default {
const dockItems = ref([
{
label: 'Finder',
icon: "/demo/images/dock/finder.svg",
icon: "demo/images/dock/finder.svg",
command: () => {
displayFinder.value = true;
}
},
{
label: 'Terminal',
icon: "/demo/images/dock/terminal.svg",
icon: "demo/images/dock/terminal.svg",
command: () => {
displayTerminal.value = true;
}
},
{
label: 'App Store',
icon: "/demo/images/dock/appstore.svg",
icon: "demo/images/dock/appstore.svg",
command: () => {
toast.add({ severity: 'error', summary: 'An unexpected error occurred while signing in.', detail: 'UNTRUSTED_CERT_TITLE', group: 'tc', life: 3000 });
}
},
{
label: 'Safari',
icon: "/demo/images/dock/safari.svg",
icon: "demo/images/dock/safari.svg",
command: () => {
toast.add({ severity: 'warn', summary: 'Safari has stopped working', group: 'tc', life: 3000 });
}
},
{
label: 'Photos',
icon: "/demo/images/dock/photos.svg",
icon: "demo/images/dock/photos.svg",
command: () => {
displayPhotos.value = true;
}
},
{
label: 'GitHub',
icon: "/demo/images/dock/github.svg",
icon: "demo/images/dock/github.svg",
},
{
label: 'Trash',
icon: "/demo/images/dock/trash.png",
icon: "demo/images/dock/trash.png",
command: () => {
toast.add({ severity: 'info', summary: 'Empty Trash', life: 3000 });
}
@ -724,19 +853,19 @@ export default {
const dockBasicItems = ref([
{
label: "Finder",
icon: "/demo/images/dock/finder.svg"
icon: "demo/images/dock/finder.svg"
},
{
label: "App Store",
icon: "/demo/images/dock/appstore.svg"
icon: "demo/images/dock/appstore.svg"
},
{
label: "Photos",
icon: "/demo/images/dock/photos.svg"
icon: "demo/images/dock/photos.svg"
},
{
label: "Trash",
icon: "/demo/images/dock/trash.png"
icon: "demo/images/dock/trash.png"
}
]);
const menubarItems = ref([
@ -982,7 +1111,7 @@ export default {
padding: 0.5rem .75rem;
}
.p-menubar-root-list > .p-menuitem > .p-menuitem-link {
.p-menubar-root-list > .p-menuitem > .p-menuitem-content > .p-menuitem-link {
padding: 0.5rem .75rem;
> .p-submenu-icon {
@ -1021,22 +1150,22 @@ export default {
<h5>Basic</h5>
<div class="dock-window">
<p-dock :model="dockBasicItems" position="bottom">
<template #icon="{ item }">
<img :alt="item.label" src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" style="width: 100%" />
</template>
</p-dock>
<p-dock :model="dockBasicItems" position="top">
<template #icon="{ item }">
<img :alt="item.label" src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" style="width: 100%" />
</template>
</p-dock>
<p-dock :model="dockBasicItems" position="left">
<p-dock :model="dockBasicItems" position="right">
<template #icon="{ item }">
<img :alt="item.label" src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" style="width: 100%" />
</template>
</p-dock>
<p-dock :model="dockBasicItems" position="right">
<p-dock :model="dockBasicItems" position="bottom">
<template #icon="{ item }">
<img :alt="item.label" src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" style="width: 100%" />
</template>
</p-dock>
<p-dock :model="dockBasicItems" position="left">
<template #icon="{ item }">
<img :alt="item.label" src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" style="width: 100%" />
</template>
@ -1061,7 +1190,7 @@ export default {
<div class="dock-window dock-advanced">
<p-dock :model="dockItems">
<template #item="{ item }">
<a href="#" class="p-dock-action" v-tooltip.top="item.label" @click="onDockItemClick($event, item)">
<a href="#" class="p-dock-link" v-tooltip.top="item.label" @click="onDockItemClick($event, item)">
<img :alt="item.label" src="https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png" style="width: 100%" />
</a>
</template>
@ -1115,46 +1244,46 @@ export default {
const dockItems = ref([
{
label: 'Finder',
icon: "/demo/images/dock/finder.svg",
icon: "demo/images/dock/finder.svg",
command: () => {
displayFinder.value = true;
}
},
{
label: 'Terminal',
icon: "/demo/images/dock/terminal.svg",
icon: "demo/images/dock/terminal.svg",
command: () => {
displayTerminal.value = true;
}
},
{
label: 'App Store',
icon: "/demo/images/dock/appstore.svg",
icon: "demo/images/dock/appstore.svg",
command: () => {
toast.add({ severity: 'error', summary: 'An unexpected error occurred while signing in.', detail: 'UNTRUSTED_CERT_TITLE', group: 'tc', life: 3000 });
}
},
{
label: 'Safari',
icon: "/demo/images/dock/safari.svg",
icon: "demo/images/dock/safari.svg",
command: () => {
toast.add({ severity: 'warn', summary: 'Safari has stopped working', group: 'tc', life: 3000 });
}
},
{
label: 'Photos',
icon: "/demo/images/dock/photos.svg",
icon: "demo/images/dock/photos.svg",
command: () => {
displayPhotos.value = true;
}
},
{
label: 'GitHub',
icon: "/demo/images/dock/github.svg",
icon: "demo/images/dock/github.svg",
},
{
label: 'Trash',
icon: "/demo/images/dock/trash.png",
icon: "demo/images/dock/trash.png",
command: () => {
toast.add({ severity: 'info', summary: 'Empty Trash', life: 3000 });
}
@ -1163,19 +1292,19 @@ export default {
const dockBasicItems = ref([
{
label: "Finder",
icon: "/demo/images/dock/finder.svg"
icon: "demo/images/dock/finder.svg"
},
{
label: "App Store",
icon: "/demo/images/dock/appstore.svg"
icon: "demo/images/dock/appstore.svg"
},
{
label: "Photos",
icon: "/demo/images/dock/photos.svg"
icon: "demo/images/dock/photos.svg"
},
{
label: "Trash",
icon: "/demo/images/dock/trash.png"
icon: "demo/images/dock/trash.png"
}
]);
const menubarItems = ref([
@ -1444,11 +1573,11 @@ export default {
padding: 0.5rem .75rem;
}
.dock-demo .p-menubar .p-menubar-root-list > .p-menuitem > .p-menuitem-link {
.dock-demo .p-menubar .p-menubar-root-list > .p-menuitem > .p-menuitem-content > .p-menuitem-link {
padding: 0.5rem .75rem;
}
.dock-demo .p-menubar .p-menubar-root-list > .p-menuitem > .p-menuitem-link > .p-submenu-icon {
.dock-demo .p-menubar .p-menubar-root-list > .p-menuitem > .p-menuitem-content > .p-menuitem-link > .p-submenu-icon {
display: none;
}

View File

@ -13,22 +13,22 @@
<h5>Basic</h5>
<div class="dock-window">
<Dock :model="dockBasicItems" position="bottom">
<template #icon="{ item }">
<img :alt="item.label" :src="item.icon" style="width: 100%" />
</template>
</Dock>
<Dock :model="dockBasicItems" position="top">
<template #icon="{ item }">
<img :alt="item.label" :src="item.icon" style="width: 100%" />
</template>
</Dock>
<Dock :model="dockBasicItems" position="left">
<Dock :model="dockBasicItems" position="right">
<template #icon="{ item }">
<img :alt="item.label" :src="item.icon" style="width: 100%" />
</template>
</Dock>
<Dock :model="dockBasicItems" position="right">
<Dock :model="dockBasicItems" position="bottom">
<template #icon="{ item }">
<img :alt="item.label" :src="item.icon" style="width: 100%" />
</template>
</Dock>
<Dock :model="dockBasicItems" position="left">
<template #icon="{ item }">
<img :alt="item.label" :src="item.icon" style="width: 100%" />
</template>
@ -53,7 +53,7 @@
<div class="dock-window dock-advanced">
<Dock :model="dockItems">
<template #item="{ item }">
<a href="#" class="p-dock-action" v-tooltip.top="item.label" @click="onDockItemClick($event, item)">
<a v-tooltip.top="item.label" href="#" class="p-dock-link" @click="onDockItemClick($event, item)">
<img :alt="item.label" :src="item.icon" style="width: 100%" />
</a>
</template>
@ -80,9 +80,9 @@
</template>
<script>
import TerminalService from 'primevue/terminalservice';
import NodeService from '../../service/NodeService';
import PhotoService from '../../service/PhotoService';
import TerminalService from 'primevue/terminalservice';
import DockDoc from './DockDoc.vue';
export default {
@ -97,46 +97,46 @@ export default {
dockItems: [
{
label: 'Finder',
icon: '/demo/images/dock/finder.svg',
icon: 'demo/images/dock/finder.svg',
command: () => {
this.displayFinder = true;
}
},
{
label: 'Terminal',
icon: '/demo/images/dock/terminal.svg',
icon: 'demo/images/dock/terminal.svg',
command: () => {
this.displayTerminal = true;
}
},
{
label: 'App Store',
icon: '/demo/images/dock/appstore.svg',
icon: 'demo/images/dock/appstore.svg',
command: () => {
this.$toast.add({ severity: 'error', summary: 'An unexpected error occurred while signing in.', detail: 'UNTRUSTED_CERT_TITLE', group: 'tc', life: 3000 });
}
},
{
label: 'Safari',
icon: '/demo/images/dock/safari.svg',
icon: 'demo/images/dock/safari.svg',
command: () => {
this.$toast.add({ severity: 'warn', summary: 'Safari has stopped working', group: 'tc', life: 3000 });
}
},
{
label: 'Photos',
icon: '/demo/images/dock/photos.svg',
icon: 'demo/images/dock/photos.svg',
command: () => {
this.displayPhotos = true;
}
},
{
label: 'GitHub',
icon: '/demo/images/dock/github.svg'
icon: 'demo/images/dock/github.svg'
},
{
label: 'Trash',
icon: '/demo/images/dock/trash.png',
icon: 'demo/images/dock/trash.png',
command: () => {
this.$toast.add({ severity: 'info', summary: 'Empty Trash', life: 3000 });
}
@ -145,19 +145,19 @@ export default {
dockBasicItems: [
{
label: 'Finder',
icon: '/demo/images/dock/finder.svg'
icon: 'demo/images/dock/finder.svg'
},
{
label: 'App Store',
icon: '/demo/images/dock/appstore.svg'
icon: 'demo/images/dock/appstore.svg'
},
{
label: 'Photos',
icon: '/demo/images/dock/photos.svg'
icon: 'demo/images/dock/photos.svg'
},
{
label: 'Trash',
icon: '/demo/images/dock/trash.png'
icon: 'demo/images/dock/trash.png'
}
],
menubarItems: [
@ -381,7 +381,7 @@ export default {
padding: 0.5rem 0.75rem;
}
.p-menubar-root-list > .p-menuitem > .p-menuitem-link {
.p-menubar-root-list > .p-menuitem > .p-menuitem-content > .p-menuitem-link {
padding: 0.5rem 0.75rem;
> .p-submenu-icon {

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="DropdownDemo" :sources="sources" github="dropdown/DropdownDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -87,8 +86,8 @@ export default {
<h5>Filtering</h5>
<p>
Filtering allows searching items in the list using an input field at the header. In order to use filtering, enable <i>filter</i> property. By default, optionLabel is used when searching and <i>filterFields</i> can be used to customize
the fields being utilized. Furthermore, <i>filterMatchMode</i> is available to define the search algorithm. Valid values are "contains" (default), "startsWith" and "endsWith".
Filtering allows searching items in the list using an input field at the header. In order to use filtering, enable <i>filter</i> property. By default, optionLabel is used when searching and <i>filterFields</i> can be used to customize the
fields being utilized. Furthermore, <i>filterMatchMode</i> is available to define the search algorithm. Valid values are "contains" (default), "startsWith" and "endsWith".
</p>
<pre v-code><code>
@ -98,14 +97,14 @@ export default {
<h5>Templating</h5>
<p>
Label of an option is used as the display text of an item by default, for custom content support define an <i>option</i> template that gets the option instance as a parameter. In addition <i>value</i>, <i>optiongroup</i>,
<i>header</i>, <i>footer</i>, <i>emptyfilter</i> and <i>empty</i> slots are provided for further customization.
Label of an option is used as the display text of an item by default, for custom content support define an <i>option</i> template that gets the option instance as a parameter. In addition <i>value</i>, <i>optiongroup</i>, <i>header</i>,
<i>footer</i>, <i>emptyfilter</i> and <i>empty</i> slots are provided for further customization.
</p>
<pre v-code><code><template v-pre>
&lt;Dropdown v-model="selectedCar" :options="cars" optionLabel="brand" :filter="true" placeholder="Select a Car" :showClear="true"&gt;
&lt;template #value="slotProps"&gt;
&lt;div class="p-dropdown-car-value" v-if="slotProps.value"&gt;
&lt;img :alt="slotProps.value.brand" :src="'/demo/images/car/' + slotProps.value.brand + '.png'" /&gt;
&lt;img :alt="slotProps.value.brand" :src="'demo/images/car/' + slotProps.value.brand + '.png'" /&gt;
&lt;span&gt;{{slotProps.value.brand}}&lt;/span&gt;
&lt;/div&gt;
&lt;span v-else&gt;
@ -114,7 +113,7 @@ export default {
&lt;/template&gt;
&lt;template #option="slotProps"&gt;
&lt;div class="p-dropdown-car-option"&gt;
&lt;img :alt="slotProps.option.brand" :src="'/demo/images/car/' + slotProps.option.brand + '.png'" /&gt;
&lt;img :alt="slotProps.option.brand" :src="'demo/images/car/' + slotProps.option.brand + '.png'" /&gt;
&lt;span&gt;{{slotProps.option.brand}}&lt;/span&gt;
&lt;/div&gt;
&lt;/template&gt;
@ -309,12 +308,30 @@ export default {
<td>false</td>
<td>Whether the dropdown is in loading state.</td>
</tr>
<tr>
<td>dropdownIcon</td>
<td>string</td>
<td>pi pi-chevron-down</td>
<td>Icon to display in dropdown</td>
</tr>
<tr>
<td>loadingIcon</td>
<td>string</td>
<td>pi pi-spinner pi-spin</td>
<td>Icon to display in loading state.</td>
</tr>
<tr>
<td>filterIcon</td>
<td>string</td>
<td>pi pi-search</td>
<td>Icon to display in filter input</td>
</tr>
<tr>
<td>clearIcon</td>
<td>string</td>
<td>pi pi-times</td>
<td>Icon to display in clear button</td>
</tr>
<tr>
<td>resetFilterOnHide</td>
<td>boolean</td>
@ -325,7 +342,7 @@ export default {
<td>virtualScrollerOptions</td>
<td>object</td>
<td>null</td>
<td>Whether to use the virtualScroller feature. The properties of <nuxt-link to="/virtualscroller">VirtualScroller</nuxt-link> component can be used like an object in it.</td>
<td>Whether to use the virtualScroller feature. The properties of <router-link to="/virtualscroller">VirtualScroller</router-link> component can be used like an object in it.</td>
</tr>
<tr>
<td>autoOptionFocus</td>
@ -558,7 +575,7 @@ export default {
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -615,13 +632,13 @@ export default {
<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>
Value to describe the component can either be provided with <i>aria-labelledby</i> or <i>aria-label</i> props. The dropdown element has a <i>combobox</i> role in addition to <i>aria-haspopup</i> and <i>aria-expanded</i> attributes. If
the editable option is enabled <i>aria-autocomplete</i> is also added. The relation between the combobox and the popup is created with <i>aria-controls</i> and <i>aria-activedescendant</i> attribute is used to instruct screen reader
which option to read during keyboard navigation within the popup list.
Value to describe the component can either be provided with <i>aria-labelledby</i> or <i>aria-label</i> props. The dropdown element has a <i>combobox</i> role in addition to <i>aria-haspopup</i> and <i>aria-expanded</i> attributes. If the
editable option is enabled <i>aria-autocomplete</i> is also added. The relation between the combobox and the popup is created with <i>aria-controls</i> and <i>aria-activedescendant</i> attribute is used to instruct screen reader which
option to read during keyboard navigation within the popup list.
</p>
<p>
The popup list has an id that refers to the <i>aria-controls</i> attribute of the <i>combobox</i> element and uses <i>listbox</i> as the role. Each list item has an <i>option</i> role, an id to match the
<i>aria-activedescendant</i> of the input element along with <i>aria-label</i>, <i>aria-selected</i> and <i>aria-disabled</i> attributes.
The popup list has an id that refers to the <i>aria-controls</i> attribute of the <i>combobox</i> element and uses <i>listbox</i> as the role. Each list item has an <i>option</i> role, an id to match the <i>aria-activedescendant</i> of
the input element along with <i>aria-label</i>, <i>aria-selected</i> and <i>aria-disabled</i> attributes.
</p>
<p>If filtering is enabled, <i>filterInputProps</i> can be defined to give <i>aria-*</i> props to the filter input element.</p>
@ -798,7 +815,6 @@ export default {
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -29,7 +29,7 @@
<h5>Advanced with Templating, Filtering and Clear Icon</h5>
<Dropdown v-model="selectedCountry" :options="countries" optionLabel="name" :filter="true" placeholder="Select a Country" :showClear="true">
<template #value="slotProps">
<div class="country-item country-item-value" v-if="slotProps.value">
<div v-if="slotProps.value" class="country-item country-item-value">
<img src="../../assets/images/flag_placeholder.png" :class="'flag flag-' + slotProps.value.code.toLowerCase()" />
<div>{{ slotProps.value.name }}</div>
</div>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="DynamicDialogDemo" :sources="sources" :extFiles="extFiles" :service="['ProductService']" :data="['products-small']" github="dynamicdialog/DynamicDialogDemo.vue">
<h5>DialogService</h5>
<p>Dynamic dialogs require the <i>DialogService</i> to be configured globally.</p>
@ -161,7 +160,7 @@ export default {
</code></pre>
<h5>Customizing a Dialog</h5>
<p><i>props</i> option is used to customize the dynamically generated Dialog, refer to the <nuxt-link to="/dialog">Dialog</nuxt-link> documentation for the whole list of options.</p>
<p><i>props</i> option is used to customize the dynamically generated Dialog, refer to the <router-link to="/dialog">Dialog</router-link> documentation for the whole list of options.</p>
<pre v-code.script><code>
import { h } from 'vue';
@ -309,8 +308,13 @@ export default {
</tbody>
</table>
</div>
<h5>Accessibility</h5>
<p>DynamicDialog uses the Dialog component internally, visit <router-link to="/dialog">dialog</router-link> for more information.</p>
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>
@ -514,7 +518,7 @@ export default {
<p-column field="name" header="Name"></p-column>
<p-column header="Image">
<template #body="slotProps">
<img :src="'/demo/images/product/' + slotProps.data.image" @error="(e) => e.target.src = 'https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png'" :alt="slotProps.data.name" class="shadow-2 w-4rem" />
<img :src="'demo/images/product/' + slotProps.data.image" @error="(e) => e.target.src = 'https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png'" :alt="slotProps.data.name" class="shadow-2 w-4rem" />
</template>
</p-column>
<p-column field="category" header="Category"></p-column>
@ -612,7 +616,7 @@ export default {
<Column field="name" header="Name"></Column>
<Column header="Image">
<template #body="slotProps">
<img :src="'/demo/images/product/' + slotProps.data.image" @error="(e) => e.target.src = 'https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png'" :alt="slotProps.data.name" class="shadow-2 w-4rem" />
<img :src="'demo/images/product/' + slotProps.data.image" @error="(e) => e.target.src = 'https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png'" :alt="slotProps.data.name" class="shadow-2 w-4rem" />
</template>
</Column>
<Column field="category" header="Category"></Column>
@ -711,7 +715,7 @@ export default {
<Column field="name" header="Name"></Column>
<Column header="Image">
<template #body="slotProps">
<img :src="'/demo/images/product/' + slotProps.data.image" @error="(e) => e.target.src = 'https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png'" :alt="slotProps.data.name" class="shadow-2 w-4rem" />
<img :src="'demo/images/product/' + slotProps.data.image" @error="(e) => e.target.src = 'https://www.primefaces.org/wp-content/uploads/2020/05/placeholder.png'" :alt="slotProps.data.name" class="shadow-2 w-4rem" />
</template>
</Column>
<Column field="category" header="Category"></Column>

View File

@ -4,7 +4,7 @@
There are <strong>{{ totalProducts }}</strong> products in total in this list.
</p>
<div class="flex justify-content-end">
<Button type="button" label="Close" @click="closeDialog"></Button>
<Button autofocus type="button" label="Close" @click="closeDialog"></Button>
</div>
</div>
</template>

View File

@ -8,7 +8,7 @@
<Column field="name" header="Name"></Column>
<Column header="Image">
<template #body="slotProps">
<img :src="'/demo/images/product/' + slotProps.data.image" :alt="slotProps.data.name" class="shadow-2 w-4rem" />
<img :src="'demo/images/product/' + slotProps.data.image" :alt="slotProps.data.name" class="shadow-2 w-4rem" />
</template>
</Column>
<Column field="category" header="Category"></Column>

View File

@ -21,10 +21,10 @@
</template>
<script>
import { h } from 'vue';
import Button from 'primevue/button';
import ProductListDemo from './ProductListDemo';
import { h } from 'vue';
import DynamicDialogDoc from './DynamicDialogDoc.vue';
import ProductListDemo from './ProductListDemo';
export default {
methods: {
@ -51,6 +51,7 @@ export default {
},
onClose: (options) => {
const data = options.data;
if (data) {
const buttonType = data.buttonType;
const summary_and_detail = buttonType ? { summary: 'No Product Selected', detail: `Pressed '${buttonType}' button` } : { summary: 'Product Selected', detail: data.name };

View File

@ -14,22 +14,19 @@
<Editor v-model="value1" editorStyle="height: 320px" />
<h5>Customized</h5>
<ClientOnly>
<Editor v-model="value2" editorStyle="height: 320px">
<template v-slot:toolbar>
<span class="ql-formats">
<button class="ql-bold" v-tooltip.bottom="'Bold'"></button>
<button class="ql-italic" v-tooltip.bottom="'Italic'"></button>
<button class="ql-underline" v-tooltip.bottom="'Underline'"></button>
<button v-tooltip.bottom="'Bold'" class="ql-bold"></button>
<button v-tooltip.bottom="'Italic'" class="ql-italic"></button>
<button v-tooltip.bottom="'Underline'" class="ql-underline"></button>
</span>
</template>
</Editor>
</ClientOnly>
</div>
</div>
<ClientOnly>
<EditorDoc />
</ClientOnly>
</div>
</template>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="FieldsetDemo" :sources="sources" github="fieldset/FieldsetDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -100,7 +99,7 @@ import Fieldset from 'primevue/fieldset';
</tr>
<tr>
<td>toggleButtonProps</td>
<td>string</td>
<td>object</td>
<td>null</td>
<td>Uses to pass the custom value to read for the anchor inside the component.</td>
</tr>
@ -150,7 +149,7 @@ import Fieldset from 'primevue/fieldset';
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -181,12 +180,11 @@ import Fieldset from 'primevue/fieldset';
</div>
<h5>Accessibility</h5>
<DevelopmentSection>
<h6>Screen Reader</h6>
<p>
Fieldset component uses the semantic <i>fieldset</i> element. When toggleable option is enabled, a clickable element with <i>button</i> role is included inside the <i>legend</i> element, this button has <i>aria-controls</i> to
define the id of the content section along with <i>aria-expanded</i> for the visibility state. The value to read the button defaults to the value of the <i>legend</i> property and can be customized by defining an
<i>aria-label</i> or <i>aria-labelledby</i> via the <i>toggleButtonProps</i> property.
Fieldset component uses the semantic <i>fieldset</i> element. When toggleable option is enabled, a clickable element with <i>button</i> role is included inside the <i>legend</i> element, this button has <i>aria-controls</i> to define the
id of the content section along with <i>aria-expanded</i> for the visibility state. The value to read the button defaults to the value of the <i>legend</i> property and can be customized by defining an <i>aria-label</i> or
<i>aria-labelledby</i> via the <i>toggleButtonProps</i> property.
</p>
<p>The content uses <i>region</i>, defines an id that matches the <i>aria-controls</i> of the content toggle button and <i>aria-labelledby</i> referring to the id of the header.</p>
@ -219,12 +217,10 @@ import Fieldset from 'primevue/fieldset';
</tbody>
</table>
</div>
</DevelopmentSection>
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="FileUploadDemo" :sources="sources" github="fileupload/FileUploadDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -82,12 +81,57 @@ myUploader(event) {
</code></pre>
<h5>Empty Template</h5>
<p>When there is no file selected, you may use the empty slot to display content.</p>
<h5>Templating</h5>
<p>FileUpload component is extremely customizable thanks to the templating features, both the <i>header</i> and <i>content</i> sections provide custom slots.</p>
<pre v-code><code>
&lt;FileUpload name="demo[]" url="./upload"&gt;
&lt;FileUpload name="demo[]" url="./upload.php" @upload="onTemplatedUpload($event)" :multiple="true" accept="image/*" :maxFileSize="1000000" @select="onSelectedFiles"&gt;
&lt;template #header="&#123; chooseCallback, uploadCallback, clearCallback, files &#125;"&gt;
&lt;div class="flex flex-wrap justify-content-between align-items-center flex-1 gap-2"&gt;
&lt;div class="flex gap-2"&gt;
&lt;Button @click="chooseCallback()" icon="pi pi-images" class="p-button-rounded"&gt;&lt;/Button&gt;
&lt;Button @click="uploadCallback()" icon="pi pi-cloud-upload" class="p-button-rounded p-button-success" :disabled="!files || files.length === 0"&gt;&lt;/Button&gt;
&lt;Button @click="clearCallback()" icon="pi pi-times" class="p-button-rounded p-button-danger" :disabled="!files || files.length === 0"&gt;&lt;/Button&gt;
&lt;/div&gt;
&lt;ProgressBar :value="totalSizePercent" :showValue="false" :class="['md:w-20rem h-1rem w-full md:ml-auto', &#123;'exceeded-progress-bar': (totalSizePercent &gt; 100)&#125;]"&gt;&lt;span class="white-space-nowrap"&gt;&#123;&#123; totalSize &#125;&#125;B / 1Mb&lt;/span&gt;&lt;/ProgressBar&gt;
&lt;/div&gt;
&lt;/template&gt;
&lt;template #content="&#123; files, uploadedFiles, onUploadedFileRemove, onFileRemove &#125;"&gt;
&lt;div v-if="files.length &gt; 0"&gt;
&lt;h5&gt;Pending&lt;/h5&gt;
&lt;div class="flex flex-wrap p-5 gap-5"&gt;
&lt;div v-for="(file, index) of files" :key="file.name + file.type + file.size" class="card m-0 px-6 flex flex-column border-1 surface-border align-items-center gap-3"&gt;
&lt;div&gt;
&lt;img role="presentation" :alt="file.name" :src="file.objectURL" height="50" class="shadow-2" /&gt;
&lt;/div&gt;
&lt;span class="font-semibold"&gt;&#123;&#123; file.name &#125;&#125;&lt;/span&gt;
&lt;div&gt;&#123;&#123; formatSize(file.size) &#125;&#125;&lt;/div&gt;
&lt;Badge value="Pending" severity="warning" /&gt;
&lt;Button icon="pi pi-times" @click="onRemoveTemplatingFile(file, onFileRemove, index)" class="p-button-outlined p-button-danger p-button-rounded" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div v-if="uploadedFiles.length &gt; 0"&gt;
&lt;h5&gt;Completed&lt;/h5&gt;
&lt;div class="flex flex-wrap p-0 sm:p-5 gap-5"&gt;
&lt;div v-for="(file, index) of uploadedFiles" :key="file.name + file.type + file.size" class="card m-0 px-6 flex flex-column border-1 surface-border align-items-center gap-3"&gt;
&lt;div&gt;
&lt;img role="presentation" :alt="file.name" :src="file.objectURL" width="100" class="shadow-2" /&gt;
&lt;/div&gt;
&lt;span class="font-semibold"&gt;&#123;&#123; file.name &#125;&#125;&lt;/span&gt;
&lt;div&gt;&#123;&#123; formatSize(file.size) &#125;&#125;&lt;/div&gt;
&lt;Badge value="Completed" class="mt-3" severity="success" /&gt;
&lt;Button icon="pi pi-times" @click="onUploadedFileRemove(index)" class="p-button-outlined p-button-danger p-button-rounded" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/template&gt;
&lt;template #empty&gt;
&lt;p&gt;Drag and drop files to here to upload.&lt;/p&gt;
&lt;div class="flex align-items-center justify-content-center flex-column"&gt;
&lt;i class="pi pi-cloud-upload border-2 border-circle p-5 text-8xl text-400 border-400" /&gt;
&lt;p class="mt-4 mb-0"&gt;Drag and drop files to here to upload.&lt;/p&gt;
&lt;/div&gt;
&lt;/template&gt;
&lt;/FileUpload&gt;
@ -165,6 +209,12 @@ myUploader(event) {
<td>Maximum number of files exceeded, limit is &#123;0&#125; at most.</td>
<td>Message to display when number of files to be uploaded exceeeds the limit.</td>
</tr>
<tr>
<td>invalidFileTypeMessage</td>
<td>string</td>
<td>"&#123;0&#125;: Invalid file type, allowed file types: &#123;1&#125;"".</td>
<td>Message of the invalid file type.</td>
</tr>
<tr>
<td>fileLimit</td>
<td>number</td>
@ -187,25 +237,25 @@ myUploader(event) {
<td>chooseLabel</td>
<td>string</td>
<td>null</td>
<td>Label of the choose button. Defaults to PrimeVue <nuxt-link to="/locale">Locale</nuxt-link> configuration.</td>
<td>Label of the choose button. Defaults to PrimeVue <router-link to="/locale">Locale</router-link> configuration.</td>
</tr>
<tr>
<td>uploadLabel</td>
<td>string</td>
<td>Upload</td>
<td>Label of the upload button. Defaults to PrimeVue <nuxt-link to="/locale">Locale</nuxt-link> configuration.</td>
<td>Label of the upload button. Defaults to PrimeVue <router-link to="/locale">Locale</router-link> configuration.</td>
</tr>
<tr>
<td>cancelLabel</td>
<td>string</td>
<td>Cancel</td>
<td>Label of the cancel button. Defaults to PrimeVue <nuxt-link to="/locale">Locale</nuxt-link> configuration.</td>
<td>Label of the cancel button. Defaults to PrimeVue <router-link to="/locale">Locale</router-link> configuration.</td>
</tr>
<tr>
<td>customUpload</td>
<td>boolean</td>
<td>false</td>
<td>Whether to use the default upload or a manual implementation defined in uploadHandler callback. Defaults to PrimeVue <nuxt-link to="/locale">Locale</nuxt-link> configuration.</td>
<td>Whether to use the default upload or a manual implementation defined in uploadHandler callback. Defaults to PrimeVue <router-link to="/locale">Locale</router-link> configuration.</td>
</tr>
<tr>
<td>showUploadButton</td>
@ -328,7 +378,15 @@ myUploader(event) {
event.file: Removed file. <br />
event.files: Remaining files to be uploaded.
</td>
<td>Callback to invoke when a singe file is removed from the list.</td>
<td>Callback to invoke when a single file is removed from the file list to upload.</td>
</tr>
<tr>
<td>removeUploadedFile</td>
<td>
event.file: Removed uploaded file. <br />
event.files: Remaining uploaded files.
</td>
<td>Callback to invoke when a single uploaded file is removed from the uploaded file list.</td>
</tr>
</tbody>
</table>
@ -344,6 +402,27 @@ myUploader(event) {
</tr>
</thead>
<tbody>
<tr>
<td>header</td>
<td>
files: Files to upload <br />
uploadedFiles: Uploaded Files <br />
chooseCallback: Choose function <br />
uploadCallback: Upload function <br />
clearCallback: Clear function
</td>
</tr>
<tr>
<td>content</td>
<td>
files: Files to upload <br />
uploadedFiles: Uploaded Files <br />
progress: Uploaded progress as number <br />
messages: Status messages about upload process <br />
removeFileCallback(index): Function to remove a file <br />
removeUploadedFileCallback(index): Function to remove an uploaded file
</td>
</tr>
<tr>
<td>empty</td>
<td>-</td>
@ -353,7 +432,7 @@ myUploader(event) {
</div>
<h5>Styling</h5>
<p>Following is the list of structural style classes, for theming classes visit <nuxt-link to="/theming">theming</nuxt-link> page.</p>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
@ -367,6 +446,14 @@ myUploader(event) {
<td>p-fileupload</td>
<td>Container element.</td>
</tr>
<tr>
<td>p-fileupload-basic</td>
<td>Container element in basic mode.</td>
</tr>
<tr>
<td>p-fileupload-advanced</td>
<td>Container element in advanced mode.</td>
</tr>
<tr>
<td>p-fileupload-buttonbar</td>
<td>Header containing the buttons.</td>
@ -375,6 +462,42 @@ myUploader(event) {
<td>p-fileupload-content</td>
<td>Content section.</td>
</tr>
<tr>
<td>p-fileupload-file</td>
<td>File item.</td>
</tr>
<tr>
<td>p-fileupload-file-thumbnail</td>
<td>Image preview of a file.</td>
</tr>
<tr>
<td>p-fileupload-file-details</td>
<td>Container of file details.</td>
</tr>
<tr>
<td>p-fileupload-file-name</td>
<td>File name element.</td>
</tr>
<tr>
<td>p-fileupload-file-size</td>
<td>File size element.</td>
</tr>
<tr>
<td>p-fileupload-file-badge</td>
<td>File badge element.</td>
</tr>
<tr>
<td>p-fileupload-file-actions</td>
<td>Container of file actions.</td>
</tr>
<tr>
<td>p-fileupload-file-remove</td>
<td>Button to remove a file.</td>
</tr>
<tr>
<td>p-fileupload-empty</td>
<td>Container of the empty slot.</td>
</tr>
</tbody>
</table>
</div>
@ -382,7 +505,6 @@ myUploader(event) {
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>
@ -398,12 +520,68 @@ export default {
<Toast />
<h5>Advanced</h5>
<FileUpload name="demo[]" url="./upload.php" @upload="onUpload" :multiple="true" accept="image/*" :maxFileSize="1000000">
<FileUpload name="demo[]" url="https://www.primefaces.org/upload.php" @upload="onAdvancedUpload($event)" :multiple="true" accept="image/*" :maxFileSize="1000000">
<template #content>
<ul v-if="uploadedFiles && uploadedFiles[0]">
<li v-for="file of uploadedFiles[0]" :key="file">{{ file.name }} - {{ file.size }} bytes</li>
</ul>
</template>
<template #empty>
<p>Drag and drop files to here to upload.</p>
</template>
</FileUpload>
<h5>Templating</h5>
<FileUpload name="demo[]" url="./upload.php" @upload="onTemplatedUpload($event)" :multiple="true" accept="image/*" :maxFileSize="1000000" @select="onSelectedFiles">
<template #header="{ chooseCallback, uploadCallback, clearCallback, files }">
<div class="flex flex-wrap justify-content-between align-items-center flex-1 gap-2">
<div class="flex gap-2">
<Button @click="chooseCallback()" icon="pi pi-images" class="p-button-rounded"></Button>
<Button @click="uploadEvent(uploadCallback)" icon="pi pi-cloud-upload" class="p-button-rounded p-button-success" :disabled="!files || files.length === 0"></Button>
<Button @click="clearCallback()" icon="pi pi-times" class="p-button-rounded p-button-danger" :disabled="!files || files.length === 0"></Button>
</div>
<ProgressBar :value="totalSizePercent" :showValue="false" :class="['md:w-20rem h-1rem w-full md:ml-auto', {'exceeded-progress-bar': (totalSizePercent > 100)}]"><span class="white-space-nowrap">{{ totalSize }}B / 1Mb</span></ProgressBar>
</div>
</template>
<template #content="{ files, uploadedFiles, removeUploadedFileCallback, fileRemoveCallback }">
<div v-if="files.length > 0">
<h5>Pending</h5>
<div class="flex flex-wrap p-5 gap-5">
<div v-for="(file, index) of files" :key="file.name + file.type + file.size" class="card m-0 px-6 flex flex-column border-1 surface-border align-items-center gap-3">
<div>
<img role="presentation" :alt="file.name" :src="file.objectURL" width="100" height="50" class="shadow-2" />
</div>
<span class="font-semibold">{{ file.name }}</span>
<div>{{ formatSize(file.size) }}</div>
<Badge value="Pending" severity="warning" />
<Button icon="pi pi-times" @click="onRemoveTemplatingFile(file, fileRemoveCallback, index)" class="p-button-outlined p-button-danger p-button-rounded" />
</div>
</div>
</div>
<div v-if="uploadedFiles.length > 0">
<h5>Completed</h5>
<div class="flex flex-wrap p-0 sm:p-5 sm:p-5 gap-5">
<div v-for="(file, index) of uploadedFiles" :key="file.name + file.type + file.size" class="card m-0 px-6 flex flex-column border-1 surface-border align-items-center gap-3">
<div>
<img role="presentation" :alt="file.name" :src="file.objectURL" width="100" height="50" class="shadow-2" />
</div>
<span class="font-semibold">{{ file.name }}</span>
<div>{{ formatSize(file.size) }}</div>
<Badge value="Completed" class="mt-3" severity="success" />
<Button icon="pi pi-times" @click="removeUploadedFileCallback(index)" class="p-button-outlined p-button-danger p-button-rounded" />
</div>
</div>
</div>
</template>
<template #empty>
<div class="flex align-items-center justify-content-center flex-column">
<i class="pi pi-cloud-upload border-2 border-circle p-5 text-8xl text-400 border-400" />
<p class="mt-4 mb-0">Drag and drop files to here to upload.</p>
</div>
</template>
</FileUpload>
<h5>Basic</h5>
<FileUpload mode="basic" name="demo[]" url="./upload.php" accept="image/*" :maxFileSize="1000000" @upload="onUpload" />
@ -414,13 +592,69 @@ export default {
<script>
export default {
data() {
return {
uploadedFiles: [],
files: [],
totalSize: 0,
totalSizePercent: 0
};
},
methods: {
onRemoveTemplatingFile(file, onFileRemove, index) {
onFileRemove(index);
this.totalSize -= parseInt(this.formatSize(file.size));
this.totalSizePercent = this.totalSize / 10;
},
onClearTemplatingUpload(clear) {
clear();
this.totalSize = 0;
this.totalSizePercent = 0;
},
onSelectedFiles(event) {
this.files = event.files;
this.files.forEach((file) => {
this.totalSize += parseInt(this.formatSize(file.size));
});
},
onAdvancedUpload() {
this.$toast.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded', life: 3000 });
},
uploadEvent(callback) {
this.totalSizePercent = this.totalSize / 10;
callback();
},
onTemplatedUpload() {
this.totalSize = 0;
this.totalSizePercent = 0;
this.$toast.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded', life: 3000 });
},
onUpload() {
this.$toast.add({severity: 'info', summary: 'Success', detail: 'File Uploaded', life: 3000});
this.$toast.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded', life: 3000 });
},
formatSize(bytes) {
if (bytes === 0) {
return '0 B';
}
let k = 1000,
dm = 3,
sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
}
}
};
<\\/script>
<style lang="scss" scoped>
::v-deep(.custom-progress-bar) {
.p-progressbar-value {
background-color: #f44336;
}
}
</style>
`
},
'composition-api': {
@ -431,12 +665,68 @@ export default {
<Toast />
<h5>Advanced</h5>
<FileUpload name="demo[]" url="./upload.php" @upload="onUpload" :multiple="true" accept="image/*" :maxFileSize="1000000">
<FileUpload name="demo[]" url="https://www.primefaces.org/upload.php" @upload="onAdvancedUpload($event)" :multiple="true" accept="image/*" :maxFileSize="1000000">
<template #content>
<ul v-if="uploadedFiles && uploadedFiles[0]">
<li v-for="file of uploadedFiles[0]" :key="file">{{ file.name }} - {{ file.size }} bytes</li>
</ul>
</template>
<template #empty>
<p>Drag and drop files to here to upload.</p>
</template>
</FileUpload>
<h5>Templating</h5>
<FileUpload name="demo[]" url="./upload.php" @upload="onTemplatedUpload($event)" :multiple="true" accept="image/*" :maxFileSize="1000000" @select="onSelectedFiles">
<template #header="{ chooseCallback, uploadCallback, clearCallback, files }">
<div class="flex flex-wrap justify-content-between align-items-center flex-1 gap-2">
<div class="flex gap-2">
<Button @click="chooseCallback()" icon="pi pi-images" class="p-button-rounded"></Button>
<Button @click="uploadEvent(uploadCallback)" icon="pi pi-cloud-upload" class="p-button-rounded p-button-success" :disabled="!files || files.length === 0"></Button>
<Button @click="clearCallback()" icon="pi pi-times" class="p-button-rounded p-button-danger" :disabled="!files || files.length === 0"></Button>
</div>
<ProgressBar :value="totalSizePercent" :showValue="false" :class="['md:w-20rem h-1rem w-full md:ml-auto', {'exceeded-progress-bar': (totalSizePercent > 100)}]"><span class="white-space-nowrap">{{ totalSize }}B / 1Mb</span></ProgressBar>
</div>
</template>
<template #content="{ files, uploadedFiles, removeUploadedFileCallback, fileRemoveCallback }">
<div v-if="files.length > 0">
<h5>Pending</h5>
<div class="flex flex-wrap p-0 sm:p-5 gap-5">
<div v-for="(file, index) of files" :key="file.name + file.type + file.size" class="card m-0 px-6 flex flex-column border-1 surface-border align-items-center gap-3">
<div>
<img role="presentation" :alt="file.name" :src="file.objectURL" width="100" height="50" class="shadow-2" />
</div>
<span class="font-semibold">{{ file.name }}</span>
<div>{{ formatSize(file.size) }}</div>
<Badge value="Pending" severity="warning" />
<Button icon="pi pi-times" @click="onRemoveTemplatingFile(file, fileRemoveCallback, index)" class="p-button-outlined p-button-danger p-button-rounded" />
</div>
</div>
</div>
<div v-if="uploadedFiles.length > 0">
<h5>Completed</h5>
<div class="flex flex-wrap p-0 sm:p-5 gap-5">
<div v-for="(file, index) of uploadedFiles" :key="file.name + file.type + file.size" class="card m-0 px-6 flex flex-column border-1 surface-border align-items-center gap-3">
<div>
<img role="presentation" :alt="file.name" :src="file.objectURL" width="100" height="50" class="shadow-2" />
</div>
<span class="font-semibold">{{ file.name }}</span>
<div>{{ formatSize(file.size) }}</div>
<Badge value="Completed" class="mt-3" severity="success" />
<Button icon="pi pi-times" @click="removeUploadedFileCallback(index)" class="p-button-outlined p-button-danger p-button-rounded" />
</div>
</div>
</div>
</template>
<template #empty>
<div class="flex align-items-center justify-content-center flex-column">
<i class="pi pi-cloud-upload border-2 border-circle p-5 text-8xl text-400 border-400" />
<p class="mt-4 mb-0">Drag and drop files to here to upload.</p>
</div>
</template>
</FileUpload>
<h5>Basic</h5>
<FileUpload mode="basic" name="demo[]" url="./upload.php" accept="image/*" :maxFileSize="1000000" @upload="onUpload" />
@ -452,31 +742,149 @@ import { useToast } from 'primevue/usetoast';
export default {
setup() {
const toast = useToast();
const onUpload = () => {
toast.add({severity: 'info', summary: 'Success', detail: 'File Uploaded', life: 3000});
const uploadedFile = ref([]);
const files = ref([]);
const totalSize = ref(0);
const totalSizePercent = ref(0);
const onRemoveTemplatingFile = (file, onFileRemove, index) => {
onFileRemove(index);
totalSize.value -= parseInt(this.formatSize(file.size));
totalSizePercent.value = totalSize.value / 10;
}
return { onUpload };
const onClearTemplatingUpload = (clear) => {
clear();
totalSize.value = 0;
totalSizePercent.value = 0;
}
const onSelectedFiles = (event) => {
files.value = event.files;
files.value.forEach((file) => {
totalSize.value += parseInt(this.formatSize(file.size));
});
}
const onAdvancedUpload = () => {
toast.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded', life: 3000 });
}
const uploadEvent = (callback) => {
totalSizePercent.value = totalSize.value / 10;
callback();
},
const onTemplatedUpload = () => {
totalSize.value = 0;
totalSizePercent.value = 0;
toast.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded', life: 3000 });
}
const onUpload = () => {
toast.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded', life: 3000 });
}
const formatSize = (bytes) => {
if (bytes === 0) {
return '0 B';
}
let k = 1000,
dm = 3,
sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
return { onUpload, onRemoveTemplatingFile, onClearTemplatingUpload, onSelectedFiles, onAdvancedUpload, uploadEvent, onTemplatedUpload, onUpload, formatSize };
}
}
<\\/script>
<style lang="scss" scoped>
::v-deep(.custom-progress-bar) {
.p-progressbar-value {
background-color: #f44336;
}
}
</style>
`
},
'browser-source': {
tabName: 'Browser Source',
imports: `<script src="https://unpkg.com/primevue@^3/fileupload/fileupload.min.js"><\\/script>
<script src="https://unpkg.com/primevue@^3/badge/badge.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>
<h5>Advanced</h5>
<p-fileupload name="demo[]" url="./upload.php" @upload="onUpload" :multiple="true" accept="image/*" :max-file-size="1000000">
<p-fileupload name="demo[]" url="https://www.primefaces.org/upload.php" @upload="onAdvancedUpload($event)" :multiple="true" accept="image/*" :max-file-size="1000000">
<template #content>
<ul v-if="uploadedFiles && uploadedFiles[0]">
<li v-for="file of uploadedFiles[0]" :key="file">{{ file.name }} - {{ file.size }} bytes</li>
</ul>
</template>
<template #empty>
<p>Drag and drop files to here to upload.</p>
</template>
</p-fileupload>
<h5>Templating</h5>
<p-fileupload name="demo[]" url="./upload.php" @upload="onTemplatedUpload($event)" :multiple="true" accept="image/*" :max-file-size="1000000" @select="onSelectedFiles">
<template #header="{ chooseCallback, uploadCallback, clearCallback, files }">
<div class="flex flex-wrap justify-content-between align-items-center flex-1 gap-2">
<div class="flex gap-2">
<p-button @click="chooseCallback()" icon="pi pi-images" class="p-button-rounded"></p-button>
<p-button @click="uploadEvent(uploadCallback)" icon="pi pi-cloud-upload" class="p-button-rounded p-button-success" :disabled="!files || files.length === 0"></p-button>
<p-button @click="clearCallback()" icon="pi pi-times" class="p-button-rounded p-button-danger" :disabled="!files || files.length === 0"></p-button>
</div>
<p-progressbar :value="totalSizePercent" :show-value="false" :class="['md:w-20rem h-1rem w-full md:ml-auto', {'exceeded-progress-bar': (totalSizePercent > 100)}]"><span class="white-space-nowrap">{{ totalSize }}B / 1Mb</span></p-progressbar>
</div>
</template>
<template #content="{ files, uploadedFiles, removeUploadedFileCallback, fileRemoveCallback }">
<div v-if="files.length > 0">
<h5>Pending</h5>
<div class="flex flex-wrap p-0 sm:p-5 gap-5">
<div v-for="(file, index) of files" :key="file.name + file.type + file.size" class="card m-0 px-6 flex flex-column border-1 surface-border align-items-center gap-3">
<div>
<img role="presentation" :alt="file.name" :src="file.objectURL" width="100" height="50" class="shadow-2" />
</div>
<span class="font-semibold">{{ file.name }}</span>
<div>{{ formatSize(file.size) }}</div>
<p-badge value="Pending" severity="warning"></p-badge>
<p-button icon="pi pi-times" @click="onRemoveTemplatingFile(file, fileRemoveCallback, index)" class="p-button-outlined p-button-danger p-button-rounded"></p-button>
</div>
</div>
</div>
<div v-if="uploadedFiles.length > 0">
<h5>Completed</h5>
<div class="flex flex-wrap p-0 sm:p-5 gap-5">
<div v-for="(file, index) of uploadedFiles" :key="file.name + file.type + file.size" class="card m-0 px-6 flex flex-column border-1 surface-border align-items-center gap-3">
<div>
<img role="presentation" :alt="file.name" :src="file.objectURL" width="100" height="50" class="shadow-2" />
</div>
<span class="font-semibold">{{ file.name }}</span>
<div>{{ formatSize(file.size) }}</div>
<p-badge value="Completed" class="mt-3" severity="success"></p-badge>
<p-button icon="pi pi-times" @click="removeUploadedFileCallback(index)" class="p-button-outlined p-button-danger p-button-rounded"></p-button>
</div>
</div>
</div>
</template>
<template #empty>
<div class="flex align-items-center justify-content-center flex-column">
<i class="pi pi-cloud-upload border-2 border-circle p-5 text-8xl text-400 border-400"></i>
<p class="mt-4 mb-0">Drag and drop files to here to upload.</p>
</div>
</template>
</p-fileupload>
<h5>Basic</h5>
<p-fileupload mode="basic" name="demo[]" url="./upload.php" accept="image/*" :max-file-size="1000000" @upload="onUpload"></p-fileupload>
@ -491,22 +899,71 @@ export default {
const App = {
setup() {
const toast = useToast();
const onUpload = () => {
toast.add({severity: 'info', summary: 'Success', detail: 'File Uploaded', life: 3000});
const uploadedFile = ref([]);
const files = ref([]);
const totalSize = ref(0);
const totalSizePercent = ref(0);
return {toast, uploadedFile,files,totalSize,totalSizePercent};
},
methods: {
onRemoveTemplatingFile(file, fileRemoveCallback, index) {
fileRemoveCallback(index);
this.totalSize -= parseInt(this.formatSize(file.size));
this.totalSizePercent = this.totalSize / 10;
},
onClearTemplatingUpload(clear) {
clear();
this.totalSize = 0;
this.totalSizePercent = 0;
},
onSelectedFiles(event) {
this.files = event.files;
this.files.forEach((file) => {
this.totalSize += parseInt(this.formatSize(file.size));
});
},
onAdvancedUpload() {
this.$toast.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded', life: 3000 });
},
uploadEvent(callback) {
this.totalSizePercent = this.totalSize / 10;
callback();
},
onTemplatedUpload() {
this.totalSize = 0;
this.totalSizePercent = 0;
this.$toast.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded', life: 3000 });
},
onUpload() {
this.$toast.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded', life: 3000 });
},
formatSize(bytes) {
if (bytes === 0) {
return '0 B';
}
return { onUpload };
let k = 1000,
dm = 3,
sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
},
components: {
"p-fileupload": primevue.fileupload,
"p-button": primevue.button,
"p-badge": primevue.badge,
"p-progressbar": primevue.progressbar,
"p-toast": primevue.toast
}
};
createApp(App)
.use(primevue.config.default)
.use(primevue.toastservice)
.mount("#app");
const app = createApp(App)
app.use(primevue.config.default)
app.use(primevue.toastservice)
app.mount("#app");
<\\/script>
`
}

View File

@ -11,12 +11,65 @@
<div class="content-section implementation">
<div class="card">
<h5>Advanced</h5>
<FileUpload name="demo[]" url="./upload.php" @upload="onUpload" :multiple="true" accept="image/*" :maxFileSize="1000000">
<FileUpload name="demo[]" url="./upload.php" @upload="onAdvancedUpload($event)" :multiple="true" accept="image/*" :maxFileSize="1000000">
<template #empty>
<p>Drag and drop files to here to upload.</p>
</template>
</FileUpload>
<h5>Templating</h5>
<FileUpload name="demo[]" url="./upload.php" @upload="onTemplatedUpload($event)" :multiple="true" accept="image/*" :maxFileSize="1000000" @select="onSelectedFiles">
<template #header="{ chooseCallback, uploadCallback, clearCallback, files }">
<div class="flex flex-wrap justify-content-between align-items-center flex-1 gap-2">
<div class="flex gap-2">
<Button @click="chooseCallback()" icon="pi pi-images" class="p-button-rounded"></Button>
<Button @click="uploadEvent(uploadCallback)" icon="pi pi-cloud-upload" class="p-button-rounded p-button-success" :disabled="!files || files.length === 0"></Button>
<Button @click="clearCallback()" icon="pi pi-times" class="p-button-rounded p-button-danger" :disabled="!files || files.length === 0"></Button>
</div>
<ProgressBar :value="totalSizePercent" :showValue="false" :class="['md:w-20rem h-1rem w-full md:ml-auto', { 'exceeded-progress-bar': totalSizePercent > 100 }]"
><span class="white-space-nowrap">{{ totalSize }}B / 1Mb</span></ProgressBar
>
</div>
</template>
<template #content="{ files, uploadedFiles, removeUploadedFileCallback, fileRemoveCallback }">
<div v-if="files.length > 0">
<h5>Pending</h5>
<div class="flex flex-wrap p-0 sm:p-5 gap-5">
<div v-for="(file, index) of files" :key="file.name + file.type + file.size" class="card m-0 px-6 flex flex-column border-1 surface-border align-items-center gap-3">
<div>
<img role="presentation" :alt="file.name" :src="file.objectURL" width="100" height="50" class="shadow-2" />
</div>
<span class="font-semibold">{{ file.name }}</span>
<div>{{ formatSize(file.size) }}</div>
<Badge value="Pending" severity="warning" />
<Button icon="pi pi-times" @click="onRemoveTemplatingFile(file, fileRemoveCallback, index)" class="p-button-outlined p-button-danger p-button-rounded" />
</div>
</div>
</div>
<div v-if="uploadedFiles.length > 0">
<h5>Completed</h5>
<div class="flex flex-wrap p-0 sm:p-5 gap-5">
<div v-for="(file, index) of uploadedFiles" :key="file.name + file.type + file.size" class="card m-0 px-6 flex flex-column border-1 surface-border align-items-center gap-3">
<div>
<img role="presentation" :alt="file.name" :src="file.objectURL" width="100" height="50" class="shadow-2" />
</div>
<span class="font-semibold">{{ file.name }}</span>
<div>{{ formatSize(file.size) }}</div>
<Badge value="Completed" class="mt-3" severity="success" />
<Button icon="pi pi-times" @click="removeUploadedFileCallback(index)" class="p-button-outlined p-button-danger p-button-rounded" />
</div>
</div>
</div>
</template>
<template #empty>
<div class="flex align-items-center justify-content-center flex-column">
<i class="pi pi-cloud-upload border-2 border-circle p-5 text-8xl text-400 border-400" />
<p class="mt-4 mb-0">Drag and drop files to here to upload.</p>
</div>
</template>
</FileUpload>
<h5>Basic</h5>
<FileUpload mode="basic" name="demo[]" url="./upload.php" accept="image/*" :maxFileSize="1000000" @upload="onUpload" />
@ -31,11 +84,56 @@
<script>
import FileUploadDoc from './FileUploadDoc';
export default {
data() {
return {
uploadedFiles: [],
files: [],
totalSize: 0,
totalSizePercent: 0
};
},
methods: {
onRemoveTemplatingFile(file, fileRemoveCallback, index) {
fileRemoveCallback(index);
this.totalSize -= parseInt(this.formatSize(file.size));
this.totalSizePercent = this.totalSize / 10;
},
onClearTemplatingUpload(clear) {
clear();
this.totalSize = 0;
this.totalSizePercent = 0;
},
onSelectedFiles(event) {
this.files = event.files;
this.files.forEach((file) => {
this.totalSize += parseInt(this.formatSize(file.size));
});
},
onAdvancedUpload() {
this.$toast.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded', life: 3000 });
},
uploadEvent(callback) {
this.totalSizePercent = this.totalSize / 10;
callback();
},
onTemplatedUpload() {
this.$toast.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded', life: 3000 });
},
onUpload() {
this.$toast.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded', life: 3000 });
},
formatSize(bytes) {
if (bytes === 0) {
return '0 B';
}
let k = 1000,
dm = 3,
sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
},
components: {
@ -45,7 +143,9 @@ export default {
</script>
<style lang="scss" scoped>
p {
margin: 0;
::v-deep(.custom-progress-bar) {
.p-progressbar-value {
background-color: var(--red-500);
}
}
</style>

View File

@ -1,5 +1,4 @@
<template>
<ClientOnly>
<AppDoc name="FilterServiceDemo" :sources="sources" :service="['CustomerService']" :data="['customers-large']" github="filterservice/FilterServiceDemo.vue">
<h5>Import via Module</h5>
<pre v-code.script><code>
@ -234,7 +233,6 @@ FilterService.filters['isPrimeNumber'](568985673); //false
<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
</ClientOnly>
</template>
<script>

Some files were not shown because too many files have changed in this diff Show More