Skip to content

Commit 1b2aff1

Browse files
authored
Merge pull request #79 from Alessy/drag-handle
feat: (draghandle) drag handle implementation
2 parents c570433 + 116f3f5 commit 1b2aff1

11 files changed

+115
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
.example-box {
2+
width: 200px;
3+
height: 200px;
4+
padding: 10px;
5+
box-sizing: border-box;
6+
border: solid 1px #ccc;
7+
color: rgba(0, 0, 0, 0.87);
8+
display: flex;
9+
justify-content: center;
10+
align-items: center;
11+
text-align: center;
12+
background: #fff;
13+
border-radius: 4px;
14+
position: relative;
15+
z-index: 1;
16+
transition: box-shadow 200ms cubic-bezier(0, 0, 0.2, 1);
17+
box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2),
18+
0 2px 2px 0 rgba(0, 0, 0, 0.14),
19+
0 1px 5px 0 rgba(0, 0, 0, 0.12);
20+
}
21+
22+
.example-handle {
23+
position: absolute;
24+
top: 10px;
25+
right: 10px;
26+
color: #ccc;
27+
cursor: move;
28+
width: 24px;
29+
height: 24px;
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<h5 style="margin-bottom: 20px">1. Drag the items around using handle</h5>
2+
3+
<div class="example-container">
4+
<div *ngFor="let item of items"
5+
ngSortgridItem
6+
[ngSortGridItems]="items"
7+
class="example-box">
8+
9+
<h1 style="color: darkslategray">
10+
{{ item }}
11+
</h1>
12+
13+
<div class="example-handle" ngSortgridDragHandle>
14+
<svg width="24px" fill="currentColor" viewBox="0 0 24 24">
15+
<path d="M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z"></path>
16+
<path d="M0 0h24v24H0z" fill="none"></path>
17+
</svg>
18+
</div>
19+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import {Component} from '@angular/core';
2+
3+
@Component({
4+
selector: 'ngsg-demo-drag-handle',
5+
templateUrl: 'drag-handle.component.html',
6+
styleUrls: ['./drag-handle.component.css']
7+
})
8+
export class DragHandleComponent {
9+
10+
public items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
11+
}
12+

projects/ng-sortgrid-demo/src/app/introduction/introduction.component.html

+6
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,10 @@ <h1>5. Scrolling</h1>
3636

3737
<button routerLink="scrolling" class="btn btn-primary" style="margin-bottom: 50px">Check out the demo...</button>
3838

39+
<hr class="chaptor-separator"/>
40+
41+
<h1>6. Customizing the drag area using a handle</h1>
42+
<ngsg-demo-step title="Apply the ngSortgridDragHandle directive" image="gs7.png"></ngsg-demo-step>
43+
<ngsg-demo-drag-handle></ngsg-demo-drag-handle>
44+
3945
</div>

projects/ng-sortgrid-demo/src/app/introduction/introduction.module.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {NgsgModule} from '../../../../ng-sortgrid/src/lib/ngsg.module';
55
import {SharedModule} from '../shared/shared.module';
66

77
import {AsyncPipeMemoryComponent} from './examples/async-pipe/async-pipe-memory.component';
8+
import { DragHandleComponent } from './examples/drag-handle/drag-handle.component';
89
import {GettingStartedMemoryComponent} from './examples/getting-started/getting-started-memory.component';
910
import {GroupsMemoryComponent} from './examples/groups/groups-memory.component';
1011
import {ReactOnChangesMemoryComponent} from './examples/react-on-changes/react-on-changes-memory.component';
@@ -17,7 +18,8 @@ import {IntroductionRoutingModule} from './introduction.routing.module';
1718
GettingStartedMemoryComponent,
1819
ReactOnChangesMemoryComponent,
1920
GroupsMemoryComponent,
20-
AsyncPipeMemoryComponent
21+
AsyncPipeMemoryComponent,
22+
DragHandleComponent
2123
],
2224
imports: [
2325
CommonModule,
25 KB
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { NgsgDragHandleDirective } from './ngsg-drag-handle.directive';
2+
3+
describe('NgsgDragHandleDirective', () => {
4+
let sut: NgsgDragHandleDirective;
5+
6+
const elementRef = { nativeElement: {} } as any;
7+
8+
beforeEach(() => {
9+
sut = new NgsgDragHandleDirective(
10+
elementRef
11+
);
12+
});
13+
14+
it('should create an instance', () => {
15+
expect(sut).toBeTruthy();
16+
});
17+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Directive, ElementRef } from '@angular/core';
2+
3+
@Directive({
4+
selector: '[ngSortgridDragHandle]'
5+
})
6+
export class NgsgDragHandleDirective {
7+
8+
constructor(public el: ElementRef){}
9+
}

projects/ng-sortgrid/src/lib/ngsg-item.directive.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ describe('NgsgItemDirective', () => {
4848
);
4949
});
5050

51-
it('should set the draggable attribute on the elment', () => {
51+
it('should not set the draggable attribute on the elment', () => {
5252
sut.ngAfterViewInit();
53-
expect((elementRef.nativeElement as any).draggable).toBeTruthy();
53+
expect((elementRef.nativeElement as any).draggable).toBeFalsy();
5454
});
5555

5656
it('should not set selectedElements if the event did not occur on the host', () => {

projects/ng-sortgrid/src/lib/ngsg-item.directive.ts

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
AfterViewInit,
3+
ContentChild,
34
Directive,
45
ElementRef,
56
EventEmitter,
@@ -23,6 +24,7 @@ import {NgsgReflectService} from './sort/reflection/ngsg-reflect.service';
2324
import {NgsgSortService} from './sort/sort/ngsg-sort.service';
2425
import {NgsgStoreService} from './store/ngsg-store.service';
2526
import { NgsgClassService } from './helpers/class/ngsg-class.service';
27+
import { NgsgDragHandleDirective } from './ngsg-drag-handle.directive';
2628

2729
const selector = '[ngSortgridItem]';
2830

@@ -37,6 +39,9 @@ export class NgsgItemDirective implements OnInit, OnChanges, AfterViewInit, OnDe
3739

3840
@Output() sorted = new EventEmitter<NgsgOrderChange<any>>();
3941

42+
@ContentChild(NgsgDragHandleDirective) handle: NgsgDragHandleDirective;
43+
44+
private handleElement: HTMLElement;
4045
private selected = false;
4146
private destroy$ = new Subject();
4247

@@ -82,7 +87,14 @@ export class NgsgItemDirective implements OnInit, OnChanges, AfterViewInit, OnDe
8287
}
8388

8489
ngAfterViewInit(): void {
85-
this.el.nativeElement.draggable = true;
90+
this.handleElement = this.handle?.el?.nativeElement || this.el.nativeElement;
91+
92+
fromEvent<DragEvent>(this.handleElement, 'mousedown').pipe(
93+
takeUntil(this.destroy$)
94+
).subscribe(() => {
95+
this.el.nativeElement.draggable = true;
96+
}
97+
);
8698
}
8799

88100
ngOnDestroy(): void {
@@ -119,6 +131,7 @@ export class NgsgItemDirective implements OnInit, OnChanges, AfterViewInit, OnDe
119131

120132
@HostListener('dragend')
121133
drop(): void {
134+
this.el.nativeElement.draggable = false;
122135
if (!this.ngsgStore.hasSelectedItems(this.ngSortGridGroup)) {
123136
return;
124137
}
+3-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { NgModule } from '@angular/core';
22

33
import { NgsgItemDirective } from './ngsg-item.directive';
4+
import { NgsgDragHandleDirective } from './ngsg-drag-handle.directive';
45

56
@NgModule({
6-
declarations: [NgsgItemDirective],
7-
exports: [NgsgItemDirective]
7+
declarations: [NgsgItemDirective, NgsgDragHandleDirective],
8+
exports: [NgsgItemDirective, NgsgDragHandleDirective]
89
})
910
export class NgsgModule {}

0 commit comments

Comments
 (0)