Merge branch 'master' into v4

pull/5701/head
tugcekucukoglu 2024-05-03 09:51:16 +03:00
commit d61c9f5e61
40 changed files with 2703 additions and 120 deletions

View File

@ -1,5 +1,37 @@
# Changelog
## [3.52.0](https://github.com/primefaces/primevue/tree/3.52.0) (2024-04-26)
[Full Changelog](https://github.com/primefaces/primevue/compare/3.51.0...3.52.0)
**Fixed bugs:**
- InputOp: Digits only doesn't work on mobile [\#5635](https://github.com/primefaces/primevue/issues/5635)
- Calendar: Hours are set to 00 when clicking the "Today" button [\#5620](https://github.com/primefaces/primevue/issues/5620)
- Paginator: Responsive Templating showing multiple layouts on break points [\#5604](https://github.com/primefaces/primevue/issues/5604)
- InputNumber: The InputNumber is not working properly in the new version [\#5602](https://github.com/primefaces/primevue/issues/5602)
- Menu / Stepper: Pass Through Unstyled Mode [\#5599](https://github.com/primefaces/primevue/issues/5599)
- Hydration defects [\#5593](https://github.com/primefaces/primevue/issues/5593)
- InputNumber: Cannot input number 0 in Hungarian(QWERTZ) layout [\#5577](https://github.com/primefaces/primevue/issues/5577)
- Menu: support style property for submenuHeader item [\#5562](https://github.com/primefaces/primevue/issues/5562)
- InputNumber Not Working android [\#5545](https://github.com/primefaces/primevue/issues/5545)
- InputNumber: Cannot input numbers in AZERTY layout [\#5508](https://github.com/primefaces/primevue/issues/5508)
- DataTable: rowClass, rowStyle typing defects [\#5498](https://github.com/primefaces/primevue/issues/5498)
- DataTable: Modifying value of expendedRow is not reflected [\#5372](https://github.com/primefaces/primevue/issues/5372)
- InputNumber can't enter 0.0x using minFractionDigits/mode="currency" [\#5170](https://github.com/primefaces/primevue/issues/5170)
- Calendar: Input value is not updated when model is changed externally [\#4938](https://github.com/primefaces/primevue/issues/4938)
**Implemented New Features and Enhancements:**
- AutoComplete: Enter does not submit form [\#5618](https://github.com/primefaces/primevue/issues/5618)
- Knob: Added valueTemplate function support [\#5616](https://github.com/primefaces/primevue/issues/5616)
- Tree: Missing Passthrough Options [\#5574](https://github.com/primefaces/primevue/issues/5574)
- Sidebar: dismissable prop can't be changed dynamically [\#5563](https://github.com/primefaces/primevue/issues/5563)
- TreeTable: filterField ignored [\#5525](https://github.com/primefaces/primevue/issues/5525)
- ScrollPanel: Errors in moveBar() when xBar and yBar attributes don't exist [\#5518](https://github.com/primefaces/primevue/issues/5518)
- Toast: Race condition on remove [\#5225](https://github.com/primefaces/primevue/issues/5225)
- Dropdown: aria-label missing from inner ul element [\#5277](https://github.com/primefaces/primevue/issues/5277)
## [3.51.0](https://github.com/primefaces/primevue/tree/3.51.0) (2024-04-04)
[Full Changelog](https://github.com/primefaces/primevue/compare/3.50.0...3.51.0)

View File

@ -99,7 +99,7 @@ const FileUploadProps = [
name: 'customUpload',
type: 'boolean',
default: 'false',
description: 'Whether to use the default upload or a manual implementation defined in uploadHandler callback. Defaults to PrimeVue Locale configuration.'
description: 'Whether to use the default upload or a manual implementation defined in uploadHandler callback.'
},
{
name: 'showUploadButton',

View File

@ -73,9 +73,9 @@ const KnobProps = [
},
{
name: 'valueTemplate',
type: 'string',
type: 'function | string',
default: '{value}',
description: 'Template string of the value.'
description: 'Template of the value.'
},
{
name: 'tabindex',

View File

@ -89,6 +89,7 @@
{
"name": "FloatLabel",
"to": "/floatlabel"
"to": "/floatlabel"
},
{
"name": "IconField",
@ -451,6 +452,7 @@
{
"name": "MeterGroup",
"to": "/metergroup"
"to": "/metergroup"
},
{
"name": "ScrollTop",

View File

@ -121,5 +121,3 @@ export default {
}
};
</script>
:style="{backgroundImage: imageBg('diamond')}">

View File

@ -132,7 +132,7 @@
<slot name="header" :value="modelValue" :suggestions="visibleOptions"></slot>
<VirtualScroller :ref="virtualScrollerRef" v-bind="virtualScrollerOptions" :style="{ height: scrollHeight }" :items="visibleOptions" :tabindex="-1" :disabled="virtualScrollerDisabled" :pt="ptm('virtualScroller')">
<template v-slot:content="{ styleClass, contentRef, items, getItemOptions, contentStyle, itemSize }">
<ul :ref="(el) => listRef(el, contentRef)" :id="id + '_list'" :class="[cx('list'), styleClass]" :style="contentStyle" role="listbox" v-bind="ptm('list')">
<ul :ref="(el) => listRef(el, contentRef)" :id="id + '_list'" :class="[cx('list'), styleClass]" :style="contentStyle" role="listbox" :aria-label="listAriaLabel" v-bind="ptm('list')">
<template v-for="(option, i) of items" :key="getOptionRenderKey(option, getOptionIndex(i, getItemOptions))">
<li v-if="isOptionGroup(option)" :id="id + '_' + getOptionIndex(i, getItemOptions)" :style="{ height: itemSize ? itemSize + 'px' : undefined }" :class="cx('itemGroup')" role="option" v-bind="ptm('itemGroup')">
<slot name="optiongroup" :option="option.optionGroup" :item="option.optionGroup" :index="getOptionIndex(i, getItemOptions)">{{ getOptionGroupLabel(option.optionGroup) }}</slot>
@ -641,8 +641,6 @@ export default {
this.hide();
}
event.preventDefault();
},
onEscapeKey(event) {
this.overlayVisible && this.hide(true);
@ -942,6 +940,9 @@ export default {
selectedMessageText() {
return this.hasSelectedOption ? this.selectionMessageText.replaceAll('{0}', this.multiple ? this.modelValue.length : '1') : this.emptySelectionMessageText;
},
listAriaLabel() {
return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.listLabel : undefined;
},
focusedOptionId() {
return this.focusedOptionIndex !== -1 ? `${this.id}_${this.focusedOptionIndex}` : null;
},

File diff suppressed because it is too large Load Diff

View File

@ -161,6 +161,9 @@ export default {
},
containerRef(el) {
this.container = el;
},
listAriaLabel() {
return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.listLabel : undefined;
}
},
directives: {

View File

@ -322,6 +322,7 @@ export interface PrimeVueLocaleAriaOptions {
zoomOut?: string;
rotateRight?: string;
rotateLeft?: string;
listLabel?: string;
}
export interface PrimeVueLocaleOptions {

View File

@ -120,7 +120,8 @@ export const defaultOptions = {
zoomIn: 'Zoom In',
zoomOut: 'Zoom Out',
rotateRight: 'Rotate Right',
rotateLeft: 'Rotate Left'
rotateLeft: 'Rotate Left',
listLabel: 'Option List'
}
},
filterMatchModeOptions: {

View File

@ -282,6 +282,7 @@ export default {
},
watch: {
expandedRows: {
deep: true,
immediate: true,
handler(newValue) {
this.d_rowExpanded = this.dataKey ? newValue?.[ObjectUtils.resolveFieldData(this.rowData, this.dataKey)] !== undefined : newValue?.some((d) => this.equals(this.rowData, d));

View File

@ -1135,12 +1135,15 @@ export interface DataTableProps {
editingRows?: any[] | DataTableEditingRows;
/**
* A function that takes the row data as a parameter and returns a string to apply a particular class for the row.
* The return value is added to the row's :classes array (see Vue.js class bindings).
*/
rowClass?: (data: any) => object | undefined;
rowClass?: (data: any) => string | object | undefined;
/**
* A function that takes the row data as a parameter and returns the inline style for the corresponding row.
* A function that takes the row data as a parameter and returns the inline style object for the corresponding row.
* The function may also return an array of style objects which will be merged.
* The return value of this function is directly applied as a Vue.js style-binding on the table row.
*/
rowStyle?: (data: any) => object | undefined;
rowStyle?: (data: any) => object | object[] | undefined;
/**
* When specified, enables horizontal and/or vertical scrolling.
* @defaultValue false

View File

@ -59,6 +59,15 @@ export default {
$pcDrawer: this,
$parentInstance: this
};
},
watch: {
dismissable(newValue) {
if (newValue) {
this.bindOutsideClickListener();
} else {
this.unbindOutsideClickListener();
}
}
}
};
</script>

View File

@ -120,4 +120,12 @@ describe('Drawer.vue', () => {
expect(wrapper.vm.containerVisible).toBeFalsy();
});
it('When component is mounted , dismissable property should still be reactive', async () => {
await wrapper.setProps({ dismissable: false, visible: true });
await wrapper.setProps({ dismissable: true });
expect(wrapper.vm.containerVisible).toBeTruthy();
});
});

View File

@ -70,6 +70,10 @@ export interface InputNumberInputEvent {
* New value
*/
value: string | number | undefined;
/**
* currentValue
*/
formattedValue: string;
}
/**

View File

@ -10,6 +10,7 @@
:aria-valuemin="min"
:aria-valuemax="max"
:aria-valuenow="modelValue"
:inputmode="mode === 'decimal' && !minFractionDigits ? 'numeric' : 'decimal'"
:disabled="disabled"
:readonly="readonly"
:placeholder="placeholder"
@ -19,6 +20,7 @@
:variant="variant"
@input="onUserInput"
@keydown="onInputKeyDown"
@keypress="onInputKeyPress"
@paste="onPaste"
@click="onInputClick"
@focus="onInputFocus"
@ -355,8 +357,9 @@ export default {
return;
}
if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) {
if (event.altKey || event.ctrlKey || event.metaKey) {
this.isSpecialChar = true;
this.lastValue = this.$refs.input.$el.value;
return;
}
@ -504,23 +507,26 @@ export default {
break;
default:
if (this.readonly) {
return;
}
event.preventDefault();
let char = event.key;
const isDecimalSign = this.isDecimalSign(char);
const isMinusSign = this.isMinusSign(char);
if (((event.code.startsWith('Digit') || event.code.startsWith('Numpad')) && Number(char) >= 0 && Number(char) <= 9) || isMinusSign || isDecimalSign) {
this.insert(event, char, { isDecimalSign, isMinusSign });
}
break;
}
},
onInputKeyPress(event) {
if (this.readonly) {
return;
}
let char = event.key;
let isDecimalSign = this.isDecimalSign(char);
const isMinusSign = this.isMinusSign(char);
if (event.code !== 'Enter') {
event.preventDefault();
}
if ((Number(char) >= 0 && Number(char) <= 9) || isMinusSign || isDecimalSign) {
this.insert(event, char, { isDecimalSign, isMinusSign });
}
},
onPaste(event) {
event.preventDefault();
let data = (event.clipboardData || window['clipboardData']).getData('Text');
@ -830,10 +836,7 @@ export default {
this.$refs.input.$el.setSelectionRange(selectionEnd, selectionEnd);
} else if (newLength === currentLength) {
if (operation === 'insert' || operation === 'delete-back-single') {
const re = /[.,]/g;
const newSelectionEnd = selectionEnd + Number(re.test(value) || re.test(insertedValueStr));
this.$refs.input.$el.setSelectionRange(newSelectionEnd, newSelectionEnd);
this.$refs.input.$el.setSelectionRange(selectionEnd + 1, selectionEnd + 1);
} else if (operation === 'delete-single') {
this.$refs.input.$el.setSelectionRange(selectionEnd - 1, selectionEnd - 1);
} else if (operation === 'delete-range' || operation === 'spin') {

View File

@ -157,7 +157,7 @@ export default {
break;
default:
if ((this.integerOnly && !((event.code.startsWith('Digit') || event.code.startsWith('Numpad')) && Number(event.key) >= 0 && Number(event.key) <= 9)) || (this.tokens.join('').length >= this.length && event.code !== 'Delete')) {
if ((this.integerOnly && !(Number(event.key) >= 0 && Number(event.key) <= 9)) || (this.tokens.join('').length >= this.length && event.code !== 'Delete')) {
event.preventDefault();
}

View File

@ -62,7 +62,7 @@ export default {
default: true
},
valueTemplate: {
type: String,
type: [String, Function],
default: '{value}'
},
tabindex: {

View File

@ -178,7 +178,7 @@ export interface KnobProps {
* Template string of the value.
* @defaultValue '{value}'
*/
valueTemplate?: string | undefined;
valueTemplate?: (val: number) => string | string | undefined;
/**
* Index of the element in tabbing order.
* @defaultValue 0

View File

@ -44,4 +44,16 @@ describe('Knob.vue', () => {
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([30]);
});
it('should work with string valueTemplate', async () => {
await wrapper.setProps({ valueTemplate: '{value}%' });
expect(wrapper.find('.p-knob-text').text()).toBe('20%');
});
it('should work with function valueTemplate', async () => {
await wrapper.setProps({ valueTemplate: (val) => val * 10 });
expect(wrapper.find('.p-knob-text').text()).toBe('200');
});
});

View File

@ -215,7 +215,11 @@ export default {
return this.valueRadians > this.zeroRadians ? 0 : 1;
},
valueToDisplay() {
return this.valueTemplate.replace(/{value}/g, this.modelValue);
if (typeof this.valueTemplate === 'string') {
return this.valueTemplate.replace(/{value}/g, this.modelValue);
} else {
return this.valueTemplate(this.modelValue);
}
}
}
};

View File

@ -32,6 +32,7 @@
:item="child"
:templates="$slots"
:focusedOptionId="focusedOptionId"
:unstyled="unstyled"
@item-click="itemClick"
@item-mousemove="itemMouseMove"
:pt="pt"
@ -40,7 +41,19 @@
</template>
</template>
<li v-else-if="visible(item) && item.separator" :key="'separator' + i.toString()" :class="[cx('separator'), item.class]" :style="item.style" role="separator" v-bind="ptm('separator')"></li>
<PVMenuitem v-else :key="label(item) + i.toString()" :id="id + '_' + i" :item="item" :index="i" :templates="$slots" :focusedOptionId="focusedOptionId" @item-click="itemClick" @item-mousemove="itemMouseMove" :pt="pt" />
<PVMenuitem
v-else
:key="label(item) + i.toString()"
:id="id + '_' + i"
:item="item"
:index="i"
:templates="$slots"
:focusedOptionId="focusedOptionId"
:unstyled="unstyled"
@item-click="itemClick"
@item-mousemove="itemMouseMove"
:pt="pt"
/>
</template>
</ul>
<div v-if="$slots.end" :class="cx('end')" v-bind="ptm('end')">

View File

@ -117,7 +117,7 @@
<div :class="cx('wrapper')" :style="{ 'max-height': virtualScrollerDisabled ? scrollHeight : '' }" v-bind="ptm('wrapper')">
<VirtualScroller :ref="virtualScrollerRef" v-bind="virtualScrollerOptions" :items="visibleOptions" :style="{ height: scrollHeight }" :tabindex="-1" :disabled="virtualScrollerDisabled" :pt="ptm('virtualScroller')">
<template v-slot:content="{ styleClass, contentRef, items, getItemOptions, contentStyle, itemSize }">
<ul :ref="(el) => listRef(el, contentRef)" :id="id + '_list'" :class="[cx('list'), styleClass]" :style="contentStyle" role="listbox" aria-multiselectable="true" v-bind="ptm('list')">
<ul :ref="(el) => listRef(el, contentRef)" :id="id + '_list'" :class="[cx('list'), styleClass]" :style="contentStyle" role="listbox" aria-multiselectable="true" :aria-label="listAriaLabel" v-bind="ptm('list')">
<template v-for="(option, i) of items" :key="getOptionRenderKey(option, getOptionIndex(i, getItemOptions))">
<li v-if="isOptionGroup(option)" :id="id + '_' + getOptionIndex(i, getItemOptions)" :style="{ height: itemSize ? itemSize + 'px' : undefined }" :class="cx('itemGroup')" role="option" v-bind="ptm('itemGroup')">
<slot name="optiongroup" :option="option.optionGroup" :index="getOptionIndex(i, getItemOptions)">{{ getOptionGroupLabel(option.optionGroup) }}</slot>
@ -1082,6 +1082,12 @@ export default {
toggleAllAriaLabel() {
return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria[this.allSelected ? 'selectAll' : 'unselectAll'] : undefined;
},
closeAriaLabel() {
return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.close : undefined;
},
listAriaLabel() {
return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.listLabel : undefined;
},
virtualScrollerDisabled() {
return !this.virtualScrollerOptions;
}

View File

@ -175,7 +175,6 @@ export default {
innerHTML += `
@media screen ${minValue} {
.paginator[${this.attributeSelector}],
.p-paginator-default{
display: flex;
}
}

View File

@ -129,22 +129,27 @@ export default {
this.scrollYRatio = ownHeight / totalHeight;
this.frame = this.requestAnimationFrame(() => {
if (this.scrollXRatio >= 1) {
this.$refs.xBar.setAttribute('data-p-scrollpanel-hidden', 'true');
!this.isUnstyled && DomHandler.addClass(this.$refs.xBar, 'p-scrollpanel-hidden');
} else {
this.$refs.xBar.setAttribute('data-p-scrollpanel-hidden', 'false');
!this.isUnstyled && DomHandler.removeClass(this.$refs.xBar, 'p-scrollpanel-hidden');
this.$refs.xBar.style.cssText = 'width:' + Math.max(this.scrollXRatio * 100, 10) + '%; left:' + (this.$refs.content.scrollLeft / totalWidth) * 100 + '%;bottom:' + bottom + 'px;';
if (this.$refs.xBar) {
if (this.scrollXRatio >= 1) {
this.$refs.xBar.setAttribute('data-p-scrollpanel-hidden', 'true');
!this.isUnstyled && DomHandler.addClass(this.$refs.xBar, 'p-scrollpanel-hidden');
} else {
this.$refs.xBar.setAttribute('data-p-scrollpanel-hidden', 'false');
!this.isUnstyled && DomHandler.removeClass(this.$refs.xBar, 'p-scrollpanel-hidden');
this.$refs.xBar.style.cssText = 'width:' + Math.max(this.scrollXRatio * 100, 10) + '%; left:' + (this.$refs.content.scrollLeft / totalWidth) * 100 + '%;bottom:' + bottom + 'px;';
}
}
if (this.scrollYRatio >= 1) {
this.$refs.yBar.setAttribute('data-p-scrollpanel-hidden', 'true');
!this.isUnstyled && DomHandler.addClass(this.$refs.yBar, 'p-scrollpanel-hidden');
} else {
this.$refs.yBar.setAttribute('data-p-scrollpanel-hidden', 'false');
!this.isUnstyled && DomHandler.removeClass(this.$refs.yBar, 'p-scrollpanel-hidden');
this.$refs.yBar.style.cssText = 'height:' + Math.max(this.scrollYRatio * 100, 10) + '%; top: calc(' + (this.$refs.content.scrollTop / totalHeight) * 100 + '% - ' + this.$refs.xBar.clientHeight + 'px);right:' + right + 'px;';
if (this.$refs.yBar) {
if (this.scrollYRatio >= 1) {
this.$refs.yBar.setAttribute('data-p-scrollpanel-hidden', 'true');
!this.isUnstyled && DomHandler.addClass(this.$refs.yBar, 'p-scrollpanel-hidden');
} else {
this.$refs.yBar.setAttribute('data-p-scrollpanel-hidden', 'false');
!this.isUnstyled && DomHandler.removeClass(this.$refs.yBar, 'p-scrollpanel-hidden');
this.$refs.yBar.style.cssText =
'height:' + Math.max(this.scrollYRatio * 100, 10) + '%; top: calc(' + (this.$refs.content.scrollTop / totalHeight) * 100 + '% - ' + this.$refs.xBar.clientHeight + 'px);right:' + right + 'px;';
}
}
});
}

View File

@ -31,6 +31,7 @@
:clickCallback="(event) => onItemClick(event, index)"
:getStepPT="getStepPT"
:getStepProp="getStepProp"
:unstyled="unstyled"
/>
</slot>
<slot v-if="index !== stepperpanels.length - 1" name="separator">
@ -42,6 +43,7 @@
:active="isStepActive(index)"
:highlighted="index < d_activeStep"
:getStepPT="getStepPT(step, 'separator', index)"
:unstyled="unstyled"
/>
</slot>
</li>
@ -61,6 +63,7 @@
:nextCallback="(event) => nextCallback(event, index)"
:getStepPT="getStepPT"
:aria-labelledby="getStepHeaderActionId(index)"
:unstyled="unstyled"
/>
</template>
</div>

View File

@ -72,17 +72,12 @@ export default {
this.messages = [...this.messages, message];
},
remove(params) {
let index = -1;
const index = this.messages.findIndex((m) => m.id === params.message.id);
for (let i = 0; i < this.messages.length; i++) {
if (this.messages[i] === params.message) {
index = i;
break;
}
if (index !== -1) {
this.messages.splice(index, 1);
this.$emit(params.type, { message: params.message });
}
this.messages.splice(index, 1);
this.$emit(params.type, { message: params.message });
},
onAdd(message) {
if (this.group == message.group) {

View File

@ -31,7 +31,7 @@
<component v-if="templates['checkboxicon']" :is="templates['checkboxicon']" :checked="slotProps.checked" :partialChecked="partialChecked" :class="slotProps.class" />
</template>
</Checkbox>
<component v-if="templates['nodeicon']" :is="templates['nodeicon']" :node="node" :class="[cx('nodeIcon')]"></component>
<component v-if="templates['nodeicon']" :is="templates['nodeicon']" :node="node" :class="[cx('nodeIcon')]" v-bind="getPTOptions('nodeIcon')"></component>
<span v-else :class="[cx('nodeIcon'), node.icon]" v-bind="getPTOptions('nodeIcon')"></span>
<span :class="cx('label')" v-bind="getPTOptions('label')" @keydown.stop>
<component v-if="templates[node.type] || templates['default']" :is="templates[node.type] || templates['default']" :node="node" />

View File

@ -488,12 +488,12 @@ export default {
for (let j = 0; j < this.columns.length; j++) {
let col = this.columns[j];
let filterField = this.columnProp(col, 'field');
let filterField = this.columnProp(col, 'filterField') || this.columnProp(col, 'field');
//local
if (Object.prototype.hasOwnProperty.call(this.filters, this.columnProp(col, 'field'))) {
if (Object.prototype.hasOwnProperty.call(this.filters, filterField)) {
let filterMatchMode = this.columnProp(col, 'filterMatchMode') || 'startsWith';
let filterValue = this.filters[this.columnProp(col, 'field')];
let filterValue = this.filters[filterField];
let filterConstraint = FilterService.filters[filterMatchMode];
let paramsWithoutNode = { filterField, filterValue, filterConstraint, strict };

View File

@ -6,39 +6,56 @@
</p>
</DocSectionText>
<div class="card flex justify-content-center">
<AutoComplete v-model="value" :suggestions="items" @complete="search" forceSelection />
<AutoComplete v-model="selectedCountry" forceSelection optionLabel="name" :suggestions="filteredCountries" @complete="search" />
</div>
<DocSectionCode :code="code" />
<DocSectionCode :code="code" :service="['CountryService']" />
</template>
<script>
import { CountryService } from '@/service/CountryService';
export default {
data() {
return {
value: '',
items: [],
countries: null,
selectedCountry: null,
filteredCountries: null,
code: {
basic: `
<AutoComplete v-model="value" :suggestions="items" @complete="search" forceSelection />
<AutoComplete v-model="selectedCountry" forceSelection optionLabel="name" :suggestions="filteredCountries" @complete="search" />
`,
options: `
<template>
<div class="card flex justify-content-center">
<AutoComplete v-model="value" :suggestions="items" @complete="search" forceSelection />
<AutoComplete v-model="selectedCountry" forceSelection optionLabel="name" :suggestions="filteredCountries" @complete="search" />
</div>
</template>
<script>
import { CountryService } from '@/service/CountryService';
export default {
data() {
return {
value: '',
items: []
countries: null,
selectedCountry: null,
filteredCountries: null
};
},
mounted() {
CountryService.getCountries().then((data) => (this.countries = data));
},
methods: {
search(event) {
this.items = [...Array(10).keys()].map((item) => event.query + '-' + item);
setTimeout(() => {
if (!event.query.trim().length) {
this.filteredCountries = [...this.countries];
} else {
this.filteredCountries = this.countries.filter((country) => {
return country.name.toLowerCase().startsWith(event.query.toLowerCase());
});
}
}, 250);
}
}
};
@ -47,27 +64,53 @@ export default {
composition: `
<template>
<div class="card flex justify-content-center">
<AutoComplete v-model="value" :suggestions="items" @complete="search" forceSelection />
<AutoComplete v-model="selectedCountry" forceSelection optionLabel="name" :suggestions="filteredCountries" @complete="search" />
</div>
</template>
<script setup>
import { ref } from "vue";
import { ref, onMounted } from "vue";
import { CountryService } from "@/service/CountryService";
onMounted(() => {
CountryService.getCountries().then((data) => (countries.value = data));
});
const countries = ref();
const selectedCountry = ref();
const filteredCountries = ref();
const value = ref("");
const items = ref([]);
const search = (event) => {
items.value = [...Array(10).keys()].map((item) => event.query + '-' + item);
setTimeout(() => {
if (!event.query.trim().length) {
filteredCountries.value = [...countries.value];
} else {
filteredCountries.value = countries.value.filter((country) => {
return country.name.toLowerCase().startsWith(event.query.toLowerCase());
});
}
}, 250);
}
<\/script>
`
}
};
},
mounted() {
CountryService.getCountries().then((data) => (this.countries = data));
},
methods: {
search(event) {
this.items = [...Array(10).keys()].map((item) => event.query + '-' + item);
setTimeout(() => {
if (!event.query.trim().length) {
this.filteredCountries = [...this.countries];
} else {
this.filteredCountries = this.countries.filter((country) => {
return country.name.toLowerCase().startsWith(event.query.toLowerCase());
});
}
}, 250);
}
}
};

View File

@ -24,14 +24,12 @@ export default {
code: {
basic: `
<Breadcrumb :home="home" :model="items">
<template #item="item">
<template #item="{ item }">
<a class="cursor-pointer" :href="item.url">
<span :class="item.icon"></span>
</a>
</template>
<template #separator> / </template>
<template #item="{ item }">
<a class="cursor-pointer" :href="item.url">
<span :class="item.icon"></span>
</a>
</template>
<template #separator> / </template>
</Breadcrumb>
`,
options: `

View File

@ -17159,6 +17159,13 @@
"readonly": false,
"type": "string",
"default": ""
},
{
"name": "listLabel",
"optional": true,
"readonly": false,
"type": "string",
"default": ""
}
],
"methods": []
@ -35484,6 +35491,14 @@
"type": "undefined | string | number",
"default": "",
"description": "New value"
},
{
"name": "formattedValue",
"optional": false,
"readonly": false,
"type": "string",
"default": "",
"description": "currentValue"
}
],
"methods": []
@ -37575,9 +37590,8 @@
"name": "valueTemplate",
"optional": true,
"readonly": false,
"type": "string",
"default": "'{value}'",
"description": "Template string of the value."
"type": "Function",
"default": ""
},
{
"name": "tabindex",

View File

@ -1,6 +1,6 @@
<template>
<DocSectionText v-bind="$attrs">
<p>ContextMenu requires a collection of menuitems as its <i>model</i> and the <i>show</i> method needs to be called explicity using an event of the target like <i>contextmenu</i> to display the menu.</p>
<p>The <i>command</i> property defines the callback to run when an item is activated by click or a key event.</p>
</DocSectionText>
<div class="card flex md:justify-content-center">
<ul class="m-0 p-0 list-none border-1 surface-border border-round p-3 flex flex-column gap-2 w-full md:w-30rem">

View File

@ -1,6 +1,6 @@
<template>
<DocSectionText v-bind="$attrs">
<p>When content exceeeds viewport, Dialog automatically becomes scrollable.</p>
<p>When content exceeds viewport, Dialog automatically becomes scrollable.</p>
</DocSectionText>
<div class="card flex justify-content-center">

View File

@ -1,6 +1,6 @@
<template>
<DocSectionText v-bind="$attrs">
<p>Label is a string template that can be customized with the <i>valueTemplate</i> property having <i>60</i> as the placeholder .</p>
<p>The label can be customized with the <i>valueTemplate</i> property using either a template string or a function.</p>
</DocSectionText>
<div class="card flex justify-content-center">
<Knob v-model="value" valueTemplate="{value}%" />

View File

@ -58,7 +58,7 @@ export default {
},
{
label: 'Vite.js',
url: 'https://vuejs.org/'
url: 'https://vitejs.dev/'
}
]
}
@ -138,7 +138,7 @@ export default {
},
{
label: 'Vite.js',
url: 'https://vuejs.org/'
url: 'https://vitejs.dev/'
}
]
}
@ -207,7 +207,7 @@ const items = ref([
},
{
label: 'Vite.js',
url: 'https://vuejs.org/'
url: 'https://vitejs.dev/'
}
]
}

View File

@ -4,13 +4,15 @@
<DocSectionCode :code="code1" importCode hideToggleCode hideStackBlitz />
<p>In case all components are imported, particular components can still be excluded with the <i>exclude</i> option.</p>
<DocSectionCode :code="code2" importCode hideToggleCode hideStackBlitz />
<p>Use the <i>prefix</i> option to give a prefix to the registered component names.</p>
<p>By default, for compatibility reasons, Chart and Editor components are excluded. To include them simply set the <i>exclude</i> option to an empty list.</p>
<DocSectionCode :code="code3" importCode hideToggleCode hideStackBlitz />
<p>Use the <i>prefix</i> option to give a prefix to the registered component names.</p>
<DocSectionCode :code="code4" importCode hideToggleCode hideStackBlitz />
<p>
Component registration can be customized further by implementing the <i>name</i> function that gets an object representing the import metadata. <i>name</i> is the label of the component, <i>as</i> is the default export name and
<i>from</i> is the import path.
</p>
<DocSectionCode :code="code4" importCode hideToggleCode hideStackBlitz />
<DocSectionCode :code="code5" importCode hideToggleCode hideStackBlitz />
</DocSectionText>
</template>
@ -39,6 +41,15 @@ primevue: {
},
code3: {
basic: `
primevue: {
components: {
exclude: []
}
}
`
},
code4: {
basic: `
primevue: {
components: {
prefix: 'Prime'
@ -47,7 +58,7 @@ primevue: {
}
`
},
code4: {
code5: {
basic: `
primevue: {
components: {

View File

@ -55,6 +55,10 @@
<td>p-focus</td>
<td>Container element when it is in focus.</td>
</tr>
<tr>
<td>p-highlight</td>
<td>Container element when it is selected.</td>
</tr>
</tbody>
</table>
</div>

View File

@ -7,11 +7,11 @@
</DocSectionText>
<div class="card flex flex-wrap p-fluid gap-3">
<div class="flex-auto md:flex md:justify-content-start md:align-items-center flex-column">
<label for="mask" class="font-bold block mb-2">Mask Mode</label>
<label class="font-bold block mb-2">Mask Mode</label>
<Tree :value="nodes" @node-expand="onNodeExpand" :loading="loading" class="w-full md:w-30rem"></Tree>
</div>
<div class="flex-auto md:flex md:justify-content-start md:align-items-center flex-column">
<label for="mask" class="font-bold block mb-2">Icon Mode</label>
<label class="font-bold block mb-2">Icon Mode</label>
<Tree :value="nodes2" @node-expand="onNodeExpand2" loadingMode="icon" class="w-full md:w-30rem"></Tree>
</div>
</div>
@ -34,11 +34,11 @@ export default {
<template>
<div class="card flex flex-wrap p-fluid gap-3">
<div class="flex-auto md:flex md:justify-content-start md:align-items-center flex-column">
<label for="mask" class="font-bold block mb-2">Mask Mode</label>
<label class="font-bold block mb-2">Mask Mode</label>
<Tree :value="nodes" @node-expand="onNodeExpand" :loading="loading" class="w-full md:w-30rem"></Tree>
</div>
<div class="flex-auto md:flex md:justify-content-start md:align-items-center flex-column">
<label for="mask" class="font-bold block mb-2">Icon Mode</label>
<label class="font-bold block mb-2">Icon Mode</label>
<Tree :value="nodes2" @node-expand="onNodeExpand2" loadingMode="icon" class="w-full md:w-30rem"></Tree>
</div>
</div>
@ -55,10 +55,10 @@ export default {
},
mounted() {
this.loading = true;
this.nodes2 = this.initateNodes2();
this.nodes2 = this.initiateNodes2();
setTimeout(() => {
this.nodes = this.initateNodes();
this.nodes = this.initiateNodes();
this.loading = false;
this.nodes2.map((node) => (node.loading = false));
}, 2000);
@ -112,7 +112,7 @@ export default {
}, 500);
}
},
initateNodes() {
initiateNodes() {
return [
{
key: '0',
@ -131,7 +131,7 @@ export default {
}
];
},
initateNodes2() {
initiateNodes2() {
return [
{
key: '0',
@ -161,11 +161,11 @@ export default {
<template>
<div class="card flex flex-wrap p-fluid gap-3">
<div class="flex-auto md:flex md:justify-content-start md:align-items-center flex-column">
<label for="mask" class="font-bold block mb-2">Mask Mode</label>
<label class="font-bold block mb-2">Mask Mode</label>
<Tree :value="nodes" @node-expand="onNodeExpand" :loading="loading" class="w-full md:w-30rem"></Tree>
</div>
<div class="flex-auto md:flex md:justify-content-start md:align-items-center flex-column">
<label for="mask" class="font-bold block mb-2">Icon Mode</label>
<label class="font-bold block mb-2">Icon Mode</label>
<Tree :value="nodes2" @node-expand="onNodeExpand2" loadingMode="icon" class="w-full md:w-30rem"></Tree>
</div>
</div>
@ -183,7 +183,7 @@ onMounted(() => {
nodes2.value = initiateNodes2();
setTimeout(() => {
nodes.value = initateNodes();
nodes.value = initiateNodes();
loading.value = false;
nodes2.value.map((node) => (node.loading = false));
}, 2000);
@ -239,7 +239,7 @@ const onNodeExpand2 = (node) => {
}
};
const initateNodes = () => {
const initiateNodes = () => {
return [
{
key: '0',
@ -259,7 +259,7 @@ const initateNodes = () => {
];
};
const initateNodes2 = () => {
const initiateNodes2 = () => {
return [
{
key: '0',
@ -315,10 +315,10 @@ const initateNodes2 = () => {
},
mounted() {
this.loading = true;
this.nodes2 = this.initateNodes2();
this.nodes2 = this.initiateNodes2();
setTimeout(() => {
this.nodes = this.initateNodes();
this.nodes = this.initiateNodes();
this.loading = false;
this.nodes2.map((node) => (node.loading = false));
}, 2000);
@ -373,7 +373,7 @@ const initateNodes2 = () => {
}, 500);
}
},
initateNodes() {
initiateNodes() {
return [
{
key: '0',
@ -392,7 +392,7 @@ const initateNodes2 = () => {
}
];
},
initateNodes2() {
initiateNodes2() {
return [
{
key: '0',

View File

@ -18,12 +18,12 @@ export default {
selectedValue: null,
code: {
basic: `
<TreeSelect v-model="selectedValue" :options="nodes" placeholder="Select Item" class="md:w-20rem w-full" />
<TreeSelect v-model="selectedValue" variant="filled" :options="nodes" placeholder="Select Item" class="md:w-20rem w-full" />
`,
options: `
<template>
<div class="card flex justify-content-center">
<TreeSelect v-model="selectedValue" :options="nodes" placeholder="Select Item" class="md:w-20rem w-full" />
<TreeSelect v-model="selectedValue" variant="filled" :options="nodes" placeholder="Select Item" class="md:w-20rem w-full" />
</div>
</template>
@ -46,7 +46,7 @@ export default {
composition: `
<template>
<div class="card flex justify-content-center">
<TreeSelect v-model="selectedValue" :options="nodes" placeholder="Select Item" class="md:w-20rem w-full" />
<TreeSelect v-model="selectedValue" variant="filled" :options="nodes" placeholder="Select Item" class="md:w-20rem w-full" />
</div>
</template>