@measured/dnd
Advanced tools
Comparing version 16.6.0-canary.27e9f8e to 16.6.0-canary.4cba1d1
{ | ||
"name": "@measured/dnd", | ||
"version": "16.6.0-canary.27e9f8e", | ||
"version": "16.6.0-canary.4cba1d1", | ||
"private": false, | ||
@@ -5,0 +5,0 @@ "description": "Beautiful and accessible drag and drop for lists with React, with iframe and CSS transform support", |
@@ -55,3 +55,3 @@ import { BoxModel, getBox } from 'css-box-model'; | ||
const isInIframe = win !== window; | ||
const isInIframe = win !== window && win.frameElement; | ||
@@ -58,0 +58,0 @@ if (isInIframe) { |
@@ -35,2 +35,3 @@ import type { BoxModel, Position } from 'css-box-model'; | ||
transform: Transform | null; | ||
parents: DroppableDescriptor[]; | ||
} | ||
@@ -48,2 +49,3 @@ | ||
transform, | ||
parents, | ||
}: Args): DroppableDimension => { | ||
@@ -103,2 +105,3 @@ const frame: Scrollable | null = (() => { | ||
transform, | ||
parents, | ||
}; | ||
@@ -105,0 +108,0 @@ |
@@ -78,2 +78,49 @@ import type { Position, Rect } from 'css-box-model'; | ||
/** | ||
* normalizeFamilies | ||
* | ||
* Groups all items that share a common root `parent`, and selects the deepest item | ||
* in that group that contains the center point of the dragged item to represent | ||
* the "family". | ||
*/ | ||
function normalizeFamilies( | ||
pageBorderBox: Rect, | ||
candidates: DroppableDimension[], | ||
) { | ||
const families = candidates.reduce<Record<string, DroppableDimension[][]>>( | ||
(acc, candidate) => { | ||
const familyName = candidate.parents[0]?.id || candidate.descriptor.id; | ||
const family = acc[familyName] || []; | ||
const generation = candidate.parents.length; | ||
family[generation] = [...(family[generation] || []), candidate]; | ||
return { | ||
...acc, | ||
[familyName]: family, | ||
}; | ||
}, | ||
{}, | ||
); | ||
return Object.keys(families).map((familyName) => { | ||
const family = families[familyName].flat(); | ||
const reversedFamily = [...family].reverse(); | ||
// Get first member of family that contains the draggable | ||
const chosenMember = reversedFamily.find((member) => { | ||
return ( | ||
pageBorderBox.center.x < member.page.borderBox.right && | ||
pageBorderBox.center.x > member.page.borderBox.left && | ||
pageBorderBox.center.y > member.page.borderBox.top && | ||
pageBorderBox.center.y < member.page.borderBox.bottom | ||
); | ||
}); | ||
return chosenMember || family[0]; | ||
}); | ||
} | ||
export default function getDroppableOver({ | ||
@@ -150,3 +197,10 @@ pageBorderBox, | ||
// Multiple options returned | ||
// Select the best candidate from each group that share a common root ancestor | ||
const normalizedCandidates = normalizeFamilies(pageBorderBox, candidates); | ||
// All candidates were in the same family | ||
if (normalizedCandidates.length === 1) { | ||
return normalizedCandidates[0].descriptor.id; | ||
} | ||
// Should only occur with really large items | ||
@@ -157,4 +211,4 @@ // Going to use fallback: distance from home | ||
draggable, | ||
candidates, | ||
candidates: normalizedCandidates, | ||
}); | ||
} |
@@ -157,2 +157,3 @@ import type { BoxModel, Rect, Position } from 'css-box-model'; | ||
transform: Transform | null; | ||
parents: DroppableDescriptor[]; | ||
} | ||
@@ -159,0 +160,0 @@ export interface DraggableLocation { |
@@ -5,3 +5,3 @@ export default function getIframe(el: HTMLElement) { | ||
if (refWindow && refWindow.self !== refWindow.parent) { | ||
const iframe = refWindow.frameElement as HTMLIFrameElement; | ||
const iframe = refWindow.frameElement as HTMLIFrameElement | null; | ||
@@ -8,0 +8,0 @@ return iframe; |
@@ -89,3 +89,7 @@ import { BoxModel, Rect, Spacing } from 'css-box-model'; | ||
if (refWindow && refWindow.self !== refWindow.parent) { | ||
if ( | ||
refWindow && | ||
refWindow.self !== refWindow.parent && | ||
refWindow.frameElement | ||
) { | ||
const iframe = refWindow.frameElement as HTMLIFrameElement; | ||
@@ -92,0 +96,0 @@ |
@@ -17,2 +17,3 @@ import { getBox, withScroll, createBox, expand } from 'css-box-model'; | ||
import { Offset } from '../iframe/offset-types'; | ||
import { prefix } from '../data-attributes'; | ||
@@ -100,2 +101,33 @@ const getClient = ( | ||
const getParents = (ref: HTMLElement) => { | ||
const contextId = ref.getAttribute(`${prefix}-droppable-context-id`); | ||
const parentDescriptors: DroppableDescriptor[] = []; | ||
if (!contextId) return []; | ||
let currentEl: HTMLElement | null | undefined = ref; | ||
while (currentEl) { | ||
currentEl = currentEl.parentElement?.closest( | ||
`[${prefix}-droppable-context-id="${contextId}"]`, | ||
); | ||
const id = currentEl?.getAttribute(`${prefix}-droppable-id`); | ||
if (id) { | ||
parentDescriptors.push({ | ||
id, | ||
mode: 'standard', | ||
type: 'DEFAULT', | ||
}); | ||
} | ||
} | ||
// Parents need reversing | ||
parentDescriptors.reverse(); | ||
return parentDescriptors; | ||
}; | ||
export default ({ | ||
@@ -137,2 +169,4 @@ ref, | ||
const parents = getParents(ref); | ||
const dimension: DroppableDimension = getDroppableDimension({ | ||
@@ -148,2 +182,3 @@ descriptor, | ||
transform, | ||
parents, | ||
}); | ||
@@ -150,0 +185,0 @@ |
@@ -13,24 +13,27 @@ import { Position } from 'css-box-model'; | ||
if (win.parent !== win.self) { | ||
const iframe = win.frameElement as HTMLIFrameElement; | ||
const rect = iframe.getBoundingClientRect(); | ||
const iframe = win.frameElement as HTMLIFrameElement | null; | ||
const transform = getTransform(iframe); | ||
if (iframe) { | ||
const rect = iframe.getBoundingClientRect(); | ||
offsetX = rect.left; | ||
offsetY = rect.top; | ||
const transform = getTransform(iframe); | ||
if (transform) { | ||
const { x: transformedX, y: transformedY } = applyTransformPoint( | ||
x, | ||
y, | ||
transform.matrix, | ||
transform.origin, | ||
); | ||
offsetX = rect.left; | ||
offsetY = rect.top; | ||
const point: Position = { | ||
x: transformedX + offsetX, | ||
y: transformedY + offsetY, | ||
}; | ||
if (transform) { | ||
const { x: transformedX, y: transformedY } = applyTransformPoint( | ||
x, | ||
y, | ||
transform.matrix, | ||
transform.origin, | ||
); | ||
return point; | ||
const point: Position = { | ||
x: transformedX + offsetX, | ||
y: transformedY + offsetY, | ||
}; | ||
return point; | ||
} | ||
} | ||
@@ -37,0 +40,0 @@ } |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
1433626
41749