ngx-virtual-dnd 3.1.3 → 3.2.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -18
- package/fesm2022/ngx-virtual-dnd.mjs +351 -9
- package/fesm2022/ngx-virtual-dnd.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ngx-virtual-dnd.d.ts +67 -4
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@ Inspired by [react-virtualized-dnd](https://github.com/forecast-it/react-virtual
|
|
|
15
15
|
- **Container Constraints** - Constrain drag preview to container boundaries
|
|
16
16
|
- **Axis Locking** - Lock dragging to horizontal or vertical axis
|
|
17
17
|
- **Custom Previews** - Template-based drag preview and placeholder customization
|
|
18
|
+
- **Shift Animations** - Opt-in sliding of displaced items, plus a per-step event for haptics
|
|
18
19
|
- **Keyboard Accessible** - Space to grab, arrows to move, Escape to cancel
|
|
19
20
|
- **Touch Support** - Works with mouse and touch, with configurable delay/threshold
|
|
20
21
|
- **Angular 21+** - Signals, standalone components, modern patterns
|
|
@@ -45,15 +46,15 @@ import {
|
|
|
45
46
|
DragPreviewComponent,
|
|
46
47
|
],
|
|
47
48
|
template: `
|
|
48
|
-
<!-- Item template -->
|
|
49
|
-
<ng-template #itemTpl let-item>
|
|
50
|
-
<div class="item" [vdndDraggable]="item.id" [vdndDraggableData]="item">
|
|
51
|
-
{{ item.name }}
|
|
52
|
-
</div>
|
|
53
|
-
</ng-template>
|
|
54
|
-
|
|
55
49
|
<!-- Lists wrapped in a group -->
|
|
56
50
|
<div vdndGroup="my-group">
|
|
51
|
+
<!-- Item template: declare it inside vdndGroup so the draggables inherit the group -->
|
|
52
|
+
<ng-template #itemTpl let-item>
|
|
53
|
+
<div class="item" [vdndDraggable]="item.id" [vdndDraggableData]="item">
|
|
54
|
+
{{ item.name }}
|
|
55
|
+
</div>
|
|
56
|
+
</ng-template>
|
|
57
|
+
|
|
57
58
|
<vdnd-sortable-list
|
|
58
59
|
droppableId="list-1"
|
|
59
60
|
group="my-group"
|
|
@@ -98,6 +99,8 @@ export class MyComponent {
|
|
|
98
99
|
|
|
99
100
|
**That's it!** `VirtualSortableListComponent` handles placeholder positioning, sticky items during drag, and virtual scroll integration automatically.
|
|
100
101
|
|
|
102
|
+
> Every draggable and droppable needs a group (from a `vdndGroup` ancestor or `vdndDraggableGroup` / `vdndDroppableGroup`), even for a single list — without one, drag is disabled. Templates resolve the group from where they are **declared**, so keep the `<ng-template>` inside the `vdndGroup` element.
|
|
103
|
+
|
|
101
104
|
## API Overview
|
|
102
105
|
|
|
103
106
|
The library exports these main pieces (use IDE completion for full details):
|
|
@@ -300,6 +303,40 @@ Configure auto-scroll behavior when dragging near container edges:
|
|
|
300
303
|
|
|
301
304
|
Set `[autoScrollEnabled]="false"` to disable auto-scroll entirely. These options are available on `VirtualSortableListComponent`, `DroppableDirective`, and `ScrollableDirective`.
|
|
302
305
|
|
|
306
|
+
### Shift Animations & Haptics
|
|
307
|
+
|
|
308
|
+
Items displaced by the placeholder jump into place by default. Provide `VDND_ANIMATION_CONFIG` to make them slide instead (a compositor-only `transform` animation, works with virtual scrolling and dynamic heights):
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
import { VDND_ANIMATION_CONFIG } from 'ngx-virtual-dnd';
|
|
312
|
+
|
|
313
|
+
// app.config.ts (app-wide) or any component's `providers` (that subtree only)
|
|
314
|
+
providers: [{ provide: VDND_ANIMATION_CONFIG, useValue: { shiftDuration: 200 } }];
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
| Option | Default | Description |
|
|
318
|
+
| --------------- | ---------------------------- | ----------------------------------- |
|
|
319
|
+
| `shiftDuration` | `200` | Slide duration in ms (`0` disables) |
|
|
320
|
+
| `shiftEasing` | `cubic-bezier(0.2, 0, 0, 1)` | CSS easing function |
|
|
321
|
+
|
|
322
|
+
The animation is skipped when the user prefers reduced motion. If the placeholder moves again mid-slide, items continue from where they currently are. Values are read each time an animation starts, so a getter can toggle it at runtime.
|
|
323
|
+
|
|
324
|
+
For haptic feedback on every step, listen to `(placeholderMove)` on `vdndDroppable` or `vdnd-sortable-list`. It fires each time the placeholder moves within that list (every item displacement), including when it enters the list — not for the initial pick-up or when it leaves:
|
|
325
|
+
|
|
326
|
+
```html
|
|
327
|
+
<vdnd-sortable-list ... (placeholderMove)="onPlaceholderMove($event)" />
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
import { Haptics } from '@capacitor/haptics';
|
|
332
|
+
|
|
333
|
+
onPlaceholderMove(event: PlaceholderMoveEvent): void {
|
|
334
|
+
Haptics.selectionChanged(); // or navigator.vibrate?.(10) on the web
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
`PlaceholderMoveEvent` carries `draggableId`, `sourceDroppableId`, `droppableId`, `previousIndex` (`null` when the placeholder just entered the list) and `currentIndex`, using the same index convention as `DropEvent.destination.index`.
|
|
339
|
+
|
|
303
340
|
### Disabling Drag & Drop
|
|
304
341
|
|
|
305
342
|
Use the `disabled` input to conditionally disable draggables, droppables, or entire lists:
|
|
@@ -339,13 +376,13 @@ For maximum control, use individual components instead of `VirtualSortableListCo
|
|
|
339
376
|
DragPreviewComponent,
|
|
340
377
|
],
|
|
341
378
|
template: `
|
|
342
|
-
<ng-template #itemTpl let-item>
|
|
343
|
-
<div class="item" [vdndDraggable]="item.id" [vdndDraggableData]="item">
|
|
344
|
-
{{ item.name }}
|
|
345
|
-
</div>
|
|
346
|
-
</ng-template>
|
|
347
|
-
|
|
348
379
|
<div vdndGroup="demo">
|
|
380
|
+
<ng-template #itemTpl let-item>
|
|
381
|
+
<div class="item" [vdndDraggable]="item.id" [vdndDraggableData]="item">
|
|
382
|
+
{{ item.name }}
|
|
383
|
+
</div>
|
|
384
|
+
</ng-template>
|
|
385
|
+
|
|
349
386
|
<div vdndDroppable="list-1" (drop)="onDrop($event)">
|
|
350
387
|
<vdnd-virtual-scroll
|
|
351
388
|
droppableId="list-1"
|
|
@@ -433,6 +470,7 @@ The library emits events with position data. Implement announcements in your app
|
|
|
433
470
|
```typescript
|
|
434
471
|
@Component({
|
|
435
472
|
template: `
|
|
473
|
+
<!-- Inside a vdndGroup, like any draggable -->
|
|
436
474
|
<div
|
|
437
475
|
vdndDraggable="item-1"
|
|
438
476
|
(dragStart)="announce('Grabbed ' + item.name)"
|
|
@@ -490,11 +528,12 @@ ARIA attributes (`aria-grabbed`, `aria-dropeffect`, `tabindex`) are managed auto
|
|
|
490
528
|
|
|
491
529
|
All event types are importable from `ngx-virtual-dnd`.
|
|
492
530
|
|
|
493
|
-
| Output
|
|
494
|
-
|
|
|
495
|
-
| `(dragStart)`
|
|
496
|
-
| `(dragEnd)`
|
|
497
|
-
| `(drop)`
|
|
531
|
+
| Output | Event Type | Emitted By |
|
|
532
|
+
| ------------------- | ---------------------- | ---------------------------------------------------- |
|
|
533
|
+
| `(dragStart)` | `DragStartEvent` | `DraggableDirective` |
|
|
534
|
+
| `(dragEnd)` | `DragEndEvent` | `DraggableDirective` |
|
|
535
|
+
| `(drop)` | `DropEvent` | `DroppableDirective`, `VirtualSortableListComponent` |
|
|
536
|
+
| `(placeholderMove)` | `PlaceholderMoveEvent` | `DroppableDirective`, `VirtualSortableListComponent` |
|
|
498
537
|
|
|
499
538
|
`DragEndEvent.destinationIndex` is `null` when no drop occurred — an Escape cancel, a release outside every droppable, or a release over a disabled droppable — so branch on `destinationIndex === null` to detect that. The `cancelled` boolean is `true` only for an active Escape cancel.
|
|
500
539
|
|