Refactor #3922 - For CascadeSelect
parent
1f00024df1
commit
d180ac7002
|
@ -184,6 +184,12 @@ const CascadeSelectProps = [
|
|||
type: 'string',
|
||||
default: 'null',
|
||||
description: 'Identifier of the underlying input element.'
|
||||
},
|
||||
{
|
||||
name: 'pt',
|
||||
type: 'any',
|
||||
default: 'null',
|
||||
description: 'Uses to pass attributes to DOM elements inside the component.'
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -10,6 +10,16 @@
|
|||
import { HTMLAttributes, InputHTMLAttributes, VNode } from 'vue';
|
||||
import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers';
|
||||
|
||||
export declare type CascadeSelectPassThroughOptionType = CascadeSelectPassThroughAttributes | ((options: CascadeSelectPassThroughMethodOptions) => CascadeSelectPassThroughAttributes) | null | undefined;
|
||||
|
||||
/**
|
||||
* Custom passthrough(pt) option method.
|
||||
*/
|
||||
export interface CascadeSelectPassThroughMethodOptions {
|
||||
props: CascadeSelectProps;
|
||||
state: CascadeSelectState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom change event
|
||||
* @see {@link CascadeSelectEmits.change}
|
||||
|
@ -31,6 +41,124 @@ export interface CascadeSelectChangeEvent {
|
|||
*/
|
||||
export interface CascadeSelectGroupChangeEvent extends CascadeSelectChangeEvent {}
|
||||
|
||||
/**
|
||||
* Custom passthrough(pt) options.
|
||||
* @see {@link CascadeSelectProps.pt}
|
||||
*/
|
||||
export interface CascadeSelectPassThroughOptions {
|
||||
/**
|
||||
* Uses to pass attributes to the root's DOM element.
|
||||
*/
|
||||
root?: CascadeSelectPassThroughOptionType;
|
||||
/**
|
||||
* Uses to pass attributes to the input's DOM element.
|
||||
*/
|
||||
input?: CascadeSelectPassThroughOptionType;
|
||||
/**
|
||||
* Uses to pass attributes to the label's DOM element.
|
||||
*/
|
||||
label?: CascadeSelectPassThroughOptionType;
|
||||
/**
|
||||
* Uses to pass attributes to the dropdown button's DOM element.
|
||||
*/
|
||||
dropdownButton?: CascadeSelectPassThroughOptionType;
|
||||
/**
|
||||
* Uses to pass attributes to the loading icon's DOM element.
|
||||
*/
|
||||
loadingIcon?: CascadeSelectPassThroughOptionType;
|
||||
/**
|
||||
* Uses to pass attributes to the dropdown icon's DOM element.
|
||||
*/
|
||||
dropdownIcon?: CascadeSelectPassThroughOptionType;
|
||||
/**
|
||||
* Uses to pass attributes to the panel's DOM element.
|
||||
*/
|
||||
panel?: CascadeSelectPassThroughOptionType;
|
||||
/**
|
||||
* Uses to pass attributes to the list's DOM element.
|
||||
*/
|
||||
list?: CascadeSelectPassThroughOptionType;
|
||||
/**
|
||||
* Uses to pass attributes to the item's DOM element.
|
||||
*/
|
||||
item?: CascadeSelectPassThroughOptionType;
|
||||
/**
|
||||
* Uses to pass attributes to the content's DOM element.
|
||||
*/
|
||||
content?: CascadeSelectPassThroughOptionType;
|
||||
/**
|
||||
* Uses to pass attributes to the text's DOM element.
|
||||
*/
|
||||
text?: CascadeSelectPassThroughOptionType;
|
||||
/**
|
||||
* Uses to pass attributes to the input sria's DOM element.
|
||||
*/
|
||||
inputAria?: CascadeSelectPassThroughOptionType;
|
||||
/**
|
||||
* Uses to pass attributes to the search result message text aria's DOM element.
|
||||
*/
|
||||
searchResultAria?: CascadeSelectPassThroughOptionType;
|
||||
/**
|
||||
* Uses to pass attributes to the selected message text aria's DOM element.
|
||||
*/
|
||||
selectedMessageAria?: CascadeSelectPassThroughOptionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom passthrough attributes for each DOM elements
|
||||
*/
|
||||
export interface CascadeSelectPassThroughAttributes {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines focused item info
|
||||
*/
|
||||
export interface CascadeSelectFocusedOptionInfo {
|
||||
/**
|
||||
* Active item index
|
||||
*/
|
||||
index: number;
|
||||
/**
|
||||
* Active item level
|
||||
*/
|
||||
level: number;
|
||||
/**
|
||||
* Parent key info
|
||||
*/
|
||||
parentKey: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines current inline state in CascadeSelect component.
|
||||
*/
|
||||
export interface CascadeSelectState {
|
||||
/**
|
||||
* Current id state as a string
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Current focused state as a boolean.
|
||||
* @defaultValue false
|
||||
*/
|
||||
focused: boolean;
|
||||
/**
|
||||
* Current focused item info.
|
||||
* @type {CascadeSelectFocusedOptionInfo}
|
||||
*/
|
||||
focusedOptionInfo: CascadeSelectFocusedOptionInfo;
|
||||
/**
|
||||
* Current focused state as a boolean.
|
||||
* @defaultValue false
|
||||
*/
|
||||
activeOptionPath: any[];
|
||||
/**
|
||||
* Current overlay visible state as a boolean.
|
||||
* @defaultValue false
|
||||
*/
|
||||
overlayVisible: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines valid properties in CascadeSelect component.
|
||||
*/
|
||||
|
@ -180,6 +308,11 @@ export interface CascadeSelectProps {
|
|||
* Establishes a string value that labels the component.
|
||||
*/
|
||||
'aria-label'?: string | undefined;
|
||||
/**
|
||||
* Uses to pass attributes to DOM elements inside the component.
|
||||
* @type {CascadeSelectPassThroughOptions}
|
||||
*/
|
||||
pt?: CascadeSelectPassThroughOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div ref="container" :class="containerClass" @click="onContainerClick($event)">
|
||||
<div class="p-hidden-accessible">
|
||||
<div ref="container" :class="containerClass" @click="onContainerClick($event)" v-bind="ptm('root')">
|
||||
<div class="p-hidden-accessible" v-bind="ptm('inputAria')">
|
||||
<input
|
||||
ref="focusInput"
|
||||
:id="inputId"
|
||||
|
@ -21,30 +21,30 @@
|
|||
@focus="onFocus"
|
||||
@blur="onBlur"
|
||||
@keydown="onKeyDown"
|
||||
v-bind="inputProps"
|
||||
v-bind="{ ...inputProps, ...ptm('input') }"
|
||||
/>
|
||||
</div>
|
||||
<span :class="labelClass">
|
||||
<span :class="labelClass" v-bind="ptm('label')">
|
||||
<slot name="value" :value="modelValue" :placeholder="placeholder">
|
||||
{{ label }}
|
||||
</slot>
|
||||
</span>
|
||||
<div class="p-cascadeselect-trigger" role="button" tabindex="-1" aria-hidden="true">
|
||||
<div class="p-cascadeselect-trigger" role="button" tabindex="-1" aria-hidden="true" v-bind="ptm('dropdownButton')">
|
||||
<slot v-if="loading" name="loadingicon" class="p-cascadeselect-trigger-icon">
|
||||
<span v-if="loadingIcon" :class="['p-cascadeselect-trigger-icon pi-spin', loadingIcon]" aria-hidden="true" />
|
||||
<SpinnerIcon v-else class="p-cascadeselect-trigger-icon" spin aria-hidden="true" />
|
||||
<span v-if="loadingIcon" :class="['p-cascadeselect-trigger-icon pi-spin', loadingIcon]" aria-hidden="true" v-bind="ptm('loadingIcon')" />
|
||||
<SpinnerIcon v-else class="p-cascadeselect-trigger-icon" spin aria-hidden="true" v-bind="ptm('loadingIcon')" />
|
||||
</slot>
|
||||
<slot v-else name="dropdownicon" class="p-cascadeselect-trigger-icon">
|
||||
<component :is="dropdownIcon ? 'span' : 'ChevronDownIcon'" :class="['p-cascadeselect-trigger-icon', dropdownIcon]" aria-hidden="true" />
|
||||
<component :is="dropdownIcon ? 'span' : 'ChevronDownIcon'" :class="['p-cascadeselect-trigger-icon', dropdownIcon]" aria-hidden="true" v-bind="ptm('dropdownIcon')" />
|
||||
</slot>
|
||||
</div>
|
||||
<span role="status" aria-live="polite" class="p-hidden-accessible">
|
||||
<span role="status" aria-live="polite" class="p-hidden-accessible" v-bind="ptm('searchResultAria')">
|
||||
{{ searchResultMessageText }}
|
||||
</span>
|
||||
<Portal :appendTo="appendTo">
|
||||
<transition name="p-connected-overlay" @enter="onOverlayEnter" @after-enter="onOverlayAfterEnter" @leave="onOverlayLeave" @after-leave="onOverlayAfterLeave">
|
||||
<div v-if="overlayVisible" :ref="overlayRef" :style="panelStyle" :class="panelStyleClass" @click="onOverlayClick" @keydown="onOverlayKeyDown" v-bind="panelProps">
|
||||
<div class="p-cascadeselect-items-wrapper">
|
||||
<div v-if="overlayVisible" :ref="overlayRef" :style="panelStyle" :class="panelStyleClass" @click="onOverlayClick" @keydown="onOverlayKeyDown" v-bind="{ ...panelProps, ...ptm('panel') }">
|
||||
<div class="p-cascadeselect-items-wrapper" v-bind="ptm('wrapper')">
|
||||
<CascadeSelectSub
|
||||
:id="id + '_tree'"
|
||||
role="tree"
|
||||
|
@ -62,10 +62,11 @@
|
|||
:optionGroupLabel="optionGroupLabel"
|
||||
:optionGroupChildren="optionGroupChildren"
|
||||
@option-change="onOptionChange"
|
||||
:pt="pt"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<span role="status" aria-live="polite" class="p-hidden-accessible">
|
||||
<span role="status" aria-live="polite" class="p-hidden-accessible" v-bind="ptm('selectedMessageAria')">
|
||||
{{ selectedMessageText }}
|
||||
</span>
|
||||
</div>
|
||||
|
@ -75,6 +76,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import BaseComponent from 'primevue/basecomponent';
|
||||
import AngleRightIcon from 'primevue/icons/angleright';
|
||||
import ChevronDownIcon from 'primevue/icons/chevrondown';
|
||||
import SpinnerIcon from 'primevue/icons/spinner';
|
||||
|
@ -85,6 +87,7 @@ import CascadeSelectSub from './CascadeSelectSub.vue';
|
|||
|
||||
export default {
|
||||
name: 'CascadeSelect',
|
||||
extends: BaseComponent,
|
||||
emits: ['update:modelValue', 'change', 'focus', 'blur', 'click', 'group-change', 'before-show', 'before-hide', 'hide', 'show'],
|
||||
props: {
|
||||
modelValue: null,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<ul class="p-cascadeselect-panel p-cascadeselect-items">
|
||||
<ul class="p-cascadeselect-panel p-cascadeselect-items" v-bind="ptm('list')">
|
||||
<template v-for="(processedOption, index) of options" :key="getOptionLabelToRender(processedOption)">
|
||||
<li
|
||||
:id="getOptionId(processedOption)"
|
||||
|
@ -11,10 +11,11 @@
|
|||
:aria-level="level + 1"
|
||||
:aria-setsize="options.length"
|
||||
:aria-posinset="index + 1"
|
||||
v-bind="ptm('item')"
|
||||
>
|
||||
<div v-ripple class="p-cascadeselect-item-content" @click="onOptionClick($event, processedOption)">
|
||||
<div v-ripple class="p-cascadeselect-item-content" @click="onOptionClick($event, processedOption)" v-bind="ptm('content')">
|
||||
<component v-if="templates['option']" :is="templates['option']" :option="processedOption.option" />
|
||||
<span v-else class="p-cascadeselect-item-text">{{ getOptionLabelToRender(processedOption) }}</span>
|
||||
<span v-else class="p-cascadeselect-item-text" v-bind="ptm('text')">{{ getOptionLabelToRender(processedOption) }}</span>
|
||||
<component
|
||||
v-if="isOptionGroup(processedOption)"
|
||||
:is="templates['optiongroupicon'] ? templates['optiongroupicon'] : optionGroupIcon ? 'span' : 'AngleRightIcon'"
|
||||
|
@ -39,6 +40,7 @@
|
|||
:optionGroupLabel="optionGroupLabel"
|
||||
:optionGroupChildren="optionGroupChildren"
|
||||
@option-change="onOptionChange"
|
||||
:pt="pt"
|
||||
/>
|
||||
</li>
|
||||
</template>
|
||||
|
@ -46,12 +48,14 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import BaseComponent from 'primevue/basecomponent';
|
||||
import AngleRightIcon from 'primevue/icons/angleright';
|
||||
import Ripple from 'primevue/ripple';
|
||||
import { DomHandler, ObjectUtils } from 'primevue/utils';
|
||||
|
||||
export default {
|
||||
name: 'CascadeSelectSub',
|
||||
extends: BaseComponent,
|
||||
emits: ['option-change'],
|
||||
props: {
|
||||
selectId: String,
|
||||
|
|
|
@ -10,6 +10,7 @@ import { ButtonPassThroughOptions } from '../button';
|
|||
import { CalendarPassThroughOptions } from '../calendar';
|
||||
import { CardPassThroughOptions } from '../card';
|
||||
import { CarouselPassThroughOptions } from '../carousel';
|
||||
import { CascadeSelectPassThroughOptions } from '../cascadeselect';
|
||||
import { ChartPassThroughOptions } from '../chart';
|
||||
import { ChipPassThroughOptions } from '../chip';
|
||||
import { ConfirmDialogPassThroughOptions } from '../confirmdialog';
|
||||
|
@ -79,6 +80,7 @@ interface PrimeVuePTOptions {
|
|||
calendar?: CalendarPassThroughOptions;
|
||||
card?: CardPassThroughOptions;
|
||||
carousel?: CarouselPassThroughOptions;
|
||||
cascadeselect?: CascadeSelectPassThroughOptions;
|
||||
chart?: ChartPassThroughOptions;
|
||||
chip?: ChipPassThroughOptions;
|
||||
confirmdialog?: ConfirmDialogPassThroughOptions;
|
||||
|
|
Loading…
Reference in New Issue