Refactor #3965 - For Picklist

pull/4030/head
Bahadır Sofuoğlu 2023-06-02 18:43:30 +03:00
parent 7b563f1a7e
commit 2d28fe4908
4 changed files with 217 additions and 163 deletions

View File

@ -62,10 +62,10 @@ const classes = {
] ]
}; };
const { load: loadStyle } = useStyle(styles, { id: 'primevue_organizationchart_style', manual: true }); const { load: loadStyle } = useStyle(styles, { id: 'primevue_orderlist_style', manual: true });
export default { export default {
name: 'BaseOrganizationChart', name: 'BaseOrderList',
extends: BaseComponent, extends: BaseComponent,
props: { props: {
modelValue: { modelValue: {

View File

@ -0,0 +1,166 @@
<script>
import BaseComponent from 'primevue/basecomponent';
import { useStyle } from 'primevue/usestyle';
const styles = `
.p-picklist {
display: flex;
}
.p-picklist-buttons {
display: flex;
flex-direction: column;
justify-content: center;
}
.p-picklist-list-wrapper {
flex: 1 1 50%;
}
.p-picklist-list {
list-style-type: none;
margin: 0;
padding: 0;
overflow: auto;
min-height: 12rem;
max-height: 24rem;
}
.p-picklist-item {
cursor: pointer;
overflow: hidden;
position: relative;
}
.p-picklist-item.p-picklist-flip-enter-active.p-picklist-flip-enter-to,
.p-picklist-item.p-picklist-flip-leave-active.p-picklist-flip-leave-to {
transition: none !important;
}
`;
const classes = {
root: ({ props }) => [
'p-picklist p-component',
{
'p-picklist-striped': props.stripedRows
}
],
sourceControls: 'p-picklist-buttons p-picklist-source-controls',
sourceWrapper: 'p-picklist-list-wrapper p-picklist-source-wrapper',
sourceList: 'p-picklist-list p-picklist-source-list',
item: ({ context }) => [
'p-picklist-item',
{
'p-highlight': context.active,
'p-focus': context.focused
}
],
buttons: 'p-picklist-buttons p-picklist-transfer-buttons',
targetWrapper: 'p-picklist-list-wrapper p-picklist-target-wrapper',
targetHeader: 'p-picklist-header',
targetList: 'p-picklist-list p-picklist-target',
targetControls: 'p-picklist-buttons p-picklist-target-controls'
};
const { load: loadStyle } = useStyle(styles, { id: 'primevue_picklist_style', manual: true });
export default {
name: 'BasePickList',
extends: BaseComponent,
props: {
modelValue: {
type: Array,
default: () => [[], []]
},
selection: {
type: Array,
default: () => [[], []]
},
dataKey: {
type: String,
default: null
},
listStyle: {
type: null,
default: null
},
metaKeySelection: {
type: Boolean,
default: true
},
responsive: {
type: Boolean,
default: true
},
breakpoint: {
type: String,
default: '960px'
},
stripedRows: {
type: Boolean,
default: false
},
showSourceControls: {
type: Boolean,
default: true
},
showTargetControls: {
type: Boolean,
default: true
},
targetListProps: {
type: null,
default: null
},
sourceListProps: {
type: null,
default: null
},
moveUpButtonProps: {
type: null,
default: null
},
moveTopButtonProps: {
type: null,
default: null
},
moveDownButtonProps: {
type: null,
default: null
},
moveBottomButtonProps: {
type: null,
default: null
},
moveToTargetProps: {
type: null,
default: null
},
moveAllToTargetProps: {
type: null,
default: null
},
moveToSourceProps: {
type: null,
default: null
},
moveAllToSourceProps: {
type: null,
default: null
},
tabindex: {
type: Number,
default: 0
}
},
css: {
classes,
loadStyle
},
provide() {
return {
$parentInstance: this
};
}
};
</script>

View File

@ -340,6 +340,11 @@ export interface PickListProps {
* @type {PickListPassThroughOptions} * @type {PickListPassThroughOptions}
*/ */
pt?: PickListPassThroughOptions; pt?: PickListPassThroughOptions;
/**
* When enabled, it removes component related styles in the core.
* @defaultValue false
*/
unstyled?: boolean;
} }
/** /**

View File

@ -1,6 +1,6 @@
<template> <template>
<div :class="containerClass" v-bind="ptm('root')"> <div :class="cx('root')" v-bind="ptm('root')">
<div v-if="showSourceControls" class="p-picklist-buttons p-picklist-source-controls" v-bind="ptm('sourceControls')"> <div v-if="showSourceControls" :class="cx('sourceControls')" v-bind="ptm('sourceControls')">
<slot name="sourcecontrolsstart"></slot> <slot name="sourcecontrolsstart"></slot>
<PLButton :aria-label="moveUpAriaLabel" :disabled="moveDisabled(0)" type="button" @click="moveUp($event, 0)" v-bind="moveUpButtonProps" :pt="ptm('sourceMoveUpButton')"> <PLButton :aria-label="moveUpAriaLabel" :disabled="moveDisabled(0)" type="button" @click="moveUp($event, 0)" v-bind="moveUpButtonProps" :pt="ptm('sourceMoveUpButton')">
<template #icon> <template #icon>
@ -32,7 +32,7 @@
</PLButton> </PLButton>
<slot name="sourcecontrolsend"></slot> <slot name="sourcecontrolsend"></slot>
</div> </div>
<div class="p-picklist-list-wrapper p-picklist-source-wrapper" v-bind="ptm('sourceWrapper')"> <div :class="cx('sourceWrapper')" v-bind="ptm('sourceWrapper')">
<div v-if="$slots.sourceheader" class="p-picklist-header" v-bind="ptm('sourceHeader')"> <div v-if="$slots.sourceheader" class="p-picklist-header" v-bind="ptm('sourceHeader')">
<slot name="sourceheader"></slot> <slot name="sourceheader"></slot>
</div> </div>
@ -41,7 +41,7 @@
:id="idSource + '_list'" :id="idSource + '_list'"
name="p-picklist-flip" name="p-picklist-flip"
tag="ul" tag="ul"
class="p-picklist-list p-picklist-source" :class="cx('sourceList')"
:style="listStyle" :style="listStyle"
role="listbox" role="listbox"
aria-multiselectable="true" aria-multiselectable="true"
@ -56,7 +56,15 @@
<li <li
:id="idSource + '_' + i" :id="idSource + '_' + i"
v-ripple v-ripple
:class="itemClass(item, `${idSource}_${i}`, 0)" :class="
cx('item', {
context: {
active: isSelected(item, 0),
focused: `${idSource}_${i}` === focusedOptionId
}
})
"
:data-p-highlight="isSelected(item, 1)"
@click="onItemClick($event, item, i, 0)" @click="onItemClick($event, item, i, 0)"
@dblclick="onItemDblClick($event, item, 0)" @dblclick="onItemDblClick($event, item, 0)"
@touchend="onItemTouchEnd" @touchend="onItemTouchEnd"
@ -70,7 +78,7 @@
</template> </template>
</transition-group> </transition-group>
</div> </div>
<div class="p-picklist-buttons p-picklist-transfer-buttons" v-bind="ptm('buttons')"> <div :class="cx('buttons')" v-bind="ptm('buttons')">
<slot name="movecontrolsstart"></slot> <slot name="movecontrolsstart"></slot>
<PLButton :aria-label="moveToTargetAriaLabel" type="button" @click="moveToTarget" :disabled="moveDisabled(0)" v-bind="moveToTargetProps" :pt="ptm('moveToTargetButton')"> <PLButton :aria-label="moveToTargetAriaLabel" type="button" @click="moveToTarget" :disabled="moveDisabled(0)" v-bind="moveToTargetProps" :pt="ptm('moveToTargetButton')">
<template #icon> <template #icon>
@ -102,8 +110,8 @@
</PLButton> </PLButton>
<slot name="movecontrolsend"></slot> <slot name="movecontrolsend"></slot>
</div> </div>
<div class="p-picklist-list-wrapper p-picklist-target-wrapper" v-bind="ptm('targetWrapper')"> <div :class="cx('targetWrapper')" v-bind="ptm('targetWrapper')">
<div v-if="$slots.targetheader" class="p-picklist-header" v-bind="ptm('targetHeader')"> <div v-if="$slots.targetheader" :class="cx('targetHeader')" v-bind="ptm('targetHeader')">
<slot name="targetheader"></slot> <slot name="targetheader"></slot>
</div> </div>
<transition-group <transition-group
@ -111,7 +119,7 @@
:id="idTarget + '_list'" :id="idTarget + '_list'"
name="p-picklist-flip" name="p-picklist-flip"
tag="ul" tag="ul"
class="p-picklist-list p-picklist-target" :class="cx('targetList')"
:style="listStyle" :style="listStyle"
role="listbox" role="listbox"
aria-multiselectable="true" aria-multiselectable="true"
@ -126,7 +134,15 @@
<li <li
:id="idTarget + '_' + i" :id="idTarget + '_' + i"
v-ripple v-ripple
:class="itemClass(item, `${idTarget}_${i}`, 1)" :class="
cx('item', {
context: {
active: isSelected(item, 1),
focused: `${idTarget}_${i}` === focusedOptionId
}
})
"
:data-p-highlight="isSelected(item, 1)"
@click="onItemClick($event, item, i, 1)" @click="onItemClick($event, item, i, 1)"
@dblclick="onItemDblClick($event, item, 1)" @dblclick="onItemDblClick($event, item, 1)"
@keydown="onItemKeyDown($event, 'targetList')" @keydown="onItemKeyDown($event, 'targetList')"
@ -141,7 +157,7 @@
</template> </template>
</transition-group> </transition-group>
</div> </div>
<div v-if="showTargetControls" class="p-picklist-buttons p-picklist-target-controls" v-bind="ptm('targetControls')"> <div v-if="showTargetControls" :class="cx('targetControls')" v-bind="ptm('targetControls')">
<slot name="targetcontrolsstart"></slot> <slot name="targetcontrolsstart"></slot>
<PLButton :aria-label="moveUpAriaLabel" :disabled="moveDisabled(1)" type="button" @click="moveUp($event, 1)" v-bind="moveUpButtonProps" :pt="ptm('targetMoveUpButton')"> <PLButton :aria-label="moveUpAriaLabel" :disabled="moveDisabled(1)" type="button" @click="moveUp($event, 1)" v-bind="moveUpButtonProps" :pt="ptm('targetMoveUpButton')">
<template #icon> <template #icon>
@ -177,7 +193,7 @@
</template> </template>
<script> <script>
import BaseComponent from 'primevue/basecomponent'; import BasePickList from './BasePickList.vue';
import Button from 'primevue/button'; import Button from 'primevue/button';
import AngleDoubleDownIcon from 'primevue/icons/angledoubledown'; import AngleDoubleDownIcon from 'primevue/icons/angledoubledown';
import AngleDoubleLeftIcon from 'primevue/icons/angledoubleleft'; import AngleDoubleLeftIcon from 'primevue/icons/angledoubleleft';
@ -192,94 +208,8 @@ import { DomHandler, ObjectUtils, UniqueComponentId } from 'primevue/utils';
export default { export default {
name: 'PickList', name: 'PickList',
extends: BaseComponent, extends: BasePickList,
emits: ['update:modelValue', 'reorder', 'update:selection', 'selection-change', 'move-to-target', 'move-to-source', 'move-all-to-target', 'move-all-to-source', 'focus', 'blur'], emits: ['update:modelValue', 'reorder', 'update:selection', 'selection-change', 'move-to-target', 'move-to-source', 'move-all-to-target', 'move-all-to-source', 'focus', 'blur'],
props: {
modelValue: {
type: Array,
default: () => [[], []]
},
selection: {
type: Array,
default: () => [[], []]
},
dataKey: {
type: String,
default: null
},
listStyle: {
type: null,
default: null
},
metaKeySelection: {
type: Boolean,
default: true
},
responsive: {
type: Boolean,
default: true
},
breakpoint: {
type: String,
default: '960px'
},
stripedRows: {
type: Boolean,
default: false
},
showSourceControls: {
type: Boolean,
default: true
},
showTargetControls: {
type: Boolean,
default: true
},
targetListProps: {
type: null,
default: null
},
sourceListProps: {
type: null,
default: null
},
moveUpButtonProps: {
type: null,
default: null
},
moveTopButtonProps: {
type: null,
default: null
},
moveDownButtonProps: {
type: null,
default: null
},
moveBottomButtonProps: {
type: null,
default: null
},
moveToTargetProps: {
type: null,
default: null
},
moveAllToTargetProps: {
type: null,
default: null
},
moveToSourceProps: {
type: null,
default: null
},
moveAllToSourceProps: {
type: null,
default: null
},
tabindex: {
type: Number,
default: 0
}
},
itemTouched: false, itemTouched: false,
reorderDirection: null, reorderDirection: null,
styleElement: null, styleElement: null,
@ -344,7 +274,7 @@ export default {
return ObjectUtils.findIndexInList(item, this.d_selection[listIndex]) != -1; return ObjectUtils.findIndexInList(item, this.d_selection[listIndex]) != -1;
}, },
onListFocus(event, listType) { onListFocus(event, listType) {
const selectedFirstItem = DomHandler.findSingle(this.$refs[listType].$el, 'li.p-picklist-item.p-highlight'); const selectedFirstItem = DomHandler.findSingle(this.$refs[listType].$el, '[data-p-highlight="true"]');
const findIndex = ObjectUtils.findIndexInList(selectedFirstItem, this.$refs[listType].$el.children); const findIndex = ObjectUtils.findIndexInList(selectedFirstItem, this.$refs[listType].$el.children);
this.focused[listType] = true; this.focused[listType] = true;
@ -623,7 +553,7 @@ export default {
const selectedIndex = ObjectUtils.findIndexInList(item, this.d_selection); const selectedIndex = ObjectUtils.findIndexInList(item, this.d_selection);
const selected = selectedIndex != -1; const selected = selectedIndex != -1;
const metaSelection = this.itemTouched ? false : this.metaKeySelection; const metaSelection = this.itemTouched ? false : this.metaKeySelection;
const selectedId = DomHandler.find(this.$refs[listType].$el, '.p-picklist-item')[index].getAttribute('id'); const selectedId = DomHandler.find(this.$refs[listType].$el, '[data-pc-section="item"]')[index].getAttribute('id');
this.focusedOptionIndex = selectedId; this.focusedOptionIndex = selectedId;
let _selection; let _selection;
@ -723,8 +653,8 @@ export default {
event.preventDefault(); event.preventDefault();
}, },
onEnterKey(event, listType) { onEnterKey(event, listType) {
const items = DomHandler.find(this.$refs[listType].$el, 'li.p-picklist-item'); const items = DomHandler.find(this.$refs[listType].$el, '[data-pc-section="item"]');
const focusedItem = DomHandler.findSingle(this.$refs[listType].$el, `li.p-picklist-item[id=${this.focusedOptionIndex}]`); const focusedItem = DomHandler.findSingle(this.$refs[listType].$el, `[data-pc-section="item"][id=${this.focusedOptionIndex}]`);
const matchedOptionIndex = [...items].findIndex((item) => item === focusedItem); const matchedOptionIndex = [...items].findIndex((item) => item === focusedItem);
const listId = listType === 'sourceList' ? 0 : 1; const listId = listType === 'sourceList' ? 0 : 1;
@ -737,9 +667,9 @@ export default {
if (event.shiftKey) { if (event.shiftKey) {
const listId = listType === 'sourceList' ? 0 : 1; const listId = listType === 'sourceList' ? 0 : 1;
const items = DomHandler.find(this.$refs[listType].$el, 'li.p-picklist-item'); const items = DomHandler.find(this.$refs[listType].$el, '[data-pc-section="item"]');
const selectedItemIndex = ObjectUtils.findIndexInList(this.d_selection[listId][0], [...this.modelValue[listId]]); const selectedItemIndex = ObjectUtils.findIndexInList(this.d_selection[listId][0], [...this.modelValue[listId]]);
const focusedItem = DomHandler.findSingle(this.$refs[listType].$el, `li.p-picklist-item[id=${this.focusedOptionIndex}]`); const focusedItem = DomHandler.findSingle(this.$refs[listType].$el, `[data-pc-section="item"][id=${this.focusedOptionIndex}]`);
const matchedOptionIndex = [...items].findIndex((item) => item === focusedItem); const matchedOptionIndex = [...items].findIndex((item) => item === focusedItem);
this.d_selection[listId] = [...this.modelValue[listId]].slice(Math.min(selectedItemIndex, matchedOptionIndex), Math.max(selectedItemIndex, matchedOptionIndex) + 1); this.d_selection[listId] = [...this.modelValue[listId]].slice(Math.min(selectedItemIndex, matchedOptionIndex), Math.max(selectedItemIndex, matchedOptionIndex) + 1);
@ -751,8 +681,8 @@ export default {
onHomeKey(event, listType) { onHomeKey(event, listType) {
if (event.ctrlKey && event.shiftKey) { if (event.ctrlKey && event.shiftKey) {
const listId = listType === 'sourceList' ? 0 : 1; const listId = listType === 'sourceList' ? 0 : 1;
const items = DomHandler.find(this.$refs[listType].$el, 'li.p-picklist-item'); const items = DomHandler.find(this.$refs[listType].$el, '[data-pc-section="item"]');
const focusedItem = DomHandler.findSingle(this.$refs[listType].$el, `li.p-picklist-item[id=${this.focusedOptionIndex}]`); const focusedItem = DomHandler.findSingle(this.$refs[listType].$el, `[data-pc-section="item"][id=${this.focusedOptionIndex}]`);
const matchedOptionIndex = [...items].findIndex((item) => item === focusedItem); const matchedOptionIndex = [...items].findIndex((item) => item === focusedItem);
this.d_selection[listId] = [...this.modelValue[listId]].slice(0, matchedOptionIndex + 1); this.d_selection[listId] = [...this.modelValue[listId]].slice(0, matchedOptionIndex + 1);
@ -764,11 +694,11 @@ export default {
event.preventDefault(); event.preventDefault();
}, },
onEndKey(event, listType) { onEndKey(event, listType) {
const items = DomHandler.find(this.$refs[listType].$el, 'li.p-picklist-item'); const items = DomHandler.find(this.$refs[listType].$el, '[data-pc-section="item"]');
if (event.ctrlKey && event.shiftKey) { if (event.ctrlKey && event.shiftKey) {
const listId = listType === 'sourceList' ? 0 : 1; const listId = listType === 'sourceList' ? 0 : 1;
const focusedItem = DomHandler.findSingle(this.$refs[listType].$el, `li.p-picklist-item[id=${this.focusedOptionIndex}]`); const focusedItem = DomHandler.findSingle(this.$refs[listType].$el, `[data-pc-section="item"][id=${this.focusedOptionIndex}]`);
const matchedOptionIndex = [...items].findIndex((item) => item === focusedItem); const matchedOptionIndex = [...items].findIndex((item) => item === focusedItem);
this.d_selection[listId] = [...this.modelValue[listId]].slice(matchedOptionIndex, items.length); this.d_selection[listId] = [...this.modelValue[listId]].slice(matchedOptionIndex, items.length);
@ -780,20 +710,20 @@ export default {
event.preventDefault(); event.preventDefault();
}, },
findNextOptionIndex(index, listType) { findNextOptionIndex(index, listType) {
const items = DomHandler.find(this.$refs[listType].$el, 'li.p-picklist-item'); const items = DomHandler.find(this.$refs[listType].$el, '[data-pc-section="item"]');
const matchedOptionIndex = [...items].findIndex((link) => link.id === index); const matchedOptionIndex = [...items].findIndex((link) => link.id === index);
return matchedOptionIndex > -1 ? matchedOptionIndex + 1 : 0; return matchedOptionIndex > -1 ? matchedOptionIndex + 1 : 0;
}, },
findPrevOptionIndex(index, listType) { findPrevOptionIndex(index, listType) {
const items = DomHandler.find(this.$refs[listType].$el, 'li.p-picklist-item'); const items = DomHandler.find(this.$refs[listType].$el, '[data-pc-section="item"]');
const matchedOptionIndex = [...items].findIndex((link) => link.id === index); const matchedOptionIndex = [...items].findIndex((link) => link.id === index);
return matchedOptionIndex > -1 ? matchedOptionIndex - 1 : 0; return matchedOptionIndex > -1 ? matchedOptionIndex - 1 : 0;
}, },
changeFocusedOptionIndex(index, listType) { changeFocusedOptionIndex(index, listType) {
const items = DomHandler.find(this.$refs[listType].$el, 'li.p-picklist-item'); const items = DomHandler.find(this.$refs[listType].$el, '[data-pc-section="item"]');
let order = index >= items.length ? items.length - 1 : index < 0 ? 0 : index; let order = index >= items.length ? items.length - 1 : index < 0 ? 0 : index;
@ -801,14 +731,14 @@ export default {
this.scrollInView(items[order].getAttribute('id'), listType); this.scrollInView(items[order].getAttribute('id'), listType);
}, },
scrollInView(id, listType) { scrollInView(id, listType) {
const element = DomHandler.findSingle(this.$refs[listType].$el, `li[id="${id}"]`); const element = DomHandler.findSingle(this.$refs[listType].$el, `[data-pc-section="item"][id="${id}"]`);
if (element) { if (element) {
element.scrollIntoView && element.scrollIntoView({ block: 'nearest', inline: 'start' }); element.scrollIntoView && element.scrollIntoView({ block: 'nearest', inline: 'start' });
} }
}, },
updateListScroll(listElement) { updateListScroll(listElement) {
const listItems = DomHandler.find(listElement, '.p-picklist-item.p-highlight'); const listItems = DomHandler.find(listElement, '[data-pc-section="item"][data-p-highlight="true"]');
if (listItems && listItems.length) { if (listItems && listItems.length) {
switch (this.reorderDirection) { switch (this.reorderDirection) {
@ -904,9 +834,6 @@ export default {
}, },
moveSourceDisabled() { moveSourceDisabled() {
return ObjectUtils.isEmpty(this.targetList); return ObjectUtils.isEmpty(this.targetList);
},
itemClass(item, id, listIndex) {
return ['p-picklist-item', { 'p-highlight': this.isSelected(item, listIndex), 'p-focus': id === this.focusedOptionId }];
} }
}, },
computed: { computed: {
@ -919,14 +846,6 @@ export default {
focusedOptionId() { focusedOptionId() {
return this.focusedOptionIndex !== -1 ? this.focusedOptionIndex : null; return this.focusedOptionIndex !== -1 ? this.focusedOptionIndex : null;
}, },
containerClass() {
return [
'p-picklist p-component',
{
'p-picklist-striped': this.stripedRows
}
];
},
sourceList() { sourceList() {
return this.modelValue && this.modelValue[0] ? this.modelValue[0] : null; return this.modelValue && this.modelValue[0] ? this.modelValue[0] : null;
}, },
@ -977,39 +896,3 @@ export default {
} }
}; };
</script> </script>
<style>
.p-picklist {
display: flex;
}
.p-picklist-buttons {
display: flex;
flex-direction: column;
justify-content: center;
}
.p-picklist-list-wrapper {
flex: 1 1 50%;
}
.p-picklist-list {
list-style-type: none;
margin: 0;
padding: 0;
overflow: auto;
min-height: 12rem;
max-height: 24rem;
}
.p-picklist-item {
cursor: pointer;
overflow: hidden;
position: relative;
}
.p-picklist-item.p-picklist-flip-enter-active.p-picklist-flip-enter-to,
.p-picklist-item.p-picklist-flip-leave-active.p-picklist-flip-leave-to {
transition: none !important;
}
</style>