radiocampus: style update
This commit is contained in:
		
							
								
								
									
										105
									
								
								radiocampus/assets/src/components/AList.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								radiocampus/assets/src/components/AList.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,105 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div>
 | 
			
		||||
        <!-- FIXME: header and footer should be inside list tags -->
 | 
			
		||||
        <slot name="header"></slot>
 | 
			
		||||
        <component :is="listTag" :class="listClass">
 | 
			
		||||
            <template v-for="(item,index) in items" :key="index">
 | 
			
		||||
                <component :is="itemTag" :class="itemClass" @click="select(index)"
 | 
			
		||||
                        :draggable="orderable" :data-index="index"
 | 
			
		||||
                        @dragstart="onDragStart" @dragover="onDragOver" @drop="onDrop">
 | 
			
		||||
                    <slot name="item" :selected="index == selectedIndex" :set="set" :index="index" :item="item"></slot>
 | 
			
		||||
                </component>
 | 
			
		||||
            </template>
 | 
			
		||||
        </component>
 | 
			
		||||
        <slot name="footer"></slot>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
    emits: ['select', 'unselect', 'move', 'remove'],
 | 
			
		||||
    data() {
 | 
			
		||||
        return {
 | 
			
		||||
            selectedIndex: this.defaultIndex,
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    props: {
 | 
			
		||||
        listClass: String,
 | 
			
		||||
        itemClass: String,
 | 
			
		||||
        defaultIndex: { type: Number, default: -1},
 | 
			
		||||
        set: Object,
 | 
			
		||||
        orderable: { type: Boolean, default: false },
 | 
			
		||||
        itemTag: { default: 'li' },
 | 
			
		||||
        listTag: { default: 'ul' },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    computed: {
 | 
			
		||||
        model() { return this.set.model },
 | 
			
		||||
        items() { return this.set.items },
 | 
			
		||||
        length() { return this.set.length },
 | 
			
		||||
 | 
			
		||||
        selected() {
 | 
			
		||||
            return this.selectedIndex > -1 && this.items.length > this.selectedIndex > -1
 | 
			
		||||
                ? this.items[this.selectedIndex] : null;
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    methods: {
 | 
			
		||||
        get(index) { return this.set.get(index) },
 | 
			
		||||
        find(pred) { return this.set.find(pred) },
 | 
			
		||||
        findIndex(pred) { return this.set.findIndex(pred) },
 | 
			
		||||
 | 
			
		||||
        remove(index, select=false) {
 | 
			
		||||
            const item = this.set.get(index)
 | 
			
		||||
            if(!item)
 | 
			
		||||
                return
 | 
			
		||||
 | 
			
		||||
            this.set.remove(index);
 | 
			
		||||
            if(index < this.selectedIndex)
 | 
			
		||||
                this.selectedIndex--;
 | 
			
		||||
            if(select && this.selectedIndex == index)
 | 
			
		||||
                this.select(index)
 | 
			
		||||
            this.$emit('remove', {index, item, set: this.set})
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        select(index) {
 | 
			
		||||
            this.selectedIndex = index > -1  && this.items.length ? index % this.items.length : -1;
 | 
			
		||||
            this.$emit('select', { item: this.selected, index: this.selectedIndex });
 | 
			
		||||
            return this.selectedIndex;
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        unselect() {
 | 
			
		||||
            this.$emit('unselect', { item: this.selected, index: this.selectedIndex});
 | 
			
		||||
            this.selectedIndex = -1;
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onDragStart(ev) {
 | 
			
		||||
            const dataset = ev.target.dataset;
 | 
			
		||||
            const data = `row:${dataset.index}`
 | 
			
		||||
            ev.dataTransfer.setData("text/cell", data)
 | 
			
		||||
            ev.dataTransfer.dropEffect = 'move'
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onDragOver(ev) {
 | 
			
		||||
            ev.preventDefault()
 | 
			
		||||
            ev.dataTransfer.dropEffect = 'move'
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onDrop(ev) {
 | 
			
		||||
            const data = ev.dataTransfer.getData("text/cell")
 | 
			
		||||
            if(!data || !data.startsWith('row:'))
 | 
			
		||||
                return
 | 
			
		||||
 | 
			
		||||
            ev.preventDefault()
 | 
			
		||||
            const from = Number(data.slice(4))
 | 
			
		||||
            const target = ev.target.tagName == this.itemTag ? ev.target
 | 
			
		||||
                                : ev.target.closest(this.itemTag)
 | 
			
		||||
            this.$emit('move', {
 | 
			
		||||
                from, target,
 | 
			
		||||
                to: Number(target.dataset.index),
 | 
			
		||||
                set: this.set,
 | 
			
		||||
            })
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
		Reference in New Issue
	
	Block a user