Skip to content

Commit b4e0183

Browse files
committed
feat: JS 实现客户端拖动动画样式
1 parent 5a6ae2f commit b4e0183

File tree

4 files changed

+153
-110
lines changed

4 files changed

+153
-110
lines changed

src/BootstrapBlazor.Server/Components/Samples/TreeViews.razor

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<h3>@Localizer["TreeViewsTitle"]</h3>
66
<h4>@Localizer["TreeViewsDescription"]</h4>
77

8-
<Tips class="mt-3">
8+
@* <Tips class="mt-3">
99
<div class="mb-3"><code>Tree</code> @((MarkupString)Localizer["TreeViewsTips1"].Value) <code>TItem="TreeFoo"</code></div>
1010
<ul class="ul-demo mb-0">
1111
<li>@((MarkupString)Localizer["TreeViewsTips2"].Value)</li>
@@ -50,18 +50,17 @@
5050
</section>
5151
<TreeView Items="@CheckedItems" ShowCheckbox="true" OnTreeItemChecked="@OnTreeItemChecked" AutoCheckChildren="@AutoCheckChildren" AutoCheckParent="@AutoCheckParent"></TreeView>
5252
<ConsoleLogger @ref="Logger2"></ConsoleLogger>
53-
</DemoBlock>
53+
</DemoBlock> *@
5454

5555
<DemoBlock Title="@Localizer["TreeViewDraggableTitle"]"
5656
Introduction="@Localizer["TreeViewDraggableIntro"]"
5757
Name="TreeDraggable">
5858
<section ignore>@((MarkupString)Localizer["TreeViewDraggableDescription"].Value)</section>
59-
<TreeView Items="@DraggableItems" OnTreeItemClick="@OnTreeItemClick" ShowToolbar="true"
60-
AllowDrag="true" OnDragItemEndAsync="OnDragItemEndAsync">
59+
<TreeView Items="@DraggableItems" AllowDrag="true" OnDragItemEndAsync="OnDragItemEndAsync">
6160
</TreeView>
6261
</DemoBlock>
6362

64-
<DemoBlock Title="@Localizer["TreeViewTreeDisableTitle"]"
63+
@* <DemoBlock Title="@Localizer["TreeViewTreeDisableTitle"]"
6564
Introduction="@Localizer["TreeViewTreeDisableIntro"]"
6665
Name="TreeDisable">
6766
<section ignore>@((MarkupString)Localizer["TreeViewTreeDisableDescription"].Value)</section>
@@ -218,4 +217,4 @@
218217
219218
<AttributeTable Items="@GetAttributes()"></AttributeTable>
220219
221-
<AttributeTable Items="@GetTreeItemAttributes()" Title="@Localizer["TreeViewsAttribute"]"></AttributeTable>
220+
<AttributeTable Items="@GetTreeItemAttributes()" Title="@Localizer["TreeViewsAttribute"]"></AttributeTable> *@

src/BootstrapBlazor/Components/TreeView/TreeView.razor.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,12 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
390390
/// <inheritdoc/>
391391
/// </summary>
392392
/// <returns></returns>
393-
protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, new { Invoke = Interop, Method = nameof(TriggerKeyDown) });
393+
protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, new
394+
{
395+
Invoke = Interop,
396+
Method = nameof(TriggerKeyDown),
397+
AllowDrag
398+
});
394399

395400
private bool _keyboardArrowUpDownTrigger;
396401

src/BootstrapBlazor/Components/TreeView/TreeView.razor.js

Lines changed: 111 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import EventHandler from "../../modules/event-handler.js"
2+
import { insertBefore } from "../../modules/utility.js"
23

34
export function init(id, options) {
45
const el = document.getElementById(id)
56
if (el === null) {
67
return
78
}
89

9-
const { invoke, method } = options
10+
const { invoke, method, allowDrag } = options
1011
EventHandler.on(el, 'keydown', '.tree-root', e => {
1112
if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
1213
const v = el.getAttribute('data-bb-keyboard');
@@ -26,6 +27,115 @@ export function init(id, options) {
2627
}
2728
}
2829
});
30+
31+
if (allowDrag) {
32+
resetTreeViewRow(el);
33+
34+
EventHandler.on(el, 'dragstart', e => {
35+
console.log(e.target);
36+
el.targetItem = e.target;
37+
el.targetItem.classList.add('drag-item');
38+
e.dataTransfer.setData('text/plain', '');
39+
e.dataTransfer.effectAllowed = 'move';
40+
el.classList.add('dragging');
41+
console.log('Drag start event triggered');
42+
});
43+
44+
EventHandler.on(el, 'dragend', e => {
45+
el.classList.remove('dragging');
46+
el.targetItem.classList.remove('drag-item');
47+
const overItem = el.querySelector('.tree-drag-inside-over');
48+
if (overItem) {
49+
overItem.classList.remove('tree-drag-inside-over');
50+
}
51+
const belowItem = el.querySelector('.tree-node-placeholder');
52+
if (belowItem) {
53+
belowItem.remove();
54+
}
55+
delete el.targetItem;
56+
console.log('Drag end event triggered');
57+
});
58+
59+
EventHandler.on(el, 'dragenter', '.tree-drop-child-inside', e => {
60+
e.preventDefault();
61+
62+
const item = e.delegateTarget;
63+
item.classList.add('tree-drag-inside-over');
64+
console.log('inside Drag enter event triggered');
65+
});
66+
EventHandler.on(el, 'dragenter', '.tree-drop-child-below', e => {
67+
e.preventDefault()
68+
69+
const item = e.delegateTarget;
70+
const placeholder = createPlaceholder();
71+
item.appendChild(placeholder);
72+
console.log('below Drag enter event triggered');
73+
});
74+
75+
EventHandler.on(el, 'dragleave', '.tree-drop-child-inside', e => {
76+
e.preventDefault()
77+
78+
const item = e.delegateTarget;
79+
item.classList.remove('tree-drag-inside-over');
80+
console.log('inside Drag leave event triggered');
81+
});
82+
EventHandler.on(el, 'dragleave', '.tree-drop-child-below', e => {
83+
e.preventDefault()
84+
85+
const item = e.delegateTarget;
86+
item.classList.remove('tree-drag-below-over');
87+
item.innerHTML = "";
88+
console.log('below Drag leave event triggered');
89+
});
90+
91+
EventHandler.on(el, 'dragover', '.tree-drop-zone', e => {
92+
e.preventDefault()
93+
});
94+
}
95+
}
96+
97+
const resetTreeViewRow = el => {
98+
const rows = [...el.querySelectorAll('.tree-content')];
99+
rows.forEach(row => {
100+
const node = row.querySelector('.tree-node');
101+
if (node) {
102+
node.setAttribute('draggable', 'true');
103+
const dropzone = createDropzone();
104+
insertBefore(node, dropzone);
105+
}
106+
});
107+
}
108+
109+
const createDropzone = () => {
110+
const div = document.createElement('div');
111+
div.classList.add(`tree-drop-zone`);
112+
113+
const inside = document.createElement('div');
114+
inside.classList.add(`tree-drop-child-inside`);
115+
116+
const below = document.createElement('div');
117+
below.classList.add(`tree-drop-child-below`);
118+
119+
div.appendChild(inside);
120+
div.appendChild(below);
121+
122+
return div
123+
}
124+
125+
const createPlaceholder = () => {
126+
const div = document.createElement('div');
127+
div.classList.add(`tree-node-placeholder`);
128+
129+
const circle = document.createElement('div');
130+
circle.classList.add(`tree-node-ph-circle`);
131+
132+
const line = document.createElement('div');
133+
line.classList.add(`tree-node-ph-line`);
134+
135+
div.appendChild(circle);
136+
div.appendChild(line);
137+
138+
return div
29139
}
30140

31141
export function scroll(id, options) {

src/BootstrapBlazor/Components/TreeView/TreeView.razor.scss

Lines changed: 31 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -175,99 +175,55 @@
175175

176176
.tree-drop-zone {
177177
position: absolute;
178-
top: 4px;
179-
left: 18px;
178+
top: 0px;
179+
left: 0;
180180
right: 0;
181-
bottom: -5px;
181+
bottom: -6px;
182182
background-color: transparent;
183183
display: grid;
184-
grid-template-rows: 1fr 8px;
185-
background-color: #f2747440;
186-
pointer-events: all;
184+
grid-template-rows: 1fr 5px;
187185

188186
.tree-drop-child-inside {
189187
grid-row: 1 / 2;
190-
background-color: #aad4ff;
191188

192-
&.tree-drag-over {
193-
border: solid 1px var(--bb-tree-drop-preview-color);
189+
&.tree-drag-inside-over {
190+
border: solid 2px var(--bb-tree-drop-preview-color);
194191
border-radius: var(--bs-border-radius);
195192
}
196193
}
197194

198195
.tree-drop-child-below {
199196
grid-row: 2 / 3;
200-
background-color: #f2747440;
201-
}
202-
}
203-
204-
.tree-preview-child-last {
205-
position: absolute;
206-
top: -2px;
207-
left: -2px;
208-
right: -2px;
209-
bottom: -2px;
210-
border: 2px solid var(--bb-tree-drop-preview-color);
211-
border-radius: 6px;
212-
pointer-events: none;
213-
z-index: 1;
214-
background: transparent;
215-
}
216-
217-
.tree-preview-child-first {
218-
position: absolute;
219-
bottom: -4px;
220-
height: 8px;
221-
left: 20px;
222-
right: 0;
223-
display: flex;
224-
flex-direction: row;
225-
align-items: center;
226-
pointer-events: none;
227-
228-
.tree-preview-circle {
229-
width: 8px;
230-
height: 8px;
231-
border-radius: 50%;
232-
background-color: var(--bb-tree-drop-preview-color);
233-
}
234-
235-
.tree-preview-line {
236-
flex: 1;
237-
height: 2px;
238-
background-color: var(--bb-tree-drop-preview-color);
239-
}
240-
}
241-
242-
.tree-preview-below {
243-
position: absolute;
244-
bottom: -4px;
245-
height: 8px;
246-
left: 0;
247-
right: 0;
248-
display: flex;
249-
flex-direction: row;
250-
align-items: center;
251-
pointer-events: none;
197+
z-index: 2;
252198

253-
.tree-preview-circle {
254-
width: 8px;
255-
height: 8px;
256-
border-radius: 50%;
257-
background-color: var(--bb-tree-drop-preview-color);
258-
}
199+
.tree-node-placeholder {
200+
position: absolute;
201+
bottom: 0px;
202+
left: 18px;
203+
right: 0;
204+
display: flex;
205+
flex-direction: row;
206+
align-items: center;
207+
pointer-events: none;
208+
209+
.tree-node-ph-circle {
210+
width: 8px;
211+
height: 8px;
212+
border-radius: 50%;
213+
background-color: var(--bb-tree-drop-preview-color);
214+
}
259215

260-
.tree-preview-line {
261-
flex: 1;
262-
height: 2px;
263-
background-color: var(--bb-tree-drop-preview-color);
216+
.tree-node-ph-line {
217+
flex: 1;
218+
min-width: 0px;
219+
width: 1%;
220+
height: 2px;
221+
background-color: var(--bb-tree-drop-preview-color);
222+
}
223+
}
264224
}
265225
}
266226

267-
.tree-drop-pass {
268-
pointer-events: none;
269-
}
270-
271227
&.dragging {
272228
.tree-node:not(.drag-item) {
273229
pointer-events: none;
@@ -280,32 +236,5 @@
280236
opacity: 0.5;
281237
background-color: #d4edff;
282238
}
283-
284-
.tree-node-placeholder {
285-
position: absolute;
286-
bottom: -4px;
287-
height: 8px;
288-
left: 0;
289-
right: 0;
290-
display: flex;
291-
flex-direction: row;
292-
align-items: center;
293-
pointer-events: none;
294-
295-
.tree-node-ph-circle {
296-
width: 8px;
297-
height: 8px;
298-
border-radius: 50%;
299-
background-color: var(--bb-tree-drop-preview-color);
300-
}
301-
302-
.tree-node-ph-line {
303-
flex: 1;
304-
min-width: 0px;
305-
width: 1%;
306-
height: 2px;
307-
background-color: var(--bb-tree-drop-preview-color);
308-
}
309-
}
310239
}
311240
}

0 commit comments

Comments
 (0)