Refactor #3965 - Refactor on OrderList

pull/4016/head
Bahadır Sofuoğlu 2023-06-02 12:10:49 +03:00
parent 155fb26785
commit 1950d500ea
3 changed files with 191 additions and 155 deletions

View File

@ -0,0 +1,146 @@
<script>
import BaseComponent from 'primevue/basecomponent';
import { useStyle } from 'primevue/usestyle';
const styles = `
.p-orderlist {
display: flex;
}
.p-orderlist-controls {
display: flex;
flex-direction: column;
justify-content: center;
}
.p-orderlist-list-container {
flex: 1 1 auto;
}
.p-orderlist-list {
list-style-type: none;
margin: 0;
padding: 0;
overflow: auto;
min-height: 12rem;
max-height: 24rem;
}
.p-orderlist-item {
cursor: pointer;
overflow: hidden;
position: relative;
}
.p-orderlist.p-state-disabled .p-orderlist-item,
.p-orderlist.p-state-disabled .p-button {
cursor: default;
}
.p-orderlist.p-state-disabled .p-orderlist-list {
overflow: hidden;
}
`;
const classes = {
root: ({ props }) => [
'p-orderlist p-component',
{
'p-orderlist-striped': props.stripedRows
}
],
controls: 'p-orderlist-controls',
header: 'p-orderlist-header',
container: 'p-orderlist-list-container',
list: 'p-orderlist-list',
item: ({ context }) => [
'p-orderlist-item',
{
'p-highlight': context.active,
'p-focus': context.focused
}
]
};
const { load: loadStyle } = useStyle(styles, { id: 'primevue_organizationchart_style', manual: true });
export default {
name: 'BaseOrganizationChart',
extends: BaseComponent,
props: {
modelValue: {
type: Array,
default: null
},
selection: {
type: Array,
default: null
},
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
},
tabindex: {
type: Number,
default: 0
},
listProps: {
type: null,
default: null
},
moveUpButtonProps: {
type: null,
default: null
},
moveTopButtonProps: {
type: null,
default: null
},
moveDownButtonProps: {
type: null,
default: null
},
moveBottomButtonProps: {
type: null,
default: null
},
'aria-labelledby': {
type: String,
default: null
},
'aria-label': {
type: String,
default: null
}
},
css: {
classes,
loadStyle
},
provide() {
return {
$parentInstance: this
};
}
};
</script>

View File

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

View File

@ -1,29 +1,29 @@
<template>
<div :class="containerClass" v-bind="ptm('root')">
<div class="p-orderlist-controls" v-bind="ptm('controls')">
<div :class="cx('root')" v-bind="ptm('root')">
<div :class="cx('controls')" v-bind="ptm('controls')">
<slot name="controlsstart"></slot>
<OLButton type="button" @click="moveUp" :aria-label="moveUpAriaLabel" :disabled="moveDisabled()" v-bind="moveUpButtonProps" :pt="ptm('moveUpButton')">
<OLButton type="button" @click="moveUp" :aria-label="moveUpAriaLabel" :disabled="moveDisabled()" v-bind="moveUpButtonProps" :pt="ptm('moveUpButton')" :unstyle="unstyled">
<template #icon>
<slot name="moveupicon">
<AngleUpIcon v-bind="ptm('moveUpButton')['icon']" />
</slot>
</template>
</OLButton>
<OLButton type="button" @click="moveTop" :aria-label="moveTopAriaLabel" :disabled="moveDisabled()" v-bind="moveTopButtonProps" :pt="ptm('moveTopButton')">
<OLButton type="button" @click="moveTop" :aria-label="moveTopAriaLabel" :disabled="moveDisabled()" v-bind="moveTopButtonProps" :pt="ptm('moveTopButton')" :unstyle="unstyled">
<template #icon>
<slot name="movetopicon">
<AngleDoubleUpIcon v-bind="ptm('moveTopButton')['icon']" />
</slot>
</template>
</OLButton>
<OLButton type="button" @click="moveDown" :aria-label="moveDownAriaLabel" :disabled="moveDisabled()" v-bind="moveDownButtonProps" :pt="ptm('moveDownButton')">
<OLButton type="button" @click="moveDown" :aria-label="moveDownAriaLabel" :disabled="moveDisabled()" v-bind="moveDownButtonProps" :pt="ptm('moveDownButton')" :unstyle="unstyled">
<template #icon>
<slot name="movedownicon">
<AngleDownIcon v-bind="ptm('moveDownButton')['icon']" />
</slot>
</template>
</OLButton>
<OLButton type="button" @click="moveBottom" :aria-label="moveBottomAriaLabel" :disabled="moveDisabled()" v-bind="moveBottomButtonProps" :pt="ptm('moveBottomButton')">
<OLButton type="button" @click="moveBottom" :aria-label="moveBottomAriaLabel" :disabled="moveDisabled()" v-bind="moveBottomButtonProps" :pt="ptm('moveBottomButton')" :unstyle="unstyled">
<template #icon>
<slot name="movebottomicon">
<AngleDoubleDownIcon v-bind="ptm('moveBottomButton')['icon']" />
@ -32,8 +32,8 @@
</OLButton>
<slot name="controlsend"></slot>
</div>
<div class="p-orderlist-list-container" v-bind="ptm('container')">
<div v-if="$slots.header" class="p-orderlist-header" v-bind="ptm('header')">
<div :class="cx('container')" v-bind="ptm('container')">
<div v-if="$slots.header" :class="cx('header')" v-bind="ptm('header')">
<slot name="header"></slot>
</div>
<transition-group
@ -41,7 +41,7 @@
:id="id + '_list'"
name="p-orderlist-flip"
tag="ul"
class="p-orderlist-list"
:class="cx('list')"
:style="listStyle"
role="listbox"
aria-multiselectable="true"
@ -59,7 +59,15 @@
:id="id + '_' + i"
v-ripple
role="option"
:class="itemClass(item, `${id}_${i}`)"
:class="
cx('item', {
context: {
active: isSelected(item),
focused: `${id}_${i}` === focusedOptionId
}
})
"
:data-p-highlight="isSelected(item)"
@click="onItemClick($event, item, i)"
@touchend="onItemTouchEnd"
:aria-selected="isSelected(item)"
@ -75,7 +83,7 @@
</template>
<script>
import BaseComponent from 'primevue/basecomponent';
import BaseOrderList from './BaseOrderList.vue';
import Button from 'primevue/button';
import AngleDoubleDownIcon from 'primevue/icons/angledoubledown';
import AngleDoubleUpIcon from 'primevue/icons/angledoubleup';
@ -86,74 +94,8 @@ import { DomHandler, ObjectUtils, UniqueComponentId } from 'primevue/utils';
export default {
name: 'OrderList',
extends: BaseComponent,
extends: BaseOrderList,
emits: ['update:modelValue', 'reorder', 'update:selection', 'selection-change', 'focus', 'blur'],
props: {
modelValue: {
type: Array,
default: null
},
selection: {
type: Array,
default: null
},
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
},
tabindex: {
type: Number,
default: 0
},
listProps: {
type: null,
default: null
},
moveUpButtonProps: {
type: null,
default: null
},
moveTopButtonProps: {
type: null,
default: null
},
moveDownButtonProps: {
type: null,
default: null
},
moveBottomButtonProps: {
type: null,
default: null
},
'aria-labelledby': {
type: String,
default: null
},
'aria-label': {
type: String,
default: null
}
},
itemTouched: false,
reorderDirection: null,
styleElement: null,
@ -203,7 +145,8 @@ export default {
return ObjectUtils.findIndexInList(item, this.d_selection) != -1;
},
onListFocus(event) {
const selectedFirstItem = DomHandler.findSingle(this.list, 'li.p-orderlist-item.p-highlight');
const selectedFirstItem = DomHandler.findSingle(this.list, '[data-p-highlight="true"]');
const findIndex = ObjectUtils.findIndexInList(selectedFirstItem, this.list.children);
this.focused = true;
@ -282,8 +225,8 @@ export default {
},
onHomeKey(event) {
if (event.ctrlKey && event.shiftKey) {
const items = DomHandler.find(this.list, 'li.p-orderlist-item');
const focusedItem = DomHandler.findSingle(this.list, `li.p-orderlist-item[id=${this.focusedOptionIndex}]`);
const items = DomHandler.find(this.list, '[data-pc-section="item"]');
const focusedItem = DomHandler.findSingle(this.list, `[data-pc-section="item"][id=${this.focusedOptionIndex}]`);
const matchedOptionIndex = [...items].findIndex((item) => item === focusedItem);
this.d_selection = [...this.modelValue].slice(0, matchedOptionIndex + 1);
@ -296,21 +239,21 @@ export default {
},
onEndKey(event) {
if (event.ctrlKey && event.shiftKey) {
const items = DomHandler.find(this.list, 'li.p-orderlist-item');
const focusedItem = DomHandler.findSingle(this.list, `li.p-orderlist-item[id=${this.focusedOptionIndex}]`);
const items = DomHandler.find(this.list, '[data-pc-section="item"]');
const focusedItem = DomHandler.findSingle(this.list, `[data-pc-section="item"][id=${this.focusedOptionIndex}]`);
const matchedOptionIndex = [...items].findIndex((item) => item === focusedItem);
this.d_selection = [...this.modelValue].slice(matchedOptionIndex, items.length);
this.$emit('update:selection', this.d_selection);
} else {
this.changeFocusedOptionIndex(DomHandler.find(this.list, 'li.p-orderlist-item').length - 1);
this.changeFocusedOptionIndex(DomHandler.find(this.list, '[data-pc-section="item"]').length - 1);
}
event.preventDefault();
},
onEnterKey(event) {
const items = DomHandler.find(this.list, 'li.p-orderlist-item');
const focusedItem = DomHandler.findSingle(this.list, `li.p-orderlist-item[id=${this.focusedOptionIndex}]`);
const items = DomHandler.find(this.list, '[data-pc-section="item"]');
const focusedItem = DomHandler.findSingle(this.list, `[data-pc-section="item"][id=${this.focusedOptionIndex}]`);
const matchedOptionIndex = [...items].findIndex((item) => item === focusedItem);
this.onItemClick(event, this.modelValue[matchedOptionIndex], matchedOptionIndex);
@ -319,9 +262,9 @@ export default {
},
onSpaceKey(event) {
if (event.shiftKey) {
const items = DomHandler.find(this.list, 'li.p-orderlist-item');
const items = DomHandler.find(this.list, '[data-pc-section="item"]');
const selectedItemIndex = ObjectUtils.findIndexInList(this.d_selection[0], [...this.modelValue]);
const focusedItem = DomHandler.findSingle(this.list, `li.p-orderlist-item[id=${this.focusedOptionIndex}]`);
const focusedItem = DomHandler.findSingle(this.list, `[data-pc-section="item"][id=${this.focusedOptionIndex}]`);
const matchedOptionIndex = [...items].findIndex((item) => item === focusedItem);
this.d_selection = [...this.modelValue].slice(Math.min(selectedItemIndex, matchedOptionIndex), Math.max(selectedItemIndex, matchedOptionIndex) + 1);
@ -331,19 +274,19 @@ export default {
}
},
findNextOptionIndex(index) {
const items = DomHandler.find(this.list, 'li.p-orderlist-item');
const items = DomHandler.find(this.list, '[data-pc-section="item"]');
const matchedOptionIndex = [...items].findIndex((link) => link.id === index);
return matchedOptionIndex > -1 ? matchedOptionIndex + 1 : 0;
},
findPrevOptionIndex(index) {
const items = DomHandler.find(this.list, 'li.p-orderlist-item');
const items = DomHandler.find(this.list, '[data-pc-section="item"]');
const matchedOptionIndex = [...items].findIndex((link) => link.id === index);
return matchedOptionIndex > -1 ? matchedOptionIndex - 1 : 0;
},
changeFocusedOptionIndex(index) {
const items = DomHandler.find(this.list, 'li.p-orderlist-item');
const items = DomHandler.find(this.list, '[data-pc-section="item"]');
let order = index >= items.length ? items.length - 1 : index < 0 ? 0 : index;
@ -351,7 +294,7 @@ export default {
this.scrollInView(this.focusedOptionIndex);
},
scrollInView(id) {
const element = DomHandler.findSingle(this.list, `li[id="${id}"]`);
const element = DomHandler.findSingle(this.list, `[data-pc-section="item"][id="${id}"]`);
if (element) {
element.scrollIntoView && element.scrollIntoView({ block: 'nearest', inline: 'start' });
@ -470,7 +413,8 @@ export default {
const selectedIndex = ObjectUtils.findIndexInList(item, this.d_selection);
const selected = selectedIndex != -1;
const metaSelection = this.itemTouched ? false : this.metaKeySelection;
const selectedId = DomHandler.find(this.list, '.p-orderlist-item')[index].getAttribute('id');
const selectedId = DomHandler.find(this.list, '[data-pc-section="item"]')[index].getAttribute('id');
this.focusedOptionIndex = selectedId;
@ -504,28 +448,17 @@ export default {
findNextItem(item) {
let nextItem = item.nextElementSibling;
if (nextItem) return !DomHandler.hasClass(nextItem, 'p-orderlist-item') ? this.findNextItem(nextItem) : nextItem;
if (nextItem) return !(DomHandler.getAttribute(nextItem, 'data-p-section') === 'item') ? this.findNextItem(nextItem) : nextItem;
else return null;
},
findPrevItem(item) {
let prevItem = item.previousElementSibling;
if (prevItem) return !DomHandler.hasClass(prevItem, 'p-orderlist-item') ? this.findPrevItem(prevItem) : prevItem;
if (prevItem) return !(DomHandler.getAttribute(nextItem, 'data-p-section') === 'item') ? this.findPrevItem(prevItem) : prevItem;
else return null;
},
findFirstItem() {
return DomHandler.findSingle(this.list, '.p-orderlist-item');
},
findLastItem() {
const items = DomHandler.find(this.list, '.p-orderlist-item');
return items[items.length - 1];
},
itemClass(item, id) {
return ['p-orderlist-item', { 'p-highlight': this.isSelected(item), 'p-focus': id === this.focusedOptionId }];
},
updateListScroll() {
const listItems = DomHandler.find(this.list, '.p-orderlist-item.p-highlight');
const listItems = DomHandler.find(this.list, '[data-pc-section="item"][data-p-highlight="true"]');
if (listItems && listItems.length) {
switch (this.reorderDirection) {
@ -598,14 +531,6 @@ export default {
}
},
computed: {
containerClass() {
return [
'p-orderlist p-component',
{
'p-orderlist-striped': this.stripedRows
}
];
},
attributeSelector() {
return UniqueComponentId();
},
@ -637,43 +562,3 @@ export default {
}
};
</script>
<style>
.p-orderlist {
display: flex;
}
.p-orderlist-controls {
display: flex;
flex-direction: column;
justify-content: center;
}
.p-orderlist-list-container {
flex: 1 1 auto;
}
.p-orderlist-list {
list-style-type: none;
margin: 0;
padding: 0;
overflow: auto;
min-height: 12rem;
max-height: 24rem;
}
.p-orderlist-item {
cursor: pointer;
overflow: hidden;
position: relative;
}
.p-orderlist.p-state-disabled .p-orderlist-item,
.p-orderlist.p-state-disabled .p-button {
cursor: default;
}
.p-orderlist.p-state-disabled .p-orderlist-list {
overflow: hidden;
}
</style>