Merge branch 'master' into issue-3166
commit
13b9fd9537
|
@ -387,11 +387,15 @@ const AutoCompleteSlots = [
|
|||
},
|
||||
{
|
||||
name: 'content',
|
||||
description: 'Custom content for the virtual scroller'
|
||||
description: 'Custom content for the virtual scroller.'
|
||||
},
|
||||
{
|
||||
name: 'loader',
|
||||
description: 'Custom content for the virtual scroller loader items'
|
||||
description: 'Custom content for the virtual scroller loader items.'
|
||||
},
|
||||
{
|
||||
name: 'empty',
|
||||
description: 'Custom empty template when there is no data to display.'
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -46,6 +46,12 @@ const SidebarProps = [
|
|||
type: 'string',
|
||||
default: 'close',
|
||||
description: 'Aria label of the close icon.'
|
||||
},
|
||||
{
|
||||
name: 'blockScroll',
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
description: 'Whether background scroll should be blocked when sidebar is visible.'
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -0,0 +1,298 @@
|
|||
import { afterEach } from 'vitest';
|
||||
import FilterService from '../FilterService';
|
||||
const filters = FilterService.filters;
|
||||
|
||||
import { ObjectUtils } from 'primevue/utils';
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
const checkParametersNullOrUndefined = (filterType) => {
|
||||
it('When value parameter is undefined', () => {
|
||||
expect(filters[filterType]('value', undefined)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('When value parameter is null', () => {
|
||||
expect(filters[filterType]('value', null)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('When filter parameter is undefined', () => {
|
||||
expect(filters[filterType](undefined, 'filter')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('When filter parameter is null', () => {
|
||||
expect(filters[filterType](undefined, 'filter')).toBeFalsy();
|
||||
});
|
||||
};
|
||||
|
||||
describe('FilterService', () => {
|
||||
describe('StartsWith filter test', () => {
|
||||
checkParametersNullOrUndefined('startsWith');
|
||||
it('When value and filter parameter is not null or undefined', () => {
|
||||
vi.spyOn(ObjectUtils, 'removeAccents').mockReturnValue('value');
|
||||
|
||||
const startsWith = filters.startsWith('value', 'filter', 'tr');
|
||||
|
||||
expect(startsWith).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Contains filter test', () => {
|
||||
checkParametersNullOrUndefined('contains');
|
||||
|
||||
it('When value and filter parameter is not null or undefined', () => {
|
||||
vi.spyOn(ObjectUtils, 'removeAccents').mockReturnValue('value');
|
||||
|
||||
const contains = filters.contains('value', 'filter', 'tr');
|
||||
|
||||
expect(contains).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('NotContains filter test', () => {
|
||||
checkParametersNullOrUndefined('notContains');
|
||||
|
||||
it('When value and filter parameter is not null or undefined', () => {
|
||||
vi.spyOn(ObjectUtils, 'removeAccents').mockReturnValue('value');
|
||||
|
||||
const notContains = filters.notContains('value', 'filter', 'tr');
|
||||
|
||||
expect(notContains).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('endsWith filter test', () => {
|
||||
checkParametersNullOrUndefined('endsWith');
|
||||
|
||||
it('When value and filter parameter is not null or undefined', () => {
|
||||
vi.spyOn(ObjectUtils, 'removeAccents').mockReturnValue('value');
|
||||
|
||||
const endsWith = filters.endsWith('value', 'filter', 'tr');
|
||||
|
||||
expect(endsWith).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('equals filter test', () => {
|
||||
checkParametersNullOrUndefined('equals');
|
||||
|
||||
it('When value and filter parameter has getTime property', () => {
|
||||
const getTimeMock = vi.fn(() => true);
|
||||
const equals = filters.equals({ getTime: getTimeMock }, { getTime: getTimeMock }, 'tr');
|
||||
|
||||
expect(equals).toBeTruthy();
|
||||
});
|
||||
|
||||
it('When value and filter parameter is not null or undefined', () => {
|
||||
vi.spyOn(ObjectUtils, 'removeAccents').mockReturnValue('value');
|
||||
|
||||
const equals = filters.equals('value', 'filter', 'tr');
|
||||
|
||||
expect(equals).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('notEquals filter test', () => {
|
||||
it('When filter parameter is undefined', () => {
|
||||
expect(filters.notEquals('value', undefined)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('When value parameter is undefined', () => {
|
||||
expect(filters.notEquals(undefined, 'filter')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('When value parameter is null', () => {
|
||||
expect(filters.notEquals(undefined, 'filter')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('When value and filter parameter has getTime property', () => {
|
||||
const getTimeMock = vi.fn(() => true);
|
||||
const notEquals = filters.notEquals({ getTime: getTimeMock }, { getTime: getTimeMock }, 'tr');
|
||||
|
||||
expect(notEquals).toBeFalsy();
|
||||
});
|
||||
|
||||
it('When value and filter parameter is not null or undefined', () => {
|
||||
vi.spyOn(ObjectUtils, 'removeAccents').mockReturnValue('value');
|
||||
|
||||
const notEquals = filters.notEquals('value', 'filter', 'tr');
|
||||
|
||||
expect(notEquals).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('in filter test', () => {
|
||||
checkParametersNullOrUndefined('in');
|
||||
|
||||
it('When value parameter equal to any filter word', () => {
|
||||
vi.spyOn(ObjectUtils, 'removeAccents').mockImplementation((value, filter) => value === filter);
|
||||
|
||||
const inFilter = filters.in('e', 'filter');
|
||||
|
||||
expect(inFilter).toBeTruthy();
|
||||
});
|
||||
|
||||
it('When value parameter not equal to any filter word', () => {
|
||||
vi.spyOn(ObjectUtils, 'removeAccents').mockImplementation((value, filter) => value === filter);
|
||||
|
||||
const inFilter = filters.in('d', 'filter');
|
||||
|
||||
expect(inFilter).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('between filter test', () => {
|
||||
checkParametersNullOrUndefined('between');
|
||||
it('When value has getTime func and smaller than filter[0]', () => {
|
||||
const filterGetTime = vi.fn(() => 1);
|
||||
const filterGetTime1 = vi.fn(() => 3);
|
||||
const valueGetTime = vi.fn(() => 2);
|
||||
|
||||
const between = filters.between({ getTime: valueGetTime }, [{ getTime: filterGetTime }, { getTime: filterGetTime1 }], 'tr');
|
||||
|
||||
expect(between).toBeTruthy();
|
||||
});
|
||||
|
||||
it('When value has getTime func and smaller than filter[0]', () => {
|
||||
const filter = 1;
|
||||
const filter1 = 2;
|
||||
const value = 2;
|
||||
|
||||
const between = filters.between(value, [filter, filter1], 'tr');
|
||||
|
||||
expect(between).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('lt filter test', () => {
|
||||
checkParametersNullOrUndefined('lt');
|
||||
it('When value has getTime func and smaller than filter', () => {
|
||||
const filterGetTime = vi.fn(() => 2);
|
||||
const valueGetTime = vi.fn(() => 1);
|
||||
|
||||
const lt = filters.lt({ getTime: valueGetTime }, { getTime: filterGetTime });
|
||||
|
||||
expect(lt).toBeTruthy();
|
||||
});
|
||||
|
||||
it('When value smaller than filter', () => {
|
||||
const filter = 2;
|
||||
const value = 1;
|
||||
|
||||
const lt = filters.lt(value, filter);
|
||||
|
||||
expect(lt).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('lte filter test', () => {
|
||||
checkParametersNullOrUndefined('lte');
|
||||
it('When value has getTime func and smaller than filter', () => {
|
||||
const filterGetTime = vi.fn(() => 2);
|
||||
const valueGetTime = vi.fn(() => 1);
|
||||
|
||||
const lte = filters.lte({ getTime: valueGetTime }, { getTime: filterGetTime });
|
||||
|
||||
expect(lte).toBeTruthy();
|
||||
});
|
||||
|
||||
it('When value smaller than filter', () => {
|
||||
const filter = 2;
|
||||
const value = 1;
|
||||
|
||||
const lte = filters.lte(value, filter);
|
||||
|
||||
expect(lte).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('gt filter test', () => {
|
||||
checkParametersNullOrUndefined('gt');
|
||||
it('When value has getTime func and smaller than filter[0]', () => {
|
||||
const filterGetTime = vi.fn(() => 2);
|
||||
const valueGetTime = vi.fn(() => 1);
|
||||
|
||||
const gt = filters.gt({ getTime: valueGetTime }, { getTime: filterGetTime });
|
||||
|
||||
expect(gt).toBeFalsy();
|
||||
});
|
||||
|
||||
it('When value smaller than filter[0]', () => {
|
||||
const filter = 2;
|
||||
const value = 1;
|
||||
|
||||
const gt = filters.gt(value, filter);
|
||||
|
||||
expect(gt).toBeFalsy();
|
||||
});
|
||||
});
|
||||
describe('gte filter test', () => {
|
||||
checkParametersNullOrUndefined('gte');
|
||||
it('When value has getTime func and smaller than filter[0]', () => {
|
||||
const filterGetTime = vi.fn(() => 2);
|
||||
const valueGetTime = vi.fn(() => 1);
|
||||
|
||||
const gte = filters.gte({ getTime: valueGetTime }, { getTime: filterGetTime });
|
||||
|
||||
expect(gte).toBeFalsy();
|
||||
});
|
||||
|
||||
it('When value parameter smaller than filter[0]', () => {
|
||||
const filter = 2;
|
||||
const value = 1;
|
||||
|
||||
const gte = filters.gte(value, filter);
|
||||
|
||||
expect(gte).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('dateIs filter test', () => {
|
||||
checkParametersNullOrUndefined('dateIs');
|
||||
it('When value and filter are equal', () => {
|
||||
const filter = new Date(1993, 6, 28, 14, 39, 7);
|
||||
const value = new Date(1993, 6, 28, 14, 39, 7);
|
||||
|
||||
const dateIs = filters.dateIs(value, filter);
|
||||
|
||||
expect(dateIs).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('dateIsNot filter test', () => {
|
||||
checkParametersNullOrUndefined('dateIsNot');
|
||||
it('When value and filter are not equal', () => {
|
||||
const filter = new Date(1993, 6, 28, 14, 39, 7);
|
||||
const value = new Date(1993, 6, 28, 14, 39, 7);
|
||||
|
||||
const dateIsNot = filters.dateIsNot(value, filter);
|
||||
|
||||
expect(dateIsNot).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('dateBefore filter test', () => {
|
||||
checkParametersNullOrUndefined('dateBefore');
|
||||
it('When filter value bigger than value', () => {
|
||||
const filter = new Date(1996, 6, 28, 14, 39, 8);
|
||||
const value = new Date(1993, 6, 28, 14, 39, 7);
|
||||
|
||||
const dateBefore = filters.dateBefore(value, filter);
|
||||
|
||||
expect(dateBefore).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('dateAfter filter test', () => {
|
||||
checkParametersNullOrUndefined('dateAfter');
|
||||
it('When value is not smaller than value', () => {
|
||||
const filter = new Date(1996, 6, 28, 14, 39, 8);
|
||||
const value = new Date(1993, 6, 28, 14, 39, 7);
|
||||
|
||||
const dateAfter = filters.dateAfter(value, filter);
|
||||
|
||||
expect(dateAfter).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -381,6 +381,10 @@ export interface AutoCompleteSlots {
|
|||
*/
|
||||
options: any[];
|
||||
}) => VNode[];
|
||||
/**
|
||||
* Custom empty template when there is no data to display.
|
||||
*/
|
||||
empty: () => VNode[];
|
||||
}
|
||||
|
||||
export declare type AutoCompleteEmits = {
|
||||
|
|
|
@ -119,6 +119,9 @@
|
|||
<!--TODO: Deprecated since v3.16.0-->
|
||||
</li>
|
||||
</template>
|
||||
<li v-if="!items || (items && items.length === 0)" class="p-autocomplete-empty-message" role="option">
|
||||
<slot name="empty">{{ searchResultMessageText }}</slot>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<template v-if="$slots.loader" v-slot:loader="{ options }">
|
||||
|
@ -323,7 +326,7 @@ export default {
|
|||
watch: {
|
||||
suggestions() {
|
||||
if (this.searching) {
|
||||
ObjectUtils.isNotEmpty(this.suggestions) ? this.show() : this.hide();
|
||||
ObjectUtils.isNotEmpty(this.suggestions) ? this.show() : !!this.$slots.empty ? this.show() : this.hide();
|
||||
this.focusedOptionIndex = this.overlayVisible && this.autoOptionFocus ? this.findFirstFocusedOptionIndex() : -1;
|
||||
this.searching = false;
|
||||
}
|
||||
|
@ -663,29 +666,19 @@ export default {
|
|||
this.multiple && event.stopPropagation(); // To prevent onArrowRightKeyOnMultiple method
|
||||
},
|
||||
onHomeKey(event) {
|
||||
const target = event.currentTarget;
|
||||
const len = target.value.length;
|
||||
|
||||
if (event.shiftKey) {
|
||||
event.currentTarget.setSelectionRange(0, len);
|
||||
} else {
|
||||
event.currentTarget.setSelectionRange(0, 0);
|
||||
}
|
||||
const { currentTarget } = event;
|
||||
const len = currentTarget.value.length;
|
||||
|
||||
currentTarget.setSelectionRange(0, event.shiftKey ? len : 0);
|
||||
this.focusedOptionIndex = -1;
|
||||
|
||||
event.preventDefault();
|
||||
},
|
||||
onEndKey(event) {
|
||||
const target = event.currentTarget;
|
||||
const len = target.value.length;
|
||||
|
||||
if (event.shiftKey) {
|
||||
event.currentTarget.setSelectionRange(0, len);
|
||||
} else {
|
||||
target.setSelectionRange(len, len);
|
||||
}
|
||||
const { currentTarget } = event;
|
||||
const len = currentTarget.value.length;
|
||||
|
||||
currentTarget.setSelectionRange(event.shiftKey ? 0 : len, len);
|
||||
this.focusedOptionIndex = -1;
|
||||
|
||||
event.preventDefault();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<nav class="p-breadcrumb p-component">
|
||||
<ol class="p-breadcrumb-list">
|
||||
<BreadcrumbItem v-if="home" :item="home" class="p-breadcrumb-home" :template="$slots.item" :exact="exact" />
|
||||
<BreadcrumbItem v-if="home" :item="home" class="p-breadcrumb-home" :exact="exact" />
|
||||
<template v-for="item of model" :key="item.label">
|
||||
<li class="p-menuitem-separator">
|
||||
<span class="pi pi-chevron-right" aria-hidden="true"></span>
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
import { RouterLinkStub, shallowMount } from '@vue/test-utils';
|
||||
import { beforeEach, expect } from 'vitest';
|
||||
import BreadcrumbItem from './BreadcrumbItem.vue';
|
||||
|
||||
let wrapper = null;
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallowMount(BreadcrumbItem, {
|
||||
global: {
|
||||
mocks: {
|
||||
$router: {
|
||||
currentRoute: {
|
||||
path: vi.fn()
|
||||
},
|
||||
navigate: () => true
|
||||
}
|
||||
},
|
||||
stubs: {
|
||||
'router-link': RouterLinkStub
|
||||
}
|
||||
},
|
||||
props: {
|
||||
item: { label: 'Computer', visible: () => true },
|
||||
template: null
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('BreadcrumbItem', () => {
|
||||
it('When component is mount, text should be exists', () => {
|
||||
expect(wrapper.find('.p-menuitem-text').exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('When tag is triggered, onClick method should be called', async () => {
|
||||
const onClickSpy = vi.spyOn(wrapper.vm, 'onClick');
|
||||
const tag = wrapper.find('a');
|
||||
|
||||
tag.trigger('click');
|
||||
expect(tag.exists()).toBe(true);
|
||||
expect(onClickSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('When onClick method called and item has a command callback, callback should be triggered', async () => {
|
||||
await wrapper.setProps({ item: { label: 'Computer', visible: () => false, command: vi.fn() } });
|
||||
|
||||
const spy = vi.spyOn(wrapper.vm.item, 'command');
|
||||
|
||||
wrapper.vm.onClick();
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('When linkClass method called and isActive-isExactActive, tag classes should be effected', async () => {
|
||||
await wrapper.setProps({ exact: true });
|
||||
|
||||
expect(wrapper.vm.linkClass({ isActive: true, isExactActive: true })).toEqual([
|
||||
'p-menuitem-link',
|
||||
{
|
||||
'router-link-active': true,
|
||||
'router-link-active-exact': true
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it('When item prop has a visible, visible method should be return falsy', async () => {
|
||||
await wrapper.setProps({ item: { label: 'Computer', visible: false, command: vi.fn() } });
|
||||
|
||||
expect(wrapper.vm.visible()).toBeFalsy();
|
||||
});
|
||||
|
||||
it('When item prop has a disabled function, disabled method should be return truthy', async () => {
|
||||
await wrapper.setProps({ item: { disabled: () => true } });
|
||||
|
||||
expect(wrapper.vm.disabled()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('When item prop has a label function, disabled method should be return truthy', async () => {
|
||||
await wrapper.setProps({ item: { label: () => true } });
|
||||
|
||||
expect(wrapper.vm.label()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('When item prop has a icon, icon element class should contain item prop icon', async () => {
|
||||
await wrapper.setProps({ item: { icon: 'pi-discord' } });
|
||||
|
||||
expect(wrapper.find('a > span').classes()).toContain('pi-discord');
|
||||
});
|
||||
});
|
|
@ -1,7 +1,7 @@
|
|||
import { HTMLAttributes, InputHTMLAttributes, VNode } from 'vue';
|
||||
import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers';
|
||||
|
||||
type CalendarValueType = Date | Date[] | undefined;
|
||||
type CalendarValueType = string | Date | string[] | Date[] | undefined;
|
||||
|
||||
type CalendarSlotDateType = { day: number; month: number; year: number; today: boolean; selectable: boolean };
|
||||
|
||||
|
|
|
@ -1783,7 +1783,7 @@ export default {
|
|||
throw 'Invalid Time';
|
||||
}
|
||||
|
||||
this.pm = ampm === this.$primevue.config.locale.am || ampm === this.$primevue.config.locale.am.toLowerCase();
|
||||
this.pm = ampm === this.$primevue.config.locale.pm || ampm === this.$primevue.config.locale.pm.toLowerCase();
|
||||
let time = this.parseTime(timeString);
|
||||
|
||||
value.setHours(time.hour);
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
:id="inputId"
|
||||
type="checkbox"
|
||||
:value="value"
|
||||
:class="inputClass"
|
||||
:style="inputStyle"
|
||||
:name="name"
|
||||
:checked="checked"
|
||||
:tabindex="tabindex"
|
||||
|
@ -21,7 +19,7 @@
|
|||
v-bind="inputProps"
|
||||
/>
|
||||
</div>
|
||||
<div ref="box" :class="['p-checkbox-box', { 'p-highlight': checked, 'p-disabled': disabled, 'p-focus': focused }]">
|
||||
<div ref="box" :class="['p-checkbox-box', inputClass, { 'p-highlight': checked, 'p-disabled': disabled, 'p-focus': focused }]" :style="inputStyle">
|
||||
<span :class="['p-checkbox-icon', { 'pi pi-check': checked }]"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -14,6 +14,10 @@ describe('Chip.vue', () => {
|
|||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('should exists', () => {
|
||||
expect(wrapper.find('.p-chip.p-component').exists()).toBe(true);
|
||||
expect(wrapper.find('.p-chip-icon').classes()).toContain('pi-primevue');
|
||||
|
@ -26,4 +30,19 @@ describe('Chip.vue', () => {
|
|||
|
||||
expect(wrapper.find('.p-chip.p-component').exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('When removable is true and keydown triggered OnKeydown method should be called', async () => {
|
||||
const closeSpy = vi.spyOn(wrapper.vm, 'onKeydown');
|
||||
|
||||
await wrapper.find('.p-chip-remove-icon').trigger('keydown');
|
||||
|
||||
expect(closeSpy).toHaveBeenCalled();
|
||||
});
|
||||
it('When onKeyDown method triggered close method should be called', async () => {
|
||||
const closeSpy = vi.spyOn(wrapper.vm, 'close');
|
||||
|
||||
await wrapper.vm.onKeydown({ key: 'Enter' });
|
||||
|
||||
expect(closeSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Vue, { Plugin } from 'vue';
|
||||
import { Plugin } from 'vue';
|
||||
import { ConfirmationOptions } from '../confirmationoptions';
|
||||
|
||||
declare const plugin: Plugin;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<CDialog v-model:visible="visible" role="alertdialog" class="p-confirm-dialog" :modal="true" :header="header" :blockScroll="blockScroll" :position="position" :breakpoints="breakpoints" :closeOnEscape="closeOnEscape" @update:visible="onHide">
|
||||
<template v-if="!$slots.message">
|
||||
<i :class="iconClass" />
|
||||
<span class="p-confirm-dialog-message">{{ message }}</span>
|
||||
<i v-if="confirmation.icon" :class="iconClass" />
|
||||
<span :class="{ 'p-confirm-dialog-message': confirmation.icon }">{{ message }}</span>
|
||||
</template>
|
||||
<component v-else :is="$slots.message" :message="confirmation"></component>
|
||||
<template #footer>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<Portal>
|
||||
<transition name="p-confirm-popup" @enter="onEnter" @leave="onLeave" @after-leave="onAfterLeave">
|
||||
<transition name="p-confirm-popup" @enter="onEnter" @after-enter="onAfterEnter" @leave="onLeave" @after-leave="onAfterLeave">
|
||||
<div v-if="visible" :ref="containerRef" v-focustrap role="alertdialog" :class="containerClass" :aria-modal="visible" @click="onOverlayClick" @keydown="onOverlayKeydown" v-bind="$attrs">
|
||||
<template v-if="!$slots.message">
|
||||
<div class="p-confirm-popup-content">
|
||||
|
@ -35,7 +35,9 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
confirmation: null
|
||||
confirmation: null,
|
||||
autoFocusAccept: null,
|
||||
autoFocusReject: null
|
||||
};
|
||||
},
|
||||
target: null,
|
||||
|
@ -129,13 +131,18 @@ export default {
|
|||
}
|
||||
},
|
||||
onEnter(el) {
|
||||
this.focus();
|
||||
this.autoFocusAccept = this.confirmation.defaultFocus === undefined || this.confirmation.defaultFocus === 'accept' ? true : false;
|
||||
this.autoFocusReject = this.confirmation.defaultFocus === 'reject' ? true : false;
|
||||
|
||||
this.bindOutsideClickListener();
|
||||
this.bindScrollListener();
|
||||
this.bindResizeListener();
|
||||
|
||||
ZIndexUtils.set('overlay', el, this.$primevue.config.zIndex.overlay);
|
||||
},
|
||||
onAfterEnter() {
|
||||
this.focus();
|
||||
},
|
||||
onLeave() {
|
||||
this.unbindOutsideClickListener();
|
||||
this.unbindScrollListener();
|
||||
|
@ -221,7 +228,7 @@ export default {
|
|||
let focusTarget = this.container.querySelector('[autofocus]');
|
||||
|
||||
if (focusTarget) {
|
||||
focusTarget.focus();
|
||||
focusTarget.focus({ preventScroll: true }); // Firefox requires preventScroll
|
||||
}
|
||||
},
|
||||
isTargetClicked(event) {
|
||||
|
@ -276,12 +283,6 @@ export default {
|
|||
},
|
||||
rejectClass() {
|
||||
return ['p-confirm-popup-reject p-button-sm', this.confirmation ? this.confirmation.rejectClass || 'p-button-text' : null];
|
||||
},
|
||||
autoFocusAccept() {
|
||||
return this.confirmation.defaultFocus === undefined || this.confirmation.defaultFocus === 'accept' ? true : false;
|
||||
},
|
||||
autoFocusReject() {
|
||||
return this.confirmation.defaultFocus === 'reject' ? true : false;
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
|
|
@ -107,8 +107,8 @@ export default {
|
|||
getItemKey(processedItem) {
|
||||
return this.getItemId(processedItem);
|
||||
},
|
||||
getItemProp(processedItem, name) {
|
||||
return processedItem && processedItem.item ? ObjectUtils.getItemValue(processedItem.item[name]) : undefined;
|
||||
getItemProp(processedItem, name, params) {
|
||||
return processedItem && processedItem.item ? ObjectUtils.getItemValue(processedItem.item[name], params) : undefined;
|
||||
},
|
||||
getItemLabel(processedItem) {
|
||||
return this.getItemProp(processedItem, 'label');
|
||||
|
@ -129,9 +129,7 @@ export default {
|
|||
return ObjectUtils.isNotEmpty(processedItem.items);
|
||||
},
|
||||
onItemClick(event, processedItem) {
|
||||
const command = this.getItemProp(processedItem, 'command');
|
||||
|
||||
command && command({ originalEvent: event, item: processedItem.item });
|
||||
this.getItemProp(processedItem, 'command', { originalEvent: event, item: processedItem.item });
|
||||
this.$emit('item-click', { originalEvent: event, processedItem, isFocus: true });
|
||||
},
|
||||
onItemMouseEnter(event, processedItem) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import { VirtualScrollerProps } from '../virtualscroller';
|
|||
|
||||
type DataTablePaginatorPositionType = 'top' | 'bottom' | 'both' | undefined;
|
||||
|
||||
type DataTableSortFieldType = string | ((item: any) => string) | undefined;
|
||||
type DataTableSortFieldType = string | ((item: any) => string) | undefined | null;
|
||||
|
||||
type DataTableDataKeyType = string | ((item: any) => string) | undefined;
|
||||
|
||||
|
@ -684,7 +684,7 @@ export interface DataTableProps {
|
|||
/**
|
||||
* One or more field names to use in row grouping.
|
||||
*/
|
||||
groupRowsBy?: (field: string) => object | string[] | string | undefined;
|
||||
groupRowsBy?: ((field: string) => object) | string[] | string | undefined;
|
||||
/**
|
||||
* Whether the row groups can be expandable.
|
||||
*/
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<button class="ql-italic" type="button"></button>
|
||||
<button class="ql-underline" type="button"></button>
|
||||
</span>
|
||||
<span class="ql-formats">
|
||||
<span :key="reRenderColorKey" class="ql-formats">
|
||||
<select class="ql-color"></select>
|
||||
<select class="ql-background"></select>
|
||||
</span>
|
||||
|
@ -69,10 +69,16 @@ export default {
|
|||
editorStyle: null,
|
||||
modules: null
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
reRenderColorKey: 0
|
||||
};
|
||||
},
|
||||
quill: null,
|
||||
watch: {
|
||||
modelValue(newValue, oldValue) {
|
||||
if (newValue !== oldValue && this.quill && !this.quill.hasFocus()) {
|
||||
this.reRenderColorKey++;
|
||||
this.renderValue(newValue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -252,11 +252,11 @@ export interface FileUploadSlots {
|
|||
/**
|
||||
* Function to remove an uploaded file.
|
||||
*/
|
||||
removeUploadedFileCallback: () => void;
|
||||
removeUploadedFileCallback: (index: number) => void;
|
||||
/**
|
||||
* Function to remove a file.
|
||||
*/
|
||||
removeFileCallback: () => void;
|
||||
removeFileCallback: (index: number) => void;
|
||||
/**
|
||||
* Uploaded progress as number.
|
||||
*/
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
:aria-setsize="ariaSetSize"
|
||||
:aria-posinset="getAriaPosInset(getOptionIndex(i, getItemOptions))"
|
||||
@click="onOptionSelect($event, option, getOptionIndex(i, getItemOptions))"
|
||||
@mousedown="onOptionMouseDown($event, getOptionIndex(i, getItemOptions))"
|
||||
@mousemove="onOptionMouseMove($event, getOptionIndex(i, getItemOptions))"
|
||||
@touchend="onOptionTouchEnd()"
|
||||
>
|
||||
|
@ -254,7 +255,7 @@ export default {
|
|||
},
|
||||
onListFocus(event) {
|
||||
this.focused = true;
|
||||
this.focusedOptionIndex = this.autoOptionFocus ? this.findFirstFocusedOptionIndex() : -1;
|
||||
this.focusedOptionIndex = this.focusedOptionIndex !== -1 ? this.focusedOptionIndex : this.autoOptionFocus ? this.findFirstFocusedOptionIndex() : -1;
|
||||
this.$emit('focus', event);
|
||||
},
|
||||
onListBlur(event) {
|
||||
|
@ -332,6 +333,9 @@ export default {
|
|||
this.optionTouched = false;
|
||||
index !== -1 && (this.focusedOptionIndex = index);
|
||||
},
|
||||
onOptionMouseDown(event, index) {
|
||||
this.changeFocusedOptionIndex(event, index);
|
||||
},
|
||||
onOptionMouseMove(event, index) {
|
||||
if (this.focusOnHover) {
|
||||
this.changeFocusedOptionIndex(event, index);
|
||||
|
|
|
@ -118,8 +118,8 @@ export default {
|
|||
getItemKey(processedItem) {
|
||||
return this.getItemId(processedItem);
|
||||
},
|
||||
getItemProp(processedItem, name) {
|
||||
return processedItem && processedItem.item ? ObjectUtils.getItemValue(processedItem.item[name]) : undefined;
|
||||
getItemProp(processedItem, name, params) {
|
||||
return processedItem && processedItem.item ? ObjectUtils.getItemValue(processedItem.item[name], params) : undefined;
|
||||
},
|
||||
getItemLabel(processedItem) {
|
||||
return this.getItemProp(processedItem, 'label');
|
||||
|
@ -140,9 +140,7 @@ export default {
|
|||
return ObjectUtils.isNotEmpty(processedItem.items);
|
||||
},
|
||||
onItemClick(event, processedItem) {
|
||||
const command = this.getItemProp(processedItem, 'command');
|
||||
|
||||
command && command({ originalEvent: event, item: processedItem.item });
|
||||
this.getItemProp(processedItem, 'command', { originalEvent: event, item: processedItem.item });
|
||||
this.$emit('item-click', { originalEvent: event, processedItem, isFocus: true });
|
||||
},
|
||||
onItemMouseEnter(event, processedItem) {
|
||||
|
|
|
@ -109,8 +109,8 @@ export default {
|
|||
getItemKey(processedItem) {
|
||||
return this.getItemId(processedItem);
|
||||
},
|
||||
getItemProp(processedItem, name) {
|
||||
return processedItem && processedItem.item ? ObjectUtils.getItemValue(processedItem.item[name]) : undefined;
|
||||
getItemProp(processedItem, name, params) {
|
||||
return processedItem && processedItem.item ? ObjectUtils.getItemValue(processedItem.item[name], params) : undefined;
|
||||
},
|
||||
getItemLabel(processedItem) {
|
||||
return this.getItemProp(processedItem, 'label');
|
||||
|
@ -131,9 +131,7 @@ export default {
|
|||
return ObjectUtils.isNotEmpty(processedItem.items);
|
||||
},
|
||||
onItemClick(event, processedItem) {
|
||||
const command = this.getItemProp(processedItem, 'command');
|
||||
|
||||
command && command({ originalEvent: event, item: processedItem.item });
|
||||
this.getItemProp(processedItem, 'command', { originalEvent: event, item: processedItem.item });
|
||||
this.$emit('item-click', { originalEvent: event, processedItem, isFocus: true });
|
||||
},
|
||||
onItemMouseEnter(event, processedItem) {
|
||||
|
|
|
@ -660,8 +660,12 @@ export default {
|
|||
pressedInInputText && (this.focusedOptionIndex = -1);
|
||||
},
|
||||
onHomeKey(event, pressedInInputText = false) {
|
||||
const { currentTarget } = event;
|
||||
|
||||
if (pressedInInputText) {
|
||||
event.currentTarget.setSelectionRange(0, 0);
|
||||
const len = currentTarget.value.length;
|
||||
|
||||
currentTarget.setSelectionRange(0, event.shiftKey ? len : 0);
|
||||
this.focusedOptionIndex = -1;
|
||||
} else {
|
||||
let metaKey = event.metaKey || event.ctrlKey;
|
||||
|
@ -679,11 +683,12 @@ export default {
|
|||
event.preventDefault();
|
||||
},
|
||||
onEndKey(event, pressedInInputText = false) {
|
||||
if (pressedInInputText) {
|
||||
const target = event.currentTarget;
|
||||
const len = target.value.length;
|
||||
const { currentTarget } = event;
|
||||
|
||||
target.setSelectionRange(len, len);
|
||||
if (pressedInInputText) {
|
||||
const len = currentTarget.value.length;
|
||||
|
||||
currentTarget.setSelectionRange(event.shiftKey ? 0 : len, len);
|
||||
this.focusedOptionIndex = -1;
|
||||
} else {
|
||||
let metaKey = event.metaKey || event.ctrlKey;
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
v-bind="listProps"
|
||||
>
|
||||
<template v-for="(item, i) of modelValue" :key="getItemKey(item, i)">
|
||||
<li :id="id + '_' + i" v-ripple role="option" :class="itemClass(item, `${id}_${i}`)" @click="onItemClick($event, item, i)" @touchend="onItemTouchEnd" :aria-selected="isSelected(item)">
|
||||
<li :id="id + '_' + i" v-ripple role="option" :class="itemClass(item, `${id}_${i}`)" @click="onItemClick($event, item, i)" @touchend="onItemTouchEnd" :aria-selected="isSelected(item)" @mousedown="onOptionMouseDown(i)">
|
||||
<slot name="item" :item="item" :index="i"> </slot>
|
||||
</li>
|
||||
</template>
|
||||
|
@ -148,9 +148,12 @@ export default {
|
|||
},
|
||||
onListFocus(event) {
|
||||
const selectedFirstItem = DomHandler.findSingle(this.list, 'li.p-orderlist-item.p-highlight');
|
||||
const index = selectedFirstItem ? ObjectUtils.findIndexInList(selectedFirstItem, this.list.children) : '0';
|
||||
const findIndex = ObjectUtils.findIndexInList(selectedFirstItem, this.list.children);
|
||||
|
||||
this.focused = true;
|
||||
|
||||
const index = this.focusedOptionIndex !== -1 ? this.focusedOptionIndex : selectedFirstItem ? findIndex : -1;
|
||||
|
||||
this.changeFocusedOptionIndex(index);
|
||||
this.$emit('focus', event);
|
||||
},
|
||||
|
@ -195,6 +198,10 @@ export default {
|
|||
break;
|
||||
}
|
||||
},
|
||||
onOptionMouseDown(index) {
|
||||
this.focused = true;
|
||||
this.focusedOptionIndex = index;
|
||||
},
|
||||
onArrowDownKey(event) {
|
||||
const optionIndex = this.findNextOptionIndex(this.focusedOptionIndex);
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ export default {
|
|||
collapsed: Boolean,
|
||||
toggleButtonProps: {
|
||||
type: null,
|
||||
defaault: null
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
|
|
@ -201,11 +201,10 @@ export default {
|
|||
},
|
||||
changeActiveItem(event, item, selfActive = false) {
|
||||
if (!this.isItemDisabled(item)) {
|
||||
this.activeItem = selfActive ? item : this.activeItem && ObjectUtils.equals(item, this.activeItem) ? null : item;
|
||||
|
||||
const active = this.isItemActive(item);
|
||||
const eventName = active ? 'panel-open' : 'panel-close';
|
||||
const eventName = !active ? 'panel-open' : 'panel-close';
|
||||
|
||||
this.activeItem = selfActive ? item : this.activeItem && this.activeItem === item ? null : item;
|
||||
this.changeExpandedKeys({ item, expanded: !active });
|
||||
this.$emit(eventName, { originalEvent: event, item });
|
||||
}
|
||||
|
|
|
@ -96,8 +96,8 @@ export default {
|
|||
getItemKey(processedItem) {
|
||||
return this.getItemId(processedItem);
|
||||
},
|
||||
getItemProp(processedItem, name) {
|
||||
return processedItem && processedItem.item ? ObjectUtils.getItemValue(processedItem.item[name]) : undefined;
|
||||
getItemProp(processedItem, name, params) {
|
||||
return processedItem && processedItem.item ? ObjectUtils.getItemValue(processedItem.item[name], params) : undefined;
|
||||
},
|
||||
getItemLabel(processedItem) {
|
||||
return this.getItemProp(processedItem, 'label');
|
||||
|
@ -118,9 +118,7 @@ export default {
|
|||
return ObjectUtils.isNotEmpty(processedItem.items);
|
||||
},
|
||||
onItemClick(event, processedItem) {
|
||||
const command = this.getItemProp(processedItem, 'command');
|
||||
|
||||
command && command({ originalEvent: event, item: processedItem.item });
|
||||
this.getItemProp(processedItem, 'command', { originalEvent: event, item: processedItem.item });
|
||||
this.$emit('item-toggle', { processedItem, expanded: !this.isItemActive(processedItem) });
|
||||
},
|
||||
onItemToggle(event) {
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
@click="onItemClick($event, item, i, 0)"
|
||||
@dblclick="onItemDblClick($event, item, 0)"
|
||||
@touchend="onItemTouchEnd"
|
||||
@mousedown="onOptionMouseDown(i, 'sourceList')"
|
||||
role="option"
|
||||
:aria-selected="isSelected(item, 0)"
|
||||
>
|
||||
|
@ -80,6 +81,7 @@
|
|||
@click="onItemClick($event, item, i, 1)"
|
||||
@dblclick="onItemDblClick($event, item, 1)"
|
||||
@keydown="onItemKeyDown($event, 'targetList')"
|
||||
@mousedown="onOptionMouseDown(i, 'targetList')"
|
||||
@touchend="onItemTouchEnd"
|
||||
role="option"
|
||||
:aria-selected="isSelected(item, 1)"
|
||||
|
@ -236,9 +238,12 @@ export default {
|
|||
},
|
||||
onListFocus(event, listType) {
|
||||
const selectedFirstItem = DomHandler.findSingle(this.$refs[listType].$el, 'li.p-picklist-item.p-highlight');
|
||||
const index = selectedFirstItem ? ObjectUtils.findIndexInList(selectedFirstItem, this.$refs[listType].$el.children) : '0';
|
||||
const findIndex = ObjectUtils.findIndexInList(selectedFirstItem, this.$refs[listType].$el.children);
|
||||
|
||||
this.focused[listType] = true;
|
||||
|
||||
const index = this.focusedOptionIndex !== -1 ? this.focusedOptionIndex : selectedFirstItem ? findIndex : -1;
|
||||
|
||||
this.changeFocusedOptionIndex(index, listType);
|
||||
this.$emit('focus', event);
|
||||
},
|
||||
|
@ -247,6 +252,10 @@ export default {
|
|||
this.focusedOptionIndex = -1;
|
||||
this.$emit('blur', event);
|
||||
},
|
||||
onOptionMouseDown(index, listType) {
|
||||
this.focused[listType] = true;
|
||||
this.focusedOptionIndex = index;
|
||||
},
|
||||
moveUp(event, listIndex) {
|
||||
if (this.d_selection && this.d_selection[listIndex]) {
|
||||
let valueList = [...this.modelValue[listIndex]];
|
||||
|
|
|
@ -18,17 +18,74 @@ describe('RadioButton.vue', () => {
|
|||
expect(wrapper.find('input').attributes().type).toBe('radio');
|
||||
});
|
||||
|
||||
it('should clicked', async () => {
|
||||
await wrapper.vm.onClick({});
|
||||
it('When disabled true and onClick triggered click emit should not be called', async () => {
|
||||
await wrapper.setProps({ disabled: true });
|
||||
await wrapper.vm.onClick();
|
||||
|
||||
expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['Tatooine']);
|
||||
expect(wrapper.emitted().change[0]).toEqual([{}]);
|
||||
expect(wrapper.emitted()['click']).toEqual(undefined);
|
||||
expect(wrapper.emitted()['update:modelValue']).toEqual(undefined);
|
||||
});
|
||||
|
||||
it('should checked', async () => {
|
||||
it('When disabled false and onClick triggered click emit should be called', async () => {
|
||||
await wrapper.vm.onClick();
|
||||
|
||||
expect(wrapper.emitted()['update:modelValue'].length).toEqual(1);
|
||||
expect(wrapper.emitted().change.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('When value and modelValue equal and onClick triggered change emit should not be called', async () => {
|
||||
await wrapper.setProps({ modelValue: 'test', value: 'test' });
|
||||
await wrapper.vm.onClick();
|
||||
|
||||
expect(wrapper.emitted()['change']).toEqual(undefined);
|
||||
});
|
||||
|
||||
it('When modelValue changed, Checked should be effected', async () => {
|
||||
await wrapper.setProps({ modelValue: 'Tatooine' });
|
||||
|
||||
expect(wrapper.vm.checked).toBe(true);
|
||||
expect(wrapper.find('.p-radiobutton').classes()).toContain('p-radiobutton-checked');
|
||||
});
|
||||
|
||||
it('When component cliked OnClick method should be called', async () => {
|
||||
const spy = vi.spyOn(wrapper.vm, 'onClick');
|
||||
|
||||
await wrapper.find('.p-radiobutton').trigger('click');
|
||||
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('When component focused onFocus method should be called', async () => {
|
||||
await wrapper.setProps({ inputId: 'test' });
|
||||
|
||||
const spy = vi.spyOn(wrapper.vm, 'onFocus');
|
||||
|
||||
await wrapper.find('#test').trigger('focus');
|
||||
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('When onFocus method triggered, false should be true', async () => {
|
||||
await wrapper.vm.onFocus();
|
||||
|
||||
expect(wrapper.vm.focused).toBeTruthy();
|
||||
expect(wrapper.emitted().focus.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('When component blur onBlur method should be called', async () => {
|
||||
await wrapper.setProps({ inputId: 'test' });
|
||||
|
||||
const blurSpy = vi.spyOn(wrapper.vm, 'onBlur');
|
||||
|
||||
await wrapper.find('#test').trigger('blur');
|
||||
|
||||
expect(blurSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('When onBlur method triggered, false should be false', async () => {
|
||||
await wrapper.vm.onBlur();
|
||||
|
||||
expect(wrapper.vm.focus).toBeFalsy();
|
||||
expect(wrapper.emitted().blur.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { VNode } from 'vue';
|
||||
import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers';
|
||||
|
||||
export interface RatingChangeEvent {
|
||||
|
|
|
@ -44,6 +44,10 @@ export interface SidebarProps {
|
|||
* Default value is true.
|
||||
*/
|
||||
modal?: boolean | undefined;
|
||||
/**
|
||||
* Whether background scroll should be blocked when sidebar is visible.
|
||||
*/
|
||||
blockScroll?: boolean | undefined;
|
||||
}
|
||||
|
||||
export interface SidebarSlots {
|
||||
|
|
|
@ -2,7 +2,6 @@ import { mount } from '@vue/test-utils';
|
|||
import PrimeVue from 'primevue/config';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import Sidebar from './Sidebar.vue';
|
||||
|
||||
describe('Sidebar.vue', () => {
|
||||
let wrapper;
|
||||
|
||||
|
@ -15,7 +14,7 @@ describe('Sidebar.vue', () => {
|
|||
}
|
||||
},
|
||||
props: {
|
||||
visible: true,
|
||||
visible: false,
|
||||
bazeZIndex: 1000
|
||||
},
|
||||
slots: {
|
||||
|
@ -23,95 +22,76 @@ describe('Sidebar.vue', () => {
|
|||
header: `<span class="header">Header Template</span>`
|
||||
}
|
||||
});
|
||||
wrapper.setProps({ visible: true });
|
||||
});
|
||||
|
||||
it('should exist', () => {
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('When component is mounted, sidebar should be exist', () => {
|
||||
expect(wrapper.find('.p-sidebar.p-component').exists()).toBe(true);
|
||||
expect(wrapper.find('.p-sidebar').classes()).toContain('p-sidebar-left');
|
||||
expect(wrapper.find('.p-sidebar').classes()).toContain('p-sidebar-active');
|
||||
});
|
||||
|
||||
it('should close', async () => {
|
||||
await wrapper.vm.hide();
|
||||
it('When mask element triggered, sidebar should be hide', async () => {
|
||||
const unbindOutsideClickListenerSpy = vi.spyOn(wrapper.vm, 'unbindOutsideClickListener');
|
||||
|
||||
expect(wrapper.emitted()['update:visible'][0]).toEqual([false]);
|
||||
await wrapper.find('.p-sidebar-mask').trigger('mousedown');
|
||||
|
||||
await wrapper.setProps({ visible: false });
|
||||
|
||||
expect(wrapper.find('.p-sidebar.p-component').exists()).toBe(false);
|
||||
expect(wrapper.emitted()['update:visible'].length).toBe(1);
|
||||
expect(unbindOutsideClickListenerSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set position', async () => {
|
||||
await wrapper.setProps({ position: 'bottom' });
|
||||
it('When transition trigger to onEnter, sidebar should be visible', async () => {
|
||||
const focusSpy = vi.spyOn(wrapper.vm, 'focus');
|
||||
|
||||
expect(wrapper.find('.p-sidebar').classes()).toContain('p-sidebar-bottom');
|
||||
await wrapper.vm.onEnter();
|
||||
|
||||
expect(wrapper.emitted().show.length).toBe(1);
|
||||
expect(wrapper.vm.maskVisible).toBeTruthy();
|
||||
expect(focusSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set position', async () => {
|
||||
await wrapper.setProps({ position: 'full' });
|
||||
it('When transition trigger to onLeave, unbindOutsideClickListener should be triggered', async () => {
|
||||
const unbindOutsideClickListenerSpy = vi.spyOn(wrapper.vm, 'unbindOutsideClickListener');
|
||||
|
||||
expect(wrapper.vm.fullScreen).toBe(true);
|
||||
expect(wrapper.find('.p-sidebar').classes()).toContain('p-sidebar-full');
|
||||
await wrapper.vm.onLeave();
|
||||
|
||||
expect(wrapper.emitted().hide.length).toBe(1);
|
||||
expect(unbindOutsideClickListenerSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should have custom close icon when provided', async () => {
|
||||
await wrapper.setProps({ closeIcon: 'pi pi-discord' });
|
||||
const icon = wrapper.find('.p-sidebar-close-icon');
|
||||
it('When transition trigger to onAfterEnter, bindOutsideClickListener should be triggered', async () => {
|
||||
const bindOutsideClickListenerSpy = vi.spyOn(wrapper.vm, 'bindOutsideClickListener');
|
||||
|
||||
expect(icon.classes()).toContain('pi-discord');
|
||||
await wrapper.vm.onAfterEnter();
|
||||
|
||||
expect(bindOutsideClickListenerSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should header slot rendered', () => {
|
||||
expect(wrapper.find('.p-sidebar-header').exists()).toBe(true);
|
||||
expect(wrapper.find('.p-sidebar-header-content').exists()).toBe(true);
|
||||
expect(wrapper.find('span.header').exists()).toBe(true);
|
||||
expect(wrapper.find('span.header').text()).toBe('Header Template');
|
||||
it('When keydown is triggered , hide method should be triggered', async () => {
|
||||
const hideSpy = vi.spyOn(wrapper.vm, 'hide');
|
||||
|
||||
await wrapper.find('.p-sidebar').trigger('keydown', { code: 'Escape' });
|
||||
|
||||
expect(hideSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should default slot rendered', () => {
|
||||
expect(wrapper.find('h3').exists()).toBe(true);
|
||||
expect(wrapper.find('h3').text()).toBe('Left Sidebar');
|
||||
it('When keydown is triggered , hide method should be triggered', async () => {
|
||||
const hideSpy = vi.spyOn(wrapper.vm, 'hide');
|
||||
|
||||
await wrapper.find('.p-sidebar-close').trigger('click');
|
||||
|
||||
expect(hideSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should keydown work', async () => {
|
||||
const event = { code: 'Escape' };
|
||||
it('When component is unmount , unbindOutsideClickListenerSpy method should be triggered', async () => {
|
||||
const unbindOutsideClickListenerSpy = vi.spyOn(wrapper.vm, 'unbindOutsideClickListener');
|
||||
|
||||
await wrapper.vm.onKeydown(event);
|
||||
await wrapper.unmount();
|
||||
|
||||
expect(wrapper.emitted()['update:visible'][0]).toEqual([false]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when visible is false', () => {
|
||||
let wrapper;
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = mount(Sidebar, {
|
||||
global: {
|
||||
plugins: [PrimeVue],
|
||||
stubs: {
|
||||
teleport: true,
|
||||
transition: false
|
||||
}
|
||||
},
|
||||
props: {
|
||||
visible: true,
|
||||
bazeZIndex: 1000
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should show and hide emit work', async () => {
|
||||
expect(wrapper.emitted()['show'][0]).toEqual([]);
|
||||
|
||||
await wrapper.setProps({ visible: false });
|
||||
|
||||
expect(wrapper.emitted()['hide'][0]).toEqual([]);
|
||||
});
|
||||
|
||||
it('should be destroyed', () => {
|
||||
wrapper.unmount();
|
||||
expect(wrapper.componentVM.container).toBe(null);
|
||||
expect(wrapper.componentVM.mask).toBe(null);
|
||||
expect(unbindOutsideClickListenerSpy).toHaveBeenCalled();
|
||||
expect(Sidebar.container).toBe(null);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<template>
|
||||
<Portal>
|
||||
<transition name="p-sidebar" @enter="onEnter" @leave="onLeave" @after-leave="onAfterLeave" appear>
|
||||
<div v-if="visible" :ref="containerRef" v-focustrap :class="containerClass" role="complementary" :aria-modal="modal" @keydown="onKeydown" v-bind="$attrs">
|
||||
<div v-if="maskVisible" ref="mask" style="maskStyle" :class="maskClasses" @mousedown="onMaskClick">
|
||||
<transition name="p-sidebar" @after-enter="onAfterEnter" @enter="onEnter" @leave="onLeave" @after-leave="onAfterLeave" appear>
|
||||
<div :ref="containerRef" v-focustrap :class="containerClass" role="complementary" :aria-modal="modal" @keydown="onKeydown" v-bind="$attrs">
|
||||
<div :ref="headerContainerRef" class="p-sidebar-header">
|
||||
<div v-if="$slots.header" class="p-sidebar-header-content">
|
||||
<slot name="header"></slot>
|
||||
|
@ -15,6 +16,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</Portal>
|
||||
</template>
|
||||
|
||||
|
@ -26,7 +28,6 @@ import { DomHandler, ZIndexUtils } from 'primevue/utils';
|
|||
|
||||
export default {
|
||||
name: 'Sidebar',
|
||||
inheritAttrs: false,
|
||||
emits: ['update:visible', 'show', 'hide'],
|
||||
props: {
|
||||
visible: {
|
||||
|
@ -60,50 +61,69 @@ export default {
|
|||
modal: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
blockScroll: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
mask: null,
|
||||
maskClickListener: null,
|
||||
container: null,
|
||||
content: null,
|
||||
headerContainer: null,
|
||||
closeButton: null,
|
||||
beforeUnmount() {
|
||||
this.destroyModal();
|
||||
outsideClickListener: null,
|
||||
data() {
|
||||
return {
|
||||
maskVisible: false
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
visible(val) {
|
||||
this.maskVisible = val;
|
||||
}
|
||||
},
|
||||
|
||||
beforeUnmount() {
|
||||
if (this.container && this.autoZIndex) {
|
||||
ZIndexUtils.clear(this.container);
|
||||
}
|
||||
|
||||
this.unbindOutsideClickListener();
|
||||
this.container = null;
|
||||
},
|
||||
methods: {
|
||||
hide() {
|
||||
this.$emit('update:visible', false);
|
||||
|
||||
this.unbindOutsideClickListener();
|
||||
this.blockScroll && DomHandler.removeClass(document.body, 'p-overflow-hidden');
|
||||
},
|
||||
onEnter(el) {
|
||||
onEnter() {
|
||||
this.$emit('show');
|
||||
|
||||
if (this.autoZIndex) {
|
||||
ZIndexUtils.set('modal', el, this.baseZIndex || this.$primevue.config.zIndex.modal);
|
||||
ZIndexUtils.set('modal', this.$refs.mask, this.baseZIndex || this.$primevue.config.zIndex.modal);
|
||||
}
|
||||
|
||||
this.maskVisible = true;
|
||||
this.focus();
|
||||
|
||||
if (this.modal && !this.fullScreen) {
|
||||
this.enableModality();
|
||||
}
|
||||
},
|
||||
onLeave() {
|
||||
this.$emit('hide');
|
||||
DomHandler.addClass(this.$refs.mask, 'p-component-overlay-leave');
|
||||
|
||||
if (this.modal && !this.fullScreen) {
|
||||
this.disableModality();
|
||||
this.$emit('hide');
|
||||
this.unbindOutsideClickListener();
|
||||
},
|
||||
onAfterLeave() {
|
||||
if (this.autoZIndex) {
|
||||
ZIndexUtils.clear(this.mask);
|
||||
}
|
||||
},
|
||||
onAfterLeave(el) {
|
||||
if (this.autoZIndex) {
|
||||
ZIndexUtils.clear(el);
|
||||
onAfterEnter() {
|
||||
this.bindOutsideClickListener();
|
||||
|
||||
if (this.blockScroll) {
|
||||
DomHandler.addClass(document.body, 'p-overflow-hidden');
|
||||
}
|
||||
},
|
||||
focus() {
|
||||
|
@ -123,54 +143,14 @@ export default {
|
|||
|
||||
focusTarget && focusTarget.focus();
|
||||
},
|
||||
enableModality() {
|
||||
if (!this.mask) {
|
||||
this.mask = document.createElement('div');
|
||||
this.mask.setAttribute('class', 'p-sidebar-mask p-component-overlay p-component-overlay-enter');
|
||||
this.mask.style.zIndex = String(parseInt(this.container.style.zIndex, 10) - 1);
|
||||
|
||||
if (this.dismissable) {
|
||||
this.bindMaskClickListener();
|
||||
}
|
||||
|
||||
document.body.appendChild(this.mask);
|
||||
DomHandler.addClass(document.body, 'p-overflow-hidden');
|
||||
}
|
||||
},
|
||||
disableModality() {
|
||||
if (this.mask) {
|
||||
DomHandler.addClass(this.mask, 'p-component-overlay-leave');
|
||||
this.mask.addEventListener('animationend', () => {
|
||||
this.destroyModal();
|
||||
});
|
||||
}
|
||||
},
|
||||
bindMaskClickListener() {
|
||||
if (!this.maskClickListener) {
|
||||
this.maskClickListener = () => {
|
||||
this.hide();
|
||||
};
|
||||
|
||||
this.mask.addEventListener('click', this.maskClickListener);
|
||||
}
|
||||
},
|
||||
onKeydown(event) {
|
||||
if (event.code === 'Escape') {
|
||||
this.hide();
|
||||
}
|
||||
},
|
||||
unbindMaskClickListener() {
|
||||
if (this.maskClickListener) {
|
||||
this.mask.removeEventListener('click', this.maskClickListener);
|
||||
this.maskClickListener = null;
|
||||
}
|
||||
},
|
||||
destroyModal() {
|
||||
if (this.mask) {
|
||||
this.unbindMaskClickListener();
|
||||
document.body.removeChild(this.mask);
|
||||
DomHandler.removeClass(document.body, 'p-overflow-hidden');
|
||||
this.mask = null;
|
||||
onMaskClick(event) {
|
||||
if (this.dismissable && this.modal && this.$refs.mask === event.target) {
|
||||
this.hide();
|
||||
}
|
||||
},
|
||||
containerRef(el) {
|
||||
|
@ -184,16 +164,43 @@ export default {
|
|||
},
|
||||
closeButtonRef(el) {
|
||||
this.closeButton = el;
|
||||
},
|
||||
getPositionClass() {
|
||||
const positions = ['left', 'right', 'top', 'bottom'];
|
||||
const pos = positions.find((item) => item === this.position);
|
||||
|
||||
return pos ? `p-sidebar-${pos}` : '';
|
||||
},
|
||||
bindOutsideClickListener() {
|
||||
if (!this.outsideClickListener) {
|
||||
this.outsideClickListener = (event) => {
|
||||
if (!this.modal && this.isOutsideClicked(event) && this.dismissable) {
|
||||
this.hide();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('click', this.outsideClickListener);
|
||||
}
|
||||
},
|
||||
unbindOutsideClickListener() {
|
||||
if (this.outsideClickListener) {
|
||||
document.removeEventListener('click', this.outsideClickListener);
|
||||
this.outsideClickListener = null;
|
||||
}
|
||||
},
|
||||
isOutsideClicked(event) {
|
||||
return this.container && !this.container.contains(event.target);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
containerClass() {
|
||||
return [
|
||||
'p-sidebar p-component p-sidebar-' + this.position,
|
||||
'p-sidebar p-component',
|
||||
this.getPositionClass(),
|
||||
{
|
||||
'p-sidebar-active': this.visible,
|
||||
'p-input-filled': this.$primevue.config.inputStyle === 'filled',
|
||||
'p-ripple-disabled': this.$primevue.config.ripple === false
|
||||
'p-ripple-disabled': this.$primevue.config.ripple === false,
|
||||
'p-sidebar-full': this.fullScreen
|
||||
}
|
||||
];
|
||||
},
|
||||
|
@ -202,6 +209,18 @@ export default {
|
|||
},
|
||||
closeAriaLabel() {
|
||||
return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.close : undefined;
|
||||
},
|
||||
maskClasses() {
|
||||
return [
|
||||
'p-sidebar-mask',
|
||||
this.getPositionClass(),
|
||||
{
|
||||
'p-component-overlay p-component-overlay-enter': this.modal,
|
||||
'p-sidebar-mask-scrollblocker': this.blockScroll,
|
||||
'p-sidebar-visible': this.maskVisible,
|
||||
'p-sidebar-full': this.fullScreen
|
||||
}
|
||||
];
|
||||
}
|
||||
},
|
||||
directives: {
|
||||
|
@ -215,134 +234,183 @@ export default {
|
|||
</script>
|
||||
|
||||
<style>
|
||||
.p-sidebar {
|
||||
.p-sidebar-mask {
|
||||
position: fixed;
|
||||
transition: transform 0.3s;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: none;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
pointer-events: none;
|
||||
background-color: transparent;
|
||||
transition-property: background-color;
|
||||
}
|
||||
|
||||
.p-sidebar-visible {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.p-sidebar-mask.p-component-overlay {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.p-sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
pointer-events: auto;
|
||||
transform: translate3d(0px, 0px, 0px);
|
||||
position: relative;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.p-sidebar-content {
|
||||
position: relative;
|
||||
overflow-y: auto;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.p-sidebar-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.p-sidebar-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.p-sidebar-left {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 20rem;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.p-sidebar-right {
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 20rem;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.p-sidebar-top {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 10rem;
|
||||
}
|
||||
|
||||
.p-sidebar-bottom {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 10rem;
|
||||
}
|
||||
|
||||
.p-sidebar-full {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
-webkit-transition: none;
|
||||
.p-sidebar-full .p-sidebar {
|
||||
transition: none;
|
||||
transform: none;
|
||||
width: 100vw !important;
|
||||
height: 100vh !important;
|
||||
max-height: 100%;
|
||||
top: 0px !important;
|
||||
left: 0px !important;
|
||||
}
|
||||
|
||||
/* Animation */
|
||||
/* Center */
|
||||
.p-sidebar-left.p-sidebar-enter-from,
|
||||
.p-sidebar-left.p-sidebar-leave-to {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
.p-sidebar-right.p-sidebar-enter-from,
|
||||
.p-sidebar-right.p-sidebar-leave-to {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
.p-sidebar-top.p-sidebar-enter-from,
|
||||
.p-sidebar-top.p-sidebar-leave-to {
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
.p-sidebar-bottom.p-sidebar-enter-from,
|
||||
.p-sidebar-bottom.p-sidebar-leave-to {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
.p-sidebar-full.p-sidebar-enter-from,
|
||||
.p-sidebar-full.p-sidebar-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.p-sidebar-full.p-sidebar-enter-active,
|
||||
.p-sidebar-full.p-sidebar-leave-active {
|
||||
transition: opacity 400ms cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||
}
|
||||
|
||||
.p-sidebar-left.p-sidebar-sm,
|
||||
.p-sidebar-right.p-sidebar-sm {
|
||||
/* Position */
|
||||
.p-sidebar-left {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.p-sidebar-right {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.p-sidebar-top {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.p-sidebar-bottom {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
/* Size */
|
||||
.p-sidebar-left .p-sidebar {
|
||||
width: 20rem;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.p-sidebar-right .p-sidebar {
|
||||
width: 20rem;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.p-sidebar-top .p-sidebar {
|
||||
height: 10rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.p-sidebar-bottom .p-sidebar {
|
||||
height: 10rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.p-sidebar-left .p-sidebar-sm,
|
||||
.p-sidebar-right .p-sidebar-sm {
|
||||
width: 20rem;
|
||||
}
|
||||
|
||||
.p-sidebar-left.p-sidebar-md,
|
||||
.p-sidebar-right.p-sidebar-md {
|
||||
.p-sidebar-left .p-sidebar-md,
|
||||
.p-sidebar-right .p-sidebar-md {
|
||||
width: 40rem;
|
||||
}
|
||||
|
||||
.p-sidebar-left.p-sidebar-lg,
|
||||
.p-sidebar-right.p-sidebar-lg {
|
||||
.p-sidebar-left .p-sidebar-lg,
|
||||
.p-sidebar-right .p-sidebar-lg {
|
||||
width: 60rem;
|
||||
}
|
||||
|
||||
.p-sidebar-top.p-sidebar-sm,
|
||||
.p-sidebar-bottom.p-sidebar-sm {
|
||||
.p-sidebar-top .p-sidebar-sm,
|
||||
.p-sidebar-bottom .p-sidebar-sm {
|
||||
height: 10rem;
|
||||
}
|
||||
|
||||
.p-sidebar-top.p-sidebar-md,
|
||||
.p-sidebar-bottom.p-sidebar-md {
|
||||
.p-sidebar-top .p-sidebar-md,
|
||||
.p-sidebar-bottom .p-sidebar-md {
|
||||
height: 20rem;
|
||||
}
|
||||
|
||||
.p-sidebar-top.p-sidebar-lg,
|
||||
.p-sidebar-bottom.p-sidebar-lg {
|
||||
.p-sidebar-top .p-sidebar-lg,
|
||||
.p-sidebar-bottom .p-sidebar-lg {
|
||||
height: 30rem;
|
||||
}
|
||||
|
||||
.p-sidebar-left .p-sidebar-view,
|
||||
.p-sidebar-right .p-sidebar-view,
|
||||
.p-sidebar-top .p-sidebar-view,
|
||||
.p-sidebar-bottom .p-sidebar-view {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.p-sidebar-left .p-sidebar-content,
|
||||
.p-sidebar-right .p-sidebar-content,
|
||||
.p-sidebar-top .p-sidebar-content,
|
||||
.p-sidebar-bottom .p-sidebar-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 64em) {
|
||||
.p-sidebar-left.p-sidebar-lg,
|
||||
.p-sidebar-left.p-sidebar-md,
|
||||
.p-sidebar-right.p-sidebar-lg,
|
||||
.p-sidebar-right.p-sidebar-md {
|
||||
.p-sidebar-left .p-sidebar-lg,
|
||||
.p-sidebar-left .p-sidebar-md,
|
||||
.p-sidebar-right .p-sidebar-lg,
|
||||
.p-sidebar-right .p-sidebar-md {
|
||||
width: 20rem;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -536,6 +536,9 @@ export default {
|
|||
.p-speeddial {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.p-speeddial-button {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
|
@ -548,6 +551,7 @@ export default {
|
|||
justify-content: center;
|
||||
transition: top 0s linear 0.2s;
|
||||
pointer-events: none;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.p-speeddial-item {
|
||||
|
|
|
@ -27,6 +27,7 @@ import { UniqueComponentId } from 'primevue/utils';
|
|||
|
||||
export default {
|
||||
name: 'SplitButton',
|
||||
emits: ['click'],
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
|
@ -91,6 +92,8 @@ export default {
|
|||
},
|
||||
onDefaultButtonClick(event) {
|
||||
this.$refs.menu.hide(event);
|
||||
|
||||
this.$emit('click');
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<span class="p-menuitem-text">{{ label(item) }}</span>
|
||||
</a>
|
||||
</template>
|
||||
<component v-else :is="$slots.item" :item="item"></component>
|
||||
<component v-else :is="$slots.item" :item="item" :index="i"></component>
|
||||
</li>
|
||||
</router-link>
|
||||
<li v-else-if="visible(item)" ref="tab" :class="getItemClass(item, i)" role="presentation" @click="onItemClick($event, item, i)" @keydown="onKeydownItem($event, item, i)">
|
||||
|
@ -31,7 +31,7 @@
|
|||
<span class="p-menuitem-text">{{ label(item) }}</span>
|
||||
</a>
|
||||
</template>
|
||||
<component v-else :is="$slots.item" :item="item"></component>
|
||||
<component v-else :is="$slots.item" :item="item" :index="i"></component>
|
||||
</li>
|
||||
</template>
|
||||
<li ref="inkbar" class="p-tabmenu-ink-bar"></li>
|
||||
|
|
|
@ -99,11 +99,11 @@ export default {
|
|||
},
|
||||
previousButtonProps: {
|
||||
type: null,
|
||||
defaault: null
|
||||
default: null
|
||||
},
|
||||
nextButtonProps: {
|
||||
type: null,
|
||||
defaault: null
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
|
|
@ -96,8 +96,8 @@ export default {
|
|||
getItemKey(processedItem) {
|
||||
return this.getItemId(processedItem);
|
||||
},
|
||||
getItemProp(processedItem, name) {
|
||||
return processedItem && processedItem.item ? ObjectUtils.getItemValue(processedItem.item[name]) : undefined;
|
||||
getItemProp(processedItem, name, params) {
|
||||
return processedItem && processedItem.item ? ObjectUtils.getItemValue(processedItem.item[name], params) : undefined;
|
||||
},
|
||||
getItemLabel(processedItem) {
|
||||
return this.getItemProp(processedItem, 'label');
|
||||
|
@ -118,9 +118,7 @@ export default {
|
|||
return ObjectUtils.isNotEmpty(processedItem.items);
|
||||
},
|
||||
onItemClick(event, processedItem) {
|
||||
const command = this.getItemProp(processedItem, 'command');
|
||||
|
||||
command && command({ originalEvent: event, item: processedItem.item });
|
||||
this.getItemProp(processedItem, 'command', { originalEvent: event, item: processedItem.item });
|
||||
this.$emit('item-click', { originalEvent: event, processedItem, isFocus: true });
|
||||
},
|
||||
onItemMouseEnter(event, processedItem) {
|
||||
|
|
|
@ -562,6 +562,10 @@ export default {
|
|||
<td>loader</td>
|
||||
<td>options: Options of the loader items for virtualscroller</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>empty</td>
|
||||
<td>-</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
@ -605,6 +609,10 @@ export default {
|
|||
<td>p-autocomplete-token-label</td>
|
||||
<td>Label of a selected item in multiple mode.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>p-autocomplete-empty-message</td>
|
||||
<td>Container element when there is no suggestion to display.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>p-overlay-open</td>
|
||||
<td>Container element when overlay is visible.</td>
|
||||
|
|
|
@ -681,7 +681,7 @@ export default {
|
|||
<Button type="button" icon="pi pi-plus" label="Expand All" @click="expandAll" class="mr-2" />
|
||||
<Button type="button" icon="pi pi-minus" label="Collapse All" @click="collapseAll" />
|
||||
</div>
|
||||
<PanelMenu :model="items" :expandedKeys="expandedKeys" />
|
||||
<PanelMenu :model="items" v-model:expandedKeys="expandedKeys" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -867,7 +867,7 @@ export default {
|
|||
<Button type="button" icon="pi pi-plus" label="Expand All" @click="expandAll" class="mr-2" />
|
||||
<Button type="button" icon="pi pi-minus" label="Collapse All" @click="collapseAll" />
|
||||
</div>
|
||||
<PanelMenu :model="items" :expandedKeys="expandedKeys" />
|
||||
<PanelMenu :model="items" v-model:expandedKeys="expandedKeys" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -1053,7 +1053,7 @@ export default {
|
|||
<p-button type="button" icon="pi pi-plus" label="Expand All" @click="expandAll" class="mr-2"></p-button>
|
||||
<p-button type="button" icon="pi pi-minus" label="Collapse All" @click="collapseAll"></p-button>
|
||||
</div>
|
||||
<p-panelmenu :model="items" :expanded-keys="expandedKeys"></p-panelmenu>
|
||||
<p-panelmenu :model="items" v-model:expanded-keys="expandedKeys"></p-panelmenu>
|
||||
</div>
|
||||
|
||||
<script type="module">
|
||||
|
|
|
@ -121,6 +121,12 @@ import Sidebar from 'primevue/sidebar';
|
|||
<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>blockScroll</td>
|
||||
<td>boolean</td>
|
||||
<td>true</td>
|
||||
<td>Whether background scroll should be blocked when sidebar is visible.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
@ -159,7 +159,10 @@ export default {
|
|||
<tbody>
|
||||
<tr>
|
||||
<td>item</td>
|
||||
<td>item: Menuitem instance</td>
|
||||
<td>
|
||||
item: Menuitem instance<br />
|
||||
index: Index of the menuitem instance
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -212,7 +212,7 @@ export default class NodeService {
|
|||
<Button type="button" icon="pi pi-plus" label="Expand All" @click="expandAll" />
|
||||
<Button type="button" icon="pi pi-minus" label="Collapse All" @click="collapseAll" />
|
||||
</div>
|
||||
<Tree :value="nodes" :expandedKeys="expandedKeys"></Tree>
|
||||
<Tree :value="nodes" v-model:expandedKeys="expandedKeys"></Tree>
|
||||
|
||||
</code></pre>
|
||||
|
||||
|
@ -894,7 +894,7 @@ export default {
|
|||
<Button type="button" icon="pi pi-plus" label="Expand All" @click="expandAll" />
|
||||
<Button type="button" icon="pi pi-minus" label="Collapse All" @click="collapseAll" />
|
||||
</div>
|
||||
<Tree :value="nodes" :expandedKeys="expandedKeys"></Tree>
|
||||
<Tree :value="nodes" v-model:expandedKeys="expandedKeys"></Tree>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -958,7 +958,7 @@ export default {
|
|||
<Button type="button" icon="pi pi-plus" label="Expand All" @click="expandAll" />
|
||||
<Button type="button" icon="pi pi-minus" label="Collapse All" @click="collapseAll" />
|
||||
</div>
|
||||
<Tree :value="nodes" :expandedKeys="expandedKeys"></Tree>
|
||||
<Tree :value="nodes" v-model:expandedKeys="expandedKeys"></Tree>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -1018,7 +1018,7 @@ export default {
|
|||
<p-button type="button" icon="pi pi-plus" label="Expand All" @click="expandAll"></p-button>
|
||||
<p-button type="button" icon="pi pi-minus" label="Collapse All" @click="collapseAll"></p-button>
|
||||
</div>
|
||||
<p-tree :value="nodes" :expanded-keys="expandedKeys"></p-tree>
|
||||
<p-tree :value="nodes" v-model:expanded-keys="expandedKeys"></p-tree>
|
||||
</div>
|
||||
|
||||
<script type="module">
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<Button type="button" icon="pi pi-plus" label="Expand All" @click="expandAll" />
|
||||
<Button type="button" icon="pi pi-minus" label="Collapse All" @click="collapseAll" />
|
||||
</div>
|
||||
<Tree :value="nodes" :expandedKeys="expandedKeys"></Tree>
|
||||
<Tree v-model:expandedKeys="expandedKeys" :value="nodes"></Tree>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -647,7 +647,7 @@ export default {
|
|||
<Button type="button" icon="pi pi-plus" label="Expand All" @click="expandAll" />
|
||||
<Button type="button" icon="pi pi-minus" label="Collapse All" @click="collapseAll" />
|
||||
</div>
|
||||
<TreeTable :value="nodes" :expandedKeys="expandedKeys">
|
||||
<TreeTable :value="nodes" v-model:expandedKeys="expandedKeys">
|
||||
<Column field="name" header="Name" :expander="true"></Column>
|
||||
<Column field="size" header="Size"></Column>
|
||||
<Column field="type" header="Type"></Column>
|
||||
|
@ -1917,7 +1917,7 @@ export default {
|
|||
<Button type="button" icon="pi pi-plus" label="Expand All" @click="expandAll" />
|
||||
<Button type="button" icon="pi pi-minus" label="Collapse All" @click="collapseAll" />
|
||||
</div>
|
||||
<TreeTable :value="nodes" :expandedKeys="expandedKeys">
|
||||
<TreeTable :value="nodes" v-model:expandedKeys="expandedKeys">
|
||||
<Column field="name" header="Name" :expander="true"></Column>
|
||||
<Column field="size" header="Size"></Column>
|
||||
<Column field="type" header="Type"></Column>
|
||||
|
@ -2008,7 +2008,7 @@ button {
|
|||
<Button type="button" icon="pi pi-plus" label="Expand All" @click="expandAll" />
|
||||
<Button type="button" icon="pi pi-minus" label="Collapse All" @click="collapseAll" />
|
||||
</div>
|
||||
<TreeTable :value="nodes" :expandedKeys="expandedKeys">
|
||||
<TreeTable :value="nodes" v-model:expandedKeys="expandedKeys">
|
||||
<Column field="name" header="Name" :expander="true"></Column>
|
||||
<Column field="size" header="Size"></Column>
|
||||
<Column field="type" header="Type"></Column>
|
||||
|
@ -2093,7 +2093,7 @@ button {
|
|||
<p-button type="button" icon="pi pi-plus" label="Expand All" @click="expandAll"></p-button>
|
||||
<p-button type="button" icon="pi pi-minus" label="Collapse All" @click="collapseAll"></p-button>
|
||||
</div>
|
||||
<p-treetable :value="nodes" :expanded-keys="expandedKeys">
|
||||
<p-treetable :value="nodes" v-model:expanded-keys="expandedKeys">
|
||||
<p-column field="name" header="Name" :expander="true"></p-column>
|
||||
<p-column field="size" header="Size"></p-column>
|
||||
<p-column field="type" header="Type"></p-column>
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
<Button type="button" icon="pi pi-plus" label="Expand All" @click="expandAll" />
|
||||
<Button type="button" icon="pi pi-minus" label="Collapse All" @click="collapseAll" />
|
||||
</div>
|
||||
<TreeTable :value="nodes" :expandedKeys="expandedKeys">
|
||||
<TreeTable v-model:expandedKeys="expandedKeys" :value="nodes">
|
||||
<Column field="name" header="Name" :expander="true"></Column>
|
||||
<Column field="size" header="Size"></Column>
|
||||
<Column field="type" header="Type"></Column>
|
||||
|
|
Loading…
Reference in New Issue