@dflex/core-instance
Advanced tools
Comparing version 3.3.1 to 3.3.2
@@ -1,2 +0,2 @@ | ||
import type { AxesCoordinatesInterface } from "@dflex/utils"; | ||
import type { IPointNum } from "@dflex/utils"; | ||
import type { AbstractInterface, AbstractInput, AbstractOpts, AllowedAttributes, AllowedDataset } from "./types"; | ||
@@ -6,3 +6,3 @@ declare class AbstractInstance implements AbstractInterface { | ||
id: string; | ||
translate: AxesCoordinatesInterface; | ||
translate: IPointNum; | ||
isInitialized: boolean; | ||
@@ -9,0 +9,0 @@ isPaused: boolean; |
@@ -61,3 +61,3 @@ "use strict"; | ||
if (!this.translate) { | ||
this.translate = new utils_1.AxesCoordinates(0, 0); | ||
this.translate = new utils_1.PointNum(0, 0); | ||
// @ts-expect-error - Just for initialization. | ||
@@ -69,3 +69,3 @@ this.hasAttribute = {}; | ||
setDataset(key, value) { | ||
if (key === "index") { | ||
if (key === "index" || key === "gridX" || key === "gridY") { | ||
this.ref.dataset[key] = `${value}`; | ||
@@ -72,0 +72,0 @@ return; |
@@ -1,10 +0,10 @@ | ||
import { AxesCoordinates } from "@dflex/utils"; | ||
import type { RectDimensions, EffectedElemDirection, Axes, AxesCoordinatesInterface } from "@dflex/utils"; | ||
import { PointNum } from "@dflex/utils"; | ||
import type { RectDimensions, EffectedElemDirection, Axis, IPointNum } from "@dflex/utils"; | ||
import AbstractInstance from "./AbstractInstance"; | ||
import type { Keys, Order, TransitionHistory, CoreInput, AbstractOpts, CoreInstanceInterface } from "./types"; | ||
import type { Keys, Order, CoreInput, AbstractOpts, CoreInstanceInterface } from "./types"; | ||
declare class CoreInstance extends AbstractInstance implements CoreInstanceInterface { | ||
#private; | ||
offset: RectDimensions; | ||
translateHistory?: AxesCoordinatesInterface<TransitionHistory>; | ||
currentPosition: AxesCoordinatesInterface; | ||
grid: AxesCoordinatesInterface; | ||
currentPosition: IPointNum; | ||
grid: IPointNum; | ||
order: Order; | ||
@@ -16,34 +16,11 @@ keys: Keys; | ||
animatedFrame: number | null; | ||
constructor(elementWithPointer: CoreInput, opts: AbstractOpts); | ||
/** | ||
* Initializes the element offset only when it's called. Since it is storing | ||
* different numbers related to transformation we don't need to invoke for | ||
* idle element because it's costly. | ||
* | ||
* @param scrollX | ||
* @param scrollY | ||
*/ | ||
private initIndicators; | ||
constructor(eleWithPointer: CoreInput, opts: AbstractOpts); | ||
resume(scrollX: number, scrollY: number): void; | ||
changeVisibility(isVisible: boolean): void; | ||
private updateCurrentIndicators; | ||
isPositionedUnder(elmY: number): boolean; | ||
isPositionedLeft(elmX: number): boolean; | ||
transformElm(): void; | ||
/** | ||
* Update element index in siblings branch | ||
* | ||
* @param i - index | ||
*/ | ||
private updateOrderIndexing; | ||
assignNewPosition(branchIDsOrder: string[], newIndex: number, oldIndex?: number, siblingsEmptyElmIndex?: number): number; | ||
/** | ||
* Set a new translate position and store the old one. | ||
* | ||
* @param elmSpace - | ||
* @param operationID - Only if moving to a new position. | ||
*/ | ||
private seTranslate; | ||
/** | ||
* | ||
* @param iDsInOrder - | ||
@@ -56,3 +33,3 @@ * @param effectedElemDirection - (+1/-1) | ||
*/ | ||
setPosition(iDsInOrder: string[], effectedElemDirection: EffectedElemDirection, elmSpace: AxesCoordinates, operationID: string, siblingsEmptyElmIndex: AxesCoordinates, axes: Axes, numberOfPassedElm?: number, isShuffle?: boolean): number; | ||
setPosition(iDsInOrder: string[], effectedElemDirection: EffectedElemDirection, elmSpace: PointNum, operationID: string, siblingsEmptyElmIndex: PointNum, axis: Axis, numberOfPassedElm?: number, isShuffle?: boolean): number; | ||
/** | ||
@@ -63,6 +40,6 @@ * Roll back element position. | ||
* @param isForceTransform | ||
* @param axes | ||
* @param axis | ||
*/ | ||
rollBack(operationID: string, isForceTransform: boolean, axes: Axes): void; | ||
rollBack(operationID: string, isForceTransform: boolean, axis: Axis): void; | ||
} | ||
export default CoreInstance; |
@@ -11,3 +11,2 @@ "use strict"; | ||
offset; | ||
translateHistory; | ||
currentPosition; | ||
@@ -21,4 +20,5 @@ grid; | ||
animatedFrame; | ||
constructor(elementWithPointer, opts) { | ||
const { order, keys, depth, scrollX, scrollY, ...element } = elementWithPointer; | ||
#translateHistory; | ||
constructor(eleWithPointer, opts) { | ||
const { order, keys, depth, scrollX, scrollY, ...element } = eleWithPointer; | ||
super(element, opts); | ||
@@ -33,15 +33,7 @@ this.order = order; | ||
if (!this.isPaused) { | ||
this.initIndicators(scrollX, scrollY); | ||
this.#initIndicators(scrollX, scrollY); | ||
} | ||
this.animatedFrame = null; | ||
} | ||
/** | ||
* Initializes the element offset only when it's called. Since it is storing | ||
* different numbers related to transformation we don't need to invoke for | ||
* idle element because it's costly. | ||
* | ||
* @param scrollX | ||
* @param scrollY | ||
*/ | ||
initIndicators(scrollX, scrollY) { | ||
#initIndicators(scrollX, scrollY) { | ||
const { height, width, left, top } = this.ref.getBoundingClientRect(); | ||
@@ -59,6 +51,21 @@ /** | ||
}; | ||
this.currentPosition = new utils_1.AxesCoordinates(this.offset.left, this.offset.top); | ||
this.grid = new utils_1.AxesCoordinates(0, 0); | ||
this.currentPosition = new utils_1.PointNum(this.offset.left, this.offset.top); | ||
/** | ||
* Initializing grid comes later when the siblings boundaries are | ||
* initialized and the element is visible. | ||
*/ | ||
this.grid = new utils_1.PointNum(0, 0); | ||
this.hasToTransform = false; | ||
} | ||
#updateCurrentIndicators(leftSpace, topSpace) { | ||
this.translate.increase(leftSpace, topSpace); | ||
const { left, top } = this.offset; | ||
/** | ||
* This offset related directly to translate Y and Y. It's isolated from | ||
* element current offset and effects only top and left. | ||
*/ | ||
this.currentPosition.setAxes(left + this.translate.x, top + this.translate.y); | ||
if (!this.isVisible) | ||
this.hasToTransform = true; | ||
} | ||
resume(scrollX, scrollY) { | ||
@@ -68,3 +75,3 @@ if (!this.isInitialized) | ||
this.initTranslate(); | ||
this.initIndicators(scrollX, scrollY); | ||
this.#initIndicators(scrollX, scrollY); | ||
} | ||
@@ -80,13 +87,2 @@ changeVisibility(isVisible) { | ||
} | ||
updateCurrentIndicators(leftSpace, topSpace) { | ||
this.translate.setAxes(this.translate.x + leftSpace, this.translate.y + topSpace); | ||
const { left, top } = this.offset; | ||
/** | ||
* This offset related directly to translate Y and Y. It's isolated from | ||
* element current offset and effects only top and left. | ||
*/ | ||
this.currentPosition.setAxes(left + this.translate.x, top + this.translate.y); | ||
if (!this.isVisible) | ||
this.hasToTransform = true; | ||
} | ||
isPositionedUnder(elmY) { | ||
@@ -107,11 +103,7 @@ return elmY < this.currentPosition.y; | ||
} | ||
/** | ||
* Update element index in siblings branch | ||
* | ||
* @param i - index | ||
*/ | ||
updateOrderIndexing(i) { | ||
#updateOrderIndexing(i) { | ||
const { self: oldIndex } = this.order; | ||
const newIndex = oldIndex + i; | ||
this.order.self = newIndex; | ||
this.setDataset("index", newIndex); | ||
return { oldIndex, newIndex }; | ||
@@ -145,3 +137,2 @@ } | ||
branchIDsOrder[newIndex] = this.id; | ||
this.setDataset("index", newIndex); | ||
return oldIndex; | ||
@@ -151,27 +142,24 @@ } | ||
* Set a new translate position and store the old one. | ||
* | ||
* @param elmSpace - | ||
* @param operationID - Only if moving to a new position. | ||
*/ | ||
seTranslate(elmSpace, axes, operationID, isForceTransform = false) { | ||
#seTranslate(elmSpace, axis, operationID, isForceTransform = false) { | ||
if (operationID) { | ||
const elmAxesHistory = { | ||
ID: operationID, | ||
pre: this.translate[axes], | ||
translate: this.translate[axis], | ||
}; | ||
if (!this.translateHistory) { | ||
this.translateHistory = | ||
axes === "x" | ||
? new utils_1.AxesCoordinates([elmAxesHistory], []) | ||
: new utils_1.AxesCoordinates([], [elmAxesHistory]); | ||
if (!this.#translateHistory) { | ||
this.#translateHistory = | ||
axis === "x" | ||
? new utils_1.Point([elmAxesHistory], []) | ||
: new utils_1.Point([], [elmAxesHistory]); | ||
} | ||
else { | ||
this.translateHistory[axes].push(elmAxesHistory); | ||
this.#translateHistory[axis].push(elmAxesHistory); | ||
} | ||
} | ||
if (axes === "x") { | ||
this.updateCurrentIndicators(elmSpace, 0); | ||
if (axis === "x") { | ||
this.#updateCurrentIndicators(elmSpace, 0); | ||
} | ||
else { | ||
this.updateCurrentIndicators(0, elmSpace); | ||
this.#updateCurrentIndicators(0, elmSpace); | ||
} | ||
@@ -194,3 +182,3 @@ if (!isForceTransform && !this.isVisible) { | ||
*/ | ||
setPosition(iDsInOrder, effectedElemDirection, elmSpace, operationID, siblingsEmptyElmIndex, axes, numberOfPassedElm = 1, isShuffle = true) { | ||
setPosition(iDsInOrder, effectedElemDirection, elmSpace, operationID, siblingsEmptyElmIndex, axis, numberOfPassedElm = 1, isShuffle = true) { | ||
/** | ||
@@ -200,6 +188,15 @@ * effectedElemDirection decides the direction of the element, negative or positive. | ||
*/ | ||
elmSpace[axes] *= effectedElemDirection[axes]; | ||
this.seTranslate(elmSpace[axes], axes, operationID); | ||
const { oldIndex, newIndex } = this.updateOrderIndexing(effectedElemDirection[axes] * numberOfPassedElm); | ||
const newStatusSiblingsHasEmptyElm = this.assignNewPosition(iDsInOrder, newIndex, isShuffle ? oldIndex : undefined, siblingsEmptyElmIndex[axes]); | ||
elmSpace[axis] *= effectedElemDirection[axis]; | ||
this.#seTranslate(elmSpace[axis], axis, operationID); | ||
const { oldIndex, newIndex } = this.#updateOrderIndexing(effectedElemDirection[axis] * numberOfPassedElm); | ||
this.grid[axis] += effectedElemDirection[axis] * numberOfPassedElm; | ||
if (process.env.NODE_ENV !== "production") { | ||
// if (this.grid[axis] !== newIndex + 1) { | ||
// throw new Error( | ||
// `Grid: is ${this.grid[axis]} while the new index is ${newIndex}` | ||
// ); | ||
// } | ||
this.setDataset(`grid${axis.toUpperCase()}`, this.grid[axis]); | ||
} | ||
const newStatusSiblingsHasEmptyElm = this.assignNewPosition(iDsInOrder, newIndex, isShuffle ? oldIndex : undefined, siblingsEmptyElmIndex[axis]); | ||
return newStatusSiblingsHasEmptyElm; | ||
@@ -212,25 +209,31 @@ } | ||
* @param isForceTransform | ||
* @param axes | ||
* @param axis | ||
*/ | ||
rollBack(operationID, isForceTransform, axes) { | ||
if (!this.translateHistory || | ||
!this.translateHistory[axes] || | ||
this.translateHistory[axes].length === 0 || | ||
this.translateHistory[axes][this.translateHistory[axes].length - 1].ID !== | ||
operationID) { | ||
rollBack(operationID, isForceTransform, axis) { | ||
if (this.#translateHistory[axis].length === 0 || | ||
this.#translateHistory[axis][this.#translateHistory[axis].length - 1] | ||
.ID !== operationID) { | ||
return; | ||
} | ||
const lastMovement = this.translateHistory[axes].pop(); | ||
const lastMovement = this.#translateHistory[axis].pop(); | ||
if (!lastMovement) | ||
return; | ||
const { pre } = lastMovement; | ||
const elmSpace = pre - this.translate[axes]; | ||
const { translate: preTranslate } = lastMovement; | ||
const elmSpace = preTranslate - this.translate[axis]; | ||
const increment = elmSpace > 0 ? 1 : -1; | ||
// Don't update UI if it's zero and wasn't transformed. | ||
this.seTranslate(elmSpace, axes, undefined, isForceTransform); | ||
const { newIndex } = this.updateOrderIndexing(increment); | ||
this.setDataset("index", newIndex); | ||
this.rollBack(operationID, isForceTransform, axes); | ||
this.#seTranslate(elmSpace, axis, undefined, isForceTransform); | ||
this.#updateOrderIndexing(increment); | ||
this.grid[axis] += increment; | ||
if (process.env.NODE_ENV !== "production") { | ||
// if (this.grid[axis] !== newIndex + 1) { | ||
// throw new Error( | ||
// `Grid: is ${this.grid[axis]} while the new index is ${newIndex}` | ||
// ); | ||
// } | ||
this.setDataset(`grid${axis.toUpperCase()}`, this.grid[axis]); | ||
} | ||
this.rollBack(operationID, isForceTransform, axis); | ||
} | ||
} | ||
exports.default = CoreInstance; |
@@ -1,2 +0,2 @@ | ||
import type { AxesCoordinatesInterface, RectDimensions, Axes, EffectedElemDirection } from "@dflex/utils"; | ||
import type { RectDimensions, Axis, EffectedElemDirection, IPointNum } from "@dflex/utils"; | ||
export interface AbstractOpts { | ||
@@ -10,11 +10,11 @@ isInitialized: boolean; | ||
}; | ||
export declare type AllowedDataset = "index" | "draggedOutPosition" | "draggedOutContainer"; | ||
export declare type AllowedDataset = "gridX" | "gridY" | "index" | "draggedOutPosition" | "draggedOutContainer"; | ||
export declare type AllowedAttributes = "dragged"; | ||
export declare type AttributesIndicators = Exclude<AllowedDataset, "index"> | AllowedAttributes; | ||
export interface AbstractInterface { | ||
isInitialized: boolean; | ||
readonly isInitialized: boolean; | ||
isPaused: boolean; | ||
ref: HTMLElement | null; | ||
id: string; | ||
translate: AxesCoordinatesInterface; | ||
readonly ref: HTMLElement | null; | ||
readonly id: string; | ||
readonly translate: IPointNum; | ||
attach(ref: HTMLElement | null): void; | ||
@@ -61,13 +61,11 @@ detach(): void; | ||
ID: string; | ||
pre: number; | ||
}[]; | ||
translate: number; | ||
}; | ||
export interface CoreInstanceInterface extends AbstractInterface { | ||
/** Initial read-only element offset */ | ||
readonly offset: RectDimensions; | ||
/** Store history of Y-transition according to unique ID. */ | ||
translateHistory?: AxesCoordinatesInterface<TransitionHistory>; | ||
/** Current element offset (x-left, y-top) */ | ||
currentPosition: AxesCoordinatesInterface; | ||
currentPosition: IPointNum; | ||
/** Element position in the grid container. */ | ||
grid: AxesCoordinatesInterface; | ||
grid: IPointNum; | ||
/** Element visibility in the scroll container. */ | ||
@@ -77,5 +75,5 @@ isVisible: boolean; | ||
animatedFrame: number | null; | ||
order: Order; | ||
keys: Keys; | ||
depth: number; | ||
readonly order: Order; | ||
readonly keys: Keys; | ||
readonly depth: number; | ||
isPositionedUnder(elmY: number): boolean; | ||
@@ -85,6 +83,6 @@ isPositionedLeft(elmX: number): boolean; | ||
changeVisibility(isVisible: boolean): void; | ||
setPosition(iDsInOrder: string[], effectedElemDirection: EffectedElemDirection, elmSpace: AxesCoordinatesInterface, operationID: string, siblingsEmptyElmIndex: AxesCoordinatesInterface, axes: Axes, vIncrement?: number, isShuffle?: boolean): number; | ||
setPosition(iDsInOrder: string[], effectedElemDirection: EffectedElemDirection, elmSpace: IPointNum, operationID: string, siblingsEmptyElmIndex: IPointNum, axis: Axis, vIncrement?: number, isShuffle?: boolean): number; | ||
transformElm(): void; | ||
assignNewPosition(branchIDsOrder: string[], newIndex: number, oldIndex?: number, siblingsHasEmptyElm?: number): number; | ||
rollBack(operationID: string, isForceTransform: boolean, axes: Axes): void; | ||
rollBack(operationID: string, isForceTransform: boolean, axis: Axis): void; | ||
} |
{ | ||
"name": "@dflex/core-instance", | ||
"version": "3.3.1", | ||
"version": "3.3.2", | ||
"main": "dist/index.js", | ||
@@ -19,3 +19,3 @@ "types": "dist/index.d.ts", | ||
"dependencies": { | ||
"@dflex/utils": "^3.3.1" | ||
"@dflex/utils": "^3.3.2" | ||
}, | ||
@@ -42,3 +42,3 @@ "keywords": [ | ||
}, | ||
"gitHead": "f1f6f51e5b66462e307cb368c77be9038894ddb9" | ||
"gitHead": "017d629fcf9db3352d54f21f5c59764096e3c40b" | ||
} |
@@ -9,2 +9,4 @@ <h1 align="center"> | ||
<h1 align="center">DFlex Core</h1> | ||
<p align="center"> | ||
@@ -35,2 +37,60 @@ <a href="https://github.com/dflex-js/dflex"> | ||
Visit DFlex site for more <https://www.dflex.dev/> | ||
Core instance is the mirror of interactive element that includes all the | ||
properties and methods to manipulate the node. | ||
## DFlex Features ✅ | ||
- Dynamic architecture. | ||
- Traverse DOM without calling browser API. | ||
- Transform elements instead of reordering the DOM tree. | ||
- Animated movement from point-x to point-y. | ||
- Prevent drag and drop layout shift. | ||
- Isolated from data flow. | ||
- Headless as it is just functions that do manipulation. | ||
- Event driven API. | ||
- Targeting each DOM node individually. | ||
- Extensible using JSON tree instead of flat recursion. | ||
## Installation 📦 | ||
```bash | ||
npm install @dflex/core-instance | ||
``` | ||
## Documentation 📖 | ||
Visit DFlex site for docs <https://www.dflex.dev/> and live demo. | ||
## Related Content 🏋️ | ||
### [**@dflex/dom-gen**](https://github.com/dflex-js/dflex/tree/master/packages/dom-gen) | ||
DFlex DOM relations generator algorithm. It Generates relations between DOM elements based | ||
on element depth so all the registered DOM can be called inside registry without | ||
the need to call browser API. Read once, implement everywhere. | ||
### [**@dflex/utils**](https://github.com/dflex-js/dflex/tree/master/packages/utils) | ||
A collection of shared functions. Mostly classes, and types that are used across | ||
the project. | ||
### [**@dflex/store**](https://github.com/dflex-js/dflex/tree/master/packages/store) | ||
DFex Store has main registry for all DOM elements that will be manipulated. It | ||
is a singleton object that is accessible from anywhere in the application. The | ||
initial release was generic but it only has the Core of the library since ^V3. | ||
### [**@dflex/draggable**](https://github.com/dflex-js/dflex/tree/master/packages/draggable) | ||
Light weight draggable element without extra functionalities that is | ||
responsible for interacting with the DOM and moving the affected element(s). | ||
### [**@dflex/dnd**](https://github.com/dflex-js/dflex/tree/master/packages/dnd) | ||
The main package that depends on the other packages. It is responsible for the | ||
magical logic of the library to introduce the drag and drop interactive | ||
functionality. | ||
## License 🤝 | ||
DFlex is [MIT License](LICENSE) since version 3.0.0 and above. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
24132
95
504
6
Updated@dflex/utils@^3.3.2