Skip to content

Latest commit

 

History

History
570 lines (376 loc) · 38.8 KB

CHANGELOG.md

File metadata and controls

570 lines (376 loc) · 38.8 KB

@dnd-kit/sortable

8.0.0

Patch Changes

7.0.2

Patch Changes

7.0.1

Patch Changes

  • #792 b6970e7 Thanks @clauderic! - The hasSortableData type-guard that is exported by @dnd-kit/sortable has been updated to also accept the Active and Over interfaces so it can be used in events such as onDragStart, onDragOver, and onDragEnd.

  • Updated dependencies [eaa6e12]:

    • @dnd-kit/core@6.0.4

7.0.0

Major Changes

  • #755 33e6dd2 Thanks @clauderic! - The UniqueIdentifier type has been updated to now accept either string or number identifiers. As a result, the id property of useDraggable, useDroppable and useSortable and the items prop of <SortableContext> now all accept either string or number identifiers.

    Migration steps

    For consumers that are using TypeScript, import the UniqueIdentifier type to have strongly typed local state:

    + import type {UniqueIdentifier} from '@dnd-kit/core';
    
    function MyComponent() {
    -  const [items, setItems] = useState(['A', 'B', 'C']);
    +  const [items, setItems] = useState<UniqueIdentifier>(['A', 'B', 'C']);
    }

    Alternatively, consumers can cast or convert the id property to a string when reading the id property of interfaces such as Active, Over, DroppableContainer and DraggableNode.

    The draggableNodes object has also been converted to a map. Consumers that were reading from the draggableNodes property that is available on the public context of <DndContext> should follow these migration steps:

    - draggableNodes[someId];
    + draggableNodes.get(someId);
  • #660 30bbd12 Thanks @clauderic! - Changes to the default sortableKeyboardCoordinates KeyboardSensor coordinate getter.

    Better handling of variable sizes

    The default sortableKeyboardCoordinates function now has better handling of lists that have items of variable sizes. We recommend that consumers re-order lists onDragOver instead of onDragEnd when sorting lists of variable sizes via the keyboard for optimal compatibility.

    Better handling of overlapping droppables

    The default sortableKeyboardCoordinates function that is exported from the @dnd-kit/sortable package has been updated to better handle cases where the collision rectangle is overlapping droppable rectangles. For example, for down arrow key, the default function had logic that would only consider collisions against droppables that were below the bottom edge of the collision rect. This was problematic when the collision rect was overlapping droppable rects, because it meant that it's bottom edge was below the top edge of the droppable, and that resulted in that droppable being skipped.

    - collisionRect.bottom > droppableRect.top
    + collisionRect.top > droppableRect.top

    This change should be backwards compatible for most consumers, but may introduce regressions in some use-cases, especially for consumers that may have copied the multiple containers examples. There is now a custom sortable keyboard coordinate getter optimized for multiple containers that you can refer to.

Minor Changes

  • #748 59ca82b Thanks @clauderic! - Automatic focus management and activator node refs.

    Introducing activator node refs

    Introducing the concept of activator node refs for useDraggable and useSortable. This allows @dnd-kit to handle common use-cases such as restoring focus on the activator node after dragging via the keyboard or only allowing the activator node to instantiate the keyboard sensor.

    Consumers of useDraggable and useSortable may now optionally set the activator node ref on the element that receives listeners:

    import {useDraggable} from '@dnd-kit/core';
    
    function Draggable(props) {
      const {
        listeners,
        setNodeRef,
    +   setActivatorNodeRef,
      } = useDraggable({id: props.id});
    
      return (
        <div ref={setNodeRef}>
          Draggable element
          <button
            {...listeners}
    +       ref={setActivatorNodeRef}
          >
            :: Drag Handle
          </button>
        </div>
      )
    }

    It's common for the activator element (the element that receives the sensor listeners) to differ from the draggable node. When this happens, @dnd-kit has no reliable way to get a reference to the activator node after dragging ends, as the original event.target that instantiated the sensor may no longer be mounted in the DOM or associated with the draggable node that was previously active.

    Automatically restoring focus

    Focus management is now automatically handled by @dnd-kit. When the activator event is a Keyboard event, @dnd-kit will now attempt to automatically restore focus back to the first focusable node of the activator node or draggable node.

    If no activator node is specified via the setActivatorNodeRef setter function of useDraggble and useSortable, @dnd-kit will automatically restore focus on the first focusable node of the draggable node set via the setNodeRef setter function of useDraggable and useSortable.

    If you were previously managing focus manually and would like to opt-out of automatic focus management, use the newly introduced restoreFocus property of the accessibility prop of <DndContext>:

    <DndContext
      accessibility={{
    +   restoreFocus: false
      }}
  • #672 10f6836 Thanks @clauderic! - SortableContext now always requests measuring of droppable containers when its items prop changes, regardless of whether or not dragging is in progress. Measuring will occur if the measuring configuration allows for it.

  • #754 224201a Thanks @clauderic! - The <SortableContext> component now optionally accepts a disabled prop to globally disable useSortable hooks rendered within it.

    The disabled prop accepts either a boolean or an object with the following shape:

    interface Disabled {
      draggable?: boolean;
      droppable?: boolean;
    }

    The useSortable hook has now been updated to also optionally accept the disabled configuration object to conditionally disable the useDraggable and/or useDroppable hooks used internally.

    Like the strategy prop, the disabled prop defined on the useSortable hook takes precedence over the disabled prop defined on the parent <SortableContext>.

Patch Changes

6.0.1

Patch Changes

  • #642 15a6017 Thanks @vosatom! - Fixed an issue that affected SortableContext performance. The sortedRects property of the SortableContext provider were being recomputed whenever coordinates changed rather than only when the order of the items changed.

  • Updated dependencies [b3b185d]:

    • @dnd-kit/core@5.0.2

6.0.0

Major Changes

  • #518 6310227 Thanks @clauderic! - Major internal refactor of measuring and collision detection.

    Summary of changes

    Previously, all collision detection algorithms were relative to the top and left points of the document. While this approach worked in most situations, it broke down in a number of different use-cases, such as fixed position droppable containers and trying to drag between containers that had different scroll positions.

    This new approach changes the frame of comparison to be relative to the viewport. This is a major breaking change, and will need to be released under a new major version bump.

    Breaking changes:

    • By default, @dnd-kit now ignores only the transforms applied to the draggable / droppable node itself, but considers all the transforms applied to its ancestors. This should provide the right balance of flexibility for most consumers.
      • Transforms applied to the droppable and draggable nodes are ignored by default, because the recommended approach for moving items on the screen is to use the transform property, which can interfere with the calculation of collisions.
      • Consumers can choose an alternate approach that does consider transforms for specific use-cases if needed by configuring the measuring prop of . Refer to the example.
    • Reduced the number of concepts related to measuring from ViewRect, LayoutRect to just a single concept of ClientRect.
      • The ClientRect interface no longer holds the offsetTop and offsetLeft properties. For most use-cases, you can replace offsetTop with top and offsetLeft with left.
      • Replaced the following exports from the @dnd-kit/core package with getClientRect:
        • getBoundingClientRect
        • getViewRect
        • getLayoutRect
        • getViewportLayoutRect
    • Removed translatedRect from the SensorContext interface. Replace usage with collisionRect.
    • Removed activeNodeClientRect on the DndContext interface. Replace with activeNodeRect.
  • #569 e7ac3d4 Thanks @clauderic! - Separated context into public and internal context providers. Certain properties that used to be available on the public DndContextDescriptor interface have been moved to the internal context provider and are no longer exposed to consumers:

    interface DndContextDescriptor {
    -  dispatch: React.Dispatch<Actions>;
    -  activators: SyntheticListeners;
    -  ariaDescribedById: {
    -    draggable: UniqueIdentifier;
    -  };
    }

    Having two distinct context providers will allow to keep certain internals such as dispatch hidden from consumers.

    It also serves as an optimization until context selectors are implemented in React, properties that change often, such as the droppable containers and droppable rects, the transform value and array of collisions should be stored on a different context provider to limit un-necessary re-renders in useDraggable, useDroppable and useSortable.

    The <InternalContext.Provider> is also reset to its default values within <DragOverlay>. This paves the way towards being able to seamlessly use components that use hooks such as useDraggable and useDroppable as children of <DragOverlay> without causing interference or namespace collisions.

    Consumers can still make calls to useDndContext() to get the active or over properties if they wish to re-render the component rendered within DragOverlay in response to user interaction, since those use the PublicContext

Minor Changes

  • #558 f3ad20d Thanks @clauderic! - Refactor of the CollisionDetection interface to return an array of Collisions:

    +export interface Collision {
    +  id: UniqueIdentifier;
    +  data?: Record<string, any>;
    +}
    
    export type CollisionDetection = (args: {
      active: Active;
      collisionRect: ClientRect;
      droppableContainers: DroppableContainer[];
      pointerCoordinates: Coordinates | null;
    -}) => UniqueIdentifier;
    +}) => Collision[];

    This is a breaking change that requires all collision detection strategies to be updated to return an array of Collision rather than a single UniqueIdentifier

    The over property remains a single UniqueIdentifier, and is set to the first item in returned in the collisions array.

    Consumers can also access the collisions property which can be used to implement use-cases such as combining droppables in user-land.

    The onDragMove, onDragOver and onDragEnd callbacks are also updated to receive the collisions array property.

    Built-in collision detections such as rectIntersection, closestCenter, closestCorners and pointerWithin adhere to the CollisionDescriptor interface, which extends the Collision interface:

    export interface CollisionDescriptor extends Collision {
      data: {
        droppableContainer: DroppableContainer;
        value: number;
        [key: string]: any;
      };
    }

    Consumers can also access the array of collisions in components wrapped by <DndContext> via the useDndContext() hook:

    import {useDndContext} from '@dnd-kit/core';
    
    function MyComponent() {
      const {collisions} = useDndContext();
    }
  • #561 02edd26 Thanks @clauderic! - Droppable containers now observe the node they are attached to via setNodeRef using ResizeObserver while dragging.

    This behaviour can be configured using the newly introduced resizeObserverConfig property.

    interface ResizeObserverConfig {
      /** Whether the ResizeObserver should be disabled entirely */
      disabled?: boolean;
      /** Resize events may affect the layout and position of other droppable containers.
       * Specify an array of `UniqueIdentifier` of droppable containers that should also be re-measured
       * when this droppable container resizes. Specifying an empty array re-measures all droppable containers.
       */
      updateMeasurementsFor?: UniqueIdentifier[];
      /** Represents the debounce timeout between when resize events are observed and when elements are re-measured */
      timeout?: number;
    }

    By default, only the current droppable is scheduled to be re-measured when a resize event is observed. However, this may not be suitable for all use-cases. When an element resizes, it can affect the layout and position of other elements, such that it may be necessary to re-measure other droppable nodes in response to that single resize event. The recomputeIds property can be used to specify which droppable ids should be re-measured in response to resize events being observed.

    For example, the useSortable preset re-computes the measurements of all sortable elements after the element that resizes, so long as they are within the same SortableContext as the element that resizes, since it's highly likely that their layout will also shift.

    Specifying an empty array for recomputeIds forces all droppable containers to be re-measured.

    For consumers that were relyings on the internals of DndContext using useDndContext(), the willRecomputeLayouts property has been renamed to measuringScheduled, and the recomputeLayouts method has been renamed to measureDroppableContainers, and now optionally accepts an array of droppable UniqueIdentifier that should be scheduled to be re-measured.

  • #570 1ade2f3 Thanks @clauderic! - Use transition for the active draggable node when keyboard sorting without a <DragOverlay />.

Patch Changes

5.1.0

Minor Changes

  • #486 d86529c Thanks @clauderic! - Improvements to better support swappable strategies:

    • Now exporting an arraySwap helper to be used instead of arrayMove onDragEnd.
    • Added the getNewIndex prop on useSortable. By default, useSortable assumes that items will be moved to their new index using arrayMove(), but this isn't always the case, especially when using strategies like rectSwappingStrategy. For those scenarios, consumers can now define custom logic that should be used to get the new index for an item on drop, for example, by computing the new order of items using arraySwap.

Patch Changes

  • Updated dependencies [d973cc6]:
    • @dnd-kit/core@4.0.2

5.0.0

Major Changes

  • #427 f96cb5d Thanks @clauderic! - - Using transform-agnostic measurements for the DragOverlay node.

    • Renamed the overlayNode property to dragOverlay on the DndContextDescriptor interface.
  • 9cfac05 Thanks @clauderic! - Renamed the wasSorting property to wasDragging on the SortableContext and AnimateLayoutChanges interfaces.

Minor Changes

Patch Changes

  • #372 dbc9601 Thanks @clauderic! - Refactored DroppableContainers type from Record<UniqueIdentifier, DroppableContainer to a custom instance that extends the Map constructor and adds a few other methods such as toArray(), getEnabled() and getNodeFor(id).

    A unique key property was also added to the DraggableNode and DroppableContainer interfaces. This prevents potential race conditions in the mount and cleanup effects of useDraggable and useDroppable. It's possible for the clean-up effect to run after another React component using useDraggable or useDroppable mounts, which causes the newly mounted element to accidentally be un-registered.

  • #350 a13dbb6 Thanks @wmain! - Breaking change: The CollisionDetection interface has been refactored. It now receives an object that contains the active draggable node, along with the collisionRect and an array of droppableContainers.

    If you've built custom collision detection algorithms, you'll need to update them. Refer to this PR for examples of how to refactor collision detection functions to the new CollisionDetection interface.

    The sortableKeyboardCoordinates method has also been updated since it relies on the closestCorners collision detection algorithm. If you were using collision detection strategies in a custom sortableKeyboardCoordinates method, you'll need to update those as well.

  • 86d1f27 Thanks @clauderic! - Fixed a bug in the horizontalListSortingStrategy where it did not check if the currentRect was undefined.

  • e42a711 Thanks @clauderic! - Fixed a bug with the default layout animation function where it could return true initially even if the list had not been sorted yet. Now checking the wasDragging property to ensure no layout animation occurs if wasDragging is false.

  • #341 e02b737 Thanks @clauderic! - Return undefined instead of null for transition in useSortable

  • Updated dependencies [13be602, aede2cc, 05d6a78, a32a4c5, f96cb5d, dea715c, dbc9601, 46ec5e4, 7006464, 0e628bc, c447880, 2ba6dfe, 8d70540, 13be602, 422d083, c4b21b4, 5a41340, a13dbb6, e2ee0dc, 1fe9b5c, 1fe9b5c, 1f5ca27]:

    • @dnd-kit/core@4.0.0
    • @dnd-kit/utilities@3.0.0

4.0.0

Patch Changes

  • Updated dependencies [d39ab11]:
    • @dnd-kit/core@3.1.0

3.1.0

Minor Changes

  • 68960c4 #295 Thanks @akhmadullin! - @dnd-kit/core is now a peerDependency rather than a dependency for other @dnd-kit packages that depend on it, such as @dnd-kit/sortable and @dnd-kit/modifiers. This is done to avoid issues with multiple versions of @dnd-kit/core being installed by some package managers such as Yarn 2.

Patch Changes

3.0.1

Patch Changes

  • a178857 #214 Thanks @clauderic! - Ensure that consumer defined data passed to useSortable is passed down to both useDraggable and useDroppable.

    The data object that is passed to useDraggable and useDroppable within useSortable also contains the sortable property, which holds a reference to the index of the item, along with the containerId and the items of its parent SortableContext.

3.0.0

Major Changes

  • a9d92cf #174 Thanks @clauderic! - Distributed assets now only target modern browsers. Browserlist config:

    defaults
    last 2 version
    not IE 11
    not dead
    

    If you need to support older browsers, include the appropriate polyfills in your project's build process.

Minor Changes

  • b7355d1 #207 Thanks @clauderic! - The data argument for useDraggable and useDroppable is now exposed in event handlers and on the active and over objects.

    Example usage:

    import {DndContext, useDraggable, useDroppable} from '@dnd-kit/core';
    
    function Draggable() {
      const {attributes, listeners, setNodeRef, transform} = useDraggable({
        id: 'draggable',
        data: {
          type: 'type1',
        },
      });
    
      /* ... */
    }
    
    function Droppable() {
      const {setNodeRef} = useDroppable({
        id: 'droppable',
        data: {
          accepts: ['type1', 'type2'],
        },
      });
    
      /* ... */
    }
    
    function App() {
      return (
        <DndContext
          onDragEnd={({active, over}) => {
            if (over?.data.current.accepts.includes(active.data.current.type)) {
              // do stuff
            }
          }}
        />
      );
    }

Patch Changes

  • fb2db94 #212 Thanks @clauderic! - Allow consumers of SortableContext to provide items of shape {id: string}[] or string[]

  • Updated dependencies [b7355d1, a9d92cf, b406cb9]:

    • @dnd-kit/core@3.0.0
    • @dnd-kit/utilities@2.0.0

2.0.1

Patch Changes

  • 92afb0f #168 Thanks @clauderic! - Make sure that the wasSorting argument of the animateLayoutChanges prop of useSortable always receives the latest value.

  • Updated dependencies [bdb1aa2]:

    • @dnd-kit/core@2.1.0

2.0.0

Major Changes

  • 8583825 #140 Thanks @clauderic! - Auto-scrolling defaults have been updated, which should generally lead to improved user experience for most consumers.

    The auto-scroller now bases its calculations based on the position of the pointer rather than the edges of the draggable element's rect by default. This change is aligned with how the native HTML 5 Drag & Drop auto-scrolling behaves.

    This behaviour can be customized using the activator option of the autoScroll prop:

    import {AutoScrollActivator, DndContext} from '@dnd-kit/core';
    
    <DndContext autoScroll={{activator: AutoScrollActivator.DraggableRect}} />;

    The auto-scroller now also looks at scrollable ancestors in order of appearance in the DOM tree, meaning it will first attempt to scroll the window, and narrow its focus down rather than the old behaviour of looking at scrollable ancestors in order of closeness to the draggable element in the DOM tree (reversed tree order).

    This generally leads to an improved user experience, but can be customized by passing a configuration object to the autoScroll prop that sets the order option to TraversalOrder.ReversedTreeOrder instead of the new default value of TraversalOrder.TreeOrder:

    import {DndContext, TraversalOrder} from '@dnd-kit/core';
    
    <DndContext autoScroll={{order: TraversalOrder.ReversedTreeOrder}} />;

    The autoscrolling thresholds, acceleration and interval can now also be customized using the autoScroll prop:

    import {DndContext} from '@dnd-kit/core';
    
    <DndContext
      autoScroll={{
        thresholds: {
          // Left and right 10% of the scroll container activate scrolling
          x: 0.1,
          // Top and bottom 25% of the scroll container activate scrolling
          y: 0.25,
        },
        // Accelerate slower than the default value (10)
        acceleration: 5,
        // Auto-scroll every 10ms instead of the default value of 5ms
        interval: 10,
      }}
    />;

    Finally, consumers can now conditionally opt out of scrolling certain scrollable ancestors using the canScroll option of the autoScroll prop:

    import {DndContext} from '@dnd-kit/core';
    
    <DndContext
      autoScroll={{
        canScroll(element) {
          if (element === document.scrollingElement) {
            return false;
          }
    
          return true;
        },
      }}
    />;

Patch Changes

  • Updated dependencies [8583825]:
    • @dnd-kit/core@2.0.0

1.1.0

Minor Changes

  • 79f6088 #144 Thanks @clauderic! - Allow consumers to determine whether to animate layout changes and when to measure nodes. Consumers can now use the animateLayoutChanges prop of useSortable to determine whether layout animations should occur. Consumers can now also decide when to measure layouts, and at what frequency using the layoutMeasuring prop of DndContext. By default, DndContext will measure layouts just-in-time after sorting has begun. Consumers can override this behaviour to either only measure before dragging begins (on mount and after dragging), or always (on mount, before dragging, after dragging). Pairing the layoutMeasuring prop on DndContext and the animateLayoutChanges prop of useSortable opens up a number of new possibilities for consumers, such as animating insertion and removal of items in a sortable list.

Patch Changes

1.0.2

Patch Changes

1.0.1

Patch Changes

  • 0b343c7 #52 Thanks @clauderic! - Add repository entry to package.json files

  • 78a7b67 Thanks @clauderic! - Fix an issue with the sortable keyboard coordinate getter not excluding disabled droppables.

  • Updated dependencies [0b343c7, 5194696, 310bbd6]:

    • @dnd-kit/utilities@1.0.1
    • @dnd-kit/core@1.0.1

1.0.0

Major Changes

Patch Changes

  • Updated dependencies [2912350]:
    • @dnd-kit/core@1.0.0
    • @dnd-kit/utilities@1.0.0

0.1.0

Minor Changes

Patch Changes

  • Updated dependencies [7bd4568]:
    • @dnd-kit/core@0.1.0
    • @dnd-kit/utilities@0.1.0