Skip to content

Using Viselect with React

TIP

This is merely a convenience wrapper around the core library. The core API is fairly simple, if you want to have full control over it, you should roll out your own wrapper in your app. Don't worry, it's not that hard!

Installation

To use Viselect with React, install its React package with:

sh
$ npm install @viselect/react
sh
$ pnpm install @viselect/react
sh
$ yarn add @viselect/react

Usage

You can use Viselect in your React project by importing the SelectionArea component from the @viselect/react package.

TIP

All options are exposed as props They're a one-to-one mapping of the original options describe here!

tsx
import {SelectionArea, SelectionEvent} from '@viselect/react';
import React, {FunctionComponent, useState} from 'react';
import './styles.css';

const App: FunctionComponent = () => {
    const [selected, setSelected] = useState<Set<number>>(() => new Set());

    const extractIds = (els: Element[]): number[] =>
        els.map(v => v.getAttribute('data-key'))
            .filter(Boolean)
            .map(Number);

    const onStart = ({ event, selection }: SelectionEvent) => {
        if (!event?.ctrlKey && !event?.metaKey) {
            selection.clearSelection();
            setSelected(() => new Set());
        }
    };

    const onMove = ({ store: { changed: { added, removed } } }: SelectionEvent) => {
        setSelected(prev => {
            const next = new Set(prev);
            extractIds(added).forEach(id => next.add(id));
            extractIds(removed).forEach(id => next.delete(id));
            return next;
        });
    };

    return (
        <>
            <SelectionArea className="container"
                           onStart={onStart}
                           onMove={onMove}
                           selectables=".selectable">
                {new Array(42).fill(0).map((_, index) => (
                    <div className={selected.has(index) ? 'selected selectable' : 'selectable'}
                         data-key={index}
                         key={index}/>
                ))}
            </SelectionArea>
        </>
    );
}
css
.container {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-evenly;
    border: 1px dashed #4f5276;
    border-radius: 15px;
    padding: 15px;
    margin: 15px 0;
    user-select: none;
}

.container div {
    height: 50px;
    width: 50px;
    margin: 3px;
    background: rgba(66, 68, 90, 0.075);
    border-radius: 10px;
    cursor: pointer;
}

div.selected {
    background: linear-gradient(45deg, #78b2ff, #218ad9);
}

.selection-area {
    background: rgba(46, 115, 252, 0.11);
    border: 1px solid rgba(98, 155, 255, 0.85);
    border-radius: 0.15em;
}

Hooks

To access the SelectionArea instance, you can use the useSelection hook provided by the @viselect/react package. The context is provided by the SelectionArea component, so make sure to use it within the component tree where the SelectionArea is rendered. It contains a SelectionArea instance.

tsx
import { useSelection } from '@viselect/react';

Released under the MIT License.