Skip to content

Commit 6cc50bd

Browse files
committed
More bug fixes for drag/drop.
1 parent 4e84d82 commit 6cc50bd

File tree

5 files changed

+85
-13
lines changed

5 files changed

+85
-13
lines changed

src/pg/tree/__examples__/basic/basic.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import PgTree from '../../tree';
33

44
import template from './basic.html';
55
import PgTreeButtonIcon from '../../../treeButtonIcon/treeButtonIcon';
6+
import PgTreeItem from 'pg/treeItem/treeItem';
67

78
const IconAccount = 'M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z';
89
const IconFile = 'M13,9V3.5L18.5,9M6,2C4.89,2 4,2.89 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2H6Z';
@@ -89,8 +90,8 @@ export default class XPgTreeBasic extends HTMLElement {
8990
// action clicked
9091
});
9192
this.$tree.addEventListener('select', (e: any) => {
92-
console.log(e.detail.items.size);
93-
this.#selectedItems = Array.from(e.detail.items);
93+
console.log(e.detail.items.length);
94+
this.#selectedItems = e.detail.items;
9495
});
9596
this.$tree.items = [
9697
createItem('Item 1', true),
@@ -109,9 +110,8 @@ export default class XPgTreeBasic extends HTMLElement {
109110

110111
let updatedTimes = 0;
111112
this.$updateItem.addEventListener('click', () => {
112-
this.#selectedItems.forEach((selected) => {
113-
const item = this.#getItem(selected);
114-
item.label = `Updated ${updatedTimes++}`;
113+
this.#selectedItems.forEach((selected: PgTreeItem) => {
114+
selected.label = `Updated ${updatedTimes++}`;
115115
});
116116
});
117117
}

src/pg/tree/tree.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,25 +35,24 @@ export default class PgTree extends HTMLElement {
3535
e.stopPropagation();
3636
const { indexes, type, ctrlKey, shiftKey } = e.detail;
3737
const item = this.#getItem(indexes);
38-
const selectedCount = this.#selected.size;
38+
const selectedCount = this.#selectedIndexes.size;
3939
const unproxyItem = getProxyValue(item);
40-
if (!ctrlKey && selectedCount && !this.#selected.has(unproxyItem)) {
41-
this.#selected.forEach((x: any) => x.selected = false);
42-
this.#selected.clear();
40+
if (!ctrlKey && selectedCount && !this.#selectedIndexes.has(unproxyItem)) {
41+
this.#selectedIndexes.forEach((x: any) => this.#getItem(x).selected = false);
4342
this.#selectedIndexes.clear();
4443
}
4544
item.selected = type === 'rename' ? true : !item.selected;
4645
if (item.selected) {
47-
this.#selected.add(item);
4846
this.#selectedIndexes.set(unproxyItem, indexes);
4947
} else {
50-
this.#selected.delete(item);
5148
this.#selectedIndexes.delete(unproxyItem);
5249
}
5350
// Dispatch Event
5451
this.dispatchEvent(new CustomEvent('select', {
5552
detail: {
56-
items: this.#selected
53+
items: Array.from(this.#selectedIndexes).map(([key, value]) => {
54+
return this.#getItem(value);
55+
})
5756
}
5857
}));
5958
});

src/pg/treeItem/treeItem.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,22 @@
9494
padding-left: calc((var(--x) * 0.5rem) + 1.25rem)
9595
}
9696

97+
[part=item].dragging {
98+
position: relative;
99+
opacity: 0.5;
100+
}
101+
[part=item].dragging::after {
102+
position: absolute;
103+
content: ' ';
104+
display: flex;
105+
top: 0;
106+
right: 0;
107+
bottom: 0;
108+
left: 0;
109+
border-radius: 0.25rem;
110+
border: 2px dashed #453C4F;
111+
}
112+
97113
[part=actions] {
98114
display: flex;
99115
gap: 0.25rem;

src/pg/treeItem/treeItem.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div part="item">
1+
<div part="item" draggable="true">
22
<button part="toggle"></button>
33
<button part="iconButton">
44
<pg-icon part="icon"></pg-icon>

src/pg/treeItem/treeItem.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ export default class PgTreeItem extends HTMLElement {
3737
this.$item.addEventListener('action', this.#handleAction.bind(this));
3838
this.$item.addEventListener('pointerenter', this.#handlePointerEnter.bind(this));
3939
this.$item.addEventListener('pointerleave', this.#handlePointerLeave.bind(this));
40+
this.$item.addEventListener('dragstart', this.#handleDragStart.bind(this));
41+
this.$item.addEventListener('dragend', this.#handleDragEnd.bind(this));
4042
this.$labelButton.addEventListener('dblclick', this.#handleDoubleClick.bind(this));
4143
this.$labelButton.addEventListener('click', this.#handleClick.bind(this));
4244
this.$iconButton.addEventListener('dblclick', this.#handleIconDoubleClick.bind(this));
@@ -304,4 +306,59 @@ export default class PgTreeItem extends HTMLElement {
304306
}
305307
}
306308

309+
#handleDragStart(event) {
310+
this.$item.classList.toggle('dragging', true);
311+
// Generate drag image showing selected item count
312+
const size = window.devicePixelRatio;
313+
const canvas = document.createElement('canvas');
314+
document.body.append(canvas);
315+
// Larger than required!
316+
canvas.width = 100 * size;
317+
canvas.height = 40 * size;
318+
canvas.style.width = `${canvas.width / size}px`;
319+
// overlap cursor offset
320+
const offsetInline = 10;
321+
const fontSize = 16;
322+
const paddingBlock = 6;
323+
const paddingInline = 6;
324+
var ctx = canvas.getContext('2d');
325+
if (ctx) {
326+
const text = '0';
327+
ctx.font = `bold ${fontSize * size}px Segoe UI`;
328+
const textSize = ctx.measureText(text);
329+
ctx.fillStyle = '#453C4F';
330+
ctx.beginPath();
331+
ctx.roundRect(
332+
(offsetInline) * size,
333+
0,
334+
(textSize.width + (paddingInline * 2)) * size,
335+
(fontSize + (paddingBlock * 2)) * size,
336+
8 + (size * 2)
337+
);
338+
ctx.fill();
339+
ctx.fillStyle = '#FFF';
340+
ctx.beginPath();
341+
ctx.roundRect(
342+
(offsetInline + 2) * size,
343+
2 * size,
344+
((textSize.width + (paddingInline * 2) - 4) * size),
345+
((fontSize + (paddingBlock * 2) - 4) * size),
346+
8
347+
);
348+
ctx.fill();
349+
ctx.fillStyle = '#453C4F';
350+
ctx.fillText(
351+
text,
352+
(offsetInline + paddingInline + 4) * size,
353+
(fontSize + paddingBlock - 2) * size
354+
);
355+
}
356+
357+
event.dataTransfer.setDragImage(canvas, 0, 0);
358+
}
359+
360+
#handleDragEnd(event) {
361+
this.$item.classList.toggle('dragging', false);
362+
}
363+
307364
}

0 commit comments

Comments
 (0)