dflex

The sophisticated Drag and Drop library you've been waiting for 🥳

MIT License

Downloads
448
Stars
1.7K
Committers
9

Bot releases are visible (Hide)

dflex - v3.9.5 ( September 12, 2023) Latest Release

Published by jalal246 about 1 year ago

This release includes several enhancements, bug fixes, and new features. Below are the details of the changes:

  1. Enhanced Scrolling Functionality

    • PR: #664
    • Description: This update implements advanced scrolling functionality, providing smoother and animated scrolling behavior.
  2. Reduced API Surface

    • PR: #666
    • Description: Unnecessary exposed methods have been removed, streamlining the API surface for improved usability.
  3. Improved Scroll Handling

    • PR: #668
    • Description: Scroll handling for non-document scroll containers has been improved, enhancing the overall scrolling experience.
  4. Scrollable Content Criteria

    • PR: #669
    • Description: Introduces scrollable content as a criterion for defining scroll containers, leading to more accurate container detection.
  5. Mutation Leak Fix

    • PR: #671
    • Description: This fix addresses a mutation leak issue and improves cleanup for non-connected DOM elements.
  6. Race Condition Prevention

    • PR: #677
    • Description: Measures have been put in place to prevent race conditions between unregistering and the mutation observer.
  7. Fixed Container Sizing

    • PR: #694
    • Description: The entire dimension is now used (instead of visible dimensions) to set fixed sizes for containers.
  8. Reconciliation Prioritization

    • PR: #695
    • Description: Prioritizes reconciliation, starting from addition to deletion in containers, for a more efficient process.
  9. Element Management Extraction

    • PR: #696
    • Description: Element management has been extracted to DFlexDOMManager, improving modularity and organization.
  10. Preventing Shifting After Reconciliation

  • PR: #697
  • Description: Fixes an issue where shifting occurred after reconciliation and before indicator reset.
  1. Latency Issue Resolution
    • PR: #698
    • Description: Resolves a latency issue in element reconciliation and improves bounding rect retrieval.
dflex - v3.9.1 (June 15, 2023)

Published by jalal246 over 1 year ago

Enhance transformed elements with default animation and custom CSS transformation options (#659, #658)

  • Allow null as a valid value for the element animation configuration: This change introduces greater flexibility in configuring element animations. Previously, an animation configuration was required, but now users have the option to use null to disable animations completely.

  • Rename super.register to addElmToRegistry in the base store's internal implementation: This modification updates the internal implementation of the base store to use the more descriptive method name addElmToRegistry instead of super.register. This improvement enhances code readability and clarity.

  • Add a unit test for the getParsedElmTransform function: This addition includes a new unit test to verify the behavior and correctness of the getParsedElmTransform function. The test covers various scenarios and ensures that the function accurately parses and returns the transform matrix of the given element.

  • Create the CSSTransform property in the RegisterInputOpts interface to allow users to specify CSS rules that will be applied to the element when it's interactively dragged: The inclusion of the CSSTransform property provides users with a convenient way to customize the visual appearance of interactive elements during dragging. By specifying CSS rules for CSSTransform, users can have precise control over various visual aspects, including background color, border styles, opacity, box-shadow, and more. These CSS rules are dynamically applied to the element while it is being transformed by dragging, and they are automatically removed when the element is settled in its new position. This enhancement enhances the overall user experience and allows for a more visually engaging dragging interaction.

  • Add the animation property to the RegisterInputOpts interface, allowing users to specify configuration options for animations applied to transformed elements during dragging. The animation property accepts an object of type Partial<AnimationOpts>, which includes properties such as easing and duration to control the animation behavior. By default, animation is applied unless explicitly configured otherwise.

type RegisterInputOpts = {
  id: string;
  readonly?: boolean;
+ animation?: Partial<AnimationOpts>;
+ CSSTransform?: CSSClass | CSSStyle;
};

Example:

const registerInput: RegisterInputOpts = {
  id: "elementId",
  readonly: false,
  animation: {
    easing: "ease-in-out",
    duration: 500,
  },
  CSSTransform: {
    background: "#ff0000",
    opacity: 0.5,
  },
};

In this example, we specify animation options by setting the animation property to an object with the easing function set to "ease-in-out" and the duration set to 500 milliseconds. Additionally, we customize the CSS applied to the element during dragging by setting the CSSTransform property to an object with background color "#ff0000" and opacity 0.5.

Please note that the animation and CSSTransform properties are optional, and you can omit them if you don't need to customize animations or apply specific CSS transformations during dragging.

Optimize build bundle (#661, #662, #663)

Full Changelog: https://github.com/dflex-js/dflex/compare/v3.9.0...v3.9.1

dflex - v3.9.0 (June 6, 2023)

Published by jalal246 over 1 year ago

Performance Enhancement: Utilizing computedStyle, Resizing Fix, and Improved Element Position Detection (#645)

Implement CSS Getters and Setters, Resize Event Handler Fix, Enhanced Element Position Detection, Refactoring, and Cleanup (#647). Introduces several improvements and fixes as follows:

  • Utilize CSS getters and setters: This update enhances the library's usage of CSS getters and setters for improved performance and compatibility.
  • Fix resizing event handler: Addressed a bug in the resizing event handler that failed to trigger the expected chain of updates related to the event. This fix ensures that the chain of updaters is correctly executed.
  • Enhanced element position detection: Introduced a unified logic to detect an element's position relative to the viewport. This enhancement provides a more consistent and accurate position calculation.
  • Remove the optional object for setting the inner scroll threshold: Eliminated the need for an optional object parameter when setting the inner scroll threshold. This simplifies the API and improves code readability.
  • Refactor and remove unnecessary methods in the Threshold class: Streamlined the Threshold class by removing unnecessary methods and increasing reliance on the Box model. This refactoring improves code efficiency and maintainability.

Migrate related box model in Threshold to the Box Model (#646): Focuses on migrating the related box model present in the threshold to the Box model. The aim is to consolidate the codebase and improve consistency. Allowing better modularization, and enhancing code maintainability and readability.

Enhance style handling in Draggable element (#655)

Enhancing the style handling in the draggable element by refactoring and optimizing the setMirrorStyle and setOrUnsetOriginStyle functions. The changes improve reusability, reduce duplication, and make the code more concise and maintainable.

Fix scroll threshold for elements outside screen viewport (#653)

Addressing an issue with scroll thresholds for elements that are located outside the screen viewport. The scroll thresholds were not correctly calculated, leading to inaccurate auto-scrolling triggers for these elements.

  • Refactoring the scroll threshold calculation logic to ensure accurate detection of elements outside the viewport.
  • Updating the scroll threshold values to align with the element's position relative to the viewport.
  • Adding appropriate comments and documentation to clarify the purpose and functionality of the scroll threshold calculations.
  • Conducting e2e testing to validate the accuracy of the updated scroll thresholds.

Improve DFlexScrollContainer performance and testability (#644)

  • Removing an extra class instance.
  • Decoupling event debouncing and testing it in isolation.
  • Refactoring updateSiblingsVisibilityLinearly to enhance conditions.

Prevent interactive containers from resizing during elements migration (#643)

Addressing the issue of interactive containers resizing during the migration of their child elements, which can lead to layout distortion and cause problems, particularly when the container becomes empty due to the migration of all children.
To mitigate this issue, the solution enforces fixed container sizes that remain consistent during element migration, ensuring that the container size is maintained and does not change unexpectedly.
It ensures that the layout remains visually consistent, and interactive elements remain correctly sized and positioned. It provides a better user experience by preventing any visual disturbances that could arise from container resizing.

Resolve scroll throttle issues during direction change (#652)

Deferred transformation for invisible elements (#651)

Fix scrollable area calculation (#648)

Refactor element rect calculation to consider scroll position (#656)

Migrate visibility test from Cypress to Playwright (#650)

Full Changelog: https://github.com/dflex-js/dflex/compare/v3.8.3...v3.9.0

dflex - v3.8.3 (March 29, 2023)

Published by jalal246 over 1 year ago

Improved Transformations, Stabilizer Mechanisms, and Upgraded Dependencies

Full Changelog: https://github.com/dflex-js/dflex/compare/v3.8.2...v3.8.3

dflex - v3.8.2 (March 13, 2023)

Published by jalal246 over 1 year ago

Bug Fixes

Full Changelog: https://github.com/dflex-js/dflex/compare/v3.8.1...v3.8.2

dflex - v3.8.1 (February 24, 2023)

Published by jalal246 over 1 year ago

Automatically unregister deleted elements (#614)

Support incremental stream (#615)

Fix MutationObserver for containers that don't belong to the same parent (#611)

  • Refactor Generator & Register (#612)
  • Refactor Unit Test (#613)

Full Changelog: https://github.com/dflex-js/dflex/compare/v3.8.0...v3.8.1

dflex - v3.8.0 (February 1, 2023)

Published by jalal246 over 1 year ago

Support streaming in an existing layer (#608)

  • Support streaming in depth:0. Allowing children to be updated continuously without clearing the store instance entirely.
  • Fix a bug in store.destroy() where in some cases migration=null causes an error when it's called.
  • Fix a bug in the branch level where the parent container belongs to the same higher parent but is not registered as siblings in DOMGen.
  • Depend on the observer to auto-clean removed elements from the store instead of using unregister.
  • Override containersTransition & commit for unnecessary usage (#609)
    • Override containersTransition options for an orphan branch.
    • Override commit options for an orphan branch with a solo element to prevent unnecessary reconciliation.
  • Add prefix to generated keys in DOM-gen (#610) to avoid potential conflict with user-ids and DFlex auto-generated keys.

Refresh element indicators after reconciling across multiple containers (#600)

  • Add global configuration to set general transformation behavior.
 React.useEffect(() => {
    store.config({
      removeContainerWhenEmpty: false,
    });
  }, []);
  • Preserve container width when empty to prevent an uncalculated shift in elements' position.
  • Refresh all elements' indicators and re-calculate Rect when reconciling across multiple containers.

Support resizing window for transformed/non-transformed containers alike (#603)

  • Resizing window will automatically:
    • Trigger reconciliation for transformed containers.
    • Non-transformed containers will update DOMRect.
  • Observers are added to the higher registered container depth instead of each parent container.

Prevent drag from updating its transformation position if it's going to reconcile (#606)

Add delay to detect nearest container iteration (#601)

Support migration into an empty container (#602)

Full Changelog: https://github.com/dflex-js/dflex/compare/v3.7.1...v3.8.0

dflex - v3.7.1 (January 17, 2023)

Published by jalal246 over 1 year ago

Fix observer disconnecting when reconciling the DOM (#594)

  • Start migrating the DOM reconciliation test between containers to the Playwright.
  • Fix the error caused by triggering the observer during DOM reconciliation.
  • Add migrated elements into the Migration instance.

Fix missing instances in minified bundle (#598)

Fix dead links under Project Content (#579)

Handle container boundaries when it's empty (#595)

  • Add container Rect.
  • Update jest config & add a new test case.

Remove unnecessary components from the playground (#593)

dflex - v3.7.0 (September 9, 2022)

Published by jalal246 about 2 years ago

Enable DOM reconciliation for transformed elements (#573)

  • Use abstract for axes point.

  • Move to the box model for more consistent geometry.

  • Add different positions for different types of dragging.

  • Support interactivity between scroll containers by allowing custom mirroring the dragged when necessary.

  • Update listener(s) allowing them to be attached to scroll containers with overflow even if they are not dynamic.

  • Initialize scroll threshold depending on the depth layer instead of the targeted container.

  • Flushing element indicators without checking the DOM state leaning more into DOM & VDOM instances.

  • Unify listeners system with payload and status.

  • Add keyboard listener to the playground app to enable commit for testing.

  • Add DFlex Cycle as a global migration holder inside the store.

  • Add DFlex Session to manage user interactivity with the DFlex app.

  • Manage reconciliation by using SK (containers key) inside Cycle. So the reconciliation only targets the affected container(s).

  • Add options for committing changes to the DOM. Users still have the ability to transform the elements indefinitely but in some cases, apps need to commit after each cycle. This feature is now enabled with embedded reconciliation that targets only affecting elements in their containers. This feature makes DFlex the first drag-and-drop framework with its own reconciler and the first one that gives the user multiple options for indefinite transformation or committing to the DOM when necessary.

dflex - v3.6.2 (August 1, 2022)

Published by jalal246 about 2 years ago

Use viewport threshold percentage to control elements visibility (https://github.com/dflex-js/dflex/pull/566)

  • Remove all separate class interfaces in the utility classes. Use class as a type instead.

  • Enhance registration. All essential data will be assigned and registered even with DFlex being framework agnostic. Register functions still have the capability to create a DFlex-Node instance, along with its container, and scroll. This decreases the scripting time for the first interactive dragging without blocking the initial mount during registration https://github.com/dflex-js/dflex/pull/565.

  • Use different types for threshold. Previously all thresholds used were external thresholds. I added a new type internal to apply the threshold percentage correctly for the scroll. An internal threshold is a threshold that checks the dragged inside the given area and is always smaller than the working area.

  • Use essential geometry for Point<number>, Point<boolean> for scroll.

  • Add more indicators to enhance scrolling. DFlex can identify thresholds, calculate invisible areas,s and based on this information do scroll animation.

  • Bind scrolling data with scroll listeners. So when scrolling DFlexScrollContainer can do all the related calculations without reading from DOM.

  • Synchronously update element visibility when scrolling. Avoid any gap that may appear during the scroll. Also, still, the visible area is the scrolling area. Elements' position won't be updated if it's not visible. But the current approach updates visibility and then scrolls so visibility is calculated before taking action.

  • Thresholds are now direction-dependent. If drag is in the bottom but going up then the threshold is false.

  • Differentiate the mechanism from the container.

Fix the wrong axis assignment caused by a typo (https://github.com/dflex-js/dflex/pull/569)

Initiate scroll overflow even if the container is not dynamic (https://github.com/dflex-js/dflex/pull/570)

dflex - v3.6.1 (July 23, 2022)

Published by jalal246 about 2 years ago

Fix Initiate elements after registration in dflex/draggable (#568)

Support concurrent elements registration by default (#565)

dflex - v3.6.0 (July 13, 2022)

Published by jalal246 over 2 years ago

Add layout mutation, listeners, and custom events (#558)

  • Add playgrounds to the type checking.
  • Add custom events instead of the previous approach which depended on emitting events by functions provided by each interactive element. DFlex events has $ prefix.
type DFlexEvents =
  | "$onDragOutContainer"
  | "$onDragOutThreshold"
  | "$onDragOver"
  | "$onDragLeave"
  | "$onLiftUpSiblings"
  | "$onMoveDownSiblings";

Implementation like any other event:

import type { DFlexEvents } from "@dflex/dnd";

const onDFlexEvent = (e: DFlexEvents) => {
 // Do something, or just don't.
};

// Later you can remove the listener with `removeEventListener`
document.addEventListener("$onDragLeave", onDFlexEvent);
  • Provide listeners a subscription approach to provide a universal state to the interactive applications. You can subscribe anywhere in the app instead of depending on the emitted events from draggable elements. Currently, DFlex supports subscriptions to LayoutState.
interface DFlexLayoutStateEvent {
  type: "layoutState",
  layoutState: "pending" | "ready" | "dragging" | "dragEnd" | "dragCancel";
}

Implementation from anywhere inside the app:

React.useEffect(() => {
  const unsubscribe = store.listeners.subscribe((e) => {
    console.info("new layout state", e);
  }, "layoutState");

  return () => {
    unsubscribe();
  };
}, []);

Remove parentID from registry input by checking branches internally (#564)

interface RegisterInput{
  id: string;
  depth?: number;
  readonly?: boolean;
};

const { id, depth, readonly } = registerInput;

React.useEffect(() => {
  if (ref.current) {
    store.register({ id, depth, readonly });
  }

  return () => {
    store.unregister(id);
  };
}, [ref.current]);

Complete migrating all core smoke test cases to Playwright (#557)

dflex - v3.5.4 (June 11, 2022)

Published by jalal246 over 2 years ago

  • Fix attaching element reference when passing id only (#553).
  • Upgrade to Cypress 10 (#554).
  • Enforce passing id and parentID for registered elements (#555).
  • Using playwright to cover core cases (#556).
dflex - v3.5.3 (May 30, 2022)

Published by jalal246 over 2 years ago

  • Fix build parsing arguments (#552)
dflex - v3.5.2 (May 30, 2022)

Published by jalal246 over 2 years ago

  • Restructure the packages (#548).
  • Refactor e2e test to the DnD playground (#549).
  • Add build script and enhance bundling size (#551).
dflex - v3.5.1 (May 21, 2022)

Published by jalal246 over 2 years ago

Refactor meta extractor to distinguish between an empty and orphan case (#524)

  • Change margin when positioning from orphan to non-orphan container (#529)

  • Refactor test description for essential cases (#528)

  • Add unit test to meta extractor (#527)

  • Refactor unit test for DnD (#526)

  • Fix margin-bottom calculation taking into consideration the last occupied position (#525)

  • Upgrade to pnpm 7.

Add essential cases for obliquity and continuity including from/to empty container (#531)

  • Remove unused instances and methods not used in the store and refactor related tests (#533).

  • Add origin length to determine when to restore and when the container is expanding (#533).

  • Refactor unit test for meta extractor (#533).

  • Fix continuity in extending orphan container (#534)

extending orphan container

  • Fix last element preservation in the origin (#536)

empty multiple then restore

  • Clear transition instances after each operation (#537)

  • Testing transform element to an into empty container (#538)

Distribute then transform into empty one

  • Handle obliquity from multiple containers bottom-up

Split multiple containers from bottom up

  • Handle obliquity from one container bottom-up

Split one container bottom up

  • Handle obliquity from multiple containers up to bottom

Split multiple containers up to bottom

Enable transforming elements between containers (#539)

  • Add options for transforming elements between containers.
interface ContainersTransition {
  /** Default=true */
  enable: boolean;

  /**
   * Support orphan to orphan transformation.
   * Default=10px
   * */
  margin: number;
}
  • Keep the element transformed to the bottom instead of consider it out of the container and resettled it in its original position (#544).

keep it at the bottom

  • Separate types from JavaScript dist files (#547).
dflex - v3.5.0 (May 10, 2022)

Published by jalal246 over 2 years ago

Support Strict Transformation Between Containers

Transformation depends on three cases:

  1. Crowded: Transform into a container with siblings more than 1.
  2. Empty: Transform into a container where there are no siblings.
  3. Orphan: Transform into a container where there is only one element there.

Calculations are made to:

  1. Translate object {x,y} => update occupied-translate. These coordinates are relative and related to the connected index. E.g: If the element left its original container and got inserted at the destination container with index-3 then the translation should be based on the insertion index. (Not the same case for the position.)
  2. Position object {x,y} => update occupied-position. These coordinates are absolute. Calculating position affects the next element's movement. E.g: If element-last-one has to move down it will check the occupied-position because can't move based on its own position so this will kill dealing with different heights/widths. So it has to move to a post-defined point. For transformation inside the list itself, it's not a problem. But for migration to a new container then the calculated value should be done before triggering any transformation. It's not a step-by-step regular movement.

Three different phases for execution:

  1. Calculate and assign position once the destination list/container is defined. Before knowing the insertion index.
  2. Calculating translation which should be done after detecting the insertion index before triggering the transformer otherwise we will calculate the next position instead of the current one.
  3. Assigning the translation after the transformer(move-down) is done. Otherwise, the dragged will be out-position= true.

Roadmap:

A- Handle the case where transformation between containers happens to the absent bottom (#493)

  • Fix undo for draggable when it's inside the position threshold but triggered or shifted slightly. Now it does trigger the undo instead of treating this case as moved out.
  • Fix dragged insertion inside the container when the breaking point is not detected. It enforces the dragged to be attached to the bottom right after the first cycle of iteration avoiding unnecessary function calls that led to the same result.
  • Avoid unnecessary updating position/translate when appending to the bottom.
  • Remove numberOfElementsTransformed and updateNumOfElementsTransformed from dragged and replace the use case with exicting indicators.
  • Support transformation when dragged is migrated to the bottom of the destination container.
  • Add test cases for transforming back and forth horizontally and vertically.

backAndForthHorizontally

B- Refactor utils to Core removing #getDiff (#494)

interface INode extends ICore {
  isConnected(): boolean;
  isPositionedUnder(elmY: number): boolean;
  isPositionedLeft(elmX: number): boolean;
  getRectBottom(): number;
  getRectRight(): number;
  getRectDiff(elm: this, axis: Axis): number;
  getDisplacement(elm: this, axis: Axis): number;
  getDistance(elm: this, axis: Axis): number;
  getOffset(): RectDimensions;
  hasSamePosition(elm: this, axis: Axis): boolean;
}

C- Check the layout shift for vertically transforming elements with different heights inside the same container (#496)

  1. Outside the container then insert:
    a. The dragged is bigger than the targeted element - moving without releasing.
    b. The dragged is smaller than the targeted element - moving without releasing.
    c. The dragged is smaller than the targeted element - move and release with iteration.

  2. Inside the container:
    a. The dragged is bigger than the targeted element - moving without releasing.
    b. The dragged is bigger than the targeted element - move and release with iteration.
    c. The dragged is smaller than the targeted element - moving without releasing.
    d. The dragged is smaller than the targeted element - move and release with iteration.

D- Enable transformation for containers orphaned by migration (#497)

In this case, the origin container has two elements.

  1. One element transformed into another container. It has a solo element now.
  2. A new element is going to be transformed into it, the container which has one element.
  3. The insertion margin shouldn't cause any layout shift.

To solve it, when the container is receiving a new element. DFlex restores the preserved last element position and calculates the margin to guarantee the given scenario where there is no shifting in positions.

orphanedCase

E- Enable transformation from origin higher than destination

One of the calculations DFlex has is defining a threshold for each layout (#418). Threshold tells the transformers when dragged is in/out its position or the container strict boundaries. This strict definition of threshold helps to improve user experience and the physical sense of elements' interactivity. It also plays role in detecting the active container when an element migrates from one to another. This definition prevents the transformation from a container having bigger height/width into another container having smaller boundaries. When leaving the position and entering a new one the transformer can't tell if the element is inside the less-boundaries container or not. To tackle this issue each depth must have a unified transforming boundary. So when the element is dragged at the same level horizontally or vertically it can be settled into the destination container and attached to the bottom which has the highest weight.

Steps to Solve it:

  • Define insertion area threshold for layouts with the same depth to optimize transformation between containers (#500), (#513).
  • Use shared utility in DOM-Gen to generate composed keys for layout depth + key (#501)
  • Add a unified container dimension for each layout that belongs to the same depth (#503) So when checking where the dragged is located different heights and widths won't be a problem given when dragged is transforming all of them has the same dimensions. Still, this needs to be improved to become more dynamic since heights and widths are constantly changing or supposed to be so.
  • Create a shared method for element insertion deals with all directions and is able to restore the positions if any (#508) and (#509)
  • Create composed translate and position methods to structure getting insertion offset and margin (#510) and (#511).

Transforn into smaller list

F- Dealing with multiple transformations without settling into a new position (#519)

This scenario requires checking all the containers that are affected by the transformation and rollback each last transformation accordingly. This is done by adding a unique id to the migration instance instead of a central one created for each clickable operation. E.g. The user clicks and transforms then one id is created for this operation. This allows to roll back each transformation connected to the same id. But to achieve multiple undo between containers the id is shifted into migration.

interface MigrationPerContainer {
  /** Last known index for draggable before transitioning. */
  index: number;
  /** Transition siblings key. */
  SK: string;
  /** Transition unique id. */
  id: string;
}

undo-multi-container

G- Enable multiple steps of transformation (#520)

  • Translate from origin to destination. The destination is not an orphan, the margin is then calculated based on the space between the last two elements in the destination container.
  • Translate from origin to destination. The destination is an orphan the margin is then calculated based on the space between the dragged and the next element in the origin container.
  • Translate from one destination to another. The destination is an orphan, same as above.

multi-steps

H- Add the ability to extend the transformation area between containers (#521). This allows accumulating all registered elements in one container.

extend horizontally

dflex - v3.4.1 (April 20, 2022)

Published by jalal246 over 2 years ago

Add experimental API supporting transformation between containers

Add synthetic offset for element insertion into a new container (#462)

  • Create a new synthetic offset for each container to deal with element migration. Taking into consideration multiple heights and widths. So, the insertion offset always matches the migrated element.
  • Element preservation offset now lives in the migration instance, supposedly grouping all related movement in one instance for maintaining purpose.
  • Refactor setDistanceIndicators calculations in one equation instead of if/else.

Fix build:w and list length when migrated to a new container (#461)

Add initial support for element transformation from one container to another (#463)

  • Fix element synthetic offset. One, unified for draggable element.
  • getDiff to calculate difference in the space for : "offset" | "occupiedPosition" | "currentPosition"
  • Refactor setDistanceIndicators to setDistanceBtwPositions

Utilize the Core (#464):

  • Create a new class for Core Utilities. It inherits from core-instance and Abstract Core and has all the utility methods for the core.
  • Refactor naming for more clarity.
interface ICoreUtils extends ICore {
  isPositionedUnder(elmY: number): boolean;
  isPositionedLeft(elmX: number): boolean;
  getRectBottom(): number;
  getRectRight(): number;
  hasSamePosition(elm: this, axis: Axis): boolean;
}

Handle insertion in the Store (#465)

  • Core instance has 1- initial element offset. The reason why is that we can always reset the movement to go back in time to the zero moment (feature will be introduced later). That leaves DFlex with another Rect option to keep the dimension on track. To do that efficiently it uses 2- CurrentPosition. Presumably, width and height stay the same but the position keeps changing. So, to get the current offset we need getOffset a new method introduced to the CoreUtils.
  • Migration has now instances used for transition periods. Wich defined as the moment where the insertion is detected to the moment where the insertion is completed. To do that we have insertionTransform and insertionOffset. We have also the prev method. Prev() and latest() returns easily the current and last migration instance. When migration is completed we set these instances to null.
  • Add handleElmMigration to the Store. It helps update the boundaries for both new and original lists.
  • Improve newElmOffset Check elmSyntheticOffset to detect the right insertion.

Add Container/Depth instance (#470)

Create Container Instance which is similar to Core. But with the current edition, we now have multiple instances each one representing a different role.

  1. Node: represents a single node in the DOM tree.
  2. Container: represents the container of nodes. Also known as siblings container since DFlex operates on the same depth following siblings approach.
interface IContainer {
  /** Strict Rect for siblings containers. */
  readonly boundaries: RectBoundaries;
  /** Numbers of total columns and rows each container has.  */
  readonly grid: IPointNum;
  /** Container scroll instance.  */
  scroll: IScroll;
  setGrid(grid: IPointNum, rect: RectDimensions): void;
  setBoundaries(rect: RectDimensions): void;
}
  1. Depth: represents the collection of containers keys grouped by the same depth. (Integrated into DOM-GEm #471)
interface IDepth {
  /** Grouping containers in the same level. */
  readonly containers: {
    [depth: number]: string[];
  };
  add(SK: string, depth: number): void;
  getByDepth(depth: number): string[];
  removeByDepth(depth: number): void;
  removeAll(): void;
}
  1. The store has a registry for nodes and Containers for each container instance. The registry with ids as keys while Contiers have a special key called SK generated by DOM-Gen.
  2. DnD store: operate both Nodes and Containers. A bridge between the two.

Refactor element(s) registration (#473) to gaurantee non-blocking element registeration.

Remove unused parent containers (#474)

Add enableContainersTransition to opts with a new playground /migration (#475)

Refactor e2e test to include transformation between containers (#476)

Fix essential transformation for different heights (#478)

Upgrade playground to React 18 (#479)

Add changesets for versioning and npm publish (#483)

Use build artifacts for e2e testing (#486), (#480)

Add docs to the main repo (#477)

dflex - v3.4.0 (Apr 05, 2022)

Published by jalal246 over 2 years ago

Use sibling registration to manage migration between containers (#449)

Revert #446 approach Depends on getting parents/children for dragged migrations by enforcing parent registration if not exist in the store. It works fine but is not what it's intended to be.

DFlex main approach in the essential design depends on a flat hierarchy. Instead of getting each element and connecting it to the parent. The store already has all elements on the same level.

Supposed we have container -a and container-b. All elements in both containers are included in the registry. Both boundaries for siblings are calculated and can be added to the threshold instance since v3.3.1.

Regular Scenario: user click -> get element -> find the parent -> matching the parent overlay recursively -> matching the children overlay recursively -> remove node/append new node to new parent.

DFlex Implementation: user click -> get element -> matching siblings overlay -> add transformation for new positions.

1. Avoid recursively looking for parents.

2. Always allow elements from the same level to interact with each other.

3. Control element migration map. Registered/same level (siblingDepth)

4. Insertion inside the containers already shipped. The scenario dragged outside the container and then moved inside. It's already done by getting the siblings' key SK so it's somehow container agnostic.

Adding Migration class (#450):

  • Replacing placeholders group them in one instance responsible for managing migration.
  • Ability to store the movement between containers. This means enabling undo multiple steps back when introducing the time travel feature.
  • Distinguish between position migration inside the same container and with different ones.
interface IAbstract {
  index: number;
  key: string;
}

interface IMigration {
  /** Get the latest migrations instance */
  latest(): IAbstract;

  /**
   * We only update indexes considering migration definition when it happens
   * outside container but not moving inside it.
   * So we update an index but we add a key.
   */
  setIndex(index: number): void;

  /** When migration from one container to another. */
  add(index: number, key: string): void;
}

Create an array for branches even if there's one child in (#457) to allow migration and flexible add/remove elements. Enhance actions by adding timeout this will cut off Cypress when there's more than one failing case.

Use direction and axis with each transformation instead global instances (#436):

  • Core updater receives one axis/direction instead of both matching the entire approach of one axis per transformation.
  • Remove setEffectedElemDirection and effectedElemDirection using the direction resulted in the update-element depending on the increase/decreas parameter.

Enhance movement across the axis (#440):

  • Update both axes at once with x/y instance.
  • Remove axis parameter from the Undo method in the core.
  • Utilize Point instance.

Refactor setPosition in the Core to include z axis (#443)

Use bi-directional axes for undoing Cell position by (#442)

Enhance element registration (#447):

  • Refactor Tracker to accept prefix and add it to the utils
  • Add private instance to generate id inside Store
  • Generate id for registered element instead of throwing err.

Migrate DEV tools and package exports:

  • Export packages as ESM and CJS and bundle them with esbuild. (#459)
  • Migrate from yarn to pnpm . And Use Vite instead of CRA for playground. (#460)

Full Changelog: https://github.com/dflex-js/dflex/compare/v3.3.2...v3.4.0

dflex - v3.3.2 - Migrate the movement controller to a grid-based

Published by jalal246 over 2 years ago

Fix mismatch version in Core package and refactor naming in Utils (#427)

  • Remove unused Lerna changelog.
  • Refactor AxesCoordinates to Point For more readability.
  • Use private hashes for Core and DOM-Gen.
  • Fix the Core mismatch version which caused using an external version instead of linking the development one.

Update grid for Core and Dragged (#429)

  • Refactor transition history type.
  • Allow adding grid positions to the dataset.
  • Add a read-only prefix to the abstract core interface.
  • Add gridPlaceholder for Dragged and update it for Core.

Reset columns for each row when calculating and positioning grid for siblings (#434)

  • Expand playground to include grid example.
  • Add new methods and instances to deal with grid containers.

Migrate transformer to a grid-based controller (#431)

Remove wrong direction flag in updateElement (#432)

Update readme to include all project packages (#433)

Remove isLeavingFromHead, public isLeavingFromTail and mousePoints (#435)

More about V3 releases and DFlex roadmap.