Skip to content

Commit

Permalink
Merge branch 'master' into feature/constraint-cues
Browse files Browse the repository at this point in the history
+ as requested, change changeset version type to minor
  • Loading branch information
irobot committed Nov 23, 2024
2 parents 0c6a28d + 2ed0363 commit 9175566
Show file tree
Hide file tree
Showing 30 changed files with 157 additions and 94 deletions.
2 changes: 1 addition & 1 deletion .changeset/metal-mice-develop.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
'@dnd-kit/core': patch
'@dnd-kit/core': minor
---

Make it possible to add visual cues when using activation constraints.
Expand Down
10 changes: 10 additions & 0 deletions packages/accessibility/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# @dnd-kit/accessibility

## 3.1.1

### Patch Changes

- [#1534](https://github.com/clauderic/dnd-kit/pull/1534) [`93602df`](https://github.com/clauderic/dnd-kit/commit/93602df08498b28749e8146e0f6143ab987bc178) Thanks [@duvallj](https://github.com/duvallj)! - Workaround `<LiveRegion>` layout bug by adding explicit `top` and `left`
attributes. Under sufficiently complex CSS conditions, the element would
overflow containers that it's not supposed to. See [this
post](https://blog.duvallj.pw/posts/2024-11-19-chrome-heisenbug-uncovered.html)
for a complete explanation.

## 3.1.0

### Minor Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/accessibility/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dnd-kit/accessibility",
"version": "3.1.0",
"version": "3.1.1",
"description": "A generic toolkit to help with accessibility",
"author": "Claudéric Demers",
"license": "MIT",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export function LiveRegion({id, announcement, ariaLiveType = "assertive"}: Props
// Hide element visually but keep it readable by screen readers
const visuallyHidden: React.CSSProperties = {
position: 'fixed',
top: 0,
left: 0,
width: 1,
height: 1,
margin: -1,
Expand Down
23 changes: 23 additions & 0 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
# @dnd-kit/core

## 6.2.0

### Minor Changes

- [#1140](https://github.com/clauderic/dnd-kit/pull/1140) [`545a41c`](https://github.com/clauderic/dnd-kit/commit/545a41c27c6919e4ca22a58a67f3fa02a7caab8a) Thanks [@anilanar](https://github.com/anilanar)! - Add `activatorEvent` to `DragStartEvent`

### Patch Changes

- [#1494](https://github.com/clauderic/dnd-kit/pull/1494) [`00ec286`](https://github.com/clauderic/dnd-kit/commit/00ec286ab2fc7969549a4b19ffd42a09b5171dbe) Thanks [@dinkinflickaa](https://github.com/dinkinflickaa)! - Improves performance by eliminating wasteful re-renders on every child item on click

- [#1400](https://github.com/clauderic/dnd-kit/pull/1400) [`995dc23`](https://github.com/clauderic/dnd-kit/commit/995dc23b7cd9019f3a920676cbe4e141e917e82c) Thanks [@12joan](https://github.com/12joan)! - Export `defaultKeyboardCoordinateGetter`

- [#1542](https://github.com/clauderic/dnd-kit/pull/1542) [`f629ec6`](https://github.com/clauderic/dnd-kit/commit/f629ec6a9c3c25b749561fac31741046d96c28dc) Thanks [@clauderic](https://github.com/clauderic)! - Fix bug with draggable and sortable elements with an `id` equal to `0`.

- [#1541](https://github.com/clauderic/dnd-kit/pull/1541) [`99643f6`](https://github.com/clauderic/dnd-kit/commit/99643f634cd55fa0bf0898365883507b28637659) Thanks [@clauderic](https://github.com/clauderic)! - Handle `touchcancel` and `pointercancel` events.

- [#1435](https://github.com/clauderic/dnd-kit/pull/1435) [`6bbe39b`](https://github.com/clauderic/dnd-kit/commit/6bbe39bba6ad9afd0bc6db1c345ad4e6b58f5e5e) Thanks [@knaveenkumar3576](https://github.com/knaveenkumar3576)! - Faster Paint with delayed flush of Effects

- [#1543](https://github.com/clauderic/dnd-kit/pull/1543) [`bcaf7c4`](https://github.com/clauderic/dnd-kit/commit/bcaf7c4e57b34dfc8ff9c4eea7a01c6e525e7874) Thanks [@clauderic](https://github.com/clauderic)! - Fix a bug with auto-scroller continuing to observe stale elements, causing them to be considered as scrollable.

- Updated dependencies [[`93602df`](https://github.com/clauderic/dnd-kit/commit/93602df08498b28749e8146e0f6143ab987bc178)]:
- @dnd-kit/accessibility@3.1.1

## 6.1.0

### Minor Changes
Expand Down
4 changes: 2 additions & 2 deletions packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dnd-kit/core",
"version": "6.1.0",
"version": "6.2.0",
"description": "dnd kit – a lightweight React library for building performant and accessible drag and drop experiences",
"author": "Claudéric Demers",
"license": "MIT",
Expand Down Expand Up @@ -31,7 +31,7 @@
},
"dependencies": {
"tslib": "^2.0.0",
"@dnd-kit/accessibility": "^3.1.0",
"@dnd-kit/accessibility": "^3.1.1",
"@dnd-kit/utilities": "^3.2.2"
},
"publishConfig": {
Expand Down
14 changes: 8 additions & 6 deletions packages/core/src/components/DndContext/DndContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ export const DndContext = memo(function DndContext({
draggable: {active: activeId, nodes: draggableNodes, translate},
droppable: {containers: droppableContainers},
} = state;
const node = activeId ? draggableNodes.get(activeId) : null;
const node = activeId != null ? draggableNodes.get(activeId) : null;
const activeRects = useRef<Active['rect']['current']>({
initial: null,
translated: null,
Expand Down Expand Up @@ -201,7 +201,7 @@ export const DndContext = memo(function DndContext({
);

useLayoutShiftScrollCompensation({
activeNode: activeId ? draggableNodes.get(activeId) : null,
activeNode: activeId != null ? draggableNodes.get(activeId) : null,
config: autoScrollOptions.layoutShiftCompensation,
initialRect: initialActiveNodeRect,
measure: measuringConfiguration.draggable.measure,
Expand Down Expand Up @@ -323,6 +323,7 @@ export const DndContext = memo(function DndContext({
activeNodeRect
);

const activeSensorRef = useRef<SensorInstance | null>(null);
const instantiateSensor = useCallback(
(
event: React.SyntheticEvent,
Expand Down Expand Up @@ -393,6 +394,7 @@ export const DndContext = memo(function DndContext({

const {onDragStart} = latestProps.current;
const event: DragStartEvent = {
activatorEvent,
active: {id, data: draggableNode.data, rect: activeRects},
};

Expand All @@ -405,6 +407,8 @@ export const DndContext = memo(function DndContext({
active: id,
});
dispatchMonitorEvent({type: 'onDragStart', event});
setActiveSensor(activeSensorRef.current);
setActivatorEvent(activatorEvent);
});
},
onMove(coordinates) {
Expand All @@ -417,10 +421,7 @@ export const DndContext = memo(function DndContext({
onCancel: createHandler(Action.DragCancel),
});

unstable_batchedUpdates(() => {
setActiveSensor(sensorInstance);
setActivatorEvent(event.nativeEvent);
});
activeSensorRef.current = sensorInstance;

function createHandler(type: Action.DragEnd | Action.DragCancel) {
return async function handler() {
Expand Down Expand Up @@ -456,6 +457,7 @@ export const DndContext = memo(function DndContext({
setOver(null);
setActiveSensor(null);
setActivatorEvent(null);
activeSensorRef.current = null;

const eventName =
type === Action.DragEnd ? 'onDragEnd' : 'onDragCancel';
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/hooks/useDraggable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const NullContext = createContext<any>(null);

const defaultRole = 'button';

const ID_PREFIX = 'Droppable';
const ID_PREFIX = 'Draggable';

export function useDraggable({
id,
Expand Down
14 changes: 4 additions & 10 deletions packages/core/src/hooks/useDroppable.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import {useCallback, useContext, useEffect, useRef} from 'react';
import {
useIsomorphicLayoutEffect,
useLatestValue,
useNodeRef,
useUniqueId,
} from '@dnd-kit/utilities';
import {useLatestValue, useNodeRef, useUniqueId} from '@dnd-kit/utilities';

import {InternalContext, Action, Data} from '../store';
import type {ClientRect, UniqueIdentifier} from '../types';
Expand Down Expand Up @@ -43,9 +38,8 @@ export function useDroppable({
resizeObserverConfig,
}: UseDroppableArguments) {
const key = useUniqueId(ID_PREFIX);
const {active, dispatch, over, measureDroppableContainers} = useContext(
InternalContext
);
const {active, dispatch, over, measureDroppableContainers} =
useContext(InternalContext);
const previous = useRef({disabled});
const resizeObserverConnected = useRef(false);
const rect = useRef<ClientRect | null>(null);
Expand Down Expand Up @@ -116,7 +110,7 @@ export function useDroppable({
resizeObserver.observe(nodeRef.current);
}, [nodeRef, resizeObserver]);

useIsomorphicLayoutEffect(
useEffect(
() => {
dispatch({
type: Action.RegisterDroppable,
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/hooks/utilities/useCachedNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ export function useCachedNode(
draggableNodes: DraggableNodes,
id: UniqueIdentifier | null
): DraggableNode['node']['current'] {
const draggableNode = id !== null ? draggableNodes.get(id) : undefined;
const draggableNode = id != null ? draggableNodes.get(id) : undefined;
const node = draggableNode ? draggableNode.node.current : null;

return useLazyMemo(
(cachedNode) => {
if (id === null) {
if (id == null) {
return null;
}

Expand Down
46 changes: 24 additions & 22 deletions packages/core/src/hooks/utilities/useRect.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {useReducer} from 'react';
import {useState} from 'react';
import {useIsomorphicLayoutEffect} from '@dnd-kit/utilities';

import type {ClientRect} from '../../types';
Expand All @@ -16,8 +16,30 @@ export function useRect(
measure: (element: HTMLElement) => ClientRect = defaultMeasure,
fallbackRect?: ClientRect | null
) {
const [rect, measureRect] = useReducer(reducer, null);
const [rect, setRect] = useState<ClientRect | null>(null);

function measureRect() {
setRect((currentRect): ClientRect | null => {
if (!element) {
return null;
}

if (element.isConnected === false) {
// Fall back to last rect we measured if the element is
// no longer connected to the DOM.
return currentRect ?? fallbackRect ?? null;
}

const newRect = measure(element);

if (JSON.stringify(currentRect) === JSON.stringify(newRect)) {
return currentRect;
}

return newRect;
});
}

const mutationObserver = useMutationObserver({
callback(records) {
if (!element) {
Expand Down Expand Up @@ -56,24 +78,4 @@ export function useRect(
}, [element]);

return rect;

function reducer(currentRect: ClientRect | null) {
if (!element) {
return null;
}

if (element.isConnected === false) {
// Fall back to last rect we measured if the element is
// no longer connected to the DOM.
return currentRect ?? fallbackRect ?? null;
}

const newRect = measure(element);

if (JSON.stringify(currentRect) === JSON.stringify(newRect)) {
return currentRect;
}

return newRect;
}
}
44 changes: 20 additions & 24 deletions packages/core/src/hooks/utilities/useRects.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {useReducer} from 'react';
import {useState} from 'react';
import {getWindow, useIsomorphicLayoutEffect} from '@dnd-kit/utilities';

import type {ClientRect} from '../../types';
Expand All @@ -18,33 +18,29 @@ export function useRects(
const windowRect = useWindowRect(
firstElement ? getWindow(firstElement) : null
);
const [rects, measureRects] = useReducer(reducer, defaultValue);
const resizeObserver = useResizeObserver({callback: measureRects});

if (elements.length > 0 && rects === defaultValue) {
measureRects();
const [rects, setRects] = useState<ClientRect[]>(defaultValue);

function measureRects() {
setRects(() => {
if (!elements.length) {
return defaultValue;
}

return elements.map((element) =>
isDocumentScrollingElement(element)
? (windowRect as ClientRect)
: new Rect(measure(element), element)
);
});
}

const resizeObserver = useResizeObserver({callback: measureRects});

useIsomorphicLayoutEffect(() => {
if (elements.length) {
elements.forEach((element) => resizeObserver?.observe(element));
} else {
resizeObserver?.disconnect();
measureRects();
}
resizeObserver?.disconnect();
measureRects();
elements.forEach((element) => resizeObserver?.observe(element));
}, [elements]);

return rects;

function reducer() {
if (!elements.length) {
return defaultValue;
}

return elements.map((element) =>
isDocumentScrollingElement(element)
? (windowRect as ClientRect)
: new Rect(measure(element), element)
);
}
}
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export {
MouseSensor,
PointerSensor,
TouchSensor,
defaultKeyboardCoordinateGetter,
useSensors,
useSensor,
} from './sensors';
Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/sensors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ export type {MouseSensorOptions, MouseSensorProps} from './mouse';
export {TouchSensor} from './touch';
export type {TouchSensorOptions, TouchSensorProps} from './touch';

export {KeyboardSensor, KeyboardCode} from './keyboard';
export {
KeyboardSensor,
KeyboardCode,
defaultKeyboardCoordinateGetter,
} from './keyboard';
export type {
KeyboardCoordinateGetter,
KeyboardSensorOptions,
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/sensors/keyboard/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export type {
} from './KeyboardSensor';
export type {KeyboardCoordinateGetter, KeyboardCodes} from './types';
export {KeyboardCode} from './types';
export {defaultKeyboardCoordinateGetter} from './defaults';
6 changes: 6 additions & 0 deletions packages/core/src/sensors/pointer/AbstractPointerSensor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ interface EventDescriptor {
}

export interface PointerEventHandlers {
cancel?: EventDescriptor;
move: EventDescriptor;
end: EventDescriptor;
}
Expand Down Expand Up @@ -109,6 +110,11 @@ export class AbstractPointerSensor implements SensorInstance {

this.listeners.add(events.move.name, this.handleMove, {passive: false});
this.listeners.add(events.end.name, this.handleEnd);

if (events.cancel) {
this.listeners.add(events.cancel.name, this.handleCancel);
}

this.windowListeners.add(EventName.Resize, this.handleCancel);
this.windowListeners.add(EventName.DragStart, preventDefault);
this.windowListeners.add(EventName.VisibilityChange, this.handleCancel);
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/sensors/pointer/PointerSensor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from './AbstractPointerSensor';

const events: PointerEventHandlers = {
cancel: {name: 'pointercancel'},
move: {name: 'pointermove'},
end: {name: 'pointerup'},
};
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/sensors/touch/TouchSensor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import type {SensorProps} from '../types';

const events: PointerEventHandlers = {
cancel: {name: 'touchcancel'},
move: {name: 'touchmove'},
end: {name: 'touchend'},
};
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/store/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function reducer(state: State, action: Actions): State {
},
};
case Action.DragMove:
if (!state.draggable.active) {
if (state.draggable.active == null) {
return state;
}

Expand Down
Loading

0 comments on commit 9175566

Please sign in to comment.