11<template >
22 <q-list >
3- <slot
4- v-if =" itemIds.length === 0"
5- name =" empty"
6- ></slot >
7-
8- <q-item
9- v-for =" (itemId, itemIndex) of itemIds"
10- :key =" itemId"
11- clickable
12- @click.capture =" (event) => selectItem(itemId, event as any)"
13- v-bind =" props.itemProps"
3+ <PassthroughComponent
4+ :is =" itemsWrapper"
5+ v-bind =" wrapperProps"
6+ v-on =" wrapperEvents"
147 >
15- <q-item-section
16- avatar
17- style =" padding-right : 4px "
18- >
19- <Checkbox :model-value =" finalSelectedItemIds.includes(itemId)" />
20- </q-item-section >
21-
228 <slot
23- name =" item"
24- :item-id =" itemId"
25- :item-index =" itemIndex"
9+ v-if =" itemIds.length === 0"
10+ name =" empty"
2611 ></slot >
27- </q-item >
12+
13+ <q-item
14+ v-for =" (itemId, itemIndex) of itemIds"
15+ :key =" itemId"
16+ clickable
17+ v-ripple
18+ class =" text-grey-1"
19+ :style =" {
20+ 'background-color': selectedItemIds.has(itemId) ? '#505050' : '',
21+ }"
22+ @click =" (event) => selectItem(itemId, event as any)"
23+ v-bind =" props.itemProps?.(itemId, itemIndex)"
24+ >
25+ <q-item-section
26+ avatar
27+ style =" padding-right : 4px "
28+ >
29+ <Checkbox
30+ :model-value =" selectedItemIds.has(itemId)"
31+ style =" pointer-events : none "
32+ />
33+ </q-item-section >
34+
35+ <slot
36+ name =" item"
37+ :item-id =" itemId"
38+ :item-index =" itemIndex"
39+ ></slot >
40+ </q-item >
41+ </PassthroughComponent >
2842 </q-list >
2943</template >
3044
3145<script setup lang="ts">
3246import type { QItemProps , QListProps } from ' quasar' ;
47+ import type { Component } from ' vue' ;
3348
3449const emit = defineEmits ([' select' , ' unselect' ]);
3550
3651// eslint-disable-next-line @typescript-eslint/no-empty-interface
3752interface Props extends QListProps {
3853 itemIds: string [];
54+ selectedItemIds: Set <string >;
55+
56+ itemProps? : (
57+ itemId : string ,
58+ itemIndex : number ,
59+ ) => QItemProps & Record <string , unknown >;
3960
40- itemProps? : QItemProps ;
61+ itemsWrapper? : string | Component ;
62+ wrapperProps? : Record <string , unknown >;
63+ wrapperEvents? : Record <string , unknown >;
4164}
4265
4366const props = defineProps <Props >();
4467
4568let lastSelectedItemId: string ;
4669
47- const baseSelectedItemIds = ref (new Set <string >());
48-
49- const finalSelectedItemIds = computed (() =>
50- props .itemIds .filter ((itemId ) => baseSelectedItemIds .value .has (itemId )),
51- );
52-
5370function selectItem(itemId : string , event : MouseEvent ) {
5471 if (event .shiftKey || internals .mobileAltKey ) {
5572 const sourceItemIndex = props .itemIds .indexOf (lastSelectedItemId );
@@ -62,24 +79,24 @@ function selectItem(itemId: string, event: MouseEvent) {
6279 ) {
6380 const sign = Math .sign (targetItemIndex - sourceItemIndex );
6481
65- const add = ! baseSelectedItemIds . value .has (itemId );
82+ const add = ! props . selectedItemIds .has (itemId );
6683
6784 for (let i = sourceItemIndex ; i !== targetItemIndex + sign ; i += sign ) {
6885 if (add ) {
69- baseSelectedItemIds . value .add (props .itemIds [i ]);
86+ props . selectedItemIds .add (props .itemIds [i ]);
7087 emit (' select' , props .itemIds [i ]);
7188 } else {
72- baseSelectedItemIds . value .delete (props .itemIds [i ]);
89+ props . selectedItemIds .delete (props .itemIds [i ]);
7390 emit (' unselect' , props .itemIds [i ]);
7491 }
7592 }
7693 }
7794 } else {
78- if (baseSelectedItemIds . value .has (itemId )) {
79- baseSelectedItemIds . value .delete (itemId );
95+ if (props . selectedItemIds .has (itemId )) {
96+ props . selectedItemIds .delete (itemId );
8097 emit (' unselect' , itemId );
8198 } else {
82- baseSelectedItemIds . value .add (itemId );
99+ props . selectedItemIds .add (itemId );
83100 emit (' select' , itemId );
84101 }
85102 }
0 commit comments