Releases: thisbeyond/solid-dnd
Release 0.7.5
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
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
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
Fixed
-
Typing error for
DragOverlay
children caused by use ofElement
instead of
JSX.Element
. -
Fix high severity vulnerability suggested by npm.
Release 0.7.1
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 asrecomputeLayouts
and
detectCollisions
is called explicitly as part ofdragStart
anddragEnd
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
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
(forstring | number
ids) and export for reuse. -
Add
rect
getter onLayout
for ease of use. When duplicating aLayout
,
can now donew Layout(existingLayout.rect)
. -
Support for custom transformers to refine
Draggable
andDroppable
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 relatedDraggable
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
previousdragMove
function, add functions (addTransformer
,
removeTransformer
) to manage transfomers on draggables and droppables, and
remove the now redundantdisplace
function.Transformers are keyed by id and orderable for ease of use and predictability,
and can be accessed via thetransfomers
property on draggables or
droppables. -
Breaking Change Sensors should now pass their initial coordinates to
sensorStart
and updated coordinates to the newsensorMove
function (which
replaces the removeddragMove
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 newbatch
behaviour. -
Breaking Change Use
DragOverlay
layout in collision detection.
Previously theDraggable
layout was used leading to unexpected behaviour
collision behaviour (such as a larger overlay not triggering aDroppable
even when over it). As part of this theusingDragOverlay
property of dnd
state is removed in faviour of trackingstate.active.overlay
data. -
Auto-center
DragOverlay
over its relatedDraggable
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
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
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
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 matchingid
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
(ordroppable.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 newCollisionDetector
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 simplercollisionDetector
. -
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 returnedDroppable
interface for consistency. -
Simplify typings for state. Whilst technically correct, the presence of
undefined
in the typing for state likedroppables
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 toundefined
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
andcreateComputed
. -
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 (bygetBoundingClientRect
). 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
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.