Selectables v2.0 ๐ฏ
Modern JavaScript library for selecting HTML elements with mouse/touch gestures. Zero dependencies, TypeScript support, works everywhere.
โจ What's New in v2.0
- ๐จ Modern ES6+ rewrite - Classes, arrow functions, modern APIs
- ๐ฑ Touch & pointer support - Works on mobile/tablet devices
- ๐ง TypeScript definitions - Full type safety included
- ๐ Better performance - Fixed scroll bugs, optimized collision detection
- ๐ More features -
selectAll(),invertSelection(),getSelected(), and more - ๐ฆ Multiple module formats - ESM, CommonJS, UMD
- ๐งช Comprehensive tests - Jest test suite with high coverage
- ๐ช No breaking changes - v1.x API still works
๐ฆ Installation
Install from npm:
Or with yarn:
๐ Quick Start
ES Module (Recommended)
import Selectables from 'selectables'; import 'selectables/css'; const selectable = new Selectables({ zone: '#my-container', elements: '.selectable-item', onSelect: (element) => { console.log('Selected:', element); } });
CommonJS
const Selectables = require('selectables'); const selectable = new Selectables({ zone: '#my-container', elements: '.selectable-item' });
Browser Global (UMD)
<link rel="stylesheet" href="https://unpkg.com/selectables@2/dist/selectables.css"> <script src="https://unpkg.com/selectables@2/dist/selectables.min.js"></script> <script> const selectable = new window.Selectables({ zone: '#my-container', elements: '.selectable-item' }); </script>
TypeScript
import Selectables, { SelectablesOptions } from 'selectables'; const options: SelectablesOptions = { zone: '#my-container', elements: '.selectable-item' }; const selectable = new Selectables(options);
๐ Module Formats
When you install from npm, you get:
- ES Module -
import Selectables from 'selectables'- Recommended for modern bundlers - CommonJS -
require('selectables')- For Node.js and legacy build tools - UMD - Browser global
window.Selectables- For direct script inclusion - Minified versions - All formats available with
.min.jssuffix (~2.5KB gzipped) - TypeScript - Full type definitions included in
selectables.d.ts - CSS -
import 'selectables/css'or<link href="...selectables.css">
๐ API Documentation
Constructor Options
interface SelectablesOptions { // Core options zone?: string | HTMLElement; // Container selector (default: '#wrapper') elements?: string; // Item selector (default: 'a') selectedClass?: string; // Class for selected items (default: 'active') // Activation keys key?: 'altKey' | 'ctrlKey' | 'metaKey' | false; // Required key to activate (default: false) moreUsing?: 'shiftKey' | 'altKey' | 'ctrlKey'; // Key to add to selection (default: 'shiftKey') // Behavior enabled?: boolean; // Auto-enable on init (default: true) selectionMode?: 'toggle' | 'add' | 'remove' | 'replace'; // Selection behavior tolerance?: 'touch' | 'fit'; // Collision detection mode minDragDistance?: number; // Min pixels to drag (default: 0) // Auto-scroll scrollOnEdge?: boolean; // Auto-scroll near edges (default: false) scrollSpeed?: number; // Scroll speed px/frame (default: 10) scrollEdgeSize?: number; // Edge trigger size (default: 50px) // Callbacks start?: (event: PointerEvent) => void; stop?: (event: PointerEvent, selected: HTMLElement[]) => void; onSelect?: (element: HTMLElement) => void; onDeselect?: (element: HTMLElement) => void; onChange?: (selected: HTMLElement[], event?: PointerEvent) => void; }
Methods
Core Methods
// Enable/disable selection selectables.enable(); selectables.disable(); selectables.destroy(); // Cleanup all listeners // Check state selectables.isEnabled(); // boolean
Selection Methods
// Programmatic selection selectables.select('.item'); // Select by selector selectables.select(element); // Select single element selectables.select([el1, el2]); // Select multiple selectables.deselect('.item'); // Deselect by selector selectables.selectAll(); // Select all items selectables.deselectAll(); // Clear selection selectables.invertSelection(); // Invert current selection selectables.toggle('.item'); // Toggle specific items // Get selection const selected = selectables.getSelected(); // Array of HTMLElements const count = selectables.getSelectedCount(); // Number const total = selectables.getItemCount(); // Total items
Configuration
// Update options at runtime selectables.setOptions({ selectedClass: 'custom-selected', minDragDistance: 10 }); // Get current options const options = selectables.getOptions();
Chaining
All methods return this for chaining:
selectables .enable() .selectAll() .invertSelection() .disable();
๐ก Usage Examples
Basic Selection
const selectable = new Selectables({ zone: '#container', elements: 'li', onSelect: (el) => console.log('Selected:', el.textContent) });
Require Alt Key
new Selectables({ zone: '#container', elements: '.item', key: 'altKey', // Must hold Alt to select start: () => console.log('Selection started with Alt key') });
Add to Selection with Shift
new Selectables({ zone: '#container', elements: '.item', moreUsing: 'shiftKey', // Hold Shift to add to selection selectedClass: 'highlighted' });
Grid/Gallery Selection
new Selectables({ zone: '#gallery', elements: '.photo', tolerance: 'fit', // Only select when fully inside selection box minDragDistance: 5, // Prevent accidental selections onChange: (selected) => { console.log(`Selected ${selected.length} photos`); } });
Auto-Scroll on Large Pages
new Selectables({ zone: '#container', elements: '.item', scrollOnEdge: true, scrollSpeed: 15, scrollEdgeSize: 50 });
Checkbox Selection
new Selectables({ zone: '#list', elements: 'li', onSelect: (el) => { el.querySelector('input[type="checkbox"]').checked = true; }, onDeselect: (el) => { el.querySelector('input[type="checkbox"]').checked = false; } });
Custom Selection Logic
const selectable = new Selectables({ zone: '#container', elements: '.item', enabled: false // Start disabled }); // Enable only when user is ready document.getElementById('enableBtn').addEventListener('click', () => { selectable.enable(); }); // Programmatic control document.getElementById('selectAllBtn').addEventListener('click', () => { selectable.selectAll(); }); document.getElementById('invertBtn').addEventListener('click', () => { selectable.invertSelection(); });
๐จ Styling
Include the CSS file for default selection box styling:
/* Default styles included in selectables.css */ .s-noselect { user-select: none; } #s-rectBox { position: absolute; z-index: 1090; border: 2px dashed #cbd3e3; background: rgba(0, 123, 255, 0.1); }
Customize the selection box:
#s-rectBox { border: 2px solid #007bff; background: rgba(0, 123, 255, 0.2); border-radius: 4px; }
๐ Migration from v1.x
v2.0 is mostly backwards compatible. Update your code for new features:
// v1.x dr = new Selectables({...}); // v2.0 - Same API, but now with more methods const selectable = new Selectables({...}); // New methods available selectable.getSelected(); selectable.selectAll(); selectable.invertSelection(); selectable.destroy(); // Important: cleanup when done
Key changes:
- Use
window.pageYOffsetinstead of deprecateddocument.body.scrollTop(fixed internally) - Touch events now work automatically via Pointer Events
- Add
.destroy()call when removing instances
๐ Browser Support
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
- Mobile browsers (iOS Safari, Chrome Android)
- No IE11 support (use v1.x for legacy browsers)
๐งช Testing
npm test # Run tests npm run test:watch # Watch mode npm run test:coverage # With coverage
๐ ๏ธ Development
npm install # Install dependencies npm run dev # Watch mode for development npm run build # Build all formats npm run lint # Lint code npm run format # Format code
๐ License
MIT ยฉ p34eu
๐ Contributing
Contributions welcome! Please read our Contributing Guide first.
๐ Changelog
v2.0.0 (2026)
- Complete ES6+ rewrite
- Touch/pointer events support
- TypeScript definitions
- New methods:
selectAll(),invertSelection(),getSelected(),destroy() - Better performance and bug fixes
- Comprehensive test suite
- Multiple build formats (ESM, CJS, UMD)
v1.4.1
- Original stable version
Made with โค๏ธ by p34eu