From 47f3b157712431c21728798ab757bff9a67b3094 Mon Sep 17 00:00:00 2001 From: jalal246 Date: Sat, 25 Feb 2023 22:35:13 +0200 Subject: [PATCH 1/9] init --- .../src/Element/DFlexCoreElement.ts | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts b/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts index 2061cb653..49ffcb04b 100644 --- a/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts +++ b/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts @@ -385,16 +385,24 @@ class DFlexCoreElement extends DFlexBaseElement { * @param cycleID */ rollBack(DOM: HTMLElement, cycleID: string): void { - if ( - !this.hasTransformed() || - this._translateHistory![this._translateHistory!.length - 1].ID !== cycleID - ) { + if (!Array.isArray(this._translateHistory)) { return; } - const lastMovement = this._translateHistory!.pop()!; + const { length } = this._translateHistory; - const { translate: preTranslate, axis } = lastMovement; + if (length === 0) { + this._translateHistory = undefined; + return; + } + + const stillInSameCycle = this._translateHistory[length - 1].ID === cycleID; + + if (!stillInSameCycle) { + return; + } + + const { translate: preTranslate, axis } = this._translateHistory.pop()!; const elmPos = { x: preTranslate.x - this.translate!.x, From 66e6adc77d069b04574665bf3562e18b6c5db2bf Mon Sep 17 00:00:00 2001 From: jalal246 Date: Sat, 25 Feb 2023 22:37:44 +0200 Subject: [PATCH 2/9] wip --- .../src/Element/DFlexCoreElement.ts | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts b/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts index 49ffcb04b..6b1132837 100644 --- a/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts +++ b/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts @@ -262,30 +262,30 @@ class DFlexCoreElement extends DFlexBaseElement { branchIDsOrder[newIndex] = this.id; } + private _pushToTranslateHistory(axis: Axes, operationID: string) { + const translate = this.translate.getInstance(); + + const elmAxesHistory: TransitionHistory = { + ID: operationID, + axis, + translate, + }; + + if (!Array.isArray(this._translateHistory)) { + this._translateHistory = []; + } + + this._translateHistory.push(elmAxesHistory); + } + /** * Set a new translate position and store the old one. */ private _seTranslate( - axis: Axes, DOM: HTMLElement, elmPos: AxesPoint, - operationID?: string, hasToFlushTransform = false ): void { - if (operationID) { - const elmAxesHistory: TransitionHistory = { - ID: operationID, - axis, - translate: { x: this.translate!.x, y: this.translate!.y }, - }; - - if (Array.isArray(this._translateHistory)) { - this._translateHistory.push(elmAxesHistory); - } else { - this._translateHistory = [elmAxesHistory]; - } - } - this._updateCurrentIndicators(elmPos); if (hasToFlushTransform) { @@ -338,7 +338,8 @@ class DFlexCoreElement extends DFlexBaseElement { elmPos[axis] *= direction; } - this._seTranslate(axis, DOM, elmPos, operationID); + this._pushToTranslateHistory(axis, operationID); + this._seTranslate(DOM, elmPos, false); const { oldIndex, newIndex } = this._updateOrderIndexing( DOM, @@ -422,7 +423,7 @@ class DFlexCoreElement extends DFlexBaseElement { } // Don't update UI if it's zero and wasn't transformed. - this._seTranslate(axis, DOM, elmPos, undefined, true); + this._seTranslate(DOM, elmPos, true); this._updateOrderIndexing(DOM, increment); From 42b42aefb9993d8be7609c2dd46091caa58b0f3b Mon Sep 17 00:00:00 2001 From: jalal246 Date: Sat, 25 Feb 2023 22:40:56 +0200 Subject: [PATCH 3/9] wip --- .../src/Element/DFlexCoreElement.ts | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts b/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts index 6b1132837..122488e11 100644 --- a/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts +++ b/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts @@ -278,16 +278,10 @@ class DFlexCoreElement extends DFlexBaseElement { this._translateHistory.push(elmAxesHistory); } - /** - * Set a new translate position and store the old one. - */ - private _seTranslate( + private _transformOrPend( DOM: HTMLElement, - elmPos: AxesPoint, - hasToFlushTransform = false + hasToFlushTransform: boolean ): void { - this._updateCurrentIndicators(elmPos); - if (hasToFlushTransform) { if (!this.isVisible && this.hasPendingTransform) { this.hasPendingTransform = false; @@ -339,7 +333,8 @@ class DFlexCoreElement extends DFlexBaseElement { } this._pushToTranslateHistory(axis, operationID); - this._seTranslate(DOM, elmPos, false); + this._updateCurrentIndicators(elmPos); + this._transformOrPend(DOM, false); const { oldIndex, newIndex } = this._updateOrderIndexing( DOM, @@ -422,8 +417,9 @@ class DFlexCoreElement extends DFlexBaseElement { this.DOMGrid[axis] += increment; } + this._updateCurrentIndicators(elmPos); // Don't update UI if it's zero and wasn't transformed. - this._seTranslate(DOM, elmPos, true); + this._transformOrPend(DOM, true); this._updateOrderIndexing(DOM, increment); From d43865d03ac0f28b5e51f85b1a90e8ecddb0c204 Mon Sep 17 00:00:00 2001 From: jalal246 Date: Sat, 25 Feb 2023 23:02:46 +0200 Subject: [PATCH 4/9] wip --- .../src/Element/DFlexCoreElement.ts | 91 ++++++++++++------- 1 file changed, 60 insertions(+), 31 deletions(-) diff --git a/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts b/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts index 122488e11..ddd9110c7 100644 --- a/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts +++ b/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts @@ -127,22 +127,18 @@ class DFlexCoreElement extends DFlexBaseElement { this.rect.setByPointAndDimensions(top, left, height, width); } - private _updateCurrentIndicators(newPos: AxesPoint): void { - this.translate!.increase(newPos); - - /** - * This offset related directly to translate Y and Y. It's isolated from - * element current offset and effects only top and left. - */ - this.rect.setAxes( - this._initialPosition.x + this.translate!.x, - this._initialPosition.y + this.translate!.y - ); - - if (!this.isVisible) { - this.hasPendingTransform = true; - } - } + // private _updateCurrentIndicators(newPos: AxesPoint): void { + // this.translate.increase(newPos); + + // /** + // * This offset related directly to translate Y and Y. It's isolated from + // * element current offset and effects only top and left. + // */ + // this.rect.setAxes( + // this._initialPosition.x + this.translate.x, + // this._initialPosition.y + this.translate.y + // ); + // } getDimensions(DOM: HTMLElement): PointNum { if (this._computedDimensions) { @@ -196,7 +192,7 @@ class DFlexCoreElement extends DFlexBaseElement { } this.animatedFrame = requestAnimationFrame(() => { - DFlexCoreElement.transform(DOM, this.translate!.x, this.translate!.y); + DFlexCoreElement.transform(DOM, this.translate.x, this.translate.y); if (this.hasPendingTransform) { this.hasPendingTransform = false; @@ -211,15 +207,15 @@ class DFlexCoreElement extends DFlexBaseElement { this.VDOMOrder.self = i; } - private _updateOrderIndexing(DOM: HTMLElement, i: number) { - const { self: oldIndex } = this.VDOMOrder; + // private _updateOrderIndexing(DOM: HTMLElement, i: number) { + // const { self: oldIndex } = this.VDOMOrder; - const newIndex = oldIndex + i; + // const newIndex = oldIndex + i; - this.updateIndex(DOM, newIndex); + // this.updateIndex(DOM, newIndex); - return { oldIndex, newIndex }; - } + // return { oldIndex, newIndex }; + // } assignNewPosition(branchIDsOrder: string[], newIndex: number): void { if (newIndex < 0 || newIndex > branchIDsOrder.length - 1) { @@ -303,6 +299,34 @@ class DFlexCoreElement extends DFlexBaseElement { this.transform(DOM); } + x( + DOM: HTMLElement, + newPos: AxesPoint, + hasToFlushTransform: boolean, + increment: number + ) { + this.translate.increase(newPos); + + /** + * This offset related directly to translate Y and Y. It's isolated from + * element current offset and effects only top and left. + */ + this.rect.setAxes( + this._initialPosition.x + this.translate.x, + this._initialPosition.y + this.translate.y + ); + + this._transformOrPend(DOM, hasToFlushTransform); + + const { self: oldIndex } = this.VDOMOrder; + + const newIndex = oldIndex + increment; + + this.updateIndex(DOM, newIndex); + + return { oldIndex, newIndex }; + } + /** * * @param DOM @@ -333,11 +357,14 @@ class DFlexCoreElement extends DFlexBaseElement { } this._pushToTranslateHistory(axis, operationID); - this._updateCurrentIndicators(elmPos); - this._transformOrPend(DOM, false); + // this.x(DOM, elmPos, false, direction * numberOfPassedElm); + // this._updateCurrentIndicators(elmPos); + // this._transformOrPend(DOM, false); - const { oldIndex, newIndex } = this._updateOrderIndexing( + const { oldIndex, newIndex } = this.x( DOM, + elmPos, + false, direction * numberOfPassedElm ); @@ -401,8 +428,8 @@ class DFlexCoreElement extends DFlexBaseElement { const { translate: preTranslate, axis } = this._translateHistory.pop()!; const elmPos = { - x: preTranslate.x - this.translate!.x, - y: preTranslate.y - this.translate!.y, + x: preTranslate.x - this.translate.x, + y: preTranslate.y - this.translate.y, }; let increment = 0; @@ -417,11 +444,13 @@ class DFlexCoreElement extends DFlexBaseElement { this.DOMGrid[axis] += increment; } - this._updateCurrentIndicators(elmPos); + this.x(DOM, elmPos, true, increment); + + // this._updateCurrentIndicators(elmPos); // Don't update UI if it's zero and wasn't transformed. - this._transformOrPend(DOM, true); + // this._transformOrPend(DOM, true); - this._updateOrderIndexing(DOM, increment); + // this._updateOrderIndexing(DOM, increment); this.rollBack(DOM, cycleID); } From 7017db0f7100a5b5f016af8149c2e06e8c7d1c4a Mon Sep 17 00:00:00 2001 From: jalal246 Date: Sun, 26 Feb 2023 02:13:09 +0200 Subject: [PATCH 5/9] wip --- .../src/Element/DFlexCoreElement.ts | 44 ++----------------- 1 file changed, 3 insertions(+), 41 deletions(-) diff --git a/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts b/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts index ddd9110c7..9af73b551 100644 --- a/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts +++ b/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts @@ -127,19 +127,6 @@ class DFlexCoreElement extends DFlexBaseElement { this.rect.setByPointAndDimensions(top, left, height, width); } - // private _updateCurrentIndicators(newPos: AxesPoint): void { - // this.translate.increase(newPos); - - // /** - // * This offset related directly to translate Y and Y. It's isolated from - // * element current offset and effects only top and left. - // */ - // this.rect.setAxes( - // this._initialPosition.x + this.translate.x, - // this._initialPosition.y + this.translate.y - // ); - // } - getDimensions(DOM: HTMLElement): PointNum { if (this._computedDimensions) { return this._computedDimensions; @@ -207,16 +194,6 @@ class DFlexCoreElement extends DFlexBaseElement { this.VDOMOrder.self = i; } - // private _updateOrderIndexing(DOM: HTMLElement, i: number) { - // const { self: oldIndex } = this.VDOMOrder; - - // const newIndex = oldIndex + i; - - // this.updateIndex(DOM, newIndex); - - // return { oldIndex, newIndex }; - // } - assignNewPosition(branchIDsOrder: string[], newIndex: number): void { if (newIndex < 0 || newIndex > branchIDsOrder.length - 1) { if (__DEV__) { @@ -299,7 +276,7 @@ class DFlexCoreElement extends DFlexBaseElement { this.transform(DOM); } - x( + private _transformationProcess( DOM: HTMLElement, newPos: AxesPoint, hasToFlushTransform: boolean, @@ -357,11 +334,8 @@ class DFlexCoreElement extends DFlexBaseElement { } this._pushToTranslateHistory(axis, operationID); - // this.x(DOM, elmPos, false, direction * numberOfPassedElm); - // this._updateCurrentIndicators(elmPos); - // this._transformOrPend(DOM, false); - const { oldIndex, newIndex } = this.x( + const { oldIndex, newIndex } = this._transformationProcess( DOM, elmPos, false, @@ -388,12 +362,6 @@ class DFlexCoreElement extends DFlexBaseElement { } } - hasTransformed(): boolean { - return ( - Array.isArray(this._translateHistory) && this._translateHistory.length > 0 - ); - } - hasTransformedFromOrigin(): boolean { return this._initialPosition.isNotEqual(this.rect.left, this.rect.top); } @@ -444,13 +412,7 @@ class DFlexCoreElement extends DFlexBaseElement { this.DOMGrid[axis] += increment; } - this.x(DOM, elmPos, true, increment); - - // this._updateCurrentIndicators(elmPos); - // Don't update UI if it's zero and wasn't transformed. - // this._transformOrPend(DOM, true); - - // this._updateOrderIndexing(DOM, increment); + this._transformationProcess(DOM, elmPos, true, increment); this.rollBack(DOM, cycleID); } From d15a1cfe383f033b86b904ba88f6c48b81bba821 Mon Sep 17 00:00:00 2001 From: jalal246 Date: Sun, 26 Feb 2023 03:07:57 +0200 Subject: [PATCH 6/9] wip --- .../src/Element/DFlexCoreElement.ts | 65 ++++++++++++------- .../src/Draggable/DraggableInteractive.ts | 10 ++- packages/dflex-dnd/src/Mechanism/EndCycle.ts | 2 +- 3 files changed, 47 insertions(+), 30 deletions(-) diff --git a/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts b/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts index 9af73b551..35fd28c34 100644 --- a/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts +++ b/packages/dflex-core-instance/src/Element/DFlexCoreElement.ts @@ -56,6 +56,14 @@ export interface DFlexElementInput { readonly: boolean; } +function resetDOMStyle(DOM: HTMLElement): void { + DOM.style.removeProperty("transform"); + + if (!DOM.getAttribute("style")) { + DOM.removeAttribute("style"); + } +} + class DFlexCoreElement extends DFlexBaseElement { private _initialPosition: PointNum; @@ -168,12 +176,12 @@ class DFlexCoreElement extends DFlexBaseElement { this.isVisible = isVisible; if (this.hasPendingTransform && this.isVisible) { - this.transform(DOM); + this._transform(DOM); this.hasPendingTransform = false; } } - transform(DOM: HTMLElement): void { + private _transform(DOM: HTMLElement, cb?: () => void): void { if (this.animatedFrame !== null) { cancelAnimationFrame(this.animatedFrame); } @@ -185,6 +193,10 @@ class DFlexCoreElement extends DFlexBaseElement { this.hasPendingTransform = false; } + if (cb) { + cb(); + } + this.animatedFrame = null; }); } @@ -194,7 +206,7 @@ class DFlexCoreElement extends DFlexBaseElement { this.VDOMOrder.self = i; } - assignNewPosition(branchIDsOrder: string[], newIndex: number): void { + assignNewIndex(branchIDsOrder: string[], newIndex: number): void { if (newIndex < 0 || newIndex > branchIDsOrder.length - 1) { if (__DEV__) { // eslint-disable-next-line no-console @@ -225,7 +237,7 @@ class DFlexCoreElement extends DFlexBaseElement { branchIDsOrder[newIndex] = this.id; } - private _leaveToNewPosition( + private _leaveToNewIndex( branchIDsOrder: string[], newIndex: number, oldIndex: number @@ -262,7 +274,7 @@ class DFlexCoreElement extends DFlexBaseElement { return; } - this.transform(DOM); + this._transform(DOM); return; } @@ -273,7 +285,7 @@ class DFlexCoreElement extends DFlexBaseElement { return; } - this.transform(DOM); + this._transform(DOM); } private _transformationProcess( @@ -349,7 +361,7 @@ class DFlexCoreElement extends DFlexBaseElement { this.DOMGrid[axis] += direction * numberOfPassedElm; } - this._leaveToNewPosition(siblings, newIndex, oldIndex); + this._leaveToNewIndex(siblings, newIndex, oldIndex); if (__DEV__) { if (featureFlags.enablePositionAssertion) { @@ -362,12 +374,15 @@ class DFlexCoreElement extends DFlexBaseElement { } } - hasTransformedFromOrigin(): boolean { - return this._initialPosition.isNotEqual(this.rect.left, this.rect.top); + restorePosition(DOM: HTMLElement): void { + this._transform(DOM); + + this.setAttribute(DOM, "INDEX", this.VDOMOrder.self); } - needDOMReconciliation(): boolean { - return this.VDOMOrder.self !== this.DOMOrder.self; + assignNewPosition(DOM: HTMLElement, t: PointNum): void { + this.translate.clone(t); + this._transform(DOM); } /** @@ -375,18 +390,13 @@ class DFlexCoreElement extends DFlexBaseElement { * * @param cycleID */ - rollBack(DOM: HTMLElement, cycleID: string): void { + rollBackPosition(DOM: HTMLElement, cycleID: string): void { if (!Array.isArray(this._translateHistory)) { return; } const { length } = this._translateHistory; - if (length === 0) { - this._translateHistory = undefined; - return; - } - const stillInSameCycle = this._translateHistory[length - 1].ID === cycleID; if (!stillInSameCycle) { @@ -414,7 +424,20 @@ class DFlexCoreElement extends DFlexBaseElement { this._transformationProcess(DOM, elmPos, true, increment); - this.rollBack(DOM, cycleID); + if (this._translateHistory.length === 0) { + this._translateHistory = undefined; + return; + } + + this.rollBackPosition(DOM, cycleID); + } + + hasTransformedFromOrigin(): boolean { + return this._initialPosition.isNotEqual(this.rect.left, this.rect.top); + } + + needDOMReconciliation(): boolean { + return this.VDOMOrder.self !== this.DOMOrder.self; } refreshIndicators(DOM: HTMLElement): void { @@ -426,11 +449,7 @@ class DFlexCoreElement extends DFlexBaseElement { this.DOMOrder.self = this.VDOMOrder.self; - DOM.style.removeProperty("transform"); - - if (!DOM.getAttribute("style")) { - DOM.removeAttribute("style"); - } + resetDOMStyle(DOM); this.initElmRect(DOM); diff --git a/packages/dflex-dnd/src/Draggable/DraggableInteractive.ts b/packages/dflex-dnd/src/Draggable/DraggableInteractive.ts index 0c8400350..beba0b6ad 100644 --- a/packages/dflex-dnd/src/Draggable/DraggableInteractive.ts +++ b/packages/dflex-dnd/src/Draggable/DraggableInteractive.ts @@ -136,7 +136,7 @@ class DraggableInteractive extends DraggableAxes { * don't like it but it is what it is. */ if (siblings[VDOMOrder.self] !== id) { - this.draggedElm.assignNewPosition(siblings, VDOMOrder.self); + this.draggedElm.assignNewIndex(siblings, VDOMOrder.self); } // If it didn't move, then do nothing. @@ -144,8 +144,7 @@ class DraggableInteractive extends DraggableAxes { return; } - this.draggedElm.transform(draggedDOM); - this.draggedElm.setAttribute(draggedDOM, "INDEX", VDOMOrder.self); + this.draggedElm.restorePosition(draggedDOM); return; } @@ -167,13 +166,12 @@ class DraggableInteractive extends DraggableAxes { VDOMOrder.self = index; - this.draggedElm.assignNewPosition(siblings, index); + this.draggedElm.assignNewIndex(siblings, index); // If it's going to reconcile to the DOM then there's no need to update the // transformation here. if (!willReconcile) { - translate.clone(this.occupiedTranslate); - this.draggedElm.transform(draggedDOM); + this.draggedElm.assignNewPosition(draggedDOM, this.occupiedTranslate); } } diff --git a/packages/dflex-dnd/src/Mechanism/EndCycle.ts b/packages/dflex-dnd/src/Mechanism/EndCycle.ts index d54d36b41..7b80c7f58 100644 --- a/packages/dflex-dnd/src/Mechanism/EndCycle.ts +++ b/packages/dflex-dnd/src/Mechanism/EndCycle.ts @@ -42,7 +42,7 @@ class EndCycle extends DFlexMechanismController { * Note: rolling back won't affect order array. It only deals with element * itself and totally ignore any instance related to store. */ - dflexElm.rollBack(DOM, cycleID); + dflexElm.rollBackPosition(DOM, cycleID); } } From f534d2500c06326ad7828cf06d67630016ec2a69 Mon Sep 17 00:00:00 2001 From: jalal246 Date: Mon, 27 Feb 2023 19:46:23 +0200 Subject: [PATCH 7/9] init --- .../src/Mechanism/DFlexMechanismController.ts | 14 +++++-- .../src/Mechanism/DFlexPositionUpdater.ts | 39 ++++++++++--------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/packages/dflex-dnd/src/Mechanism/DFlexMechanismController.ts b/packages/dflex-dnd/src/Mechanism/DFlexMechanismController.ts index 8bf85824a..5e73ca000 100644 --- a/packages/dflex-dnd/src/Mechanism/DFlexMechanismController.ts +++ b/packages/dflex-dnd/src/Mechanism/DFlexMechanismController.ts @@ -1,4 +1,4 @@ -import { AxesPoint, featureFlags, PointNum, Tracker } from "@dflex/utils"; +import { AxesPoint, Axis, featureFlags, PointNum, Tracker } from "@dflex/utils"; import { DFLEX_EVENTS, scheduler, store } from "../LayoutManager"; import type DraggableInteractive from "../Draggable"; @@ -274,7 +274,7 @@ class DFlexMechanismController extends DFlexScrollableElement { } } - private _switchElementPosition(isIncrease: boolean): void { + private _switchElementPosition(isIncrease: boolean, axis?: Axis): void { const { draggedElm } = this.draggable; const { SK, index, cycleID } = store.migration.latest(); @@ -294,7 +294,7 @@ class DFlexMechanismController extends DFlexScrollableElement { if (isIDEligible(id, draggedElm.id)) { this.draggable.setDraggedTempIndex(elmIndex); - this.updateElement(id, siblings, cycleID, isIncrease); + this.updateElement(id, siblings, cycleID, isIncrease, axis); } } @@ -407,8 +407,12 @@ class DFlexMechanismController extends DFlexScrollableElement { const { grid: siblingsGrid } = store.containers.get(SK)!; + let axis: Axis; + // Check if top or bottom. if (isOut[id].isOneTruthyByAxis("y")) { + axis = "y"; + const newRow = isOut[id].bottom ? gridPlaceholder.y + 1 : gridPlaceholder.y - 1; @@ -445,6 +449,8 @@ class DFlexMechanismController extends DFlexScrollableElement { return; } + axis = "x"; + const newCol = isOut[id].right ? gridPlaceholder.x + 1 : gridPlaceholder.x - 1; @@ -467,7 +473,7 @@ class DFlexMechanismController extends DFlexScrollableElement { return; } - this._switchElementPosition(isOut[id].right); + this._switchElementPosition(isOut[id].right, axis); } private _lockParent(isOut: boolean) { diff --git a/packages/dflex-dnd/src/Mechanism/DFlexPositionUpdater.ts b/packages/dflex-dnd/src/Mechanism/DFlexPositionUpdater.ts index ef9539eba..c822f7979 100644 --- a/packages/dflex-dnd/src/Mechanism/DFlexPositionUpdater.ts +++ b/packages/dflex-dnd/src/Mechanism/DFlexPositionUpdater.ts @@ -439,7 +439,8 @@ class DFlexPositionUpdater { id: string, siblings: Siblings, cycleID: string, - isIncrease: boolean + isIncrease: boolean, + axis: Axis = "y" ) { if (__DEV__) { // DFLex doesn't have error msg transformer yet for production. @@ -448,30 +449,30 @@ class DFlexPositionUpdater { const [element, DOM] = store.getElmWithDOM(id); - const { - keys: { SK }, - } = element; + // const { + // keys: { SK }, + // } = element; - const { grid: siblingsGrid } = store.containers.get(SK)!; + // const { grid: siblingsGrid } = store.containers.get(SK)!; - const isContainerHasCol = - this.draggable.gridPlaceholder.x + 1 <= siblingsGrid.x; + // const isContainerHasCol = + // this.draggable.gridPlaceholder.x + 1 <= siblingsGrid.x; - let axis: Axis; + // let axis: Axis; - if (isContainerHasCol) { - axis = "x"; - } else { - axis = "y"; + // if (isContainerHasCol) { + // axis = "x"; + // } else { + // axis = "y"; - // const isContainerHasRowAbove = - // this.draggable.gridPlaceholder.y + 1 <= siblingsGrid.y; + // // const isContainerHasRowAbove = + // // this.draggable.gridPlaceholder.y + 1 <= siblingsGrid.y; - // if (isContainerHasRowAbove) { - // // Bi-directional - // axis = "z"; - // } - } + // // if (isContainerHasRowAbove) { + // // // Bi-directional + // // axis = "z"; + // // } + // } if (__DEV__) { if (featureFlags.enableMechanismDebugger) { From 2d7161b082160fdb9fc46cda85b4a3a93b5d5fc5 Mon Sep 17 00:00:00 2001 From: jalal246 Date: Mon, 27 Feb 2023 22:08:14 +0200 Subject: [PATCH 8/9] wip --- .../tests/features/streamInc.spec.ts | 4 +- .../src/Mechanism/DFlexMechanismController.ts | 94 +++++++++++++++---- .../src/Mechanism/DFlexPositionUpdater.ts | 12 +-- packages/dflex-utils/src/Box/BoxNum.ts | 4 + 4 files changed, 86 insertions(+), 28 deletions(-) diff --git a/packages/dflex-dnd-playground/tests/features/streamInc.spec.ts b/packages/dflex-dnd-playground/tests/features/streamInc.spec.ts index 1d9b14a1f..1378958c5 100644 --- a/packages/dflex-dnd-playground/tests/features/streamInc.spec.ts +++ b/packages/dflex-dnd-playground/tests/features/streamInc.spec.ts @@ -74,8 +74,8 @@ test.describe("Stream incremental element then transform mutate and check the ne }); test("Siblings have the correct order in DOM", async () => { - const idsA = []; - const idsB = []; + const idsA: string[] = []; + const idsB: string[] = []; for (let i = 1; i < 5; i += 1) { idsA.push(`a-${i}`); diff --git a/packages/dflex-dnd/src/Mechanism/DFlexMechanismController.ts b/packages/dflex-dnd/src/Mechanism/DFlexMechanismController.ts index 5e73ca000..1f26b7b73 100644 --- a/packages/dflex-dnd/src/Mechanism/DFlexMechanismController.ts +++ b/packages/dflex-dnd/src/Mechanism/DFlexMechanismController.ts @@ -1,5 +1,6 @@ import { AxesPoint, Axis, featureFlags, PointNum, Tracker } from "@dflex/utils"; +import type { DFlexElement } from "@dflex/core-instance"; import { DFLEX_EVENTS, scheduler, store } from "../LayoutManager"; import type DraggableInteractive from "../Draggable"; @@ -13,6 +14,14 @@ import DFlexScrollableElement from "./DFlexScrollableElement"; export function isIDEligible(elmID: string, draggedID: string): boolean { const { registry } = store; + if (__DEV__) { + if (typeof elmID !== "string") { + throw new Error( + `isIDEligible: elmID should be string. Received: ${elmID}` + ); + } + } + return ( elmID.length > 0 && elmID !== draggedID && @@ -21,6 +30,30 @@ export function isIDEligible(elmID: string, draggedID: string): boolean { ); } +function getNextELm(at: number, siblings: string[]): DFlexElement | null { + const nextIndex = at + 1; + + if (nextIndex === siblings.length) { + return null; + } + + const id = siblings[nextIndex]; + + const nextElm = store.registry.get(id); + + if (!nextElm) { + if (__DEV__) { + throw new Error( + `getNextELm: Error in calculating next element. Calculated: ${nextIndex} in ${siblings}` + ); + } + + return null; + } + + return nextElm; +} + class DFlexMechanismController extends DFlexScrollableElement { private isOnDragOutThresholdEvtEmitted: boolean; @@ -274,7 +307,7 @@ class DFlexMechanismController extends DFlexScrollableElement { } } - private _switchElementPosition(isIncrease: boolean, axis?: Axis): void { + private _switchElementPosition(axis: Axis, isIncrease: boolean): void { const { draggedElm } = this.draggable; const { SK, index, cycleID } = store.migration.latest(); @@ -289,6 +322,12 @@ class DFlexMechanismController extends DFlexScrollableElement { // eslint-disable-next-line no-console console.log(`Switching element position to occupy: ${id}`); } + + if (typeof id !== "string") { + throw new Error( + `_switchElementPosition: elmIndex: ${elmIndex} doesn't belong to ${siblings}` + ); + } } if (isIDEligible(id, draggedElm.id)) { @@ -301,7 +340,14 @@ class DFlexMechanismController extends DFlexScrollableElement { /** * Filling the space when the head of the list is leaving the list. */ - private _fillHeadUp(): void { + private _fillHeadUp(axis: Axis): void { + if (__DEV__) { + if (featureFlags.enableMechanismDebugger) { + // eslint-disable-next-line no-console + console.log(`_fillHeadUp on axis ${axis}`); + } + } + const { occupiedPosition, draggedElm, events } = this.draggable; const { migration } = store; @@ -363,7 +409,7 @@ class DFlexMechanismController extends DFlexScrollableElement { const id = siblings[i]; if (isIDEligible(id, draggedElm.id)) { - this.updateElement(id, siblings, cycleID, true); + this.updateElement(id, siblings, cycleID, true, axis); } } } @@ -397,22 +443,34 @@ class DFlexMechanismController extends DFlexScrollableElement { private _draggedOutPositionNotifier(): void { const { - draggedElm: { - id, - keys: { SK }, - }, + draggedElm: { id }, threshold: { isOut }, gridPlaceholder, } = this.draggable; + const { SK, index } = store.migration.latest(); + const { grid: siblingsGrid } = store.containers.get(SK)!; - let axis: Axis; + const siblings = store.getElmSiblingsByKey(SK); + + const nexELm = getNextELm(index, siblings); + + const positionAxis: Axis = nexELm + ? nexELm.rect.isPositionedY(this.draggable.getAbsoluteCurrentPosition()) + ? "y" + : "x" + : "y"; + + if (__DEV__) { + if (featureFlags.enableMechanismDebugger) { + // eslint-disable-next-line no-console + console.log(`Moving on ${positionAxis}.`); + } + } // Check if top or bottom. if (isOut[id].isOneTruthyByAxis("y")) { - axis = "y"; - const newRow = isOut[id].bottom ? gridPlaceholder.y + 1 : gridPlaceholder.y - 1; @@ -421,7 +479,7 @@ class DFlexMechanismController extends DFlexScrollableElement { if (featureFlags.enableMechanismDebugger) { // eslint-disable-next-line no-console console.log( - `Detecting dragged new row: ${newRow}. siblingsGrid-y is ${siblingsGrid.y}` + `Dragged new row: ${newRow}. siblingsGrid-y:${siblingsGrid.y}` ); } } @@ -431,7 +489,7 @@ class DFlexMechanismController extends DFlexScrollableElement { // lock the parent this._lockParent(true); - this._fillHeadUp(); + this._fillHeadUp(positionAxis); return; } @@ -444,13 +502,11 @@ class DFlexMechanismController extends DFlexScrollableElement { return; } - this._switchElementPosition(isOut[id].bottom); + this._switchElementPosition(positionAxis, isOut[id].bottom); return; } - axis = "x"; - const newCol = isOut[id].right ? gridPlaceholder.x + 1 : gridPlaceholder.x - 1; @@ -459,7 +515,7 @@ class DFlexMechanismController extends DFlexScrollableElement { if (featureFlags.enableMechanismDebugger) { // eslint-disable-next-line no-console console.log( - `Detecting dragged new col: ${newCol}. siblingsGrid-x is ${siblingsGrid.x}` + `Dragged new col: ${newCol}. siblingsGrid-x:${siblingsGrid.x}` ); } } @@ -468,12 +524,12 @@ class DFlexMechanismController extends DFlexScrollableElement { // lock the parent this._lockParent(true); - this._fillHeadUp(); + this._fillHeadUp(positionAxis); return; } - this._switchElementPosition(isOut[id].right, axis); + this._switchElementPosition(positionAxis, isOut[id].right); } private _lockParent(isOut: boolean) { @@ -510,7 +566,7 @@ class DFlexMechanismController extends DFlexScrollableElement { if (!(isOutSiblingsContainer || this.isParentLocked)) { this._lockParent(true); - this._fillHeadUp(); + this._fillHeadUp("y"); } }, }); diff --git a/packages/dflex-dnd/src/Mechanism/DFlexPositionUpdater.ts b/packages/dflex-dnd/src/Mechanism/DFlexPositionUpdater.ts index c822f7979..accfa14e7 100644 --- a/packages/dflex-dnd/src/Mechanism/DFlexPositionUpdater.ts +++ b/packages/dflex-dnd/src/Mechanism/DFlexPositionUpdater.ts @@ -445,6 +445,11 @@ class DFlexPositionUpdater { if (__DEV__) { // DFLex doesn't have error msg transformer yet for production. throwOnInfiniteTransformation(id); + + if (featureFlags.enableMechanismDebugger) { + // eslint-disable-next-line no-console + console.log(`updateElement ${id}`); + } } const [element, DOM] = store.getElmWithDOM(id); @@ -474,13 +479,6 @@ class DFlexPositionUpdater { // // } // } - if (__DEV__) { - if (featureFlags.enableMechanismDebugger) { - // eslint-disable-next-line no-console - console.log(`Switching element on axis: ${axis}`); - } - } - const elmDirection: Direction = isIncrease ? -1 : 1; this.updateIndicators(element, axis, elmDirection); diff --git a/packages/dflex-utils/src/Box/BoxNum.ts b/packages/dflex-utils/src/Box/BoxNum.ts index 43bca7959..f91b3fd24 100644 --- a/packages/dflex-utils/src/Box/BoxNum.ts +++ b/packages/dflex-utils/src/Box/BoxNum.ts @@ -50,6 +50,10 @@ class BoxNum extends Box { isOutside(box: BoxNum): boolean { return !this.isInside(box); } + + isPositionedY(box: BoxNum) { + return this.bottom >= box.top || this.top <= box.bottom; + } } export default BoxNum; From 62383e9861de3b1de8efc1bd0f6a68491189df34 Mon Sep 17 00:00:00 2001 From: jalal246 Date: Tue, 28 Feb 2023 03:55:03 +0200 Subject: [PATCH 9/9] wip --- .../tests/horizontal/switchPositions.spec.ts | 62 +++++++++++++++++++ .../src/Draggable/DraggableInteractive.ts | 18 +++--- .../src/Mechanism/DFlexMechanismController.ts | 29 ++++++--- .../src/Mechanism/DFlexPositionUpdater.ts | 14 ++--- packages/dflex-utils/src/Box/Box.ts | 5 ++ packages/dflex-utils/src/Box/BoxNum.ts | 41 ++++++++++-- 6 files changed, 140 insertions(+), 29 deletions(-) create mode 100644 packages/dflex-dnd-playground/tests/horizontal/switchPositions.spec.ts diff --git a/packages/dflex-dnd-playground/tests/horizontal/switchPositions.spec.ts b/packages/dflex-dnd-playground/tests/horizontal/switchPositions.spec.ts new file mode 100644 index 000000000..f6ee7f148 --- /dev/null +++ b/packages/dflex-dnd-playground/tests/horizontal/switchPositions.spec.ts @@ -0,0 +1,62 @@ +import { + test, + Page, + Locator, + BrowserContext, + Browser, + expect, +} from "@playwright/test"; + +import { + assertDefaultChildrenIndex, + getDraggedRect, + initialize, + moveDragged, +} from "../utils"; + +test.describe("Stream incremental element then transform mutate and check the new positions", async () => { + let page: Page; + let context: BrowserContext; + let activeBrowser: Browser; + + let elmGrandParent: Locator; + + let elmP1: Locator; + let elmP2: Locator; + let elmP3: Locator; + + test.beforeAll(async ({ browser, browserName, baseURL }) => { + activeBrowser = browser; + + context = await activeBrowser.newContext(); + page = await context.newPage(); + initialize(page, browserName); + await page.goto(baseURL!); + + [elmGrandParent, elmP1, elmP2, elmP3] = await Promise.all([ + page.locator("#dflex_id_0"), + page.locator("#id-p1"), + page.locator("#id-p2"), + page.locator("#id-p3"), + ]); + }); + + test.afterAll(async () => { + await page.close(); + await context.close(); + // await activeBrowser.close(); + }); + + test("Siblings index initiated correctly at depth: 1", async () => { + await assertDefaultChildrenIndex(elmGrandParent); + }); + + test("Transforms element (#id-p3) to the left", async () => { + await getDraggedRect(elmP3); + await moveDragged(-230, -1); + await page.dispatchEvent("#id-p3", "mouseup", { + button: 0, + force: true, + }); + }); +}); diff --git a/packages/dflex-dnd/src/Draggable/DraggableInteractive.ts b/packages/dflex-dnd/src/Draggable/DraggableInteractive.ts index beba0b6ad..51f703f03 100644 --- a/packages/dflex-dnd/src/Draggable/DraggableInteractive.ts +++ b/packages/dflex-dnd/src/Draggable/DraggableInteractive.ts @@ -1,6 +1,7 @@ import { AbstractDFlexCycle, assertElementPosition, + BoxNum, featureFlags, PointNum, } from "@dflex/utils"; @@ -19,7 +20,7 @@ class DraggableInteractive extends DraggableAxes { enableCommit: Commit; - occupiedPosition: PointNum; + occupiedPosition: BoxNum; occupiedTranslate: PointNum; @@ -83,7 +84,13 @@ class DraggableInteractive extends DraggableAxes { this.setDOMAttrAndStyle(this.draggedDOM, null, true, false, null, null); } - this.occupiedPosition = new PointNum(rect.left, rect.top); + this.occupiedPosition = new BoxNum( + rect.top, + rect.right, + rect.bottom, + rect.left + ); + this.occupiedTranslate = new PointNum(translate.x, translate.y); } @@ -126,7 +133,7 @@ class DraggableInteractive extends DraggableAxes { const hasToUndo = isFallback || // dragged in position but has been clicked. - this.occupiedPosition.isEqual(rect.left, rect.top); + this.occupiedPosition.hasSamePoint(rect); if (hasToUndo) { /** @@ -149,10 +156,7 @@ class DraggableInteractive extends DraggableAxes { return; } - this.draggedElm.rect.setAxes( - this.occupiedPosition.x, - this.occupiedPosition.y - ); + this.draggedElm.rect.clone(this.occupiedPosition); if (__DEV__) { if (featureFlags.enablePositionAssertion) { diff --git a/packages/dflex-dnd/src/Mechanism/DFlexMechanismController.ts b/packages/dflex-dnd/src/Mechanism/DFlexMechanismController.ts index 1f26b7b73..20fba47e1 100644 --- a/packages/dflex-dnd/src/Mechanism/DFlexMechanismController.ts +++ b/packages/dflex-dnd/src/Mechanism/DFlexMechanismController.ts @@ -30,8 +30,12 @@ export function isIDEligible(elmID: string, draggedID: string): boolean { ); } -function getNextELm(at: number, siblings: string[]): DFlexElement | null { - const nextIndex = at + 1; +function getDirectSibling( + at: number, + siblings: string[], + isNext: boolean +): DFlexElement | null { + const nextIndex = isNext ? at + 1 : at - 1; if (nextIndex === siblings.length) { return null; @@ -280,7 +284,7 @@ class DFlexMechanismController extends DFlexScrollableElement { // placeholder as all the elements are stacked. origin.pop(); - this.draggable.occupiedPosition.clone(this.listAppendPosition!); + this.draggable.occupiedPosition.setPosition(this.listAppendPosition!); this.draggable.gridPlaceholder.setAxes(1, 1); @@ -365,7 +369,7 @@ class DFlexMechanismController extends DFlexScrollableElement { // Store it before lost it when the index is changed to the next one. migration.preserveVerticalMargin( "top", - occupiedPosition.y - prevElm.rect.bottom + occupiedPosition.top - prevElm.rect.bottom ); } @@ -388,7 +392,7 @@ class DFlexMechanismController extends DFlexScrollableElement { // Store it before lost it when the index is changed to the next one. migration.preserveVerticalMargin( "bottom", - nextElm.rect.top - (occupiedPosition.y + draggedElm.rect.height) + nextElm.rect.top - (occupiedPosition.top + draggedElm.rect.height) ); events.dispatch(DFLEX_EVENTS.ON_LIFT_UP, { @@ -446,6 +450,7 @@ class DFlexMechanismController extends DFlexScrollableElement { draggedElm: { id }, threshold: { isOut }, gridPlaceholder, + occupiedPosition, } = this.draggable; const { SK, index } = store.migration.latest(); @@ -454,13 +459,17 @@ class DFlexMechanismController extends DFlexScrollableElement { const siblings = store.getElmSiblingsByKey(SK); - const nexELm = getNextELm(index, siblings); + const isDraggedLastElm = siblings.length - 1 === index; - const positionAxis: Axis = nexELm - ? nexELm.rect.isPositionedY(this.draggable.getAbsoluteCurrentPosition()) + const nextOrPrevElm = getDirectSibling(index, siblings, !isDraggedLastElm); + + let positionAxis: Axis = "y"; + + if (nextOrPrevElm) { + positionAxis = nextOrPrevElm.rect.isPositionedY(occupiedPosition) ? "y" - : "x" - : "y"; + : "x"; + } if (__DEV__) { if (featureFlags.enableMechanismDebugger) { diff --git a/packages/dflex-dnd/src/Mechanism/DFlexPositionUpdater.ts b/packages/dflex-dnd/src/Mechanism/DFlexPositionUpdater.ts index accfa14e7..d7ce74ac3 100644 --- a/packages/dflex-dnd/src/Mechanism/DFlexPositionUpdater.ts +++ b/packages/dflex-dnd/src/Mechanism/DFlexPositionUpdater.ts @@ -213,9 +213,9 @@ class DFlexPositionUpdater { ) { const { occupiedPosition, draggedElm } = this.draggable; - const positionDiff = Math.abs( - element.rect[axis === "x" ? "left" : "top"] - occupiedPosition[axis] - ); + const b = axis === "x" ? "left" : "top"; + + const positionDiff = Math.abs(element.rect[b] - occupiedPosition[b]); const rectDiff = element.getRectDiff(draggedElm, axis); @@ -235,10 +235,10 @@ class DFlexPositionUpdater { private updateDraggable(element: DFlexElement, elmDirection: Direction) { const { rect, DOMGrid: grid } = element; - this.draggable.occupiedPosition.setAxes( - rect.left + this.draggedPositionOffset.x, - rect.top + this.draggedPositionOffset.y - ); + this.draggable.occupiedPosition.setPosition({ + x: rect.left + this.draggedPositionOffset.x, + y: rect.top + this.draggedPositionOffset.y, + }); const draggedDirection = -1 * elmDirection; diff --git a/packages/dflex-utils/src/Box/Box.ts b/packages/dflex-utils/src/Box/Box.ts index e67138422..d6bde7bad 100644 --- a/packages/dflex-utils/src/Box/Box.ts +++ b/packages/dflex-utils/src/Box/Box.ts @@ -99,6 +99,11 @@ class Box extends AbstractBox { } } + setPosition(point: AxesPoint) { + this.top = point.y; + this.left = point.x; + } + /** * Get starting point instance. * diff --git a/packages/dflex-utils/src/Box/BoxNum.ts b/packages/dflex-utils/src/Box/BoxNum.ts index f91b3fd24..4cf624102 100644 --- a/packages/dflex-utils/src/Box/BoxNum.ts +++ b/packages/dflex-utils/src/Box/BoxNum.ts @@ -1,6 +1,33 @@ import Box from "./Box"; class BoxNum extends Box { + clone(box: BoxNum) { + this.left = box.left; + this.top = box.top; + this.right = box.right; + this.bottom = box.bottom; + } + + hasSamePoint(box: BoxNum) { + return this.left === box.left && this.top === box.top; + } + + isUnder(box: BoxNum) { + return this.top > box.bottom; + } + + isAbove(box: BoxNum) { + return this.bottom < box.top; + } + + isOnLeft(box: BoxNum) { + return this.right < box.left; + } + + isOneRight(box: BoxNum) { + return this.left > box.right; + } + /** * True when it's not intersected with other box. * @@ -9,10 +36,10 @@ class BoxNum extends Box { */ isNotIntersect(box: BoxNum): boolean { return ( - this.top > box.bottom || - this.right < box.left || - this.bottom < box.top || - this.left > box.right + this.isUnder(box) || + this.isOnLeft(box) || + this.isAbove(box) || + this.isOneRight(box) ); } @@ -52,7 +79,11 @@ class BoxNum extends Box { } isPositionedY(box: BoxNum) { - return this.bottom >= box.top || this.top <= box.bottom; + return ( + (this.isUnder(box) || this.isAbove(box)) && + !this.isOnLeft(box) && + !this.isOneRight(box) + ); } }