Skip to content

Releases: thisbeyond/solid-dnd

Release 0.7.5

17 Nov 15:04
Compare
Choose a tag to compare

Fixed

  • Updated typings for DragOverlay to support function child without error.
    Thanks to pardeshirzadeh for this fix.

Changed

  • Switched to pnpm as default package manager for repository.

Release 0.7.4

04 Feb 16:31
Compare
Choose a tag to compare

Fixed

  • Optimise production builds by stripping console messages and fix errors caused
    by mixed js and jsx output. As part of this, switch to
    tsup for building the library (which should be
    faster due to the use of esbuild).

    Thanks you @thetarnav for this improvement.

Release 0.7.3

02 Nov 04:22
Compare
Choose a tag to compare

Fixed

  • Only accept primary button (left-click) for activating drag with default
    pointer sensor. Fix an issue on some platforms where the contextmenu shows on
    right-click and intercepts the pointerup events that would cancel the drag,
    leading to a sticky unintended drag.

Release 0.7.2

07 Oct 20:40
Compare
Choose a tag to compare

Fixed

  • Typing error for DragOverlay children caused by use of Element instead of
    JSX.Element.

  • Fix high severity vulnerability suggested by npm.

Release 0.7.1

11 Sep 20:00
Compare
Choose a tag to compare

Added

  • Emit more useful warnings when attempting to remove nonexistent items. Rather
    than fail with error (Cannot read properties of undefined), emit an
    appropriate console warning instead and then return.

Fixed

  • Ensure layouts recomputed before other effects on drag start. Without this,
    issues could occur where collisions were detected against stale positions and
    items moved incorrectly as a result. In addition, layouts might not have been
    recomputed correctly on drag end if adjustments were made by custom
    onDragEnd handlers. Now, core behaviour such as recomputeLayouts and
    detectCollisions is called explicitly as part of dragStart and dragEnd
    to ensure correct ordering.

  • Don't apply redundant adjustment transformer when a drag overlay is used.

  • Improve typings for DragOverlay to better describe function form.

Release 0.7.0

07 Sep 20:54
Compare
Choose a tag to compare

Refactor core to lean more into reactivity. Note there are multiple breaking
changes in this release - see below for details.

Added

  • Export DragEvent type for external use in order to avoid consumers having to
    redefine this type for custom handlers.

  • Explicitly type Id (for string | number ids) and export for reuse.

  • Add rect getter on Layout for ease of use. When duplicating a Layout,
    can now do new Layout(existingLayout.rect).

  • Support for custom transformers to refine Draggable and Droppable
    transform behaviour. Transformers are specified against an individual item and
    can be used for things like limiting drag movement to a particular axis:

    const transformer = {
      id: "constrain-x-axis",
      order: 100,
      callback: (transform) => ({ ...transform, x: 0 }),
    };
    
    onDragStart(({ draggable }) => {
      addTransformer("draggables", draggable.id, transformer);
    });
    
    onDragEnd(({ draggable }) => {
      removeTransformer("draggables", draggable.id, transformer.id);
    });
  • Support using function element form for DragOverlay children. This enables
    referencing the related Draggable directly without the need to track
    separately. For example:

    <DragOverlay>
      {(draggable) => <div>Draggable {draggable.id}</div>}
    </DragOverlay>

Changed

  • Breaking Change Refactor core to lean more into reactivity.

    Notably, make transforms a reactive computation of an array of transformers
    rather than a pre-computed set state. For example, make active draggable
    transform react to current sensor position rather than have sensor set the
    draggable position directly.

    To support this reactivity, introduce a sensorMove function in place of the
    previous dragMove function, add functions (addTransformer,
    removeTransformer) to manage transfomers on draggables and droppables, and
    remove the now redundant displace function.

    Transformers are keyed by id and orderable for ease of use and predictability,
    and can be accessed via the transfomers property on draggables or
    droppables.

  • Breaking Change Sensors should now pass their initial coordinates to
    sensorStart and updated coordinates to the new sensorMove function (which
    replaces the removed dragMove function). The included pointer sensor has
    been updated accordingly.

  • Breaking Change Move 'read state' helpers directly into the state object.
    This makes a clearer separation between actions that typically modify state vs
    accessing the state for readonly purposes. It also feels more intuitive.

    As part of this, rename the existing state entries that refer to 'ids' to
    explicitly reflect this:

    • state.active.draggable -> state.active.draggableId
    • state.active.droppable -> state.active.droppableId
    • state.active.sensor -> state.active.sensorId
    • state.previous.draggable -> state.active.draggableId
    • state.previous.droppable -> state.active.droppableId

    Also, remove all redundant helpers in favour of directly using the state:

    • activeDraggable() -> state.active.draggable
    • previousDraggable() -> state.previous.draggable
    • anyDraggableActive() -> state.active.draggable
    • activeDroppable() -> state.active.droppable
    • previousDroppable() -> state.previous.droppable
    • anyDroppableActive() -> state.active.droppable
    • activeSensor() -> state.active.sensor
  • Breaking Change Remove filter argument from recomputeLayouts. Instead,
    the core will determine which nodes to re-evaluate when called (and will also
    cache nodes to avoid redundant evaluation of layout when appropriate).

Fixed

  • Breaking change Make Solid JS 1.5 the minimum compatible version of Solid
    and update to support its breaking changes to typings, and the new batch
    behaviour.

  • Breaking Change Use DragOverlay layout in collision detection.
    Previously the Draggable layout was used leading to unexpected behaviour
    collision behaviour (such as a larger overlay not triggering a Droppable
    even when over it). As part of this the usingDragOverlay property of dnd
    state is removed in faviour of tracking state.active.overlay data.

  • Auto-center DragOverlay over its related Draggable on drag start for a
    better experience when the overlay is of differing size to the draggable.

  • Avoid reacting to irrelevant droppable changes in onDragEnd.

  • Minimise differences in layout calculations. Due to the way transforms are
    stripped from layouts, it is possible to end up with small differences in
    layout values. This is due to precision issues in JS. Attempt to minimise
    occurences by rounding to nearest whole number (pixel).

Release 0.6.1

02 May 15:05
Compare
Choose a tag to compare

Fixed

  • Ensure onDragMove is called for every move update (rather than just once).
    To do this, ensure that the relevant properties of the transform are accessed
    to set up the effect reactivity correctly. Before, only the top level
    transform object was accessed, but that is unchanging on move.

Release 0.6.0

01 May 14:22
Compare
Choose a tag to compare

Added

  • Support horizontal sorting in sortable transform algorithm. The new approach
    directly uses target droppable layout positions in order to calculate sorted
    transforms (which is more flexible and simpler).

    Note: Requires sorted items to be the same size to avoid odd visual behaviour
    as items are not currently scaled at all (though that may be implemented in
    future). This was also true of the previous algorithm.

Release 0.5.0

30 Apr 22:05
Compare
Choose a tag to compare

A significant update with multiple improvements and some breaking changes. Most
notably, provides better support for multi-sortable-list use cases.

Added

  • Seamlessly handle re-creation of draggables and droppables during active drag.

    In some use cases (such as a kanban board), an item may be moved from one
    container to another during an active drag. In turn this could cause related
    draggables and droppables to be removed and re-added. Previously this would
    just break (with the active draggable disappearing on its removal). Now, it is
    handled by deferring the cleanup of removed draggables and droppables with a
    queued microtask. If a draggable/droppable with matching id is added before
    the microtask is called, then it will not clean up and instead persist
    naturally with the new layout and node information.

    As part of this, the active draggable's transform is automatically adjusted by
    a temporary internal modifier to account for any difference between the
    previous node layout and the new node layout. This avoids jumping or
    misalignment during the drag that would otherwise be caused by the change in
    underlying node layout. In future this modifier interface may be exposed for
    other use cases.

    All layouts are also recomputed if any draggable is active when a new item is
    added.

  • Add a basic debugger to help visualise draggable and droppable positions.
    Emphasise active items in debugger. To use, place <DragDropDebugger> within
    a <DragDropProvider> hierarchy.

    Note: droppable positions are rendered untransformed to better reflect
    underlying logic (as droppable transforms are not currently considered in the
    collision detectors).

  • Add transformed helper property on items. Rather than calling
    transformLayout(layout, transform) explicitly, it is now possible to do
    draggable.transformed (or droppable.transformed) for the same computation.

  • Add a closest corners collision detector (closestCorners) to provide a more
    natural collision match when droppables are nested.

  • Add style helper (maybeTransformStyle) that only returns transform style
    when it will have an effect. This helps avoid affecting other styling (e.g.
    z-index) unintentionally. The directive form already uses this approach, and
    now manual setups can have this behaviour more easily too.

Changed

  • Breaking Change Refactor collision detection to be more context aware.

    Whilst it originally felt better to have collision detection abstracted into
    considering just layouts, in practice it limits smarter handling such as tie
    breaking on active droppable or types.

    Now, the active draggable and list of droppables is passed directly to the
    collision detection algorithm along with some additional useful context (such
    as the active droppable id). A new CollisionDetector type is also available
    for use when writing custom collision detectors.

    type CollisionDetector = (
      draggable: Draggable,
      droppables: Droppable[],
      context: { activeDroppableId: string | number | null }
    ) => Droppable | null;
  • Breaking Change As part of the changes to the collision detection
    interface, update the existing algorithms and rename to drop "layout" from
    their names:

    • closestLayoutCenter -> closestCenter
    • mostIntersectingLayout -> mostIntersecting
  • Breaking Change Rename collisionDetectionAlgorithm prop of
    DragDropProvider to the simpler collisionDetector.

  • Compute and apply appropriate transform for sortables explicitly, rather than
    rely on delegation to underlying draggable/droppable transforms.

    A sortable can be transformed either as the active draggable transform (when
    no drag overlay is used) or as a droppable transform caused by the sorting of
    the list. Correctly compute the correct transform and ensure it is used both
    in directive form and as the returned transform for the sortable interface.

    As part of this, always store the computed sortable transform against the
    droppable entry regardless of whether directive used or not. This ensures
    consistency in the data (and helps debuggers visualise the information
    accurately).

  • Include transform in returned Droppable interface for consistency.

  • Simplify typings for state. Whilst technically correct, the presence of
    undefined in the typing for state like droppables makes it more awkward
    for consumers of that state. This is because they have to account for
    undefined value even though it will never actually be present (because
    setting state to undefined removes it from the state). So simplify the
    typing and override where necessary (such as when removing values).

  • Use createEffect consistently throughout for a clearer mental model. There
    is currently no clear need for more immediate effects as provided by
    createRenderEffect and createComputed.

  • Encapsulate layout inteface in a Layout class to avoid repeated definition
    of getter properties. As part of this, remove the standalone function for
    calculating layout center in favour of a computed property (center) on the
    layout itself.

Fixed

  • Strip translation transform when computing an element's layout. If a draggable
    is active when its layout is recomputed, its currently applied transform will
    be evaluated as part of its base layout (by getBoundingClientRect). This
    results in the transforms effectively stacking over time and the item being
    misplaced. To prevent this, strip any translation transform that is applied on
    the element.

  • Reset sortable positions when indices are invalid. Prevent confusing behaviour
    caused by stale sort order when indices become invalid, but a drag is still
    active. This can happen when sorting across multiple containers for example.

  • Ensure item accessors only re-evaluate when the active/previous id value
    changes. Previously, these accessors re-evaluated (when used in an effect)
    whenever the referenced item object itself had changes, leading to confusing
    behaviour. For example, onDragEnd firing again when adding new droppables.

  • Built-in collision detection now tie-breaks on the active droppable to prevent
    potential flipping situations. When two droppables were equidistant candidates
    for collision, their naive ordering would decide which was returned as the
    match. Due to subsequent sorting, that ordering could change and the very next
    move would result in the alternative candidate matching, resulting in constant
    flipping. By tie-breaking on the active droppable this is avoided in the
    common case.

Release 0.4.2

06 Feb 16:44
Compare
Choose a tag to compare

Fixed

  • Update rollup-plugin-solid to 1.2.2 to address
    Bundlephobia build error (caused by it tripping over the
    optinal chaining syntax ?.). The plugin now targets a slightly older env in
    order to compile this syntax away.