Merge branch 'master' into v4
commit
d61c9f5e61
32
CHANGELOG.md
32
CHANGELOG.md
|
@ -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)
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -89,6 +89,7 @@
|
|||
{
|
||||
"name": "FloatLabel",
|
||||
"to": "/floatlabel"
|
||||
"to": "/floatlabel"
|
||||
},
|
||||
{
|
||||
"name": "IconField",
|
||||
|
@ -451,6 +452,7 @@
|
|||
{
|
||||
"name": "MeterGroup",
|
||||
"to": "/metergroup"
|
||||
"to": "/metergroup"
|
||||
},
|
||||
{
|
||||
"name": "ScrollTop",
|
||||
|
|
|
@ -121,5 +121,3 @@ export default {
|
|||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
:style="{backgroundImage: imageBg('diamond')}">
|
||||
|
|
|
@ -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
|
@ -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: {
|
||||
|
|
|
@ -322,6 +322,7 @@ export interface PrimeVueLocaleAriaOptions {
|
|||
zoomOut?: string;
|
||||
rotateRight?: string;
|
||||
rotateLeft?: string;
|
||||
listLabel?: string;
|
||||
}
|
||||
|
||||
export interface PrimeVueLocaleOptions {
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -59,6 +59,15 @@ export default {
|
|||
$pcDrawer: this,
|
||||
$parentInstance: this
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
dismissable(newValue) {
|
||||
if (newValue) {
|
||||
this.bindOutsideClickListener();
|
||||
} else {
|
||||
this.unbindOutsideClickListener();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -70,6 +70,10 @@ export interface InputNumberInputEvent {
|
|||
* New value
|
||||
*/
|
||||
value: string | number | undefined;
|
||||
/**
|
||||
* currentValue
|
||||
*/
|
||||
formattedValue: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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') {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ export default {
|
|||
default: true
|
||||
},
|
||||
valueTemplate: {
|
||||
type: String,
|
||||
type: [String, Function],
|
||||
default: '{value}'
|
||||
},
|
||||
tabindex: {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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')">
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -175,7 +175,6 @@ export default {
|
|||
innerHTML += `
|
||||
@media screen ${minValue} {
|
||||
.paginator[${this.attributeSelector}],
|
||||
.p-paginator-default{
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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 };
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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: `
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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}%" />
|
||||
|
|
|
@ -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/'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
Loading…
Reference in New Issue