Skip to content

Commit

Permalink
feat(datagrid): use DragDropModule from @angular/cdk
Browse files Browse the repository at this point in the history
BREAKING CHANGE: The `@angular/cdk` package is now a required peer dependency.
  • Loading branch information
kevinbuhmann committed Dec 19, 2022
1 parent 893e306 commit 3f93d4c
Show file tree
Hide file tree
Showing 9 changed files with 176 additions and 160 deletions.
28 changes: 28 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"@amanda-mitchell/semantic-release-npm-multiple": "3.5.0",
"@angular-devkit/build-angular": "15.0.2",
"@angular/animations": "15.0.2",
"@angular/cdk": "15.0.2",
"@angular/cli": "15.0.2",
"@angular/common": "15.0.2",
"@angular/compiler": "15.0.2",
Expand Down
178 changes: 90 additions & 88 deletions projects/angular/clarity.api.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions projects/angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"url": "https://github.com/vmware-clarity/ng-clarity/issues"
},
"peerDependencies": {
"@angular/cdk": "15",
"@angular/common": "15",
"@angular/core": "15",
"@cds/core": "^5.6.0 || ^6.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';

import { DomAdapter } from '../../utils/dom-adapter/dom-adapter';
import { ClrDragAndDropModule } from '../../utils/drag-and-drop/drag-and-drop.module';
import { ClrDragEvent } from '../../utils/drag-and-drop/drag-event';
import { ClrDraggable } from '../../utils/drag-and-drop/draggable/draggable';
import { DragEventType } from '../../utils/drag-and-drop/interfaces/drag-event.interface';
import { KeyCodes } from '../../utils/enums/key-codes.enum';
import { ClrDatagridColumnSeparator } from './datagrid-column-separator';
import { ColumnResizerService } from './providers/column-resizer.service';
Expand All @@ -38,12 +34,8 @@ export default function (): void {
let columnResizerService: ColumnResizerService;
let tableSizeService: TableSizeService;

let draggableDebugElement: DebugElement;
let draggableDirective: ClrDraggable<any>;

beforeEach(function () {
TestBed.configureTestingModule({
imports: [ClrDragAndDropModule],
declarations: [TestComponent, ClrDatagridColumnSeparator],
providers: [DomAdapter, DatagridRenderOrganizer],
});
Expand All @@ -59,9 +51,6 @@ export default function (): void {
columnHandleEl = fixture.nativeElement.querySelector('.datagrid-column-handle');
columnResizerService = columnSeparatorDebugElement.injector.get(ColumnResizerService);
tableSizeService = columnSeparatorDebugElement.injector.get(TableSizeService);

draggableDebugElement = fixture.debugElement.query(By.directive(ClrDraggable));
draggableDirective = draggableDebugElement.injector.get(ClrDraggable);
});

afterEach(function () {
Expand All @@ -71,47 +60,22 @@ export default function (): void {
});

it('has aria-label and aria-describedby attributes on its resize handle button', function () {
expect(draggableDebugElement.nativeElement.hasAttribute('aria-label')).toEqual(true);
expect(draggableDebugElement.nativeElement.hasAttribute('aria-describedby')).toEqual(true);
});

it('calls showTracker() methods when resizing starts', function () {
spyOn(columnSeparatorComponent, 'showTracker');
draggableDirective.dragStartEmitter.emit();

expect(columnSeparatorComponent.showTracker).toHaveBeenCalled();
expect(columnHandleEl.hasAttribute('aria-label')).toEqual(true);
expect(columnHandleEl.hasAttribute('aria-describedby')).toEqual(true);
});

it('shows resize tracker when resizing starts', function () {
columnSeparatorComponent.showTracker();
expect(resizeTrackerEl.style.height).toBe(tableSizeService.getColumnDragHeight());
});

it('calls moveTracker() methods when resizing starts', function () {
const moveEvent = new ClrDragEvent({
type: DragEventType.DRAG_MOVE,
dragPosition: { pageX: 0, pageY: 0, moveX: -123, moveY: 0 },
});

spyOn(columnSeparatorComponent, 'moveTracker');

draggableDirective.dragMoveEmitter.emit(moveEvent);
expect(columnSeparatorComponent.moveTracker).toHaveBeenCalledWith(-123);
});

it('moves resize tracker during resizing', function () {
columnSeparatorComponent.showTracker();
expect(resizeTrackerEl.style.transform).toBe('');
columnSeparatorComponent.moveTracker(-50);
expect(resizeTrackerEl.style.transform).toBe(`translateX(${columnResizerService.resizedBy}px)`);
});

it('calls hideTracker() methods when resizing starts', function () {
spyOn(columnSeparatorComponent, 'hideTracker');
draggableDirective.dragEndEmitter.emit();
expect(columnSeparatorComponent.hideTracker).toHaveBeenCalledWith();
});

it('hides resize tracker when resizing ends', function () {
columnSeparatorComponent.showTracker();
columnSeparatorComponent.moveTracker(-50);
Expand Down
15 changes: 8 additions & 7 deletions projects/angular/src/data/datagrid/datagrid-column-separator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ const KEYBOARD_RESIZE_LENGTH = 12;
class="datagrid-column-handle"
[attr.aria-label]="commonString.keys.columnSeparatorAriaLabel"
[attr.aria-describedby]="descriptionId"
clrDraggable
[clrGroup]="columnSeparatorId"
(clrDragStart)="showTracker()"
(clrDragMove)="moveTracker($event.dragPosition.moveX)"
(clrDragEnd)="hideTracker()"
cdkDrag
cdkDragLockAxis="x"
(cdkDragStarted)="showTracker()"
(cdkDragMoved)="moveTracker($event.distance.x)"
(cdkDragEnded)="hideTracker(); $event.source._dragRef.reset()"
#columnHandle
></button>
<span class="clr-sr-only" [attr.id]="descriptionId">
Expand Down Expand Up @@ -61,8 +61,6 @@ export class ClrDatagridColumnSeparator implements AfterViewInit, OnDestroy {

private unlisteners: (() => void)[] = [];

// Every column draggable separator should have its own unique ID
// in order to not conflict with other draggables/droppables.
constructor(
private columnResizerService: ColumnResizerService,
private renderer: Renderer2,
Expand Down Expand Up @@ -110,6 +108,7 @@ export class ClrDatagridColumnSeparator implements AfterViewInit, OnDestroy {
this.columnResizerService.endResize();
this.renderer.setStyle(this.resizeTrackerEl, 'display', 'none');
this.renderer.setStyle(this.resizeTrackerEl, 'transform', `translateX(0px)`);
this.renderer.setStyle(this.columnHandleEl, 'transform', `translateX(0px)`);
this.renderer.setStyle(this.document.body, 'cursor', 'auto');
}

Expand All @@ -123,8 +122,10 @@ export class ClrDatagridColumnSeparator implements AfterViewInit, OnDestroy {

private moveTrackerOnKeyDown(event: KeyboardEvent): void {
if (this.isArrowLeftKeyEvent(event)) {
event.stopPropagation();
this.moveTracker(this.columnResizerService.resizedBy - KEYBOARD_RESIZE_LENGTH);
} else if (this.isArrowRightKeyEvent(event)) {
event.stopPropagation();
this.moveTracker(this.columnResizerService.resizedBy + KEYBOARD_RESIZE_LENGTH);
}
}
Expand Down
4 changes: 2 additions & 2 deletions projects/angular/src/data/datagrid/datagrid.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import { ClrFormsModule } from '../../forms/forms.module';
import { ClrIconModule } from '../../icon/icon.module';
import { ClrSpinnerModule } from '../../progress/spinner/spinner.module';
import { ClrExpandableAnimationModule } from '../../utils/animations/expandable-animation/expandable-animation.module';
import { CdkDragModule } from '../../utils/cdk/cdk-drag.module';
import { ClrConditionalModule } from '../../utils/conditional/conditional.module';
import { ClrDragAndDropModule } from '../../utils/drag-and-drop/drag-and-drop.module';
import { ClrFocusTrapModule } from '../../utils/focus-trap/focus-trap.module';
import { ClrFocusOnViewInitModule } from '../../utils/focus/focus-on-view-init/focus-on-view-init.module';
import { ClrKeyFocusModule } from '../../utils/focus/key-focus/key-focus.module';
Expand Down Expand Up @@ -118,14 +118,14 @@ export const CLR_DATAGRID_DIRECTIVES: Type<any>[] = [
@NgModule({
imports: [
CommonModule,
CdkDragModule,
ClrIconModule,
ClrFormsModule,
FormsModule,
ClrLoadingModule,
ClrConditionalModule,
ClrOutsideClickModule,
ClrExpandableAnimationModule,
ClrDragAndDropModule,
ClrSpinnerModule,
ClrPopoverModuleNext,
ClrKeyFocusModule,
Expand Down
44 changes: 19 additions & 25 deletions projects/angular/src/data/datagrid/render/header-renderer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ import { BehaviorSubject } from 'rxjs';

import { DomAdapter } from '../../../utils/dom-adapter/dom-adapter';
import { MOCK_DOM_ADAPTER_PROVIDER, MockDomAdapter } from '../../../utils/dom-adapter/dom-adapter.mock';
import { ClrDragEvent } from '../../../utils/drag-and-drop/drag-event';
import { ClrDraggable } from '../../../utils/drag-and-drop/draggable/draggable';
import { DragEventType } from '../../../utils/drag-and-drop/interfaces/drag-event.interface';
import { ClrDatagrid } from '../datagrid';
import { ClrDatagridColumnSeparator } from '../datagrid-column-separator';
import { DatagridColumnChanges } from '../enums/column-changes.enum';
import { DatagridRenderStep } from '../enums/render-step.enum';
import { TestContext } from '../helpers.spec';
Expand Down Expand Up @@ -165,21 +163,15 @@ export default function (): void {
let columnHeader2ResizerService: ColumnResizerService;
let columnHeader3ResizerService: ColumnResizerService;
let columnHeader4ResizerService: ColumnResizerService;
let columnHeader1DraggableDebugElement: DebugElement;
let columnHeader3DraggableDebugElement: DebugElement;
let columnHeader1DraggableDirective: ClrDraggable<any>;
let columnHeader3DraggableDirective: ClrDraggable<any>;
let columnHeader1ColumnSeparatorDebugElement: DebugElement;
let columnHeader3ColumnSeparatorDebugElement: DebugElement;
const widthOf = (el: HTMLElement): number => {
return Math.round(el.getBoundingClientRect().width);
};
const emulateResizeOnColumn = (moveX: number, columnDraggable: ClrDraggable<any>): void => {
const moveEvent = new ClrDragEvent({
type: DragEventType.DRAG_MOVE,
dragPosition: { pageX: 0, pageY: 0, moveX: moveX, moveY: 0 },
});
columnDraggable.dragStartEmitter.emit();
columnDraggable.dragMoveEmitter.emit(moveEvent);
columnDraggable.dragEndEmitter.emit();
const emulateResizeOnColumn = (moveX: number, columnSeparator: ClrDatagridColumnSeparator): void => {
columnSeparator.showTracker();
columnSeparator.moveTracker(moveX);
columnSeparator.hideTracker();
};

beforeEach(function () {
Expand All @@ -200,10 +192,12 @@ export default function (): void {
column2InitialWidth = widthOf(columnHeader2Element);
column3InitialWidth = widthOf(columnHeader3Element);
column4InitialWidth = widthOf(columnHeader4Element);
columnHeader1DraggableDebugElement = context.fixture.debugElement.queryAll(By.directive(ClrDraggable))[0];
columnHeader3DraggableDebugElement = context.fixture.debugElement.queryAll(By.directive(ClrDraggable))[2];
columnHeader1DraggableDirective = columnHeader1DraggableDebugElement.injector.get(ClrDraggable);
columnHeader3DraggableDirective = columnHeader3DraggableDebugElement.injector.get(ClrDraggable);
columnHeader1ColumnSeparatorDebugElement = context.fixture.debugElement.queryAll(
By.directive(ClrDatagridColumnSeparator)
)[0];
columnHeader3ColumnSeparatorDebugElement = context.fixture.debugElement.queryAll(
By.directive(ClrDatagridColumnSeparator)
)[2];
});

it('each header should have min-width', function () {
Expand All @@ -229,7 +223,7 @@ export default function (): void {

it('expands other flexible headers if header width shrinks', function () {
const resizeBy = -20;
emulateResizeOnColumn(resizeBy, columnHeader1DraggableDirective);
emulateResizeOnColumn(resizeBy, columnHeader1ColumnSeparatorDebugElement.componentInstance);
expect(widthOf(columnHeader1Element)).toBe(column1InitialWidth + resizeBy);
expect(widthOf(columnHeader2Element)).toBeGreaterThan(column2InitialWidth);
expect(widthOf(columnHeader3Element)).toBe(
Expand All @@ -242,13 +236,13 @@ export default function (): void {
it('resized header should have fixed width class', function () {
expect(columnHeader1Element.classList.contains(STRICT_WIDTH_CLASS)).toBeFalse();
const resizeBy = -20;
emulateResizeOnColumn(resizeBy, columnHeader1DraggableDirective);
emulateResizeOnColumn(resizeBy, columnHeader1ColumnSeparatorDebugElement.componentInstance);
expect(columnHeader1Element.classList.contains(STRICT_WIDTH_CLASS)).toBeTrue();
});

it('shrinks other flexible headers if header width expands', function () {
const resizeBy = 20;
emulateResizeOnColumn(resizeBy, columnHeader1DraggableDirective);
emulateResizeOnColumn(resizeBy, columnHeader1ColumnSeparatorDebugElement.componentInstance);
expect(widthOf(columnHeader1Element)).toBe(column1InitialWidth + resizeBy);
expect(widthOf(columnHeader2Element)).toBeLessThan(column2InitialWidth);
expect(widthOf(columnHeader3Element)).toBe(
Expand All @@ -260,7 +254,7 @@ export default function (): void {

it("shouldn't shrink flexible headers below their min-width if header width expands by large amount", function () {
const resizeBy = 1000;
emulateResizeOnColumn(resizeBy, columnHeader1DraggableDirective);
emulateResizeOnColumn(resizeBy, columnHeader1ColumnSeparatorDebugElement.componentInstance);
expect(widthOf(columnHeader1Element)).toBe(column1InitialWidth + resizeBy);
expect(widthOf(columnHeader2Element)).toBe(120);
expect(widthOf(columnHeader3Element)).toBe(
Expand All @@ -272,14 +266,14 @@ export default function (): void {

it('gives header its min-width if a user tried to drag too much to left', function () {
const resizeBy = -1000;
emulateResizeOnColumn(resizeBy, columnHeader1DraggableDirective);
emulateResizeOnColumn(resizeBy, columnHeader1ColumnSeparatorDebugElement.componentInstance);
expect(widthOf(columnHeader1Element)).toBe(96);
});

it('emits new header width once resizing ends', function () {
expect(context.testComponent.newWidth).toBeUndefined();
const resizeBy = 20;
emulateResizeOnColumn(resizeBy, columnHeader3DraggableDirective);
emulateResizeOnColumn(resizeBy, columnHeader3ColumnSeparatorDebugElement.componentInstance);
expect(context.testComponent.newWidth).toBe(column3InitialWidth + resizeBy);
});
});
Expand Down
25 changes: 25 additions & 0 deletions projects/angular/src/utils/cdk/cdk-drag.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2016-2022 VMware, Inc. All Rights Reserved.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/

import { CdkDrag } from '@angular/cdk/drag-drop';
import { Directive, NgModule } from '@angular/core';

/**
* This is just a copy of CdkDrag so it can be used independent of the rest of the CdkDragDropModule.
*/
@Directive({
selector: '[cdkDrag]',
})
export class CdkDragModule_CdkDrag extends CdkDrag {}

/**
* This module allows us to avoid importing all of CdkDragDropModule which results in a smaller application bundle.
*/
@NgModule({
declarations: [CdkDragModule_CdkDrag],
exports: [CdkDragModule_CdkDrag],
})
export class CdkDragModule {}

0 comments on commit 3f93d4c

Please sign in to comment.