Install using your package manager of choice:
npm install @viselect/vue
Last but not least you'll need to add some basic styles to make your selection-area visible:
.selection-area {
background: rgba(46, 115, 252, 0.11);
border: 2px solid rgba(98, 155, 255, 0.81);
border-radius: 0.1em;
}
Additionally, to not interfere with text-selection, selection-js won't prevent any default events anymore (as of v2.0.3
). This however can cause problems with the actual
selection ("introduced" by #99, reported in #103). If you don't care about
text-selection, add the following to the container where all your selectables are located:
.container {
user-select: none;
}
Events are handled using props because you cannot return a value in events synchronously.
<template>
<SelectionArea class="container"
:options="{selectables: '.selectable'}"
:on-move="onMove"
:on-start="onStart">
<div v-for="id of range(42)"
class="selectable"
:key="id"
:data-key="id"
:class="{selected: selected.has(id)}"/>
</SelectionArea>
</template>
<script lang="ts" setup>
import {SelectionArea, SelectionEvent} from '@viselect/vue';
import {reactive} from 'vue';
const selected = reactive<Set<number>>(new Set());
const range = (to: number, offset = 0): number[] => {
return new Array(to).fill(0).map((_, i) => offset + i);
};
const extractIds = (els: Element[]): number[] => {
return els.map(v => v.getAttribute('data-key'))
.filter(Boolean)
.map(Number);
}
const onStart = ({event, selection}: SelectionEvent) => {
if (!event?.ctrlKey && !event?.metaKey) {
selection.clearSelection();
selected.clear();
}
}
const onMove = ({store: {changed: {added, removed}}}: SelectionEvent) => {
extractIds(added).forEach(id => selected.add(id));
extractIds(removed).forEach(id => selected.delete(id));
}
</script>
It's possible to get the current SelectionArea
-instance via [template refs](https://vuejs.
org/guide/essentials/template-refs.html).
<template>
<SelectionArea
class="container"
:options="{selectables: '.selectable'}"
ref="selectionAreaRef"
>
<div
v-for="id of 42"
class="selectable"
:key="id"
:data-key="id"
:class="{selected: selected.has(id)}"
/>
</SelectionArea>
</template>
<script lang="ts" setup>
import type {SelectionAreaInstance} from '@viselect/vue';
import {ref, reactive, onMounted} from 'vue';
const selected = reactive<Set<number>>(new Set());
const selectionAreaRef = ref<SelectionAreaInstance>()
onMounted(() => {
// log current selection
console.log(selectionAreaRef.value?.selection)
})
</script>