From e0f3a0bc50e21df86150f91ee8d1eb9d0537b636 Mon Sep 17 00:00:00 2001 From: Matt Driscoll Date: Wed, 6 Dec 2023 17:18:52 -0800 Subject: [PATCH 1/3] feat(list): Add `calciteListDragStart` and `calciteListDragEnd` events for when a drag starts and ends. --- .../src/components/list/list.tsx | 22 +++++++++- .../sortable-list/sortable-list.tsx | 4 +- .../src/components/value-list/value-list.tsx | 4 +- .../src/utils/sortableComponent.ts | 40 ++++++++++++------- 4 files changed, 50 insertions(+), 20 deletions(-) diff --git a/packages/calcite-components/src/components/list/list.tsx b/packages/calcite-components/src/components/list/list.tsx index 62b140c1f7f..b10cd486b6f 100755 --- a/packages/calcite-components/src/components/list/list.tsx +++ b/packages/calcite-components/src/components/list/list.tsx @@ -220,6 +220,16 @@ export class List */ @Event({ cancelable: false }) calciteListChange: EventEmitter; + /** + * Emits when the component's dragging has ended. + */ + @Event({ cancelable: false }) calciteListDragEnd: EventEmitter; + + /** + * Emits when the component's dragging has started. + */ + @Event({ cancelable: false }) calciteListDragStart: EventEmitter; + /** * Emits when the component's filter has changed. */ @@ -598,14 +608,22 @@ export class List connectSortableComponent(this); } - onDragStart(): void { + onGlobalDragStart(): void { this.disconnectObserver(); } - onDragEnd(): void { + onGlobalDragEnd(): void { this.connectObserver(); } + onDragEnd(): void { + this.calciteListDragEnd.emit(); + } + + onDragStart(): void { + this.calciteListDragStart.emit(); + } + onDragSort(detail: ListDragDetail): void { this.setParentList(); this.updateListItems(); diff --git a/packages/calcite-components/src/components/sortable-list/sortable-list.tsx b/packages/calcite-components/src/components/sortable-list/sortable-list.tsx index 347f95e1bc6..4677d575f5e 100644 --- a/packages/calcite-components/src/components/sortable-list/sortable-list.tsx +++ b/packages/calcite-components/src/components/sortable-list/sortable-list.tsx @@ -146,11 +146,11 @@ export class SortableList implements InteractiveComponent, SortableComponent { // // -------------------------------------------------------------------------- - onDragStart(): void { + onGlobalDragStart(): void { this.endObserving(); } - onDragEnd(): void { + onGlobalDragEnd(): void { this.beginObserving(); } diff --git a/packages/calcite-components/src/components/value-list/value-list.tsx b/packages/calcite-components/src/components/value-list/value-list.tsx index 25780cc7cf6..1e36e7342bb 100644 --- a/packages/calcite-components/src/components/value-list/value-list.tsx +++ b/packages/calcite-components/src/components/value-list/value-list.tsx @@ -333,11 +333,11 @@ export class ValueList< // // -------------------------------------------------------------------------- - onDragStart(): void { + onGlobalDragStart(): void { cleanUpObserver.call(this); } - onDragEnd(): void { + onGlobalDragEnd(): void { initializeObserver.call(this); } diff --git a/packages/calcite-components/src/utils/sortableComponent.ts b/packages/calcite-components/src/utils/sortableComponent.ts index c6865de793b..9348d5c4bab 100644 --- a/packages/calcite-components/src/utils/sortableComponent.ts +++ b/packages/calcite-components/src/utils/sortableComponent.ts @@ -60,19 +60,29 @@ export interface SortableComponent { canPut: (detail: DragDetail) => boolean; /** - * Called by any change to the list (add / update / remove). + * Called when any sortable component drag starts. */ - onDragSort: (detail: DragDetail) => void; + onGlobalDragStart: () => void; + + /** + * Called when any sortable component drag ends. + */ + onGlobalDragEnd: () => void; /** - * Called when a sortable component drag starts. + * Called when a component's dragging ends. */ - onDragStart: () => void; + onDragEnd?: (detail: DragDetail) => void; /** - * Called when a sortable component drag ends. + * Called when a component's dragging starts. */ - onDragEnd: () => void; + onDragStart?: (detail: DragDetail) => void; + + /** + * Called by any change to the list (add / update / remove). + */ + onDragSort: (detail: DragDetail) => void; } export interface SortableComponentItem { @@ -119,13 +129,15 @@ export function connectSortableComponent(component: SortableComponent): void { }), handle, filter: "[drag-disabled]", - onStart: () => { + onStart: ({ from: fromEl, item: dragEl, to: toEl, newIndex, oldIndex }) => { dragState.active = true; - onDragStart(); + onGlobalDragStart(); + component.onDragStart({ fromEl, dragEl, toEl, newIndex, oldIndex }); }, - onEnd: () => { + onEnd: ({ from: fromEl, item: dragEl, to: toEl, newIndex, oldIndex }) => { dragState.active = false; - onDragEnd(); + onGlobalDragEnd(); + component.onDragEnd({ fromEl, dragEl, toEl, newIndex, oldIndex }); }, onSort: ({ from: fromEl, item: dragEl, to: toEl, newIndex, oldIndex }) => { component.onDragSort({ fromEl, dragEl, toEl, newIndex, oldIndex }); @@ -157,10 +169,10 @@ export function dragActive(component: SortableComponent): boolean { return component.dragEnabled && dragState.active; } -function onDragStart(): void { - Array.from(sortableComponentSet).forEach((component) => component.onDragStart()); +function onGlobalDragStart(): void { + Array.from(sortableComponentSet).forEach((component) => component.onGlobalDragStart()); } -function onDragEnd(): void { - Array.from(sortableComponentSet).forEach((component) => component.onDragEnd()); +function onGlobalDragEnd(): void { + Array.from(sortableComponentSet).forEach((component) => component.onGlobalDragEnd()); } From db0e3921a46288c34b832e04ef8e0891acad4815 Mon Sep 17 00:00:00 2001 From: Matt Driscoll Date: Thu, 7 Dec 2023 09:38:30 -0800 Subject: [PATCH 2/3] test --- .../src/components/list/list.e2e.ts | 21 ++++++++++++++++++- .../sortable-list/sortable-list.tsx | 4 ++++ .../src/components/value-list/value-list.tsx | 4 ++++ .../src/utils/sortableComponent.ts | 4 ++-- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/packages/calcite-components/src/components/list/list.e2e.ts b/packages/calcite-components/src/components/list/list.e2e.ts index 27c6c6e9512..db811d55a62 100755 --- a/packages/calcite-components/src/components/list/list.e2e.ts +++ b/packages/calcite-components/src/components/list/list.e2e.ts @@ -659,6 +659,8 @@ describe("calcite-list", () => { calledTimes: number; newIndex: number; oldIndex: number; + startCalledTimes: number; + endCalledTimes: number; }>; it("works using a mouse", async () => { @@ -670,11 +672,19 @@ describe("calcite-list", () => { testWindow.calledTimes = 0; testWindow.newIndex = -1; testWindow.oldIndex = -1; + testWindow.startCalledTimes = 0; + testWindow.endCalledTimes = 0; list.addEventListener("calciteListOrderChange", (event: CustomEvent) => { testWindow.calledTimes++; testWindow.newIndex = event?.detail?.newIndex; testWindow.oldIndex = event?.detail?.oldIndex; }); + list.addEventListener("calciteListDragEnd", () => { + testWindow.endCalledTimes++; + }); + list.addEventListener("calciteListDragStart", () => { + testWindow.startCalledTimes++; + }); }); await dragAndDrop( @@ -696,10 +706,19 @@ describe("calcite-list", () => { const results = await page.evaluate(() => { const testWindow = window as TestWindow; - return { calledTimes: testWindow.calledTimes, oldIndex: testWindow.oldIndex, newIndex: testWindow.newIndex }; + + return { + calledTimes: testWindow.calledTimes, + oldIndex: testWindow.oldIndex, + newIndex: testWindow.newIndex, + endCalledTimes: testWindow.endCalledTimes, + startCalledTimes: testWindow.startCalledTimes, + }; }); expect(results.calledTimes).toBe(1); + expect(results.startCalledTimes).toBe(1); + expect(results.endCalledTimes).toBe(1); expect(results.oldIndex).toBe(0); expect(results.newIndex).toBe(1); }); diff --git a/packages/calcite-components/src/components/sortable-list/sortable-list.tsx b/packages/calcite-components/src/components/sortable-list/sortable-list.tsx index 4677d575f5e..85720792418 100644 --- a/packages/calcite-components/src/components/sortable-list/sortable-list.tsx +++ b/packages/calcite-components/src/components/sortable-list/sortable-list.tsx @@ -154,6 +154,10 @@ export class SortableList implements InteractiveComponent, SortableComponent { this.beginObserving(); } + onDragEnd(): void {} + + onDragStart(): void {} + onDragSort(): void { this.items = Array.from(this.el.children); this.calciteListOrderChange.emit(); diff --git a/packages/calcite-components/src/components/value-list/value-list.tsx b/packages/calcite-components/src/components/value-list/value-list.tsx index 1e36e7342bb..122eff4095f 100644 --- a/packages/calcite-components/src/components/value-list/value-list.tsx +++ b/packages/calcite-components/src/components/value-list/value-list.tsx @@ -341,6 +341,10 @@ export class ValueList< initializeObserver.call(this); } + onDragEnd(): void {} + + onDragStart(): void {} + onDragSort(): void { this.items = Array.from(this.el.querySelectorAll("calcite-value-list-item")); const values = this.items.map((item) => item.value); diff --git a/packages/calcite-components/src/utils/sortableComponent.ts b/packages/calcite-components/src/utils/sortableComponent.ts index 9348d5c4bab..98e74f3ecef 100644 --- a/packages/calcite-components/src/utils/sortableComponent.ts +++ b/packages/calcite-components/src/utils/sortableComponent.ts @@ -72,12 +72,12 @@ export interface SortableComponent { /** * Called when a component's dragging ends. */ - onDragEnd?: (detail: DragDetail) => void; + onDragEnd: (detail: DragDetail) => void; /** * Called when a component's dragging starts. */ - onDragStart?: (detail: DragDetail) => void; + onDragStart: (detail: DragDetail) => void; /** * Called by any change to the list (add / update / remove). From 9bc738d392aebbb731a72f4b4dfc45eb0ac9b7dc Mon Sep 17 00:00:00 2001 From: Matt Driscoll Date: Fri, 8 Dec 2023 10:22:06 -0800 Subject: [PATCH 3/3] add more doc --- packages/calcite-components/src/utils/sortableComponent.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/calcite-components/src/utils/sortableComponent.ts b/packages/calcite-components/src/utils/sortableComponent.ts index 98e74f3ecef..699da0de0eb 100644 --- a/packages/calcite-components/src/utils/sortableComponent.ts +++ b/packages/calcite-components/src/utils/sortableComponent.ts @@ -60,12 +60,12 @@ export interface SortableComponent { canPut: (detail: DragDetail) => boolean; /** - * Called when any sortable component drag starts. + * Called when any sortable component drag starts. For internal use only. Any public drag events should emit within `onDragStart()`. */ onGlobalDragStart: () => void; /** - * Called when any sortable component drag ends. + * Called when any sortable component drag ends. For internal use only. Any public drag events should emit within `onDragEnd()`. */ onGlobalDragEnd: () => void;