UNPKG

ngx-drag-to-select

Version:

A lightweight, fast, configurable and reactive drag-to-select component for Angular 8 and beyond

502 lines 80.1 kB
import { Component, ElementRef, Output, EventEmitter, Input, Renderer2, ViewChild, NgZone, ContentChildren, QueryList, HostBinding, PLATFORM_ID, Inject, } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; import { Subject, combineLatest, merge, from, fromEvent, BehaviorSubject, asyncScheduler } from 'rxjs'; import { switchMap, takeUntil, map, tap, filter, auditTime, mapTo, share, withLatestFrom, distinctUntilChanged, observeOn, startWith, concatMapTo, first, } from 'rxjs/operators'; import { SelectItemDirective, SELECT_ITEM_INSTANCE } from './select-item.directive'; import { ShortcutService } from './shortcut.service'; import { createSelectBox, whenSelectBoxVisible } from './operators'; import { Action, UpdateActions, } from './models'; import { AUDIT_TIME, NO_SELECT_CLASS } from './constants'; import { inBoundingBox, cursorWithinElement, clearSelection, boxIntersects, calculateBoundingClientRect, getRelativeMousePosition, getMousePosition, hasMinimumSize, } from './utils'; import { KeyboardEventsService } from './keyboard-events.service'; import * as i0 from "@angular/core"; import * as i1 from "./shortcut.service"; import * as i2 from "./keyboard-events.service"; import * as i3 from "@angular/common"; export class SelectContainerComponent { constructor(platformId, shortcuts, keyboardEvents, hostElementRef, renderer, ngZone) { this.platformId = platformId; this.shortcuts = shortcuts; this.keyboardEvents = keyboardEvents; this.hostElementRef = hostElementRef; this.renderer = renderer; this.ngZone = ngZone; this.selectOnDrag = true; this.disabled = false; this.disableDrag = false; this.selectOnClick = true; this.dragOverItems = true; this.disableRangeSelection = false; this.selectMode = false; this.selectWithShortcut = false; this.custom = false; this.hostClass = true; this.selectedItemsChange = new EventEmitter(); this.select = new EventEmitter(); this.itemSelected = new EventEmitter(); this.itemDeselected = new EventEmitter(); this.selectionStarted = new EventEmitter(); this.selectionEnded = new EventEmitter(); this._tmpItems = new Map(); this._selectedItems$ = new BehaviorSubject([]); this._selectableItems = []; this.updateItems$ = new Subject(); this.destroy$ = new Subject(); this._lastRange = [-1, -1]; this._lastStartIndex = undefined; this._newRangeStart = false; this._lastRangeSelection = new Map(); } ngAfterViewInit() { if (isPlatformBrowser(this.platformId)) { this.host = this.hostElementRef.nativeElement; this._initSelectedItemsChange(); this._calculateBoundingClientRect(); this._observeBoundingRectChanges(); this._observeSelectableItems(); const mouseup$ = this.keyboardEvents.mouseup$.pipe(filter(() => !this.disabled), tap(() => this._onMouseUp()), share()); const mousemove$ = this.keyboardEvents.mousemove$.pipe(filter(() => !this.disabled), share()); const mousedown$ = fromEvent(this.host, 'mousedown').pipe(filter((event) => event.button === 0), // only emit left mouse filter(() => !this.disabled), filter((event) => this.selectOnClick || event.target === this.host), tap((event) => this._onMouseDown(event)), share()); const dragging$ = mousedown$.pipe(filter((event) => !this.shortcuts.disableSelection(event)), filter(() => !this.selectMode), filter(() => !this.disableDrag), filter((event) => this.dragOverItems || event.target === this.host), switchMap(() => mousemove$.pipe(takeUntil(mouseup$))), share()); const currentMousePosition$ = mousedown$.pipe(map((event) => getRelativeMousePosition(event, this.host))); const show$ = dragging$.pipe(mapTo(1)); const hide$ = mouseup$.pipe(mapTo(0)); const opacity$ = merge(show$, hide$).pipe(distinctUntilChanged()); const selectBox$ = combineLatest([dragging$, opacity$, currentMousePosition$]).pipe(createSelectBox(this.host), share()); this.selectBoxClasses$ = merge(dragging$, mouseup$, this.keyboardEvents.distinctKeydown$, this.keyboardEvents.distinctKeyup$).pipe(auditTime(AUDIT_TIME), withLatestFrom(selectBox$), map(([event, selectBox]) => { return { 'dts-adding': hasMinimumSize(selectBox, 0, 0) && !this.shortcuts.removeFromSelection(event), 'dts-removing': this.shortcuts.removeFromSelection(event), }; }), distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b))); const selectOnMouseUp$ = dragging$.pipe(filter(() => !this.selectOnDrag), filter(() => !this.selectMode), filter((event) => this._cursorWithinHost(event)), switchMap((_) => mouseup$.pipe(first())), filter((event) => (!this.shortcuts.disableSelection(event) && !this.shortcuts.toggleSingleItem(event)) || this.shortcuts.removeFromSelection(event))); const selectOnDrag$ = selectBox$.pipe(auditTime(AUDIT_TIME), withLatestFrom(mousemove$, (selectBox, event) => ({ selectBox, event, })), filter(() => this.selectOnDrag), filter(({ selectBox }) => hasMinimumSize(selectBox)), map(({ event }) => event)); const selectOnKeyboardEvent$ = merge(this.keyboardEvents.distinctKeydown$, this.keyboardEvents.distinctKeyup$).pipe(auditTime(AUDIT_TIME), whenSelectBoxVisible(selectBox$), tap((event) => { if (this._isExtendedSelection(event)) { this._tmpItems.clear(); } else { this._flushItems(); } })); merge(selectOnMouseUp$, selectOnDrag$, selectOnKeyboardEvent$) .pipe(takeUntil(this.destroy$)) .subscribe((event) => this._selectItems(event)); this.selectBoxStyles$ = selectBox$.pipe(map((selectBox) => ({ top: `${selectBox.top}px`, left: `${selectBox.left}px`, width: `${selectBox.width}px`, height: `${selectBox.height}px`, opacity: selectBox.opacity, }))); this._initSelectionOutputs(mousedown$, mouseup$); } } ngAfterContentInit() { this._selectableItems = this.$selectableItems.toArray(); } selectAll() { this.$selectableItems.forEach((item) => { this._selectItem(item); }); } toggleItems(predicate) { this._filterSelectableItems(predicate).subscribe((item) => this._toggleItem(item)); } selectItems(predicate) { this._filterSelectableItems(predicate).subscribe((item) => this._selectItem(item)); } deselectItems(predicate) { this._filterSelectableItems(predicate).subscribe((item) => this._deselectItem(item)); } clearSelection() { this.$selectableItems.forEach((item) => { this._deselectItem(item); }); } update() { this._calculateBoundingClientRect(); this.$selectableItems.forEach((item) => item.calculateBoundingClientRect()); } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); } _filterSelectableItems(predicate) { // Wrap select items in an observable for better efficiency as // no intermediate arrays are created and we only need to process // every item once. return from(this._selectableItems).pipe(filter((item) => predicate(item.value))); } _initSelectedItemsChange() { this._selectedItems$.pipe(auditTime(AUDIT_TIME), takeUntil(this.destroy$)).subscribe({ next: (selectedItems) => { this.selectedItemsChange.emit(selectedItems); this.select.emit(selectedItems); }, complete: () => { this.selectedItemsChange.emit([]); }, }); } _observeSelectableItems() { // Listen for updates and either select or deselect an item this.updateItems$ .pipe(withLatestFrom(this._selectedItems$), takeUntil(this.destroy$), filter(([update]) => !update.item.dtsDisabled)) .subscribe(([update, selectedItems]) => { const item = update.item; switch (update.type) { case UpdateActions.Add: if (this._addItem(item, selectedItems)) { item._select(); } break; case UpdateActions.Remove: if (this._removeItem(item, selectedItems)) { item._deselect(); } break; } }); // Update the container as well as all selectable items if the list has changed this.$selectableItems.changes .pipe(withLatestFrom(this._selectedItems$), observeOn(asyncScheduler), takeUntil(this.destroy$)) .subscribe(([items, selectedItems]) => { const newList = items.toArray(); this._selectableItems = newList; const newValues = newList.map((item) => item.value); const removedItems = selectedItems.filter((item) => !newValues.includes(item)); if (removedItems.length) { removedItems.forEach((item) => this._removeItem(item, selectedItems)); } this.update(); }); } _observeBoundingRectChanges() { this.ngZone.runOutsideAngular(() => { const resize$ = fromEvent(window, 'resize'); const windowScroll$ = fromEvent(window, 'scroll'); const containerScroll$ = fromEvent(this.host, 'scroll'); merge(resize$, windowScroll$, containerScroll$) .pipe(startWith('INITIAL_UPDATE'), auditTime(AUDIT_TIME), takeUntil(this.destroy$)) .subscribe(() => { this.update(); }); }); } _initSelectionOutputs(mousedown$, mouseup$) { mousedown$ .pipe(filter((event) => this._cursorWithinHost(event)), tap(() => this.selectionStarted.emit()), concatMapTo(mouseup$.pipe(first())), withLatestFrom(this._selectedItems$), map(([, items]) => items), takeUntil(this.destroy$)) .subscribe((items) => { this.selectionEnded.emit(items); }); } _calculateBoundingClientRect() { this.host.boundingClientRect = calculateBoundingClientRect(this.host); } _cursorWithinHost(event) { return cursorWithinElement(event, this.host); } _onMouseUp() { this._flushItems(); this.renderer.removeClass(document.body, NO_SELECT_CLASS); } _onMouseDown(event) { if (this.shortcuts.disableSelection(event) || this.disabled) { return; } clearSelection(window); if (!this.disableDrag) { this.renderer.addClass(document.body, NO_SELECT_CLASS); } if (this.shortcuts.removeFromSelection(event)) { return; } const mousePoint = getMousePosition(event); const [currentIndex, clickedItem] = this._getClosestSelectItem(event); let [startIndex, endIndex] = this._lastRange; const isMoveRangeStart = this.shortcuts.moveRangeStart(event); const shouldResetRangeSelection = !this.shortcuts.extendedSelectionShortcut(event) || isMoveRangeStart || this.disableRangeSelection; if (shouldResetRangeSelection) { this._resetRangeStart(); } // move range start if (shouldResetRangeSelection && !this.disableRangeSelection) { if (currentIndex > -1) { this._newRangeStart = true; this._lastStartIndex = currentIndex; clickedItem.toggleRangeStart(); this._lastRangeSelection.clear(); } else { this._lastStartIndex = -1; } } if (currentIndex > -1) { startIndex = Math.min(this._lastStartIndex, currentIndex); endIndex = Math.max(this._lastStartIndex, currentIndex); this._lastRange = [startIndex, endIndex]; } if (isMoveRangeStart) { return; } this.$selectableItems.forEach((item, index) => { const itemRect = item.getBoundingClientRect(); const withinBoundingBox = inBoundingBox(mousePoint, itemRect); if (this.shortcuts.extendedSelectionShortcut(event) && this.disableRangeSelection) { return; } const withinRange = this.shortcuts.extendedSelectionShortcut(event) && startIndex > -1 && endIndex > -1 && index >= startIndex && index <= endIndex && startIndex !== endIndex; const shouldAdd = (withinBoundingBox && !this.shortcuts.toggleSingleItem(event) && !this.selectMode && !this.selectWithShortcut) || (this.shortcuts.extendedSelectionShortcut(event) && item.selected && !this._lastRangeSelection.get(item)) || withinRange || (withinBoundingBox && this.shortcuts.toggleSingleItem(event) && !item.selected) || (!withinBoundingBox && this.shortcuts.toggleSingleItem(event) && item.selected) || (withinBoundingBox && !item.selected && this.selectMode) || (!withinBoundingBox && item.selected && this.selectMode); const shouldRemove = (!withinBoundingBox && !this.shortcuts.toggleSingleItem(event) && !this.selectMode && !this.shortcuts.extendedSelectionShortcut(event) && !this.selectWithShortcut) || (this.shortcuts.extendedSelectionShortcut(event) && currentIndex > -1) || (!withinBoundingBox && this.shortcuts.toggleSingleItem(event) && !item.selected) || (withinBoundingBox && this.shortcuts.toggleSingleItem(event) && item.selected) || (!withinBoundingBox && !item.selected && this.selectMode) || (withinBoundingBox && item.selected && this.selectMode); if (shouldAdd) { this._selectItem(item); } else if (shouldRemove) { this._deselectItem(item); } if (withinRange && !this._lastRangeSelection.get(item)) { this._lastRangeSelection.set(item, true); } else if (!withinRange && !this._newRangeStart && !item.selected) { this._lastRangeSelection.delete(item); } }); // if we don't toggle a single item, we set `newRangeStart` to `false` // meaning that we are building up a range if (!this.shortcuts.toggleSingleItem(event)) { this._newRangeStart = false; } } _selectItems(event) { const selectionBox = calculateBoundingClientRect(this.$selectBox.nativeElement); this.$selectableItems.forEach((item, index) => { if (this._isExtendedSelection(event)) { this._extendedSelectionMode(selectionBox, item, event); } else { this._normalSelectionMode(selectionBox, item, event); if (this._lastStartIndex < 0 && item.selected) { item.toggleRangeStart(); this._lastStartIndex = index; } } }); } _isExtendedSelection(event) { return this.shortcuts.extendedSelectionShortcut(event) && this.selectOnDrag; } _normalSelectionMode(selectBox, item, event) { const inSelection = boxIntersects(selectBox, item.getBoundingClientRect()); const shouldAdd = inSelection && !item.selected && !this.shortcuts.removeFromSelection(event); const shouldRemove = (!inSelection && item.selected && !this.shortcuts.addToSelection(event)) || (inSelection && item.selected && this.shortcuts.removeFromSelection(event)); if (shouldAdd) { this._selectItem(item); } else if (shouldRemove) { this._deselectItem(item); } } _extendedSelectionMode(selectBox, item, event) { const inSelection = boxIntersects(selectBox, item.getBoundingClientRect()); const shoudlAdd = (inSelection && !item.selected && !this.shortcuts.removeFromSelection(event) && !this._tmpItems.has(item)) || (inSelection && item.selected && this.shortcuts.removeFromSelection(event) && !this._tmpItems.has(item)); const shouldRemove = (!inSelection && item.selected && this.shortcuts.addToSelection(event) && this._tmpItems.has(item)) || (!inSelection && !item.selected && this.shortcuts.removeFromSelection(event) && this._tmpItems.has(item)); if (shoudlAdd) { if (item.selected) { item._deselect(); } else { item._select(); } const action = this.shortcuts.removeFromSelection(event) ? Action.Delete : this.shortcuts.addToSelection(event) ? Action.Add : Action.None; this._tmpItems.set(item, action); } else if (shouldRemove) { if (this.shortcuts.removeFromSelection(event)) { item._select(); } else { item._deselect(); } this._tmpItems.delete(item); } } _flushItems() { this._tmpItems.forEach((action, item) => { if (action === Action.Add) { this._selectItem(item); } if (action === Action.Delete) { this._deselectItem(item); } }); this._tmpItems.clear(); } _addItem(item, selectedItems) { let success = false; if (!this._hasItem(item, selectedItems)) { success = true; selectedItems.push(item.value); this._selectedItems$.next(selectedItems); this.itemSelected.emit(item.value); } return success; } _removeItem(item, selectedItems) { let success = false; const value = item instanceof SelectItemDirective ? item.value : item; const index = selectedItems.indexOf(value); if (index > -1) { success = true; selectedItems.splice(index, 1); this._selectedItems$.next(selectedItems); this.itemDeselected.emit(value); } return success; } _toggleItem(item) { if (item.selected) { this._deselectItem(item); } else { this._selectItem(item); } } _selectItem(item) { this.updateItems$.next({ type: UpdateActions.Add, item }); } _deselectItem(item) { this.updateItems$.next({ type: UpdateActions.Remove, item }); } _hasItem(item, selectedItems) { return selectedItems.includes(item.value); } _getClosestSelectItem(event) { const target = event.target.closest('.dts-select-item'); let index = -1; let targetItem = null; if (target) { targetItem = target[SELECT_ITEM_INSTANCE]; index = this._selectableItems.indexOf(targetItem); } return [index, targetItem]; } _resetRangeStart() { this._lastRange = [-1, -1]; const lastRangeStart = this._getLastRangeSelection(); if (lastRangeStart && lastRangeStart.rangeStart) { lastRangeStart.toggleRangeStart(); } } _getLastRangeSelection() { if (this._lastStartIndex >= 0) { return this._selectableItems[this._lastStartIndex]; } return null; } } SelectContainerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: SelectContainerComponent, deps: [{ token: PLATFORM_ID }, { token: i1.ShortcutService }, { token: i2.KeyboardEventsService }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); SelectContainerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.3", type: SelectContainerComponent, selector: "dts-select-container", inputs: { selectedItems: "selectedItems", selectOnDrag: "selectOnDrag", disabled: "disabled", disableDrag: "disableDrag", selectOnClick: "selectOnClick", dragOverItems: "dragOverItems", disableRangeSelection: "disableRangeSelection", selectMode: "selectMode", selectWithShortcut: "selectWithShortcut", custom: "custom" }, outputs: { selectedItemsChange: "selectedItemsChange", select: "select", itemSelected: "itemSelected", itemDeselected: "itemDeselected", selectionStarted: "selectionStarted", selectionEnded: "selectionEnded" }, host: { properties: { "class.dts-custom": "this.custom", "class.dts-select-container": "this.hostClass" } }, queries: [{ propertyName: "$selectableItems", predicate: SelectItemDirective, descendants: true }], viewQueries: [{ propertyName: "$selectBox", first: true, predicate: ["selectBox"], descendants: true, static: true }], exportAs: ["dts-select-container"], ngImport: i0, template: ` <ng-content></ng-content> <div class="dts-select-box" #selectBox [ngClass]="selectBoxClasses$ | async" [ngStyle]="selectBoxStyles$ | async" ></div> `, isInline: true, styles: [":host{display:block;position:relative}\n"], directives: [{ type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], pipes: { "async": i3.AsyncPipe } }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: SelectContainerComponent, decorators: [{ type: Component, args: [{ selector: 'dts-select-container', exportAs: 'dts-select-container', template: ` <ng-content></ng-content> <div class="dts-select-box" #selectBox [ngClass]="selectBoxClasses$ | async" [ngStyle]="selectBoxStyles$ | async" ></div> `, styles: [":host{display:block;position:relative}\n"] }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }, { type: i1.ShortcutService }, { type: i2.KeyboardEventsService }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }]; }, propDecorators: { $selectBox: [{ type: ViewChild, args: ['selectBox', { static: true }] }], $selectableItems: [{ type: ContentChildren, args: [SelectItemDirective, { descendants: true }] }], selectedItems: [{ type: Input }], selectOnDrag: [{ type: Input }], disabled: [{ type: Input }], disableDrag: [{ type: Input }], selectOnClick: [{ type: Input }], dragOverItems: [{ type: Input }], disableRangeSelection: [{ type: Input }], selectMode: [{ type: Input }], selectWithShortcut: [{ type: Input }], custom: [{ type: Input }, { type: HostBinding, args: ['class.dts-custom'] }], hostClass: [{ type: HostBinding, args: ['class.dts-select-container'] }], selectedItemsChange: [{ type: Output }], select: [{ type: Output }], itemSelected: [{ type: Output }], itemDeselected: [{ type: Output }], selectionStarted: [{ type: Output }], selectionEnded: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LWNvbnRhaW5lci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZHJhZy10by1zZWxlY3Qvc3JjL2xpYi9zZWxlY3QtY29udGFpbmVyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFVBQVUsRUFDVixNQUFNLEVBQ04sWUFBWSxFQUNaLEtBQUssRUFFTCxTQUFTLEVBQ1QsU0FBUyxFQUNULE1BQU0sRUFDTixlQUFlLEVBQ2YsU0FBUyxFQUNULFdBQVcsRUFFWCxXQUFXLEVBQ1gsTUFBTSxHQUVQLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRXBELE9BQU8sRUFBYyxPQUFPLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRSxjQUFjLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFbkgsT0FBTyxFQUNMLFNBQVMsRUFDVCxTQUFTLEVBQ1QsR0FBRyxFQUNILEdBQUcsRUFDSCxNQUFNLEVBQ04sU0FBUyxFQUNULEtBQUssRUFDTCxLQUFLLEVBQ0wsY0FBYyxFQUNkLG9CQUFvQixFQUNwQixTQUFTLEVBQ1QsU0FBUyxFQUNULFdBQVcsRUFDWCxLQUFLLEdBQ04sTUFBTSxnQkFBZ0IsQ0FBQztBQUV4QixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFckQsT0FBTyxFQUFFLGVBQWUsRUFBRSxvQkFBb0IsRUFBcUIsTUFBTSxhQUFhLENBQUM7QUFFdkYsT0FBTyxFQUNMLE1BQU0sRUFLTixhQUFhLEdBR2QsTUFBTSxVQUFVLENBQUM7QUFFbEIsT0FBTyxFQUFFLFVBQVUsRUFBRSxlQUFl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