@tft/interact 13.0.0 → 15.0.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.
Files changed (50) hide show
  1. package/{esm2020 → esm2022}/index.mjs +5 -5
  2. package/{esm2020 → esm2022}/lib/directives/account-for-scale.directive.mjs +26 -26
  3. package/{esm2020 → esm2022}/lib/directives/apply-scale.directive.mjs +28 -28
  4. package/esm2022/lib/directives/auto-scroll.directive.mjs +56 -0
  5. package/{esm2020 → esm2022}/lib/directives/drag-preview.directive.mjs +20 -20
  6. package/{esm2020 → esm2022}/lib/directives/drag-root.directive.mjs +32 -32
  7. package/{esm2020 → esm2022}/lib/directives/draggable.directive.mjs +320 -320
  8. package/{esm2020 → esm2022}/lib/directives/dropzone.directive.mjs +114 -114
  9. package/{esm2020 → esm2022}/lib/directives/gesturable.directive.mjs +82 -82
  10. package/{esm2020 → esm2022}/lib/directives/index.mjs +9 -9
  11. package/esm2022/lib/directives/resizable.directive.mjs +228 -0
  12. package/esm2022/lib/interact.module.mjs +66 -0
  13. package/{esm2020 → esm2022}/lib/models/index.mjs +1 -1
  14. package/{esm2020 → esm2022}/lib/models/interact.mjs +27 -27
  15. package/{esm2020 → esm2022}/lib/pipes/array-of-n.pipe.mjs +22 -22
  16. package/{esm2020 → esm2022}/lib/pipes/index.mjs +1 -1
  17. package/{esm2020 → esm2022}/lib/services/interact.service.mjs +197 -197
  18. package/{esm2020 → esm2022}/lib/utils/helpers.mjs +34 -34
  19. package/{esm2020 → esm2022}/lib/utils/index.mjs +1 -1
  20. package/{esm2020 → esm2022}/tft-interact.mjs +4 -4
  21. package/{fesm2020 → fesm2022}/tft-interact.mjs +1155 -1155
  22. package/{fesm2020 → fesm2022}/tft-interact.mjs.map +1 -1
  23. package/index.d.ts +5 -5
  24. package/lib/directives/account-for-scale.directive.d.ts +15 -15
  25. package/lib/directives/apply-scale.directive.d.ts +11 -11
  26. package/lib/directives/auto-scroll.directive.d.ts +34 -34
  27. package/lib/directives/drag-preview.directive.d.ts +10 -10
  28. package/lib/directives/drag-root.directive.d.ts +15 -15
  29. package/lib/directives/draggable.directive.d.ts +76 -76
  30. package/lib/directives/dropzone.directive.d.ts +40 -40
  31. package/lib/directives/gesturable.directive.d.ts +27 -27
  32. package/lib/directives/index.d.ts +9 -9
  33. package/lib/directives/resizable.directive.d.ts +61 -61
  34. package/lib/interact.module.d.ts +20 -20
  35. package/lib/models/index.d.ts +1 -1
  36. package/lib/models/interact.d.ts +140 -140
  37. package/lib/pipes/array-of-n.pipe.d.ts +12 -12
  38. package/lib/pipes/index.d.ts +1 -1
  39. package/lib/services/interact.service.d.ts +83 -83
  40. package/lib/utils/helpers.d.ts +12 -12
  41. package/lib/utils/index.d.ts +1 -1
  42. package/package.json +9 -17
  43. package/tft-interact-15.0.0.tgz +0 -0
  44. package/esm2020/lib/directives/auto-scroll.directive.mjs +0 -56
  45. package/esm2020/lib/directives/resizable.directive.mjs +0 -228
  46. package/esm2020/lib/interact.module.mjs +0 -66
  47. package/fesm2015/tft-interact.mjs +0 -1203
  48. package/fesm2015/tft-interact.mjs.map +0 -1
  49. package/tft-interact-13.0.0.tgz +0 -0
  50. package/tft-interact.d.ts +0 -5
@@ -1,1203 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { Pipe, InjectionToken, Directive, Input, Injectable, Optional, Inject, EventEmitter, HostBinding, Output, Self, HostListener, SkipSelf, ContentChild, NgModule } from '@angular/core';
3
- import { DOCUMENT, CommonModule } from '@angular/common';
4
- import interact from 'interactjs';
5
- import { BehaviorSubject, combineLatest, Subject } from 'rxjs';
6
- import { shareReplay, tap, map, scan } from 'rxjs/operators';
7
-
8
- class ArrayOfNPipe {
9
- /**
10
- *
11
- * @param n the number to make an array of
12
- * @param max the max length of the array (useful for limiting rendering in ngFor loop)
13
- */
14
- transform(n, max) {
15
- const length = ((max && max < n) || n === Infinity) ? max : n;
16
- return new Array(length).fill(length).map((x, i) => i);
17
- }
18
- }
19
- ArrayOfNPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ArrayOfNPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
20
- ArrayOfNPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ArrayOfNPipe, name: "arrayOfN" });
21
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ArrayOfNPipe, decorators: [{
22
- type: Pipe,
23
- args: [{
24
- name: 'arrayOfN'
25
- }]
26
- }] });
27
-
28
- const INTERACT_ROOT_CONFIG = new InjectionToken('INTERACT_ROOT_CONFIG_PARAMS');
29
- const DEFAULT_REGISTRY_ID = 'DEFAULT';
30
- /**
31
- * Default initial value for Delta BehaviorSubject
32
- */
33
- const defaultDelta = {
34
- deltaX: 0,
35
- deltaY: 0,
36
- targetElement: null
37
- };
38
- /**
39
- * Default initial value for Size BehaviorSubject
40
- */
41
- const defaultSize = {
42
- width: null,
43
- height: null,
44
- targetElement: null
45
- };
46
- /**
47
- * Default initial value for Position BehaviorSubject
48
- */
49
- const defaultPosition = {
50
- x: 0,
51
- y: 0,
52
- targetElement: null
53
- };
54
-
55
- const TFT_DRAG_PREVIEW = new InjectionToken('DragPreviewDirective');
56
- class DragPreviewDirective {
57
- constructor(templateRef) {
58
- this.templateRef = templateRef;
59
- }
60
- }
61
- DragPreviewDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: DragPreviewDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
62
- DragPreviewDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.1", type: DragPreviewDirective, selector: "ng-template[tftDragPreview]", inputs: { dragData: "dragData" }, ngImport: i0 });
63
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: DragPreviewDirective, decorators: [{
64
- type: Directive,
65
- args: [{
66
- // eslint-disable-next-line @angular-eslint/directive-selector
67
- selector: 'ng-template[tftDragPreview]',
68
- }]
69
- }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; }, propDecorators: { dragData: [{
70
- type: Input
71
- }] } });
72
-
73
- /** Gets the closest ancestor of an element that matches a selector. */
74
- function getClosestMatchingAncestor(element, selector) {
75
- let currentElement = element.parentElement;
76
- while (currentElement) {
77
- // IE doesn't support `matches` so we have to fall back to `msMatchesSelector`.
78
- if (currentElement.matches ? currentElement.matches(selector) :
79
- currentElement.msMatchesSelector(selector)) {
80
- return currentElement;
81
- }
82
- currentElement = currentElement.parentElement;
83
- }
84
- return null;
85
- }
86
- /**
87
- * Create a copy of the HTML Element
88
- */
89
- function cloneElement$1(element) {
90
- const clone = element.cloneNode(true);
91
- clone.removeAttribute('id');
92
- return clone;
93
- }
94
- /**
95
- * Gets the root HTML element of an embedded view.
96
- * If the root is not an HTML element it gets wrapped in one.
97
- */
98
- function getRootNode(viewRef, _document) {
99
- const rootNodes = viewRef.rootNodes;
100
- if (rootNodes.length === 1 && rootNodes[0].nodeType === _document.ELEMENT_NODE) {
101
- return rootNodes[0];
102
- }
103
- const wrapper = _document.createElement('div');
104
- rootNodes.forEach(node => wrapper.appendChild(node));
105
- return wrapper;
106
- }
107
-
108
- class InteractService {
109
- constructor(rendererFactory, ngZone, rootConfig) {
110
- this.rendererFactory = rendererFactory;
111
- this.ngZone = ngZone;
112
- this.rootConfig = rootConfig;
113
- this._interactableIndex = 0;
114
- this._dropzoneIndex = 0;
115
- // TODO: consider using Map here
116
- this.dragRegistrySystem = {};
117
- this.cssUnit = 'px';
118
- this.renderer = this.rendererFactory.createRenderer(null, null);
119
- this.cssUnit = (rootConfig === null || rootConfig === void 0 ? void 0 : rootConfig.cssDimensionUnit) || 'px';
120
- }
121
- addDeltaToPosition(delta, position) {
122
- return {
123
- x: delta.deltaX + position.x,
124
- y: delta.deltaY + position.y,
125
- targetElement: position.targetElement || delta.targetElement
126
- };
127
- }
128
- addRegistryToSystem(customRegistryId = null) {
129
- const registryId = customRegistryId || this.createDropzoneId(this._dropzoneIndex++);
130
- this.dragRegistrySystem[registryId] = {};
131
- return registryId;
132
- }
133
- addDraggableToRegistry(customRegistryId = null, interactableId = null) {
134
- const registryId = customRegistryId || DEFAULT_REGISTRY_ID;
135
- // if we pass an id to createInteractableId then it is used when creating the interactable
136
- // and returned, otherwise a new id is created for the draggable.
137
- const key = this.createInteractableId(interactableId);
138
- if (!Object.prototype.hasOwnProperty.call(this.dragRegistrySystem, registryId)) {
139
- this.dragRegistrySystem[registryId] = {};
140
- }
141
- this.dragRegistrySystem[registryId][key] = this.createInteractableState(defaultPosition, defaultSize, defaultDelta);
142
- return key;
143
- }
144
- destroyInteractable(interactableId, registryId = DEFAULT_REGISTRY_ID) {
145
- const interactableSystem = this.dragRegistrySystem[registryId][interactableId];
146
- if (interactableSystem) {
147
- // unsubscribe from all the subscriptions if they're subscriptions
148
- for (const propName in interactableSystem) {
149
- const prop = interactableSystem[propName];
150
- if (prop.unsubscribe && typeof prop.unsubscribe === 'function') {
151
- prop.unsubscribe();
152
- }
153
- ;
154
- }
155
- delete this.dragRegistrySystem[registryId][interactableId];
156
- }
157
- }
158
- subscribeToInteractable(interactableId, registryId = DEFAULT_REGISTRY_ID) {
159
- return this.dragRegistrySystem[registryId][interactableId];
160
- }
161
- createInteractableState(initialPosition, initialSize, initialDelta) {
162
- const deltas$ = new BehaviorSubject(initialDelta);
163
- // tracks the size of the element
164
- const size$ = new BehaviorSubject(Object.assign(Object.assign({}, initialSize), initialDelta));
165
- // Stream of positions as they change
166
- const position$ = new BehaviorSubject(initialPosition);
167
- // All draggable data mapped together
168
- const interactable$ = combineLatest([
169
- size$.pipe(
170
- // startWith({...initialSize, ...initialDelta}),
171
- shareReplay(1),
172
- // filter(resizeEvent => !!resizeEvent.targetElement),
173
- tap(({ deltaX, deltaY, width, height, targetElement }) => {
174
- this.ngZone.runOutsideAngular(() => {
175
- this.setElementSize(width, height, targetElement);
176
- });
177
- // only reposition if necessary i.e when resizing left or up
178
- if (deltaX || deltaY) {
179
- deltas$.next({ deltaX, deltaY, targetElement });
180
- }
181
- })),
182
- deltas$.pipe(shareReplay(1), tap((delta) => {
183
- const position = position$.value;
184
- const newPosition = this.addDeltaToPosition(delta, position);
185
- position$.next(newPosition);
186
- })),
187
- position$.pipe(shareReplay(1), tap(position => {
188
- this.ngZone.runOutsideAngular(() => {
189
- this.setElementTransform(position.x, position.y, position);
190
- });
191
- }))
192
- ]).pipe(shareReplay(1), map(([size, deltas, position]) => {
193
- return {
194
- x: position.x,
195
- y: position.y,
196
- deltaX: deltas.deltaX,
197
- deltaY: deltas.deltaY,
198
- width: size.width,
199
- height: size.height,
200
- targetElement: size.targetElement || position.targetElement || deltas.targetElement
201
- };
202
- }));
203
- // TODO: update system to handle only returning interactable$
204
- return {
205
- deltas$,
206
- position$,
207
- size$,
208
- interactable$
209
- };
210
- }
211
- createInteractableId(customInteractableId = null) {
212
- return customInteractableId || `interactable${this._interactableIndex++}`;
213
- }
214
- createDropzoneId(index) {
215
- return `dropzone${index}`;
216
- }
217
- getInteractableState(interactableId, registryId = DEFAULT_REGISTRY_ID) {
218
- return this.dragRegistrySystem[registryId][interactableId].interactable$;
219
- }
220
- updateDeltas(interactId, registryId, { deltaX, deltaY }, targetElement) {
221
- if (!this.interactableExistOnRegistry(interactId, registryId))
222
- return;
223
- this.dragRegistrySystem[registryId][interactId].deltas$.next({ deltaX, deltaY, targetElement });
224
- }
225
- updatePosition(interactId, registryId, { x, y }, targetElement) {
226
- if (!this.interactableExistOnRegistry(interactId, registryId))
227
- return;
228
- this.dragRegistrySystem[registryId][interactId].position$.next({ x, y, targetElement });
229
- }
230
- updateSize(interactId, registryId, { deltaX, deltaY, width, height }, targetElement) {
231
- if (!this.interactableExistOnRegistry(interactId, registryId))
232
- return;
233
- this.dragRegistrySystem[registryId][interactId].size$.next({ deltaX, deltaY, width, height, targetElement });
234
- }
235
- interactableExistOnRegistry(interactId, registryId = DEFAULT_REGISTRY_ID) {
236
- // eslint-disable-next-line no-prototype-builtins
237
- return this.dragRegistrySystem.hasOwnProperty(registryId) && this.dragRegistrySystem[registryId].hasOwnProperty(interactId);
238
- }
239
- /**
240
- * Uses renderer to set width and height of angular component
241
- * @param width the desired width of component
242
- * @param height the desired height of component
243
- * @param target the element to transform
244
- */
245
- setElementSize(width, height, target) {
246
- if (!target)
247
- return;
248
- this.renderer.setStyle(target, 'width', `${width}${this.cssUnit}`);
249
- this.renderer.setStyle(target, 'height', `${height}${this.cssUnit}`);
250
- }
251
- /**
252
- * Uses renderer to set position of angular component
253
- * @param x position on x axis
254
- * @param y position on y axis
255
- * @param target the element to transform
256
- */
257
- setElementTransform(x, y, position) {
258
- if (!(position === null || position === void 0 ? void 0 : position.targetElement))
259
- return;
260
- this.renderer.setStyle(position.targetElement, 'left', `${x}${this.cssUnit}`);
261
- this.renderer.setStyle(position.targetElement, 'top', `${y}${this.cssUnit}`);
262
- }
263
- /**
264
- * Generates a translate string for the x and y arguments passed to
265
- * be passed to css transform
266
- * @param x the position along the x axis
267
- * @param y the position along the y axis
268
- */
269
- createTransformString(x, y) {
270
- return `translate3d(${x}${this.cssUnit}, ${y}${this.cssUnit}, 0)`;
271
- }
272
- calculatePositionInElement(zoneElement, dragElement, scale) {
273
- // TODO: this calculation may not cover a lot of scenarios, keep an eye out for possible improvements
274
- const zoneRect = zoneElement.getBoundingClientRect();
275
- const dragRect = dragElement.getBoundingClientRect();
276
- const position = scale
277
- ? {
278
- x: (dragRect.left - zoneRect.left) / scale || 1,
279
- y: (dragRect.top - zoneRect.top) / scale || 1
280
- } : {
281
- x: dragRect.left - zoneRect.left,
282
- y: dragRect.top - zoneRect.top
283
- };
284
- // console.log({ y:position.y, drt:dragRect.top, zrt: zoneRect.top})
285
- return position;
286
- }
287
- }
288
- InteractService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InteractService, deps: [{ token: i0.RendererFactory2 }, { token: i0.NgZone }, { token: INTERACT_ROOT_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
289
- InteractService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InteractService, providedIn: 'root' });
290
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InteractService, decorators: [{
291
- type: Injectable,
292
- args: [{ providedIn: 'root' }]
293
- }], ctorParameters: function () {
294
- return [{ type: i0.RendererFactory2 }, { type: i0.NgZone }, { type: undefined, decorators: [{
295
- type: Optional
296
- }, {
297
- type: Inject,
298
- args: [INTERACT_ROOT_CONFIG]
299
- }] }];
300
- } });
301
-
302
- /**
303
- * Use to apply scale to the element and tell the drag and resize directives to account for the scale when
304
- * @example <div tftAccountForScale [scale]="2.5"> <div tftDraggable> </div> </div>
305
- * @note if `dragRoot` is used this directive should be used on the same element to ensure that the drag
306
- * element accounts for scale
307
- */
308
- class AccountForScaleDirective {
309
- constructor(el) {
310
- this.el = el;
311
- // this setup allows consumers to set x, y scale independently or just set them both with scale
312
- this.scale = 1;
313
- }
314
- }
315
- AccountForScaleDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: AccountForScaleDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
316
- AccountForScaleDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.1", type: AccountForScaleDirective, selector: "[tftAccountForScale]", inputs: { scale: "scale" }, ngImport: i0 });
317
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: AccountForScaleDirective, decorators: [{
318
- type: Directive,
319
- args: [{
320
- selector: '[tftAccountForScale]'
321
- }]
322
- }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { scale: [{
323
- type: Input
324
- }] } });
325
-
326
- class DropzoneDirective {
327
- constructor(el, renderer, interactService, account_for_scale_dir) {
328
- this.el = el;
329
- this.renderer = renderer;
330
- this.interactService = interactService;
331
- this.account_for_scale_dir = account_for_scale_dir;
332
- this.dropzoneConfig = {};
333
- this.position = 'relative';
334
- // proxies to pass interact events through to consumer of directive
335
- this.dropActivate = new EventEmitter();
336
- this.dragEnter = new EventEmitter();
337
- this.dragLeave = new EventEmitter();
338
- this.dragDrop = new EventEmitter();
339
- }
340
- get scale() {
341
- var _a;
342
- return (_a = this.account_for_scale_dir) === null || _a === void 0 ? void 0 : _a.scale;
343
- }
344
- ngOnInit() {
345
- // connects
346
- this.dropzone = this.connectDropzoneEvents(this.el.nativeElement, this.dropzoneConfig);
347
- this.dropzoneId = this.interactService.addRegistryToSystem(this.dropzoneId);
348
- }
349
- ngOnChanges(changes) {
350
- if (!changes.dropzoneConfig || !this.dropzone)
351
- return;
352
- // this.dropzone.unset();
353
- // this.dropzone = this.connectDropzoneEvents(this.el.nativeElement, this.dropzoneConfig)
354
- this.dropzone.dropzone(this.dropzoneConfig);
355
- }
356
- /**
357
- * Connects element to interacts dropzone events and returns a reference to the interactable
358
- * @param nativeElement the element to tie drop events to
359
- * @param dropzoneConfig the interact configuration to use when connecting
360
- */
361
- connectDropzoneEvents(nativeElement, dropzoneConfig) {
362
- return interact(nativeElement).dropzone(dropzoneConfig)
363
- // TODO: investigate when this fires in different scenarios
364
- .on('dropactivate', (event) => {
365
- this.dropActivate.emit(this.mapDropzoneEvent(event));
366
- })
367
- .on('dragenter', (event) => {
368
- this.renderer.setProperty(event.relatedTarget, 'dropTarget', this);
369
- this.dragEnter.emit(this.mapDropzoneEvent(event));
370
- })
371
- .on('dragleave', (event) => {
372
- if (event.relatedTarget.dropTarget === this) {
373
- this.renderer.setProperty(event.relatedTarget, 'dropTarget', null);
374
- }
375
- this.dragLeave.emit(this.mapDropzoneEvent(event));
376
- })
377
- .on('drop', (event) => {
378
- this.dragDrop.emit(this.mapDropzoneEvent(event));
379
- });
380
- }
381
- /**
382
- * Maps the drop event emitted by interact to something a little easier to use
383
- * @param event the drop event emitted by interact, extended with extra fields we added to
384
- */
385
- mapDropzoneEvent(event) {
386
- var _a, _b;
387
- const zoneElement = event.target;
388
- const dragElement = (_b = (_a = event.relatedTarget) === null || _a === void 0 ? void 0 : _a.dragRef) === null || _b === void 0 ? void 0 : _b.previewRef;
389
- const scale = this.scale;
390
- const positionInDropTarget = zoneElement && dragElement
391
- ? this.interactService.calculatePositionInElement(zoneElement, dragElement, scale)
392
- : null;
393
- return {
394
- interactEvent: event,
395
- dragRef: dragElement.dragRef,
396
- dragOrigin: dragElement.dragOrigin,
397
- dropTarget: event.relatedTarget.dropTarget,
398
- positionInDropTarget
399
- };
400
- }
401
- }
402
- DropzoneDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: DropzoneDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: InteractService }, { token: AccountForScaleDirective, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
403
- DropzoneDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.1", type: DropzoneDirective, selector: "[tftDropzone]", inputs: { dropzoneId: "dropzoneId", dropzoneConfig: "dropzoneConfig", dropzoneData: "dropzoneData", position: "position" }, outputs: { dropActivate: "dropActivate", dragEnter: "dragEnter", dragLeave: "dragLeave", dragDrop: "dragDrop" }, host: { properties: { "id": "dropzoneId", "style.position": "this.position" } }, usesOnChanges: true, ngImport: i0 });
404
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: DropzoneDirective, decorators: [{
405
- type: Directive,
406
- args: [{
407
- selector: '[tftDropzone]',
408
- host: {
409
- '[id]': 'dropzoneId'
410
- }
411
- }]
412
- }], ctorParameters: function () {
413
- return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: InteractService }, { type: AccountForScaleDirective, decorators: [{
414
- type: Optional
415
- }] }];
416
- }, propDecorators: { dropzoneId: [{
417
- type: Input
418
- }], dropzoneConfig: [{
419
- type: Input
420
- }], dropzoneData: [{
421
- type: Input
422
- }], position: [{
423
- type: Input
424
- }, {
425
- type: HostBinding,
426
- args: ['style.position']
427
- }], dropActivate: [{
428
- type: Output
429
- }], dragEnter: [{
430
- type: Output
431
- }], dragLeave: [{
432
- type: Output
433
- }], dragDrop: [{
434
- type: Output
435
- }] } });
436
-
437
- /**
438
- * Use this directive to select which element to attach the element to while dragging
439
- * @example <div tftDragRoot><div tftDraggable> </div> </div>
440
- * @note this directive will overwrite any style transformations (e.g. transform: scale(2); )
441
- */
442
- class DragRootDirective {
443
- constructor(el,
444
- // This is used when passing a dragRoot as in input to a draggable element that not a child of that dragRoot
445
- // It allows the the interact service to check if the drag root has some scaling applied to it and account for it when the component is dragged
446
- account_for_scale_dir) {
447
- this.el = el;
448
- this.account_for_scale_dir = account_for_scale_dir;
449
- }
450
- }
451
- DragRootDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: DragRootDirective, deps: [{ token: i0.ElementRef }, { token: AccountForScaleDirective, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Directive });
452
- DragRootDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.1", type: DragRootDirective, selector: "[tftDragRoot]", exportAs: ["tftDragRoot"], ngImport: i0 });
453
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: DragRootDirective, decorators: [{
454
- type: Directive,
455
- args: [{
456
- selector: '[tftDragRoot]',
457
- exportAs: 'tftDragRoot'
458
- }]
459
- }], ctorParameters: function () {
460
- return [{ type: i0.ElementRef }, { type: AccountForScaleDirective, decorators: [{
461
- type: Optional
462
- }, {
463
- type: Self
464
- }] }];
465
- } });
466
-
467
- ;
468
- /**
469
- * Use to apply scale to the element and tell the drag and resize directives to account for the scale when
470
- * @example <div tftAccountForScale [scale]="2.5"> <div tftDraggable> </div> </div>
471
- * @note if `dragRoot` is used this directive should be used on the same element to ensure that the drag
472
- * element accounts for scale
473
- */
474
- class AutoScrollDirective {
475
- constructor(el) {
476
- this.el = el;
477
- /**
478
- * Limit minimum time between scroll events in milliseconds
479
- */
480
- this.autoScrollConfig = {
481
- margin: 50,
482
- distance: 3,
483
- interval: 50,
484
- speed: 300,
485
- enabled: true
486
- };
487
- this.scrollDeltaObserver = new Subject();
488
- const { scrollTop, scrollLeft } = el.nativeElement;
489
- this.scrollSubject = new BehaviorSubject({ scrollTop, scrollLeft });
490
- this.scrollObserver = this.scrollSubject.pipe(scan((previous, current) => {
491
- const scrollTop = current.scrollTop - previous.scrollTop;
492
- const scrollLeft = current.scrollLeft - previous.scrollLeft;
493
- this.scrollDeltaObserver.next({ scrollTop, scrollLeft });
494
- return current;
495
- }), shareReplay(1));
496
- this.scrollObserver.subscribe();
497
- }
498
- // this setup allows consumers to set x, y scale independently or just set them both with scale
499
- scroll(scrollEvent) {
500
- const target = scrollEvent.target;
501
- const { scrollTop, scrollLeft } = target;
502
- this.scrollSubject.next({ scrollTop, scrollLeft });
503
- }
504
- }
505
- AutoScrollDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: AutoScrollDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
506
- AutoScrollDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.1", type: AutoScrollDirective, selector: "[tftAutoScroll]", inputs: { autoScrollConfig: "autoScrollConfig" }, host: { listeners: { "scroll": "scroll($event)" } }, ngImport: i0 });
507
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: AutoScrollDirective, decorators: [{
508
- type: Directive,
509
- args: [{
510
- selector: '[tftAutoScroll]'
511
- }]
512
- }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { autoScrollConfig: [{
513
- type: Input
514
- }], scroll: [{
515
- type: HostListener,
516
- args: ['scroll', ['$event']]
517
- }] } });
518
-
519
- /** @dynamic */
520
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
521
- class DraggableDirective {
522
- constructor(el, interactService, renderer, _viewContainerRef, _document, account_for_scale_dir, dropzone_dir, drag_root_dir, auto_scroll_dir) {
523
- this.el = el;
524
- this.interactService = interactService;
525
- this.renderer = renderer;
526
- this._viewContainerRef = _viewContainerRef;
527
- this._document = _document;
528
- this.account_for_scale_dir = account_for_scale_dir;
529
- this.dropzone_dir = dropzone_dir;
530
- this.drag_root_dir = drag_root_dir;
531
- this.auto_scroll_dir = auto_scroll_dir;
532
- /* zIndex while dragging*/
533
- this.dragZIndex = 10000;
534
- this.enableDragDefault = true;
535
- /**
536
- * @deprecated replaced by 'dragDisabled' property, please migrate before v13
537
- */
538
- this.disabled = false;
539
- this.dragDisabled = false;
540
- this.showPlaceholder = false;
541
- // pipes all interact events to event emitters
542
- this.dragStart = new EventEmitter();
543
- this.dragMove = new EventEmitter();
544
- this.dragInertiaStart = new EventEmitter();
545
- this.dragEnd = new EventEmitter();
546
- }
547
- // check all the different places for scale
548
- get scale() {
549
- var _a, _b, _c, _d, _e;
550
- return ((_a = this.account_for_scale_dir) === null || _a === void 0 ? void 0 : _a.scale) || ((_c = (_b = this.drag_root_dir) === null || _b === void 0 ? void 0 : _b.account_for_scale_dir) === null || _c === void 0 ? void 0 : _c.scale) || ((_e = (_d = this.dragRoot) === null || _d === void 0 ? void 0 : _d.account_for_scale_dir) === null || _e === void 0 ? void 0 : _e.scale) || 1;
551
- }
552
- ngOnInit() {
553
- var _a, _b, _c, _d, _e;
554
- this.interactable = this.initiateDragEvents(this.dragConfig, this.el.nativeElement);
555
- this.dragRootEl = (((_b = (_a = this.dragRoot) === null || _a === void 0 ? void 0 : _a.el) === null || _b === void 0 ? void 0 : _b.nativeElement) || ((_d = (_c = this.drag_root_dir) === null || _c === void 0 ? void 0 : _c.el) === null || _d === void 0 ? void 0 : _d.nativeElement)) || this._document.body;
556
- // register with parent dropzone if it exists, otherwise use default
557
- // this gives us a place on the registry to store our drag items that don't have a dropzone
558
- this.registryId = ((_e = this.dropzone_dir) === null || _e === void 0 ? void 0 : _e.dropzoneId) || DEFAULT_REGISTRY_ID;
559
- // add draggable to directory and store its id
560
- this.interactableId = this.interactService.addDraggableToRegistry(this.registryId, this.interactableId);
561
- this.alignPositionWithInputs(this.x, this.y);
562
- // cache subscription to interactable state so we can unsubscribe onDestroy
563
- this.interactableState = this.interactService
564
- .getInteractableState(this.interactableId, this.registryId);
565
- // keep our cached position values in line with our drag state
566
- this.interactableSubscription = this.interactableState.subscribe((state) => {
567
- this.y = state.y;
568
- this.x = state.x;
569
- });
570
- this.setDragConfig();
571
- }
572
- // TODO: watch config here as well and update interactable
573
- ngOnChanges(changes) {
574
- // we do this here instead of using a setter on the input so that it
575
- // will only run once when there is a change to x and y
576
- if (changes.y || changes.x) {
577
- this.alignPositionWithInputs(this.x, this.y);
578
- }
579
- if (changes.dragConfig || changes.disabled || changes.dragDisabled) {
580
- if (!this.interactable)
581
- return;
582
- this.setDragConfig();
583
- }
584
- /**
585
- * @deprecated remove this in v13
586
- */
587
- if (changes.disabled) {
588
- console.warn(`It looks like your using the 'disabled' input on a tftDraggable directive, it has been deprecated and is replaced with 'dragDisabled', please migrate by v13`);
589
- }
590
- }
591
- setDragConfig() {
592
- const enabled = !(this.disabled || this.dragDisabled);
593
- const dragConfig = Object.assign(Object.assign({}, this.dragConfig), { enabled });
594
- this.interactable.draggable(dragConfig);
595
- }
596
- ngAfterViewInit() {
597
- this.addDragPropertiesToElement(this.el.nativeElement);
598
- if (!this.dropzone_dir) {
599
- this.previewRef = this.el.nativeElement;
600
- }
601
- }
602
- ngOnDestroy() {
603
- // clean up state and subscriptions related to destroyed component
604
- this.interactableSubscription.unsubscribe();
605
- this.interactService.destroyInteractable(this.interactableId, this.registryId);
606
- }
607
- dragMoveListener(event, element) {
608
- const { dx, dy } = event;
609
- const scale = this.scale;
610
- const deltaX = scale ? dx / scale : dx;
611
- const deltaY = scale ? dy / scale : dy;
612
- this.interactService.updateDeltas(this.interactableId, this.registryId, { deltaX, deltaY }, element);
613
- }
614
- setDragStyles(dragElement) {
615
- this.renderer.setStyle(dragElement, 'touchAction', 'none');
616
- this.renderer.setStyle(dragElement, 'zIndex', this.dragZIndex);
617
- this.renderer.setStyle(dragElement, 'position', 'absolute');
618
- }
619
- addDragPropertiesToElement(nativeElement) {
620
- this.renderer.setProperty(nativeElement, 'dropTarget', this.dropzone_dir || null);
621
- this.renderer.setProperty(nativeElement, 'dragOrigin', this.dropzone_dir || null);
622
- this.renderer.setProperty(nativeElement, 'dragRef', this);
623
- }
624
- mapDragEvent(event) {
625
- var _a;
626
- const { target, dropzone } = event;
627
- const dropzoneElement = (dropzone === null || dropzone === void 0 ? void 0 : dropzone.target) || ((_a = target.dropTarget) === null || _a === void 0 ? void 0 : _a.el.nativeElement);
628
- const scale = this.scale;
629
- const positionInDropTarget = target && dropzoneElement
630
- ? this.interactService.calculatePositionInElement(dropzoneElement, this.previewRef, scale)
631
- : null;
632
- return {
633
- interactEvent: event,
634
- dragRef: this,
635
- dragOrigin: target.dragOrigin,
636
- dropTarget: target.dropTarget,
637
- positionInDropTarget
638
- };
639
- }
640
- setPosition(x, y) {
641
- this.interactService.updatePosition(this.interactableId, this.registryId, { x, y }, this.el.nativeElement);
642
- }
643
- alignPositionWithInputs(x, y) {
644
- // short circuit if positions aren't numbers or if they haven't changed
645
- if (!this.isValidPosition(x, y))
646
- return;
647
- this.interactService.updatePosition(this.interactableId, this.registryId, { x, y }, this.el.nativeElement);
648
- }
649
- isValidPosition(x, y) {
650
- return this.isNumeric(x) && this.isNumeric(y);
651
- }
652
- // We use use this instead of isNaN here to try and help performance
653
- // We should be able to reliably restrict to numbers or falsey values
654
- isNumeric(num) {
655
- return typeof num === 'number' && !isNaN(num);
656
- }
657
- initiateDragEvents(dragConfig, nativeElement) {
658
- const defaultDragConfig = Object.assign(Object.assign(Object.assign({}, dragConfig), { enabled: !(this.disabled || this.dragDisabled) }), (this.auto_scroll_dir && {
659
- autoScroll: Object.assign(Object.assign({}, this.auto_scroll_dir.autoScrollConfig), { container: this.auto_scroll_dir.el.nativeElement })
660
- }));
661
- return interact(nativeElement).draggable(defaultDragConfig)
662
- .on('dragstart', (event) => {
663
- var _a, _b, _c;
664
- const interaction = event.interaction;
665
- // check if we should append drag element to body
666
- if (this.enableDragDefault
667
- && interaction.pointerIsDown
668
- // TODO: probably don't need following condition checks anymore remove by 2022
669
- // && !!this.dropzone_dir
670
- // && !interaction.interacting()
671
- ) {
672
- if (this._previewTemplate) {
673
- const viewRef = this._viewContainerRef.createEmbeddedView(this._previewTemplate.templateRef);
674
- this.previewRef = getRootNode(viewRef, this._document);
675
- }
676
- else {
677
- this.previewRef = cloneElement(this.el.nativeElement);
678
- }
679
- this.addDragPropertiesToElement(this.previewRef);
680
- this.setDragStyles(this.previewRef);
681
- this.dragRootEl.prepend(this.previewRef);
682
- const scale = ((_a = this.account_for_scale_dir) === null || _a === void 0 ? void 0 : _a.scale) || ((_c = (_b = this.dragRoot) === null || _b === void 0 ? void 0 : _b.account_for_scale_dir) === null || _c === void 0 ? void 0 : _c.scale) || 1;
683
- const { x, y } = this.interactService.calculatePositionInElement(this.dragRootEl, nativeElement, scale);
684
- this.interactService.updatePosition(this.interactableId, this.registryId, { x, y }, this.previewRef);
685
- if (!this.showPlaceholder) {
686
- this.renderer.setStyle(this.el.nativeElement, 'display', 'none');
687
- }
688
- }
689
- // subscribe to scroll events if they are there, by only subscribing on dragstart we avoid wasting subscriptions on interactables that aren't be dragged
690
- if (this.auto_scroll_dir) {
691
- this.subscribeToScrollEvents();
692
- }
693
- this.dragStart.emit(this.mapDragEvent(event));
694
- })
695
- .on('dragmove', (event) => {
696
- if (this.enableDragDefault) {
697
- const dragElement = this.dropzone_dir && this.previewRef || nativeElement;
698
- this.dragMoveListener(event, dragElement);
699
- }
700
- const mappedEvent = this.mapDragEvent(event);
701
- this.dragMove.emit(mappedEvent);
702
- })
703
- .on('draginertiastart', (event) => {
704
- this.dragInertiaStart.emit(this.mapDragEvent(event));
705
- })
706
- .on('dragend', (event) => {
707
- const mappedEvent = this.mapDragEvent(event);
708
- if (!!this.dropzone_dir && this.dropzone_dir === event.target.dropTarget) {
709
- const { x, y } = mappedEvent.positionInDropTarget;
710
- this.setPosition(x, y);
711
- }
712
- this.renderer.setStyle(this.el.nativeElement, 'display', '');
713
- this.dragEnd.emit(mappedEvent);
714
- // unsubscribe from scroll events if subscribed
715
- if (this.auto_scroll_dir) {
716
- this.scrollEventsSubscription.unsubscribe();
717
- }
718
- if (this.el.nativeElement !== this.previewRef) {
719
- // we do this in a timeout, so that we don't remove before the dropzone can get the boundingElementRect
720
- setTimeout(() => {
721
- this.dragRootEl.removeChild(this.previewRef);
722
- });
723
- }
724
- });
725
- }
726
- subscribeToScrollEvents() {
727
- this.scrollEventsSubscription = this.auto_scroll_dir.scrollDeltaObserver.subscribe(({ scrollLeft, scrollTop }) => {
728
- const deltaX = this.scale ? scrollLeft / this.scale : scrollLeft;
729
- const deltaY = this.scale ? scrollTop / this.scale : scrollTop;
730
- this.interactService.updateDeltas(this.interactableId, this.registryId, { deltaX, deltaY }, this.previewRef);
731
- });
732
- }
733
- }
734
- DraggableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: DraggableDirective, deps: [{ token: i0.ElementRef }, { token: InteractService }, { token: i0.Renderer2 }, { token: i0.ViewContainerRef }, { token: DOCUMENT }, { token: AccountForScaleDirective, optional: true }, { token: DropzoneDirective, optional: true, skipSelf: true }, { token: DragRootDirective, optional: true, skipSelf: true }, { token: AutoScrollDirective, optional: true, skipSelf: true }], target: i0.ɵɵFactoryTarget.Directive });
735
- DraggableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.1", type: DraggableDirective, selector: "[tftDraggable]", inputs: { x: "x", y: "y", dragZIndex: "dragZIndex", zIndex: "zIndex", interactableId: "interactableId", dragData: "dragData", enableDragDefault: "enableDragDefault", disabled: "disabled", dragDisabled: "dragDisabled", dragConfig: "dragConfig", showPlaceholder: "showPlaceholder", dragRoot: "dragRoot" }, outputs: { dragStart: "dragStart", dragMove: "dragMove", dragInertiaStart: "dragInertiaStart", dragEnd: "dragEnd" }, host: { properties: { "style.touchAction": "this.dragDisabled ? \"auto\" : \"none\"", "style.position": "\"absolute\"", "id": "interactableId" } }, queries: [{ propertyName: "_previewTemplate", first: true, predicate: DragPreviewDirective, descendants: true }], usesOnChanges: true, ngImport: i0 });
736
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: DraggableDirective, decorators: [{
737
- type: Directive,
738
- args: [{
739
- selector: '[tftDraggable]',
740
- // eslint-disable-next-line @angular-eslint/no-host-metadata-property
741
- host: {
742
- '[style.touchAction]': 'this.dragDisabled ? "auto" : "none"',
743
- '[style.position]': '"absolute"',
744
- '[id]': 'interactableId',
745
- }
746
- }]
747
- }], ctorParameters: function () {
748
- return [{ type: i0.ElementRef }, { type: InteractService }, { type: i0.Renderer2 }, { type: i0.ViewContainerRef }, { type: Document, decorators: [{
749
- type: Inject,
750
- args: [DOCUMENT]
751
- }] }, { type: AccountForScaleDirective, decorators: [{
752
- type: Optional
753
- }] }, { type: DropzoneDirective, decorators: [{
754
- type: Optional
755
- }, {
756
- type: SkipSelf
757
- }] }, { type: DragRootDirective, decorators: [{
758
- type: Optional
759
- }, {
760
- type: SkipSelf
761
- }] }, { type: AutoScrollDirective, decorators: [{
762
- type: Optional
763
- }, {
764
- type: SkipSelf
765
- }] }];
766
- }, propDecorators: { x: [{
767
- type: Input
768
- }], y: [{
769
- type: Input
770
- }], dragZIndex: [{
771
- type: Input
772
- }], zIndex: [{
773
- type: Input
774
- }], interactableId: [{
775
- type: Input
776
- }], dragData: [{
777
- type: Input
778
- }], enableDragDefault: [{
779
- type: Input
780
- }], disabled: [{
781
- type: Input
782
- }], dragDisabled: [{
783
- type: Input
784
- }], dragConfig: [{
785
- type: Input
786
- }], showPlaceholder: [{
787
- type: Input
788
- }], dragRoot: [{
789
- type: Input
790
- }], dragStart: [{
791
- type: Output
792
- }], dragMove: [{
793
- type: Output
794
- }], dragInertiaStart: [{
795
- type: Output
796
- }], dragEnd: [{
797
- type: Output
798
- }], _previewTemplate: [{
799
- type: ContentChild,
800
- args: [DragPreviewDirective]
801
- }] } });
802
- /**
803
- * Component utils
804
- */
805
- // create a clone of the component passed in and add it to the root component
806
- function cloneElement(element) {
807
- const clone = element.cloneNode(true);
808
- clone.removeAttribute('id');
809
- return clone;
810
- }
811
- function getPreviewInsertionPoint(documentRef) {
812
- // We can't use the body if the user is in fullscreen mode,
813
- // because the preview will render under the fullscreen element.
814
- return documentRef.fullscreenElement ||
815
- documentRef.webkitFullscreenElement ||
816
- documentRef.mozFullScreenElement ||
817
- documentRef.msFullscreenElement ||
818
- documentRef.body;
819
- }
820
-
821
- /** @dynamic */
822
- class ResizableDirective {
823
- constructor(el, _document, interactService, renderer, drag_root_dir, account_for_scale_dir, draggable_dir, dropzone_dir, auto_scroll_dir) {
824
- var _a;
825
- this.el = el;
826
- this._document = _document;
827
- this.interactService = interactService;
828
- this.renderer = renderer;
829
- this.drag_root_dir = drag_root_dir;
830
- this.account_for_scale_dir = account_for_scale_dir;
831
- this.draggable_dir = draggable_dir;
832
- this.dropzone_dir = dropzone_dir;
833
- this.auto_scroll_dir = auto_scroll_dir;
834
- this.enableResizeDefault = true;
835
- // TODO: should this be an input with default or should consuming user set display in styles each time
836
- this.position = 'absolute';
837
- this.resizeDisabled = false;
838
- this.resizeStart = new EventEmitter();
839
- this.resizeMove = new EventEmitter();
840
- this.resizeInertiaStart = new EventEmitter();
841
- this.resizeEnd = new EventEmitter();
842
- this.defaultConfig = {
843
- edges: { left: true, right: true, bottom: true, top: true }
844
- };
845
- this.activeEdges = { left: false, right: false, top: false, bottom: false };
846
- this.dragRootEl = ((_a = drag_root_dir === null || drag_root_dir === void 0 ? void 0 : drag_root_dir.el) === null || _a === void 0 ? void 0 : _a.nativeElement) || this._document.body;
847
- }
848
- get scale() {
849
- var _a, _b, _c;
850
- return ((_a = this.account_for_scale_dir) === null || _a === void 0 ? void 0 : _a.scale) || ((_c = (_b = this.drag_root_dir) === null || _b === void 0 ? void 0 : _b.account_for_scale_dir) === null || _c === void 0 ? void 0 : _c.scale);
851
- }
852
- ngOnInit() {
853
- var _a, _b;
854
- this.addResizePropertiesToElement(this.el.nativeElement);
855
- // we check for a dropzone, we use its id as the registry id if there is on
856
- // otherwise, we use DEFAULT_REGISTRY_ID as a registry id. This allows us to keep our interactable
857
- // drag state organized by dropzones.
858
- this.registryId = ((_a = this.dropzone_dir) === null || _a === void 0 ? void 0 : _a.dropzoneId) || DEFAULT_REGISTRY_ID;
859
- this.interactableId = ((_b = this.draggable_dir) === null || _b === void 0 ? void 0 : _b.interactableId) || this.interactService.addDraggableToRegistry(this.registryId, this.interactableId);
860
- this.interactable = this.initiateResizeEvents(Object.assign(Object.assign({}, this.defaultConfig), this.resizeConfig), this.el.nativeElement);
861
- this.alignDimensionsWithInputs(this.width, this.height);
862
- this.interactableSubscription = this.interactService
863
- .getInteractableState(this.interactableId, this.registryId)
864
- .subscribe();
865
- }
866
- ngOnChanges(changes) {
867
- if ((changes.resizeConfig || changes.resizeDisabled) && this.interactable) {
868
- this.interactable.resizable(Object.assign(Object.assign({}, this.resizeConfig), { enabled: !this.resizeDisabled }));
869
- }
870
- if (changes.width || changes.height) {
871
- this.alignDimensionsWithInputs(this.width, this.height);
872
- }
873
- }
874
- ngOnDestroy() {
875
- this.interactableSubscription.unsubscribe();
876
- this.interactService.destroyInteractable(this.interactableId, this.registryId);
877
- }
878
- resizeListener(event) {
879
- const element = this.el.nativeElement;
880
- const scale = this.scale;
881
- const { deltaRect } = event;
882
- const deltaX = deltaRect.left / scale;
883
- const deltaY = deltaRect.top / scale;
884
- // We get the width and height directly from the native element because
885
- // the event dimension can get out of sync when resizing with autoScroll
886
- const rect = element.getBoundingClientRect();
887
- const width = (rect.width + deltaRect.width) / scale;
888
- const height = (rect.height + deltaRect.height) / scale;
889
- this.interactService.updateSize(this.interactableId, this.registryId, { deltaX, deltaY, width, height }, this.el.nativeElement);
890
- }
891
- /**
892
- * hook elements into interacts resize event listeners
893
- * we spread the configs so that the consuming component only overwrites the
894
- * pieces that it explicitly indicates
895
- * @param resizeConfig
896
- * @param nativeElement
897
- */
898
- initiateResizeEvents(resizeConfig, nativeElement) {
899
- var _a;
900
- // TODO: This should try and get interactable from tft_draggable if it exists
901
- const defaultResizeConfig = Object.assign(Object.assign(Object.assign({}, resizeConfig), { enabled: !this.resizeDisabled }), (this.auto_scroll_dir && {
902
- autoScroll: Object.assign(Object.assign({}, this.auto_scroll_dir.autoScrollConfig), { container: this.auto_scroll_dir.el.nativeElement })
903
- }));
904
- const interactable = ((_a = this.draggable_dir) === null || _a === void 0 ? void 0 : _a.interactable) || interact(nativeElement);
905
- return interactable.resizable(defaultResizeConfig)
906
- .on('resizestart', (event) => {
907
- this.activeEdges = event.edges;
908
- if (this.auto_scroll_dir) {
909
- this.subscribeToScrollEvents();
910
- }
911
- this.resizeStart.emit(this.mapResizeEvent(event));
912
- })
913
- .on('resizemove', (event) => {
914
- if (this.enableResizeDefault) {
915
- this.resizeListener(event);
916
- }
917
- const mappedEvent = this.mapResizeEvent(event);
918
- this.resizeMove.emit(mappedEvent);
919
- })
920
- .on('resizeinertiastart', (event) => this.resizeInertiaStart.emit(this.mapResizeEvent(event)))
921
- .on('resizeend', (event) => {
922
- if (this.auto_scroll_dir) {
923
- this.scrollEventsSubscription.unsubscribe();
924
- }
925
- this.activeEdges = { left: false, right: false, top: false, bottom: false };
926
- this.resizeEnd.emit(this.mapResizeEvent(event));
927
- });
928
- }
929
- mapResizeEvent(event) {
930
- var _a, _b;
931
- const target = this.el.nativeElement;
932
- const relatedTarget = (_b = (_a = this.draggable_dir) === null || _a === void 0 ? void 0 : _a.dropzone_dir) === null || _b === void 0 ? void 0 : _b.el.nativeElement;
933
- const scale = this.scale;
934
- const positionInDropTarget = target && relatedTarget
935
- ? this.interactService.calculatePositionInElement(relatedTarget, target, scale)
936
- : null;
937
- return {
938
- interactEvent: event,
939
- resizeRef: this,
940
- dragRef: this.draggable_dir,
941
- dragOrigin: this.dropzone_dir,
942
- dropTarget: this.el.nativeElement.dropTarget,
943
- positionInDropTarget,
944
- size: {
945
- width: target.clientWidth / scale,
946
- height: target.clientHeight / scale
947
- }
948
- };
949
- }
950
- alignDimensionsWithInputs(width, height) {
951
- this.interactService.updateSize(this.interactableId, this.registryId, { deltaX: 0, deltaY: 0, width, height }, this.el.nativeElement);
952
- }
953
- addResizePropertiesToElement(nativeElement) {
954
- this.renderer.setProperty(nativeElement, 'resizeRef', this);
955
- }
956
- subscribeToScrollEvents() {
957
- this.scrollEventsSubscription = this.auto_scroll_dir.scrollDeltaObserver.subscribe(({ scrollLeft, scrollTop }) => {
958
- const scale = this.scale;
959
- const target = this.el.nativeElement;
960
- const { width: prevWidth, height: prevHeight } = target.getBoundingClientRect();
961
- const deltaHeight = scrollTop * (this.activeEdges.top ? -1 : this.activeEdges.bottom ? 1 : 0);
962
- const deltaWidth = scrollLeft * (this.activeEdges.left ? -1 : this.activeEdges.right ? 1 : 0);
963
- const height = (prevHeight + deltaHeight) / scale;
964
- const width = (prevWidth + deltaWidth) / scale;
965
- const deltaX = this.activeEdges.left ? (scrollLeft / scale) : 0;
966
- const deltaY = this.activeEdges.top ? (scrollTop / scale) : 0;
967
- this.interactService.updateSize(this.interactableId, this.registryId, { deltaX, deltaY, width, height }, this.el.nativeElement);
968
- });
969
- }
970
- }
971
- ResizableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ResizableDirective, deps: [{ token: i0.ElementRef }, { token: DOCUMENT }, { token: InteractService }, { token: i0.Renderer2 }, { token: DragRootDirective, optional: true }, { token: AccountForScaleDirective, optional: true }, { token: DraggableDirective, optional: true }, { token: DropzoneDirective, optional: true, skipSelf: true }, { token: AutoScrollDirective, optional: true, skipSelf: true }], target: i0.ɵɵFactoryTarget.Directive });
972
- ResizableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.1", type: ResizableDirective, selector: "[tftResizable]", inputs: { enableResizeDefault: "enableResizeDefault", position: "position", resizeConfig: "resizeConfig", interactableId: "interactableId", width: "width", height: "height", resizeDisabled: "resizeDisabled" }, outputs: { resizeStart: "resizeStart", resizeMove: "resizeMove", resizeInertiaStart: "resizeInertiaStart", resizeEnd: "resizeEnd" }, host: { properties: { "style.touchAction": "this.resizeDisabled ? \"auto\" : \"none\"", "style.position": "position", "style.boxSizing": "\"border-box\"" } }, usesOnChanges: true, ngImport: i0 });
973
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ResizableDirective, decorators: [{
974
- type: Directive,
975
- args: [{
976
- selector: '[tftResizable]',
977
- // eslint-disable-next-line @angular-eslint/no-host-metadata-property
978
- host: {
979
- // prevents touch events from colliding with with mouse events
980
- // on touch screen
981
- '[style.touchAction]': 'this.resizeDisabled ? "auto" : "none"',
982
- // default to absolute here to accommodate likely use cases
983
- // consuming component can easily over ride with position input
984
- '[style.position]': 'position',
985
- // follows interactjs suggested practices
986
- '[style.boxSizing]': '"border-box"',
987
- }
988
- }]
989
- }], ctorParameters: function () {
990
- return [{ type: i0.ElementRef }, { type: Document, decorators: [{
991
- type: Inject,
992
- args: [DOCUMENT]
993
- }] }, { type: InteractService }, { type: i0.Renderer2 }, { type: DragRootDirective, decorators: [{
994
- type: Optional
995
- }] }, { type: AccountForScaleDirective, decorators: [{
996
- type: Optional
997
- }] }, { type: DraggableDirective, decorators: [{
998
- type: Optional
999
- }] }, { type: DropzoneDirective, decorators: [{
1000
- type: Optional
1001
- }, {
1002
- type: SkipSelf
1003
- }] }, { type: AutoScrollDirective, decorators: [{
1004
- type: Optional
1005
- }, {
1006
- type: SkipSelf
1007
- }] }];
1008
- }, propDecorators: { enableResizeDefault: [{
1009
- type: Input
1010
- }], position: [{
1011
- type: Input
1012
- }], resizeConfig: [{
1013
- type: Input
1014
- }], interactableId: [{
1015
- type: Input
1016
- }], width: [{
1017
- type: Input
1018
- }], height: [{
1019
- type: Input
1020
- }], resizeDisabled: [{
1021
- type: Input
1022
- }], resizeStart: [{
1023
- type: Output
1024
- }], resizeMove: [{
1025
- type: Output
1026
- }], resizeInertiaStart: [{
1027
- type: Output
1028
- }], resizeEnd: [{
1029
- type: Output
1030
- }] } });
1031
-
1032
- /** @dynamic */
1033
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1034
- class GesturableDirective {
1035
- constructor(el, draggable_dir) {
1036
- this.el = el;
1037
- this.draggable_dir = draggable_dir;
1038
- this.gestureDisabled = false;
1039
- // pipes all interact events to event emitters
1040
- this.gestureStart = new EventEmitter();
1041
- this.gestureMove = new EventEmitter();
1042
- this.gestureEnd = new EventEmitter();
1043
- }
1044
- ngOnInit() {
1045
- var _a;
1046
- this.gesturableId = ((_a = this.draggable_dir) === null || _a === void 0 ? void 0 : _a.interactableId) || 'id';
1047
- this.interactable = this.initiateGestureEvents(this.gestureConfig, this.el.nativeElement);
1048
- this.setGestureConfig();
1049
- }
1050
- // TODO: watch config here as well and update interactable
1051
- ngOnChanges(changes) {
1052
- // we do this here instead of using a setter on the input so that it
1053
- // will only run once when there is a change to x and y
1054
- if (changes.gestureConfig || changes.gestureDisabled) {
1055
- if (!this.interactable)
1056
- return;
1057
- this.setGestureConfig();
1058
- }
1059
- }
1060
- setGestureConfig() {
1061
- const enabled = !this.gestureDisabled;
1062
- const gestureConfig = Object.assign(Object.assign({}, this.gestureConfig), { enabled });
1063
- this.interactable.gesturable(gestureConfig);
1064
- }
1065
- initiateGestureEvents(gestureConfig, nativeElement) {
1066
- var _a;
1067
- const defaultConfig = {
1068
- enabled: !this.gestureDisabled,
1069
- };
1070
- const interactable = ((_a = this.draggable_dir) === null || _a === void 0 ? void 0 : _a.interactable) || interact(nativeElement);
1071
- return interactable.gesturable(Object.assign(Object.assign({}, defaultConfig), gestureConfig))
1072
- .on('gesturestart', (event) => {
1073
- this.gestureStart.emit({ gestureRef: this, interactEvent: event });
1074
- })
1075
- .on('gesturemove', (event) => {
1076
- this.gestureMove.emit({ gestureRef: this, interactEvent: event });
1077
- })
1078
- .on('gestureend', (event) => {
1079
- this.gestureEnd.emit({ gestureRef: this, interactEvent: event });
1080
- });
1081
- }
1082
- }
1083
- GesturableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: GesturableDirective, deps: [{ token: i0.ElementRef }, { token: DraggableDirective, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
1084
- GesturableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.1", type: GesturableDirective, selector: "[tftGesturable]", inputs: { gesturableId: "gesturableId", gestureDisabled: "gestureDisabled", gestureConfig: "gestureConfig" }, outputs: { gestureStart: "gestureStart", gestureMove: "gestureMove", gestureEnd: "gestureEnd" }, host: { properties: { "id": "gesturableId" } }, usesOnChanges: true, ngImport: i0 });
1085
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: GesturableDirective, decorators: [{
1086
- type: Directive,
1087
- args: [{
1088
- selector: '[tftGesturable]',
1089
- // eslint-disable-next-line @angular-eslint/no-host-metadata-property
1090
- host: {
1091
- // '[style.touchAction]': 'this.gestureDisabled ? "auto" : "none"',
1092
- '[id]': 'gesturableId',
1093
- }
1094
- }]
1095
- }], ctorParameters: function () {
1096
- return [{ type: i0.ElementRef }, { type: DraggableDirective, decorators: [{
1097
- type: Optional
1098
- }] }];
1099
- }, propDecorators: { gesturableId: [{
1100
- type: Input
1101
- }], gestureDisabled: [{
1102
- type: Input
1103
- }], gestureConfig: [{
1104
- type: Input
1105
- }], gestureStart: [{
1106
- type: Output
1107
- }], gestureMove: [{
1108
- type: Output
1109
- }], gestureEnd: [{
1110
- type: Output
1111
- }] } });
1112
-
1113
- class ApplyScaleDirective {
1114
- constructor(el) {
1115
- this.el = el;
1116
- this._scale = 1;
1117
- }
1118
- // this setup allows consumers to set x, y scale independently or just set them both with scale
1119
- set scale(val) {
1120
- this._scale;
1121
- this.fontSize = `${val}px`;
1122
- }
1123
- ;
1124
- }
1125
- ApplyScaleDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ApplyScaleDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
1126
- ApplyScaleDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.1", type: ApplyScaleDirective, selector: "[tftApplyScale]", inputs: { scale: "scale" }, host: { properties: { "style.fontSize": "this.fontSize" } }, ngImport: i0 });
1127
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ApplyScaleDirective, decorators: [{
1128
- type: Directive,
1129
- args: [{
1130
- selector: '[tftApplyScale]'
1131
- }]
1132
- }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { scale: [{
1133
- type: Input
1134
- }], fontSize: [{
1135
- type: HostBinding,
1136
- args: ['style.fontSize']
1137
- }] } });
1138
-
1139
- const EXPORTS = [
1140
- DraggableDirective,
1141
- ResizableDirective,
1142
- DropzoneDirective,
1143
- GesturableDirective,
1144
- DragRootDirective,
1145
- AutoScrollDirective,
1146
- AccountForScaleDirective,
1147
- ApplyScaleDirective,
1148
- DragPreviewDirective,
1149
- ArrayOfNPipe,
1150
- ];
1151
- class InteractModule {
1152
- static forRoot(config) {
1153
- const defaultConfig = { cssDimensionUnit: 'px' };
1154
- return {
1155
- ngModule: InteractModule,
1156
- providers: [
1157
- { provide: INTERACT_ROOT_CONFIG, useValue: Object.assign(Object.assign({}, defaultConfig), config) },
1158
- InteractService
1159
- ]
1160
- };
1161
- }
1162
- }
1163
- InteractModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InteractModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1164
- InteractModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InteractModule, declarations: [DraggableDirective,
1165
- ResizableDirective,
1166
- DropzoneDirective,
1167
- GesturableDirective,
1168
- DragRootDirective,
1169
- AutoScrollDirective,
1170
- AccountForScaleDirective,
1171
- ApplyScaleDirective,
1172
- DragPreviewDirective,
1173
- ArrayOfNPipe], imports: [CommonModule], exports: [DraggableDirective,
1174
- ResizableDirective,
1175
- DropzoneDirective,
1176
- GesturableDirective,
1177
- DragRootDirective,
1178
- AutoScrollDirective,
1179
- AccountForScaleDirective,
1180
- ApplyScaleDirective,
1181
- DragPreviewDirective,
1182
- ArrayOfNPipe] });
1183
- InteractModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InteractModule, imports: [[CommonModule]] });
1184
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InteractModule, decorators: [{
1185
- type: NgModule,
1186
- args: [{
1187
- imports: [CommonModule],
1188
- // providers: [{ provide: INTERACT_ROOT_CONFIG, useValue: 'px' }],
1189
- declarations: [
1190
- ...EXPORTS,
1191
- ],
1192
- exports: [
1193
- ...EXPORTS
1194
- ]
1195
- }]
1196
- }] });
1197
-
1198
- /**
1199
- * Generated bundle index. Do not edit.
1200
- */
1201
-
1202
- export { AccountForScaleDirective, ApplyScaleDirective, ArrayOfNPipe, AutoScrollDirective, DEFAULT_REGISTRY_ID, DragPreviewDirective, DragRootDirective, DraggableDirective, DropzoneDirective, GesturableDirective, INTERACT_ROOT_CONFIG, InteractModule, ResizableDirective, TFT_DRAG_PREVIEW, cloneElement$1 as cloneElement, defaultDelta, defaultPosition, defaultSize, getClosestMatchingAncestor, getRootNode };
1203
- //# sourceMappingURL=tft-interact.mjs.map