@libs-ui/components-drag-drop 0.2.356-8 → 0.2.357-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 +432 -266
- package/drag-drop.directive.d.ts +3 -3
- package/drag-drop.service.d.ts +20 -14
- package/drag-item.directive.d.ts +3 -3
- package/drag-scroll.directive.d.ts +2 -2
- package/esm2022/drag-drop.directive.mjs +18 -30
- package/esm2022/drag-drop.service.mjs +22 -1
- package/esm2022/drag-item-in-container-virtual-scroll.directive.mjs +3 -3
- package/esm2022/drag-item.directive.mjs +18 -4
- package/esm2022/drag-scroll.directive.mjs +4 -2
- package/esm2022/index.mjs +1 -2
- package/fesm2022/libs-ui-components-drag-drop.mjs +60 -865
- package/fesm2022/libs-ui-components-drag-drop.mjs.map +1 -1
- package/index.d.ts +0 -1
- package/package.json +3 -3
- package/demo/demo.component.d.ts +0 -56
- package/esm2022/demo/demo.component.mjs +0 -833
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { signal, Injectable, input, inject, ElementRef, DestroyRef, Directive, ChangeDetectorRef, model, output, effect, untracked
|
|
2
|
+
import { signal, Injectable, input, inject, ElementRef, DestroyRef, Directive, ChangeDetectorRef, model, output, effect, untracked } from '@angular/core';
|
|
3
3
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
4
|
import { get, checkMouseOverInContainer, cloneIBoundingClientRect, uuid, set, cloneDeep, getViewport, checkViewInScreen, getDragEventByElement } from '@libs-ui/utils';
|
|
5
|
-
import { Subject, debounceTime, filter, fromEvent, tap, takeUntil
|
|
6
|
-
import { CommonModule } from '@angular/common';
|
|
7
|
-
import { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';
|
|
5
|
+
import { Subject, auditTime, animationFrameScheduler, debounceTime, filter, observeOn, fromEvent, tap, takeUntil } from 'rxjs';
|
|
8
6
|
|
|
9
7
|
const styleContainer = (config, viewEncapsulation, groupID) => {
|
|
10
8
|
const defaultConfig = [
|
|
@@ -115,6 +113,27 @@ class MoLibsSharedDragDropService {
|
|
|
115
113
|
onDragItemInContainerVirtualScroll = new Subject();
|
|
116
114
|
itemDragInfo;
|
|
117
115
|
container = signal(new Map());
|
|
116
|
+
// Rect cache: cache getBoundingClientRect() tại drag start, tái dùng mỗi mousemove.
|
|
117
|
+
// Gom tất cả reads vào 1 batch/rAF → tránh forced layout thrashing.
|
|
118
|
+
domRectCache = new Map();
|
|
119
|
+
cacheElementRect(element) {
|
|
120
|
+
this.domRectCache.set(element, element.getBoundingClientRect());
|
|
121
|
+
}
|
|
122
|
+
getElementRect(element) {
|
|
123
|
+
return this.domRectCache.get(element);
|
|
124
|
+
}
|
|
125
|
+
invalidateElementRect(element) {
|
|
126
|
+
this.domRectCache.delete(element);
|
|
127
|
+
}
|
|
128
|
+
clearElementRects() {
|
|
129
|
+
this.domRectCache.clear();
|
|
130
|
+
}
|
|
131
|
+
// Rebuild rects CHỈ cho items trong container bị ảnh hưởng (items đã shift vị trí).
|
|
132
|
+
// Được gọi sau cdr.detectChanges() trong handlerDragOver — KHÔNG clear toàn bộ cache.
|
|
133
|
+
rebuildContainerRects(containerElement, classItemDefine) {
|
|
134
|
+
const children = containerElement.getElementsByClassName(classItemDefine);
|
|
135
|
+
Array.from(children).forEach(el => this.domRectCache.set(el, el.getBoundingClientRect()));
|
|
136
|
+
}
|
|
118
137
|
targetItemDragFlag = 'item-drag-target';
|
|
119
138
|
classContainerDefine = 'libs-ui-drag-drop-container';
|
|
120
139
|
classItemDefine = 'libs-ui-drag-drop-item';
|
|
@@ -220,7 +239,8 @@ class LibsUiComponentsDragScrollDirective {
|
|
|
220
239
|
dragDropService = inject(MoLibsSharedDragDropService);
|
|
221
240
|
destroyRef = inject(DestroyRef);
|
|
222
241
|
ngAfterViewInit() {
|
|
223
|
-
|
|
242
|
+
// auditTime(rAF): batch cùng rAF với drag-item subscriptions → không tạo thêm layout flush riêng
|
|
243
|
+
this.dragDropService.OnDragging.pipe(auditTime(0, animationFrameScheduler), takeUntilDestroyed(this.destroyRef)).subscribe((eventDragging) => this.checkAndScrollElementToPosition(eventDragging, this.ignoreAutoScroll()));
|
|
224
244
|
this.dragDropService.OnDragEnd.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
|
225
245
|
clearInterval(this.intervalScrollToElement());
|
|
226
246
|
if (this.virtualScrollPageInfo()) {
|
|
@@ -439,6 +459,8 @@ class LibsUiComponentsDragContainerDirective extends LibsUiComponentsDragScrollD
|
|
|
439
459
|
indexSpliceListTo = indexDragOver;
|
|
440
460
|
this.cdr.detectChanges();
|
|
441
461
|
this.setAttributeElementAndItemDrag(elementContainer, false, indexSpliceListTo);
|
|
462
|
+
// Rebuild CHỈ rects của container này (items shifted), giữ nguyên cache các container khác.
|
|
463
|
+
this.dragDropService.rebuildContainerRects(elementContainer, this.dragDropService.ClassItemDefine);
|
|
442
464
|
}
|
|
443
465
|
return;
|
|
444
466
|
}
|
|
@@ -561,6 +583,8 @@ class LibsUiComponentsDragContainerDirective extends LibsUiComponentsDragScrollD
|
|
|
561
583
|
if (this.disableDragContainer()) {
|
|
562
584
|
return;
|
|
563
585
|
}
|
|
586
|
+
// Clear all remaining rect cache entries on drag end.
|
|
587
|
+
this.dragDropService.clearElementRects();
|
|
564
588
|
let rect = undefined;
|
|
565
589
|
if (this.rootElementScroll() || elementContainer) {
|
|
566
590
|
rect = (this.rootElementScroll() || elementContainer)?.getBoundingClientRect();
|
|
@@ -621,7 +645,9 @@ class LibsUiComponentsDragContainerDirective extends LibsUiComponentsDragScrollD
|
|
|
621
645
|
if (this.groupID() !== elementDrop.getAttribute('groupID') || elementDrag.getAttribute('groupID') === elementDrop.getAttribute('groupID')) {
|
|
622
646
|
return;
|
|
623
647
|
}
|
|
624
|
-
const
|
|
648
|
+
const dropIndex = Number(elementDrop.getAttribute('index')).valueOf();
|
|
649
|
+
const dropContainerOffset = elementDrop.getAttribute('dropContainer') ? 0 : 1;
|
|
650
|
+
const indexDragOver = this.groupID() !== elementDrag.getAttribute('groupID') ? dropIndex : dropIndex - dropContainerOffset;
|
|
625
651
|
const item = this.mode() === 'copy' ? cloneDeep(itemDragInfo?.item) : itemDragInfo?.item;
|
|
626
652
|
if (itemDragInfo) {
|
|
627
653
|
itemDragInfo.indexDrop = indexDragOver;
|
|
@@ -635,7 +661,7 @@ class LibsUiComponentsDragContainerDirective extends LibsUiComponentsDragScrollD
|
|
|
635
661
|
items.splice(indexDragOver, 0, item);
|
|
636
662
|
return [...items];
|
|
637
663
|
});
|
|
638
|
-
if (itemDragInfo
|
|
664
|
+
if (itemDragInfo?.itemsMove?.()) {
|
|
639
665
|
itemDragInfo.itemsDrag.set([...itemDragInfo.itemsMove()]);
|
|
640
666
|
this.setAttributeElementAndItemDrag(elementContainer);
|
|
641
667
|
}
|
|
@@ -644,31 +670,13 @@ class LibsUiComponentsDragContainerDirective extends LibsUiComponentsDragScrollD
|
|
|
644
670
|
this.setIndexElement(elementContainer);
|
|
645
671
|
};
|
|
646
672
|
[
|
|
647
|
-
{
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
},
|
|
652
|
-
{
|
|
653
|
-
|
|
654
|
-
event: this.dragDropService.OnDragOver,
|
|
655
|
-
functionCall: handlerDragOver,
|
|
656
|
-
},
|
|
657
|
-
{
|
|
658
|
-
name: 'OnDragging',
|
|
659
|
-
event: this.dragDropService.OnDragging,
|
|
660
|
-
functionCall: handlerDragging,
|
|
661
|
-
},
|
|
662
|
-
{
|
|
663
|
-
name: 'OnDragEnd',
|
|
664
|
-
event: this.dragDropService.OnDragEnd,
|
|
665
|
-
functionCall: handlerDragEnd,
|
|
666
|
-
},
|
|
667
|
-
{
|
|
668
|
-
name: 'OnDrop',
|
|
669
|
-
event: this.dragDropService.OnDrop,
|
|
670
|
-
functionCall: handlerDrop,
|
|
671
|
-
},
|
|
673
|
+
{ event: this.dragDropService.OnDragStart, functionCall: handlerDragStart },
|
|
674
|
+
{ event: this.dragDropService.OnDragOver, functionCall: handlerDragOver },
|
|
675
|
+
// observeOn(rAF): defer container dragging handler vào rAF context, batch cùng item subscriptions.
|
|
676
|
+
// Không drop event (cần xử lý mọi state change cho placeholder) — khác với auditTime của drag-item.
|
|
677
|
+
{ event: this.dragDropService.OnDragging.pipe(observeOn(animationFrameScheduler)), functionCall: handlerDragging },
|
|
678
|
+
{ event: this.dragDropService.OnDragEnd, functionCall: handlerDragEnd },
|
|
679
|
+
{ event: this.dragDropService.OnDrop, functionCall: handlerDrop },
|
|
672
680
|
].forEach((item) => item.event.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(item.functionCall));
|
|
673
681
|
}
|
|
674
682
|
get FunctionsControl() {
|
|
@@ -787,7 +795,7 @@ class LibsUiComponentsDragContainerDirective extends LibsUiComponentsDragScrollD
|
|
|
787
795
|
return;
|
|
788
796
|
}
|
|
789
797
|
childElement.removeAttribute('index');
|
|
790
|
-
if (!this.dropToGroupName()
|
|
798
|
+
if (!this.dropToGroupName()?.length) {
|
|
791
799
|
childElement.removeAttribute('dropToGroupName');
|
|
792
800
|
}
|
|
793
801
|
if (!this.placeholder()) {
|
|
@@ -926,8 +934,8 @@ class LibsUiDragItemInContainerVirtualScrollDirective {
|
|
|
926
934
|
if (!frames?.length) {
|
|
927
935
|
return;
|
|
928
936
|
}
|
|
929
|
-
for (
|
|
930
|
-
|
|
937
|
+
for (const frame of Array.from(frames)) {
|
|
938
|
+
frame.style.pointerEvents = pointerEvents;
|
|
931
939
|
}
|
|
932
940
|
}
|
|
933
941
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiDragItemInContainerVirtualScrollDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
@@ -993,7 +1001,19 @@ class LibsUiDragItemDirective extends LibsUiDragItemInContainerVirtualScrollDire
|
|
|
993
1001
|
}
|
|
994
1002
|
}
|
|
995
1003
|
element.classList.add(this.dragDropService.ClassItemDefine);
|
|
996
|
-
|
|
1004
|
+
// Tại drag start: cache rect → skip getBoundingClientRect() mỗi mousemove
|
|
1005
|
+
this.dragDropService.OnDragStart.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
|
1006
|
+
this.dragDropService.cacheElementRect(element);
|
|
1007
|
+
});
|
|
1008
|
+
// Dùng destroyRef.onDestroy() thay OnDragEnd subscription:
|
|
1009
|
+
// Virtual scroll destroy directives khi scroll out → OnDragEnd subscription bị unsubscribe
|
|
1010
|
+
// trước khi drag kết thúc → invalidateElementRect không được gọi → stale rect.
|
|
1011
|
+
// destroyRef.onDestroy() luôn chạy khi directive bị destroy, bất kể drag state.
|
|
1012
|
+
this.destroyRef.onDestroy(() => this.dragDropService.invalidateElementRect(element));
|
|
1013
|
+
// auditTime(0, animationFrameScheduler): gom TẤT CẢ item subscriptions vào 1 rAF callback.
|
|
1014
|
+
// Toàn bộ getBoundingClientRect() reads xảy ra trong 1 batch → browser chỉ flush layout 1 lần/frame.
|
|
1015
|
+
// Trailing behavior (dùng event mới nhất) tốt hơn throttleTime leading (event cũ 16ms trước).
|
|
1016
|
+
this.dragDropService.OnDragging.pipe(auditTime(0, animationFrameScheduler), takeUntilDestroyed(this.destroyRef)).subscribe((eventDragging) => {
|
|
997
1017
|
if (this.disable() || element.getAttribute('disableDragContainer') || (this.fieldId() && this.item() && eventDragging.elementDrag.getAttribute('item_id') === get(this.item(), this.fieldId()))) {
|
|
998
1018
|
return;
|
|
999
1019
|
}
|
|
@@ -1004,7 +1024,9 @@ class LibsUiDragItemDirective extends LibsUiDragItemInContainerVirtualScrollDire
|
|
|
1004
1024
|
return;
|
|
1005
1025
|
}
|
|
1006
1026
|
}
|
|
1007
|
-
|
|
1027
|
+
// Dùng cached rect (không gọi getBoundingClientRect() lại); fallback về fresh nếu cache miss
|
|
1028
|
+
const cachedRect = this.dragDropService.getElementRect(element);
|
|
1029
|
+
if (checkMouseOverInContainer(eventDragging.mousePosition, element, cachedRect) && element !== eventDragging.elementDrag && containerById && checkViewInScreen(containerById.element, element, containerById.elementScroll)) {
|
|
1008
1030
|
if (this.isDragOver()) {
|
|
1009
1031
|
return;
|
|
1010
1032
|
}
|
|
@@ -1212,836 +1234,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
1212
1234
|
}]
|
|
1213
1235
|
}], ctorParameters: () => [] });
|
|
1214
1236
|
|
|
1215
|
-
class LibsUiDragDropDemoComponent {
|
|
1216
|
-
// Basic List Items
|
|
1217
|
-
basicItems = ['Task 1', 'Task 2', 'Task 3', 'Task 4', 'Task 5'];
|
|
1218
|
-
// Kanban Board Columns
|
|
1219
|
-
columnsIds = ['todo', 'in-progress', 'done'];
|
|
1220
|
-
columns = [
|
|
1221
|
-
{
|
|
1222
|
-
id: 'todo',
|
|
1223
|
-
title: 'To Do',
|
|
1224
|
-
items: [
|
|
1225
|
-
{
|
|
1226
|
-
id: 1,
|
|
1227
|
-
title: 'Implement drag and drop',
|
|
1228
|
-
description: 'Add drag and drop functionality to the component',
|
|
1229
|
-
status: 'todo',
|
|
1230
|
-
},
|
|
1231
|
-
{
|
|
1232
|
-
id: 2,
|
|
1233
|
-
title: 'Add animations',
|
|
1234
|
-
description: 'Implement smooth animations for drag and drop',
|
|
1235
|
-
status: 'todo',
|
|
1236
|
-
},
|
|
1237
|
-
],
|
|
1238
|
-
},
|
|
1239
|
-
{
|
|
1240
|
-
id: 'in-progress',
|
|
1241
|
-
title: 'In Progress',
|
|
1242
|
-
items: [
|
|
1243
|
-
{
|
|
1244
|
-
id: 3,
|
|
1245
|
-
title: 'Fix styling issues',
|
|
1246
|
-
description: 'Resolve CSS conflicts in the component',
|
|
1247
|
-
status: 'in-progress',
|
|
1248
|
-
},
|
|
1249
|
-
],
|
|
1250
|
-
},
|
|
1251
|
-
{
|
|
1252
|
-
id: 'done',
|
|
1253
|
-
title: 'Done',
|
|
1254
|
-
items: [
|
|
1255
|
-
{
|
|
1256
|
-
id: 4,
|
|
1257
|
-
title: 'Setup project structure',
|
|
1258
|
-
description: 'Initialize the project with necessary configurations',
|
|
1259
|
-
status: 'done',
|
|
1260
|
-
},
|
|
1261
|
-
],
|
|
1262
|
-
},
|
|
1263
|
-
];
|
|
1264
|
-
// Nested Items
|
|
1265
|
-
nestedItems = [
|
|
1266
|
-
{
|
|
1267
|
-
id: 1,
|
|
1268
|
-
title: 'Project A',
|
|
1269
|
-
subItems: ['Task 1', 'Task 2', 'Task 3'],
|
|
1270
|
-
},
|
|
1271
|
-
{
|
|
1272
|
-
id: 2,
|
|
1273
|
-
title: 'Project B',
|
|
1274
|
-
subItems: ['Task 4', 'Task 5'],
|
|
1275
|
-
},
|
|
1276
|
-
{
|
|
1277
|
-
id: 3,
|
|
1278
|
-
title: 'Project C',
|
|
1279
|
-
subItems: ['Task 6', 'Task 7', 'Task 8'],
|
|
1280
|
-
},
|
|
1281
|
-
];
|
|
1282
|
-
// API Documentation
|
|
1283
|
-
inputsDoc = [
|
|
1284
|
-
{
|
|
1285
|
-
name: 'items',
|
|
1286
|
-
type: 'Array<unknown>',
|
|
1287
|
-
default: '[]',
|
|
1288
|
-
description: 'Array of items to be displayed in the container',
|
|
1289
|
-
},
|
|
1290
|
-
{
|
|
1291
|
-
name: 'mode',
|
|
1292
|
-
type: "'move' | 'copy' | 'deepCopy'",
|
|
1293
|
-
default: "'move'",
|
|
1294
|
-
description: 'Mode for drag and drop operations',
|
|
1295
|
-
},
|
|
1296
|
-
{
|
|
1297
|
-
name: 'directionDrag',
|
|
1298
|
-
type: "'horizontal' | 'vertical'",
|
|
1299
|
-
default: 'undefined',
|
|
1300
|
-
description: 'Direction of drag movement',
|
|
1301
|
-
},
|
|
1302
|
-
{
|
|
1303
|
-
name: 'viewEncapsulation',
|
|
1304
|
-
type: "'emulated' | 'none'",
|
|
1305
|
-
default: "'emulated'",
|
|
1306
|
-
description: 'View encapsulation mode for styling',
|
|
1307
|
-
},
|
|
1308
|
-
{
|
|
1309
|
-
name: 'disableDragContainer',
|
|
1310
|
-
type: 'boolean',
|
|
1311
|
-
default: 'undefined',
|
|
1312
|
-
description: 'Whether to disable drag operations for the container',
|
|
1313
|
-
},
|
|
1314
|
-
{
|
|
1315
|
-
name: 'acceptDragSameGroup',
|
|
1316
|
-
type: 'boolean',
|
|
1317
|
-
default: 'false',
|
|
1318
|
-
description: 'Whether to accept drag operations within the same group',
|
|
1319
|
-
},
|
|
1320
|
-
{
|
|
1321
|
-
name: 'placeholder',
|
|
1322
|
-
type: 'boolean',
|
|
1323
|
-
default: 'true',
|
|
1324
|
-
description: 'Whether to show placeholder during drag',
|
|
1325
|
-
},
|
|
1326
|
-
{
|
|
1327
|
-
name: 'groupName',
|
|
1328
|
-
type: 'string',
|
|
1329
|
-
default: "'groupDragAndDropDefault'",
|
|
1330
|
-
description: 'Name of the group for drag and drop operations',
|
|
1331
|
-
},
|
|
1332
|
-
{
|
|
1333
|
-
name: 'dropToGroupName',
|
|
1334
|
-
type: 'Array<string> | null',
|
|
1335
|
-
default: 'null',
|
|
1336
|
-
description: 'List of group names that can accept drops from this container',
|
|
1337
|
-
},
|
|
1338
|
-
{
|
|
1339
|
-
name: 'stylesOverride',
|
|
1340
|
-
type: 'Array<{ className: string, styles: string }>',
|
|
1341
|
-
default: 'undefined',
|
|
1342
|
-
description: 'Custom styles to override default drag-drop styling',
|
|
1343
|
-
},
|
|
1344
|
-
];
|
|
1345
|
-
outputsDoc = [
|
|
1346
|
-
{
|
|
1347
|
-
name: 'outDragStartContainer',
|
|
1348
|
-
type: 'IDragStart',
|
|
1349
|
-
description: 'Event emitted when dragging starts in the container',
|
|
1350
|
-
},
|
|
1351
|
-
{
|
|
1352
|
-
name: 'outDragOverContainer',
|
|
1353
|
-
type: 'IDragOver',
|
|
1354
|
-
description: 'Event emitted when dragging over the container',
|
|
1355
|
-
},
|
|
1356
|
-
{
|
|
1357
|
-
name: 'outDragLeaveContainer',
|
|
1358
|
-
type: 'IDragLeave',
|
|
1359
|
-
description: 'Event emitted when dragging leaves the container',
|
|
1360
|
-
},
|
|
1361
|
-
{
|
|
1362
|
-
name: 'outDragEndContainer',
|
|
1363
|
-
type: 'IDragEnd',
|
|
1364
|
-
description: 'Event emitted when dragging ends in the container',
|
|
1365
|
-
},
|
|
1366
|
-
{
|
|
1367
|
-
name: 'outDroppedContainer',
|
|
1368
|
-
type: 'IDrop',
|
|
1369
|
-
description: 'Event emitted when an item is dropped in the container',
|
|
1370
|
-
},
|
|
1371
|
-
{
|
|
1372
|
-
name: 'outDroppedContainerEmpty',
|
|
1373
|
-
type: 'IDrop',
|
|
1374
|
-
description: 'Event emitted when an item is dropped in an empty container',
|
|
1375
|
-
},
|
|
1376
|
-
{
|
|
1377
|
-
name: 'outFunctionControl',
|
|
1378
|
-
type: 'IDragDropFunctionControlEvent',
|
|
1379
|
-
description: 'Event emitted to control drag-drop functionality',
|
|
1380
|
-
},
|
|
1381
|
-
];
|
|
1382
|
-
// Interface Documentation
|
|
1383
|
-
interfacesDoc = [
|
|
1384
|
-
{
|
|
1385
|
-
name: 'IDragging',
|
|
1386
|
-
code: `interface IDragging {
|
|
1387
|
-
mousePosition: IMousePosition;
|
|
1388
|
-
elementDrag: HTMLElement;
|
|
1389
|
-
elementKeepContainer?: boolean;
|
|
1390
|
-
itemDragInfo?: IItemDragInfo;
|
|
1391
|
-
}`,
|
|
1392
|
-
description: 'Interface for drag operation events, containing information about the dragged element and mouse position',
|
|
1393
|
-
},
|
|
1394
|
-
{
|
|
1395
|
-
name: 'IDragStart',
|
|
1396
|
-
code: `interface IDragStart {
|
|
1397
|
-
mousePosition: IMousePosition;
|
|
1398
|
-
elementDrag: HTMLElement;
|
|
1399
|
-
itemDragInfo?: IItemDragInfo;
|
|
1400
|
-
}`,
|
|
1401
|
-
description: 'Interface for drag start events, triggered when dragging begins',
|
|
1402
|
-
},
|
|
1403
|
-
{
|
|
1404
|
-
name: 'IDragOver',
|
|
1405
|
-
code: `interface IDragOver {
|
|
1406
|
-
mousePosition: IMousePosition;
|
|
1407
|
-
elementDrag: HTMLElement;
|
|
1408
|
-
elementDragOver: HTMLElement;
|
|
1409
|
-
itemDragInfo?: IItemDragInfo;
|
|
1410
|
-
}`,
|
|
1411
|
-
description: 'Interface for drag over events, triggered when an element is dragged over another element',
|
|
1412
|
-
},
|
|
1413
|
-
{
|
|
1414
|
-
name: 'IDragLeave',
|
|
1415
|
-
code: `interface IDragLeave {
|
|
1416
|
-
elementDrag: HTMLElement;
|
|
1417
|
-
elementDragLeave: HTMLElement;
|
|
1418
|
-
itemDragInfo?: IItemDragInfo;
|
|
1419
|
-
}`,
|
|
1420
|
-
description: 'Interface for drag leave events, triggered when a dragged element leaves another element',
|
|
1421
|
-
},
|
|
1422
|
-
{
|
|
1423
|
-
name: 'IDragEnd',
|
|
1424
|
-
code: `interface IDragEnd {
|
|
1425
|
-
mousePosition: IMousePosition;
|
|
1426
|
-
elementDrag: HTMLElement;
|
|
1427
|
-
itemDragInfo?: IItemDragInfo;
|
|
1428
|
-
}`,
|
|
1429
|
-
description: 'Interface for drag end events, triggered when dragging ends',
|
|
1430
|
-
},
|
|
1431
|
-
{
|
|
1432
|
-
name: 'IDrop',
|
|
1433
|
-
code: `interface IDrop {
|
|
1434
|
-
elementDrag: HTMLElement;
|
|
1435
|
-
elementDrop: HTMLElement;
|
|
1436
|
-
itemDragInfo?: IItemDragInfo;
|
|
1437
|
-
}`,
|
|
1438
|
-
description: 'Interface for drop events, triggered when an element is dropped',
|
|
1439
|
-
},
|
|
1440
|
-
{
|
|
1441
|
-
name: 'IItemDragInfo',
|
|
1442
|
-
code: `interface IItemDragInfo {
|
|
1443
|
-
item: object;
|
|
1444
|
-
itemsMove?: WritableSignal<Array<unknown>>;
|
|
1445
|
-
indexDrag?: number;
|
|
1446
|
-
indexDrop?: number;
|
|
1447
|
-
itemsDrag: WritableSignal<Array<unknown>>;
|
|
1448
|
-
itemsDrop?: WritableSignal<Array<unknown>>;
|
|
1449
|
-
containerDrag?: HTMLElement;
|
|
1450
|
-
containerDrop?: HTMLElement;
|
|
1451
|
-
}`,
|
|
1452
|
-
description: 'Interface containing information about the dragged item and its containers',
|
|
1453
|
-
},
|
|
1454
|
-
{
|
|
1455
|
-
name: 'IDragItemInContainerVirtualScroll',
|
|
1456
|
-
code: `interface IDragItemInContainerVirtualScroll {
|
|
1457
|
-
itemDragInfo?: IItemDragInfo;
|
|
1458
|
-
elementDrag: HTMLElement;
|
|
1459
|
-
distanceStartElementAndMouseTop: number;
|
|
1460
|
-
distanceStartElementAndMouseLeft: number;
|
|
1461
|
-
elementContainer?: HTMLElement;
|
|
1462
|
-
dragBoundary?: boolean;
|
|
1463
|
-
dragBoundaryAcceptMouseLeaveContainer?: boolean;
|
|
1464
|
-
ignoreStopEvent?: boolean;
|
|
1465
|
-
}`,
|
|
1466
|
-
description: 'Interface for virtual scrolling drag operations, containing information about drag boundaries and container elements',
|
|
1467
|
-
},
|
|
1468
|
-
{
|
|
1469
|
-
name: 'IMousePosition',
|
|
1470
|
-
code: `interface IMousePosition {
|
|
1471
|
-
clientX: number;
|
|
1472
|
-
clientY: number;
|
|
1473
|
-
}`,
|
|
1474
|
-
description: 'Interface representing mouse position coordinates',
|
|
1475
|
-
},
|
|
1476
|
-
{
|
|
1477
|
-
name: 'IDragDropFunctionControlEvent',
|
|
1478
|
-
code: `interface IDragDropFunctionControlEvent {
|
|
1479
|
-
setAttributeElementAndItemDrag: () => Promise<void>;
|
|
1480
|
-
}`,
|
|
1481
|
-
description: 'Interface for drag and drop control functions',
|
|
1482
|
-
},
|
|
1483
|
-
];
|
|
1484
|
-
// Features
|
|
1485
|
-
features = [
|
|
1486
|
-
{
|
|
1487
|
-
id: 1,
|
|
1488
|
-
icon: '🔄',
|
|
1489
|
-
title: 'Flexible Drag and Drop',
|
|
1490
|
-
description: 'Support for container-to-container dragging with customizable group names and drop zones',
|
|
1491
|
-
},
|
|
1492
|
-
{
|
|
1493
|
-
id: 2,
|
|
1494
|
-
icon: '📜',
|
|
1495
|
-
title: 'Virtual Scrolling',
|
|
1496
|
-
description: 'Efficient handling of large lists with virtual scrolling support',
|
|
1497
|
-
},
|
|
1498
|
-
{
|
|
1499
|
-
id: 3,
|
|
1500
|
-
icon: '🎯',
|
|
1501
|
-
title: 'Custom Boundaries',
|
|
1502
|
-
description: 'Define custom drag boundaries and drop zones for precise control',
|
|
1503
|
-
},
|
|
1504
|
-
{
|
|
1505
|
-
id: 4,
|
|
1506
|
-
icon: '🎨',
|
|
1507
|
-
title: 'Styling Options',
|
|
1508
|
-
description: 'Customizable styles for drag items and containers',
|
|
1509
|
-
},
|
|
1510
|
-
];
|
|
1511
|
-
// Code Examples
|
|
1512
|
-
codeExamples = [
|
|
1513
|
-
{
|
|
1514
|
-
id: 1,
|
|
1515
|
-
title: 'Basic Usage',
|
|
1516
|
-
code: `<div LibsUiComponentsDragContainerDirective
|
|
1517
|
-
[(items)]="items"
|
|
1518
|
-
[groupName]="'myGroup'"
|
|
1519
|
-
[acceptDragSameGroup]="true">
|
|
1520
|
-
@for (item of items; track item) {
|
|
1521
|
-
<div LibsUiDragItemDirective>
|
|
1522
|
-
{{ item }}
|
|
1523
|
-
</div>
|
|
1524
|
-
}
|
|
1525
|
-
</div>`,
|
|
1526
|
-
},
|
|
1527
|
-
{
|
|
1528
|
-
id: 2,
|
|
1529
|
-
title: 'Container-to-Container',
|
|
1530
|
-
code: `<div LibsUiComponentsDragContainerDirective
|
|
1531
|
-
[(items)]="sourceItems"
|
|
1532
|
-
[groupName]="'source'">
|
|
1533
|
-
@for (item of sourceItems; track item) {
|
|
1534
|
-
<div LibsUiDragItemDirective>
|
|
1535
|
-
{{ item }}
|
|
1536
|
-
</div>
|
|
1537
|
-
}
|
|
1538
|
-
</div>
|
|
1539
|
-
|
|
1540
|
-
<div LibsUiComponentsDragContainerDirective
|
|
1541
|
-
[(items)]="targetItems"
|
|
1542
|
-
[groupName]="'target'"
|
|
1543
|
-
[dropToGroupName]="['source']">
|
|
1544
|
-
@for (item of targetItems; track item) {
|
|
1545
|
-
<div LibsUiDragItemDirective>
|
|
1546
|
-
{{ item }}
|
|
1547
|
-
</div>
|
|
1548
|
-
}
|
|
1549
|
-
</div>`,
|
|
1550
|
-
},
|
|
1551
|
-
];
|
|
1552
|
-
/**
|
|
1553
|
-
* Copy text to clipboard
|
|
1554
|
-
*/
|
|
1555
|
-
copyToClipboard(text) {
|
|
1556
|
-
navigator.clipboard.writeText(text).then(() => {
|
|
1557
|
-
alert('Copied to clipboard');
|
|
1558
|
-
}, (err) => {
|
|
1559
|
-
console.error('Could not copy text: ', err);
|
|
1560
|
-
});
|
|
1561
|
-
}
|
|
1562
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiDragDropDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1563
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LibsUiDragDropDemoComponent, isStandalone: true, selector: "lib-drag-drop-demo", ngImport: i0, template: `
|
|
1564
|
-
<div class="page-container">
|
|
1565
|
-
<header>
|
|
1566
|
-
<h1>Demo Drag and Drop Component</h1>
|
|
1567
|
-
<p>Angular component library for drag and drop functionality</p>
|
|
1568
|
-
</header>
|
|
1569
|
-
|
|
1570
|
-
<main>
|
|
1571
|
-
<section class="intro-section">
|
|
1572
|
-
<h2>Introduction</h2>
|
|
1573
|
-
<p>
|
|
1574
|
-
<code>@libs-ui/components-drag-drop</code>
|
|
1575
|
-
is a powerful Angular component that enables drag and drop functionality with features like virtual scrolling, multi-selection, and custom boundaries.
|
|
1576
|
-
</p>
|
|
1577
|
-
</section>
|
|
1578
|
-
|
|
1579
|
-
<section class="installation-section">
|
|
1580
|
-
<h2>Installation</h2>
|
|
1581
|
-
<p>To install the library, use npm or yarn:</p>
|
|
1582
|
-
|
|
1583
|
-
<div class="install-command">
|
|
1584
|
-
<pre>
|
|
1585
|
-
<code>npm install @libs-ui/components-drag-drop</code>
|
|
1586
|
-
<libs_ui-components-buttons-button
|
|
1587
|
-
[label]="'Copy'"
|
|
1588
|
-
(outClick)="copyToClipboard('npm install @libs-ui/components-drag-drop')" />
|
|
1589
|
-
</pre>
|
|
1590
|
-
</div>
|
|
1591
|
-
|
|
1592
|
-
<p>Or with yarn:</p>
|
|
1593
|
-
|
|
1594
|
-
<div class="install-command">
|
|
1595
|
-
<pre>
|
|
1596
|
-
<code>yarn add @libs-ui/components-drag-drop</code>
|
|
1597
|
-
<libs_ui-components-buttons-button
|
|
1598
|
-
[label]="'Copy'"
|
|
1599
|
-
(outClick)="copyToClipboard('yarn add @libs-ui/components-drag-drop')" />
|
|
1600
|
-
</pre>
|
|
1601
|
-
</div>
|
|
1602
|
-
</section>
|
|
1603
|
-
|
|
1604
|
-
<section class="demo-section">
|
|
1605
|
-
<h2>Live Demo</h2>
|
|
1606
|
-
<div class="demo-container">
|
|
1607
|
-
<!-- Basic List Demo -->
|
|
1608
|
-
<div class="demo-example">
|
|
1609
|
-
<h3>Basic List</h3>
|
|
1610
|
-
<div class="list-container">
|
|
1611
|
-
<div
|
|
1612
|
-
LibsUiComponentsDragContainerDirective
|
|
1613
|
-
[(items)]="basicItems"
|
|
1614
|
-
[acceptDragSameGroup]="true">
|
|
1615
|
-
@for (item of basicItems; track item) {
|
|
1616
|
-
<div
|
|
1617
|
-
class="list-item"
|
|
1618
|
-
LibsUiDragItemDirective>
|
|
1619
|
-
<span class="item-icon">📋</span>
|
|
1620
|
-
<span class="item-text">{{ item }}</span>
|
|
1621
|
-
</div>
|
|
1622
|
-
}
|
|
1623
|
-
</div>
|
|
1624
|
-
</div>
|
|
1625
|
-
</div>
|
|
1626
|
-
|
|
1627
|
-
<!-- Kanban Board Demo -->
|
|
1628
|
-
<div class="demo-example">
|
|
1629
|
-
<h3>Kanban Board</h3>
|
|
1630
|
-
<div class="kanban-board">
|
|
1631
|
-
@for (column of columns; track column) {
|
|
1632
|
-
<div
|
|
1633
|
-
class="kanban-column"
|
|
1634
|
-
LibsUiComponentsDragContainerDirective
|
|
1635
|
-
[(items)]="column.items"
|
|
1636
|
-
[groupName]="column.id"
|
|
1637
|
-
[dropToGroupName]="columnsIds"
|
|
1638
|
-
[acceptDragSameGroup]="true">
|
|
1639
|
-
<h4>{{ column.title }}</h4>
|
|
1640
|
-
@for (item of column.items; track item) {
|
|
1641
|
-
<div
|
|
1642
|
-
class="kanban-item"
|
|
1643
|
-
LibsUiDragItemDirective>
|
|
1644
|
-
<div class="kanban-item-header">
|
|
1645
|
-
<span class="item-title">{{ item.title }}</span>
|
|
1646
|
-
<span
|
|
1647
|
-
class="item-status"
|
|
1648
|
-
[class]="'status-' + item.status">
|
|
1649
|
-
{{ item.status }}
|
|
1650
|
-
</span>
|
|
1651
|
-
</div>
|
|
1652
|
-
<p class="item-description">{{ item.description }}</p>
|
|
1653
|
-
</div>
|
|
1654
|
-
}
|
|
1655
|
-
</div>
|
|
1656
|
-
}
|
|
1657
|
-
</div>
|
|
1658
|
-
</div>
|
|
1659
|
-
|
|
1660
|
-
<!-- Nested Containers Demo -->
|
|
1661
|
-
<div class="demo-example">
|
|
1662
|
-
<h3>Nested Containers copy</h3>
|
|
1663
|
-
<div class="nested-container">
|
|
1664
|
-
<div
|
|
1665
|
-
LibsUiComponentsDragContainerDirective
|
|
1666
|
-
[(items)]="nestedItems"
|
|
1667
|
-
[groupName]="'parent'"
|
|
1668
|
-
[mode]="'copy'"
|
|
1669
|
-
[acceptDragSameGroup]="true">
|
|
1670
|
-
@for (item of nestedItems; track item) {
|
|
1671
|
-
<div
|
|
1672
|
-
class="nested-item"
|
|
1673
|
-
LibsUiDragItemDirective>
|
|
1674
|
-
<div class="nested-item-header">
|
|
1675
|
-
<span class="item-title">{{ item.title }}</span>
|
|
1676
|
-
</div>
|
|
1677
|
-
<div class="nested-item-content">
|
|
1678
|
-
<div
|
|
1679
|
-
LibsUiComponentsDragContainerDirective
|
|
1680
|
-
[(items)]="item.subItems"
|
|
1681
|
-
[groupName]="'child'"
|
|
1682
|
-
[acceptDragSameGroup]="true">
|
|
1683
|
-
@for (subItem of item.subItems; track subItem) {
|
|
1684
|
-
<div
|
|
1685
|
-
class="sub-item"
|
|
1686
|
-
LibsUiDragItemDirective>
|
|
1687
|
-
{{ subItem }}
|
|
1688
|
-
</div>
|
|
1689
|
-
}
|
|
1690
|
-
</div>
|
|
1691
|
-
</div>
|
|
1692
|
-
</div>
|
|
1693
|
-
}
|
|
1694
|
-
</div>
|
|
1695
|
-
</div>
|
|
1696
|
-
</div>
|
|
1697
|
-
</div>
|
|
1698
|
-
</section>
|
|
1699
|
-
|
|
1700
|
-
<section class="api-doc-section">
|
|
1701
|
-
<h2>API Documentation</h2>
|
|
1702
|
-
|
|
1703
|
-
<h3>Inputs</h3>
|
|
1704
|
-
<div class="table-container">
|
|
1705
|
-
<table class="api-table">
|
|
1706
|
-
<thead>
|
|
1707
|
-
<tr>
|
|
1708
|
-
<th>Name</th>
|
|
1709
|
-
<th>Type</th>
|
|
1710
|
-
<th>Default</th>
|
|
1711
|
-
<th>Description</th>
|
|
1712
|
-
</tr>
|
|
1713
|
-
</thead>
|
|
1714
|
-
<tbody>
|
|
1715
|
-
@for (input of inputsDoc; track input.name) {
|
|
1716
|
-
<tr>
|
|
1717
|
-
<td>
|
|
1718
|
-
<code>{{ input.name }}</code>
|
|
1719
|
-
</td>
|
|
1720
|
-
<td>
|
|
1721
|
-
<code>{{ input.type }}</code>
|
|
1722
|
-
</td>
|
|
1723
|
-
<td>{{ input.default }}</td>
|
|
1724
|
-
<td>{{ input.description }}</td>
|
|
1725
|
-
</tr>
|
|
1726
|
-
}
|
|
1727
|
-
</tbody>
|
|
1728
|
-
</table>
|
|
1729
|
-
</div>
|
|
1730
|
-
|
|
1731
|
-
<h3>Outputs</h3>
|
|
1732
|
-
<div class="table-container">
|
|
1733
|
-
<table class="api-table">
|
|
1734
|
-
<thead>
|
|
1735
|
-
<tr>
|
|
1736
|
-
<th>Name</th>
|
|
1737
|
-
<th>Type</th>
|
|
1738
|
-
<th>Description</th>
|
|
1739
|
-
</tr>
|
|
1740
|
-
</thead>
|
|
1741
|
-
<tbody>
|
|
1742
|
-
@for (output of outputsDoc; track output.name) {
|
|
1743
|
-
<tr>
|
|
1744
|
-
<td>
|
|
1745
|
-
<code>{{ output.name }}</code>
|
|
1746
|
-
</td>
|
|
1747
|
-
<td>
|
|
1748
|
-
<code>{{ output.type }}</code>
|
|
1749
|
-
</td>
|
|
1750
|
-
<td>{{ output.description }}</td>
|
|
1751
|
-
</tr>
|
|
1752
|
-
}
|
|
1753
|
-
</tbody>
|
|
1754
|
-
</table>
|
|
1755
|
-
</div>
|
|
1756
|
-
</section>
|
|
1757
|
-
|
|
1758
|
-
<section class="interfaces-section">
|
|
1759
|
-
<h2>Interfaces</h2>
|
|
1760
|
-
<div class="interface-docs">
|
|
1761
|
-
@for (interfaceItem of interfacesDoc; track interfaceItem.name) {
|
|
1762
|
-
<div class="interface-item">
|
|
1763
|
-
<h3>{{ interfaceItem.name }}</h3>
|
|
1764
|
-
<pre><code>{{interfaceItem.code}}</code></pre>
|
|
1765
|
-
<p>{{ interfaceItem.description }}</p>
|
|
1766
|
-
</div>
|
|
1767
|
-
}
|
|
1768
|
-
</div>
|
|
1769
|
-
</section>
|
|
1770
|
-
|
|
1771
|
-
<section class="features-section">
|
|
1772
|
-
<h2>Features</h2>
|
|
1773
|
-
<ul>
|
|
1774
|
-
@for (feature of features; track feature.id) {
|
|
1775
|
-
<li>
|
|
1776
|
-
<span class="feature-icon">{{ feature.icon }}</span>
|
|
1777
|
-
<div class="feature-info">
|
|
1778
|
-
<h3>{{ feature.title }}</h3>
|
|
1779
|
-
<p>{{ feature.description }}</p>
|
|
1780
|
-
</div>
|
|
1781
|
-
</li>
|
|
1782
|
-
}
|
|
1783
|
-
</ul>
|
|
1784
|
-
</section>
|
|
1785
|
-
|
|
1786
|
-
<section class="usage-section">
|
|
1787
|
-
<h2>Usage</h2>
|
|
1788
|
-
<div class="code-examples">
|
|
1789
|
-
@for (example of codeExamples; track example.id) {
|
|
1790
|
-
<div class="code-example">
|
|
1791
|
-
<h3>{{ example.title }}</h3>
|
|
1792
|
-
<pre><code [innerHTML]="example.code"></code></pre>
|
|
1793
|
-
</div>
|
|
1794
|
-
}
|
|
1795
|
-
</div>
|
|
1796
|
-
</section>
|
|
1797
|
-
</main>
|
|
1798
|
-
</div>
|
|
1799
|
-
`, isInline: true, styles: [".page-container{max-width:1200px;margin:0 auto;padding:20px;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif;line-height:1.6;color:#333}header{text-align:center;padding:40px 0;background-color:#fff;border-radius:8px;margin-bottom:30px;box-shadow:0 2px 5px #0000001a}header h1{font-size:2.5rem;color:#2c3e50;margin-bottom:10px}header p{font-size:1.2rem;color:#7f8c8d}section{background-color:#fff;border-radius:8px;padding:30px;margin-bottom:30px;box-shadow:0 2px 5px #0000001a}h2{font-size:1.8rem;color:#2c3e50;margin-bottom:20px;padding-bottom:10px;border-bottom:2px solid #ecf0f1}h3{font-size:1.4rem;color:#34495e;margin-bottom:15px}h4{font-size:1.2rem;color:#34495e;margin-bottom:10px}p{margin-bottom:15px}code{font-family:Courier New,Courier,monospace;background-color:#f7f7f7;padding:2px 5px;border-radius:3px;font-size:.9em}pre{background-color:#f7f7f7;padding:15px;border-radius:5px;overflow-x:auto;margin-bottom:20px;display:flex;align-items:center;justify-content:space-between}pre code{background-color:transparent;padding:0}.installation-section .install-command{position:relative;margin-bottom:20px}.installation-section .copy-button{position:absolute;top:10px;right:10px;background:#3498db;color:#fff;border:none;border-radius:4px;padding:5px 10px;font-size:.9rem;cursor:pointer;transition:background .2s}.installation-section .copy-button:hover{background:#2980b9}.demo-container{display:grid;grid-template-columns:1fr;gap:30px}.demo-example{background:#f7f7f7;padding:20px;border-radius:8px;margin-bottom:20px}.list-container{max-width:400px;margin:20px auto}.list-item{padding:12px;margin:8px 0;background:#fff;border:1px solid #e0e0e0;border-radius:6px;display:flex;align-items:center;transition:transform .2s,box-shadow .2s}.list-item:hover{transform:translateY(-2px);box-shadow:0 4px 8px #0000001a}.item-icon{margin-right:12px;font-size:1.2em}.kanban-board{display:flex;gap:20px;padding:20px;overflow-x:auto}.kanban-column{flex:1;min-width:300px;background:#f5f5f5;padding:15px;border-radius:8px}.kanban-item{background:#fff;padding:12px;margin:8px 0;border-radius:6px;box-shadow:0 1px 3px #0000001a}.kanban-item-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.item-title{font-weight:500}.item-status{padding:4px 8px;border-radius:4px;font-size:.8em}.status-todo{background:#ffebee;color:#c62828}.status-in-progress{background:#fff3e0;color:#ef6c00}.status-done{background:#e8f5e9;color:#2e7d32}.item-description{font-size:.9em;color:#666}.nested-container{max-width:800px;margin:0 auto}.nested-item{background:#fff;border:1px solid #e0e0e0;border-radius:8px;margin:12px 0;overflow:hidden}.nested-item-header{padding:12px;background:#f5f5f5;border-bottom:1px solid #e0e0e0}.nested-item-content{padding:12px}.sub-item{padding:8px;margin:4px 0;background:#f9f9f9;border:1px solid #e0e0e0;border-radius:4px}.api-doc-section{margin-bottom:40px}.table-container{overflow-x:auto;margin-bottom:30px}.api-table{width:100%;border-collapse:collapse;margin-bottom:20px}.api-table th,.api-table td{padding:12px 15px;text-align:left;border-bottom:1px solid #e1e1e1}.api-table th{background-color:#f5f5f5;font-weight:700}.api-table tbody tr:hover{background-color:#f9f9f9}.features-section ul{list-style:none}.features-section li{display:flex;margin-bottom:25px;align-items:flex-start}.feature-icon{font-size:2rem;margin-right:20px;min-width:40px;text-align:center}.feature-info{flex:1}.code-examples{display:grid;grid-template-columns:1fr;gap:20px}@media (min-width: 768px){.code-examples{grid-template-columns:repeat(2,1fr)}}@media (min-width: 992px){.code-examples{grid-template-columns:repeat(3,1fr)}}.code-example{border:1px solid #ecf0f1;border-radius:5px;padding:15px}@media (max-width: 768px){header{padding:30px 0}header h1{font-size:2rem}section{padding:20px}.kanban-board{flex-direction:column}.kanban-column{min-width:100%}.feature-icon{font-size:1.5rem;margin-right:15px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: LibsUiComponentsDragContainerDirective, selector: "[LibsUiComponentsDragContainerDirective]", inputs: ["disableDragContainer", "mode", "directionDrag", "viewEncapsulation", "acceptDragSameGroup", "placeholder", "groupName", "dropToGroupName", "items", "stylesOverride"], outputs: ["itemsChange", "outDragStartContainer", "outDragOverContainer", "outDragLeaveContainer", "outDragEndContainer", "outDroppedContainer", "outDroppedContainerEmpty", "outFunctionControl"] }, { kind: "directive", type: LibsUiDragItemDirective, selector: "[LibsUiDragItemDirective]", inputs: ["fieldId", "item", "itemInContainerVirtualScroll", "throttleTimeHandlerDraggingEvent", "ignoreStopEvent", "onlyMouseDownStopEvent", "dragRootElement", "dragBoundary", "dragBoundaryAcceptMouseLeaveContainer", "elementContainer", "zIndex", "disable", "ignoreUserSelectNone"], outputs: ["outDragStart", "outDragOver", "outDragLeave", "outDragEnd", "outDropped"] }, { kind: "component", type: LibsUiComponentsButtonsButtonComponent, selector: "libs_ui-components-buttons-button", inputs: ["flagMouse", "type", "buttonCustom", "sizeButton", "label", "disable", "isPending", "imageLeft", "classInclude", "classIconLeft", "classIconRight", "classLabel", "iconOnlyType", "popover", "ignoreStopPropagationEvent", "zIndex", "widthLabelPopover", "styleIconLeft", "styleButton", "ignoreFocusWhenInputTab", "ignoreSetClickWhenShowPopover", "ignorePointerEvent", "isActive", "isHandlerEnterDocumentClickButton"], outputs: ["outClick", "outPopoverEvent", "outFunctionsControl"] }] });
|
|
1800
|
-
}
|
|
1801
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiDragDropDemoComponent, decorators: [{
|
|
1802
|
-
type: Component,
|
|
1803
|
-
args: [{ selector: 'lib-drag-drop-demo', standalone: true, imports: [CommonModule, LibsUiComponentsDragContainerDirective, LibsUiDragItemDirective, LibsUiComponentsButtonsButtonComponent], template: `
|
|
1804
|
-
<div class="page-container">
|
|
1805
|
-
<header>
|
|
1806
|
-
<h1>Demo Drag and Drop Component</h1>
|
|
1807
|
-
<p>Angular component library for drag and drop functionality</p>
|
|
1808
|
-
</header>
|
|
1809
|
-
|
|
1810
|
-
<main>
|
|
1811
|
-
<section class="intro-section">
|
|
1812
|
-
<h2>Introduction</h2>
|
|
1813
|
-
<p>
|
|
1814
|
-
<code>@libs-ui/components-drag-drop</code>
|
|
1815
|
-
is a powerful Angular component that enables drag and drop functionality with features like virtual scrolling, multi-selection, and custom boundaries.
|
|
1816
|
-
</p>
|
|
1817
|
-
</section>
|
|
1818
|
-
|
|
1819
|
-
<section class="installation-section">
|
|
1820
|
-
<h2>Installation</h2>
|
|
1821
|
-
<p>To install the library, use npm or yarn:</p>
|
|
1822
|
-
|
|
1823
|
-
<div class="install-command">
|
|
1824
|
-
<pre>
|
|
1825
|
-
<code>npm install @libs-ui/components-drag-drop</code>
|
|
1826
|
-
<libs_ui-components-buttons-button
|
|
1827
|
-
[label]="'Copy'"
|
|
1828
|
-
(outClick)="copyToClipboard('npm install @libs-ui/components-drag-drop')" />
|
|
1829
|
-
</pre>
|
|
1830
|
-
</div>
|
|
1831
|
-
|
|
1832
|
-
<p>Or with yarn:</p>
|
|
1833
|
-
|
|
1834
|
-
<div class="install-command">
|
|
1835
|
-
<pre>
|
|
1836
|
-
<code>yarn add @libs-ui/components-drag-drop</code>
|
|
1837
|
-
<libs_ui-components-buttons-button
|
|
1838
|
-
[label]="'Copy'"
|
|
1839
|
-
(outClick)="copyToClipboard('yarn add @libs-ui/components-drag-drop')" />
|
|
1840
|
-
</pre>
|
|
1841
|
-
</div>
|
|
1842
|
-
</section>
|
|
1843
|
-
|
|
1844
|
-
<section class="demo-section">
|
|
1845
|
-
<h2>Live Demo</h2>
|
|
1846
|
-
<div class="demo-container">
|
|
1847
|
-
<!-- Basic List Demo -->
|
|
1848
|
-
<div class="demo-example">
|
|
1849
|
-
<h3>Basic List</h3>
|
|
1850
|
-
<div class="list-container">
|
|
1851
|
-
<div
|
|
1852
|
-
LibsUiComponentsDragContainerDirective
|
|
1853
|
-
[(items)]="basicItems"
|
|
1854
|
-
[acceptDragSameGroup]="true">
|
|
1855
|
-
@for (item of basicItems; track item) {
|
|
1856
|
-
<div
|
|
1857
|
-
class="list-item"
|
|
1858
|
-
LibsUiDragItemDirective>
|
|
1859
|
-
<span class="item-icon">📋</span>
|
|
1860
|
-
<span class="item-text">{{ item }}</span>
|
|
1861
|
-
</div>
|
|
1862
|
-
}
|
|
1863
|
-
</div>
|
|
1864
|
-
</div>
|
|
1865
|
-
</div>
|
|
1866
|
-
|
|
1867
|
-
<!-- Kanban Board Demo -->
|
|
1868
|
-
<div class="demo-example">
|
|
1869
|
-
<h3>Kanban Board</h3>
|
|
1870
|
-
<div class="kanban-board">
|
|
1871
|
-
@for (column of columns; track column) {
|
|
1872
|
-
<div
|
|
1873
|
-
class="kanban-column"
|
|
1874
|
-
LibsUiComponentsDragContainerDirective
|
|
1875
|
-
[(items)]="column.items"
|
|
1876
|
-
[groupName]="column.id"
|
|
1877
|
-
[dropToGroupName]="columnsIds"
|
|
1878
|
-
[acceptDragSameGroup]="true">
|
|
1879
|
-
<h4>{{ column.title }}</h4>
|
|
1880
|
-
@for (item of column.items; track item) {
|
|
1881
|
-
<div
|
|
1882
|
-
class="kanban-item"
|
|
1883
|
-
LibsUiDragItemDirective>
|
|
1884
|
-
<div class="kanban-item-header">
|
|
1885
|
-
<span class="item-title">{{ item.title }}</span>
|
|
1886
|
-
<span
|
|
1887
|
-
class="item-status"
|
|
1888
|
-
[class]="'status-' + item.status">
|
|
1889
|
-
{{ item.status }}
|
|
1890
|
-
</span>
|
|
1891
|
-
</div>
|
|
1892
|
-
<p class="item-description">{{ item.description }}</p>
|
|
1893
|
-
</div>
|
|
1894
|
-
}
|
|
1895
|
-
</div>
|
|
1896
|
-
}
|
|
1897
|
-
</div>
|
|
1898
|
-
</div>
|
|
1899
|
-
|
|
1900
|
-
<!-- Nested Containers Demo -->
|
|
1901
|
-
<div class="demo-example">
|
|
1902
|
-
<h3>Nested Containers copy</h3>
|
|
1903
|
-
<div class="nested-container">
|
|
1904
|
-
<div
|
|
1905
|
-
LibsUiComponentsDragContainerDirective
|
|
1906
|
-
[(items)]="nestedItems"
|
|
1907
|
-
[groupName]="'parent'"
|
|
1908
|
-
[mode]="'copy'"
|
|
1909
|
-
[acceptDragSameGroup]="true">
|
|
1910
|
-
@for (item of nestedItems; track item) {
|
|
1911
|
-
<div
|
|
1912
|
-
class="nested-item"
|
|
1913
|
-
LibsUiDragItemDirective>
|
|
1914
|
-
<div class="nested-item-header">
|
|
1915
|
-
<span class="item-title">{{ item.title }}</span>
|
|
1916
|
-
</div>
|
|
1917
|
-
<div class="nested-item-content">
|
|
1918
|
-
<div
|
|
1919
|
-
LibsUiComponentsDragContainerDirective
|
|
1920
|
-
[(items)]="item.subItems"
|
|
1921
|
-
[groupName]="'child'"
|
|
1922
|
-
[acceptDragSameGroup]="true">
|
|
1923
|
-
@for (subItem of item.subItems; track subItem) {
|
|
1924
|
-
<div
|
|
1925
|
-
class="sub-item"
|
|
1926
|
-
LibsUiDragItemDirective>
|
|
1927
|
-
{{ subItem }}
|
|
1928
|
-
</div>
|
|
1929
|
-
}
|
|
1930
|
-
</div>
|
|
1931
|
-
</div>
|
|
1932
|
-
</div>
|
|
1933
|
-
}
|
|
1934
|
-
</div>
|
|
1935
|
-
</div>
|
|
1936
|
-
</div>
|
|
1937
|
-
</div>
|
|
1938
|
-
</section>
|
|
1939
|
-
|
|
1940
|
-
<section class="api-doc-section">
|
|
1941
|
-
<h2>API Documentation</h2>
|
|
1942
|
-
|
|
1943
|
-
<h3>Inputs</h3>
|
|
1944
|
-
<div class="table-container">
|
|
1945
|
-
<table class="api-table">
|
|
1946
|
-
<thead>
|
|
1947
|
-
<tr>
|
|
1948
|
-
<th>Name</th>
|
|
1949
|
-
<th>Type</th>
|
|
1950
|
-
<th>Default</th>
|
|
1951
|
-
<th>Description</th>
|
|
1952
|
-
</tr>
|
|
1953
|
-
</thead>
|
|
1954
|
-
<tbody>
|
|
1955
|
-
@for (input of inputsDoc; track input.name) {
|
|
1956
|
-
<tr>
|
|
1957
|
-
<td>
|
|
1958
|
-
<code>{{ input.name }}</code>
|
|
1959
|
-
</td>
|
|
1960
|
-
<td>
|
|
1961
|
-
<code>{{ input.type }}</code>
|
|
1962
|
-
</td>
|
|
1963
|
-
<td>{{ input.default }}</td>
|
|
1964
|
-
<td>{{ input.description }}</td>
|
|
1965
|
-
</tr>
|
|
1966
|
-
}
|
|
1967
|
-
</tbody>
|
|
1968
|
-
</table>
|
|
1969
|
-
</div>
|
|
1970
|
-
|
|
1971
|
-
<h3>Outputs</h3>
|
|
1972
|
-
<div class="table-container">
|
|
1973
|
-
<table class="api-table">
|
|
1974
|
-
<thead>
|
|
1975
|
-
<tr>
|
|
1976
|
-
<th>Name</th>
|
|
1977
|
-
<th>Type</th>
|
|
1978
|
-
<th>Description</th>
|
|
1979
|
-
</tr>
|
|
1980
|
-
</thead>
|
|
1981
|
-
<tbody>
|
|
1982
|
-
@for (output of outputsDoc; track output.name) {
|
|
1983
|
-
<tr>
|
|
1984
|
-
<td>
|
|
1985
|
-
<code>{{ output.name }}</code>
|
|
1986
|
-
</td>
|
|
1987
|
-
<td>
|
|
1988
|
-
<code>{{ output.type }}</code>
|
|
1989
|
-
</td>
|
|
1990
|
-
<td>{{ output.description }}</td>
|
|
1991
|
-
</tr>
|
|
1992
|
-
}
|
|
1993
|
-
</tbody>
|
|
1994
|
-
</table>
|
|
1995
|
-
</div>
|
|
1996
|
-
</section>
|
|
1997
|
-
|
|
1998
|
-
<section class="interfaces-section">
|
|
1999
|
-
<h2>Interfaces</h2>
|
|
2000
|
-
<div class="interface-docs">
|
|
2001
|
-
@for (interfaceItem of interfacesDoc; track interfaceItem.name) {
|
|
2002
|
-
<div class="interface-item">
|
|
2003
|
-
<h3>{{ interfaceItem.name }}</h3>
|
|
2004
|
-
<pre><code>{{interfaceItem.code}}</code></pre>
|
|
2005
|
-
<p>{{ interfaceItem.description }}</p>
|
|
2006
|
-
</div>
|
|
2007
|
-
}
|
|
2008
|
-
</div>
|
|
2009
|
-
</section>
|
|
2010
|
-
|
|
2011
|
-
<section class="features-section">
|
|
2012
|
-
<h2>Features</h2>
|
|
2013
|
-
<ul>
|
|
2014
|
-
@for (feature of features; track feature.id) {
|
|
2015
|
-
<li>
|
|
2016
|
-
<span class="feature-icon">{{ feature.icon }}</span>
|
|
2017
|
-
<div class="feature-info">
|
|
2018
|
-
<h3>{{ feature.title }}</h3>
|
|
2019
|
-
<p>{{ feature.description }}</p>
|
|
2020
|
-
</div>
|
|
2021
|
-
</li>
|
|
2022
|
-
}
|
|
2023
|
-
</ul>
|
|
2024
|
-
</section>
|
|
2025
|
-
|
|
2026
|
-
<section class="usage-section">
|
|
2027
|
-
<h2>Usage</h2>
|
|
2028
|
-
<div class="code-examples">
|
|
2029
|
-
@for (example of codeExamples; track example.id) {
|
|
2030
|
-
<div class="code-example">
|
|
2031
|
-
<h3>{{ example.title }}</h3>
|
|
2032
|
-
<pre><code [innerHTML]="example.code"></code></pre>
|
|
2033
|
-
</div>
|
|
2034
|
-
}
|
|
2035
|
-
</div>
|
|
2036
|
-
</section>
|
|
2037
|
-
</main>
|
|
2038
|
-
</div>
|
|
2039
|
-
`, styles: [".page-container{max-width:1200px;margin:0 auto;padding:20px;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif;line-height:1.6;color:#333}header{text-align:center;padding:40px 0;background-color:#fff;border-radius:8px;margin-bottom:30px;box-shadow:0 2px 5px #0000001a}header h1{font-size:2.5rem;color:#2c3e50;margin-bottom:10px}header p{font-size:1.2rem;color:#7f8c8d}section{background-color:#fff;border-radius:8px;padding:30px;margin-bottom:30px;box-shadow:0 2px 5px #0000001a}h2{font-size:1.8rem;color:#2c3e50;margin-bottom:20px;padding-bottom:10px;border-bottom:2px solid #ecf0f1}h3{font-size:1.4rem;color:#34495e;margin-bottom:15px}h4{font-size:1.2rem;color:#34495e;margin-bottom:10px}p{margin-bottom:15px}code{font-family:Courier New,Courier,monospace;background-color:#f7f7f7;padding:2px 5px;border-radius:3px;font-size:.9em}pre{background-color:#f7f7f7;padding:15px;border-radius:5px;overflow-x:auto;margin-bottom:20px;display:flex;align-items:center;justify-content:space-between}pre code{background-color:transparent;padding:0}.installation-section .install-command{position:relative;margin-bottom:20px}.installation-section .copy-button{position:absolute;top:10px;right:10px;background:#3498db;color:#fff;border:none;border-radius:4px;padding:5px 10px;font-size:.9rem;cursor:pointer;transition:background .2s}.installation-section .copy-button:hover{background:#2980b9}.demo-container{display:grid;grid-template-columns:1fr;gap:30px}.demo-example{background:#f7f7f7;padding:20px;border-radius:8px;margin-bottom:20px}.list-container{max-width:400px;margin:20px auto}.list-item{padding:12px;margin:8px 0;background:#fff;border:1px solid #e0e0e0;border-radius:6px;display:flex;align-items:center;transition:transform .2s,box-shadow .2s}.list-item:hover{transform:translateY(-2px);box-shadow:0 4px 8px #0000001a}.item-icon{margin-right:12px;font-size:1.2em}.kanban-board{display:flex;gap:20px;padding:20px;overflow-x:auto}.kanban-column{flex:1;min-width:300px;background:#f5f5f5;padding:15px;border-radius:8px}.kanban-item{background:#fff;padding:12px;margin:8px 0;border-radius:6px;box-shadow:0 1px 3px #0000001a}.kanban-item-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.item-title{font-weight:500}.item-status{padding:4px 8px;border-radius:4px;font-size:.8em}.status-todo{background:#ffebee;color:#c62828}.status-in-progress{background:#fff3e0;color:#ef6c00}.status-done{background:#e8f5e9;color:#2e7d32}.item-description{font-size:.9em;color:#666}.nested-container{max-width:800px;margin:0 auto}.nested-item{background:#fff;border:1px solid #e0e0e0;border-radius:8px;margin:12px 0;overflow:hidden}.nested-item-header{padding:12px;background:#f5f5f5;border-bottom:1px solid #e0e0e0}.nested-item-content{padding:12px}.sub-item{padding:8px;margin:4px 0;background:#f9f9f9;border:1px solid #e0e0e0;border-radius:4px}.api-doc-section{margin-bottom:40px}.table-container{overflow-x:auto;margin-bottom:30px}.api-table{width:100%;border-collapse:collapse;margin-bottom:20px}.api-table th,.api-table td{padding:12px 15px;text-align:left;border-bottom:1px solid #e1e1e1}.api-table th{background-color:#f5f5f5;font-weight:700}.api-table tbody tr:hover{background-color:#f9f9f9}.features-section ul{list-style:none}.features-section li{display:flex;margin-bottom:25px;align-items:flex-start}.feature-icon{font-size:2rem;margin-right:20px;min-width:40px;text-align:center}.feature-info{flex:1}.code-examples{display:grid;grid-template-columns:1fr;gap:20px}@media (min-width: 768px){.code-examples{grid-template-columns:repeat(2,1fr)}}@media (min-width: 992px){.code-examples{grid-template-columns:repeat(3,1fr)}}.code-example{border:1px solid #ecf0f1;border-radius:5px;padding:15px}@media (max-width: 768px){header{padding:30px 0}header h1{font-size:2rem}section{padding:20px}.kanban-board{flex-direction:column}.kanban-column{min-width:100%}.feature-icon{font-size:1.5rem;margin-right:15px}}\n"] }]
|
|
2040
|
-
}] });
|
|
2041
|
-
|
|
2042
1237
|
/**
|
|
2043
1238
|
* Generated bundle index. Do not edit.
|
|
2044
1239
|
*/
|
|
2045
1240
|
|
|
2046
|
-
export { LibsUiComponentsDragContainerDirective, LibsUiComponentsDragScrollDirective,
|
|
1241
|
+
export { LibsUiComponentsDragContainerDirective, LibsUiComponentsDragScrollDirective, LibsUiDragItemDirective, LibsUiDragItemInContainerVirtualScrollDirective };
|
|
2047
1242
|
//# sourceMappingURL=libs-ui-components-drag-drop.mjs.map
|