@measured/dnd
Advanced tools
Comparing version 16.6.0-canary.ebfeb3d to 16.6.0-canary.f472135
@@ -224,2 +224,3 @@ import { Position } from 'css-box-model'; | ||
shouldRespectForcePress?: boolean; | ||
disableSecondaryAnimation?: boolean; | ||
} | ||
@@ -226,0 +227,0 @@ |
{ | ||
"name": "@measured/dnd", | ||
"version": "16.6.0-canary.ebfeb3d", | ||
"version": "16.6.0-canary.f472135", | ||
"private": false, | ||
@@ -78,2 +78,3 @@ "description": "Beautiful and accessible drag and drop for lists with React, with iframe and CSS transform support", | ||
"css-box-model": "^1.2.1", | ||
"lru-cache": "^10.2.0", | ||
"memoize-one": "^6.0.0", | ||
@@ -106,4 +107,4 @@ "raf-schd": "^4.0.3", | ||
"@emotion/styled": "11.11.0", | ||
"@jest/environment": "29.7.0", | ||
"@measured/auto-frame-component": "0.1.0-canary.4686711", | ||
"@jest/environment": "29.7.0", | ||
"@release-it/conventional-changelog": "8.0.1", | ||
@@ -110,0 +111,0 @@ "@rollup/plugin-babel": "6.0.4", |
@@ -6,18 +6,26 @@ import { BoxModel, getBox } from 'css-box-model'; | ||
import { AutoScrollerOptions } from './auto-scroller-options-types'; | ||
import { Transform, getTransform } from '../../../view/transform'; | ||
const resetToOrigin = (box: BoxModel) => ({ | ||
width: box.marginBox.width, | ||
height: box.marginBox.height, | ||
top: 0, | ||
left: 0, | ||
right: box.marginBox.width, | ||
bottom: box.marginBox.height, | ||
center: { | ||
x: box.marginBox.width / 2, | ||
y: box.marginBox.height / 2, | ||
}, | ||
x: 0, | ||
y: 0, | ||
}); | ||
const resetToOrigin = (box: BoxModel, transform: Transform | null) => { | ||
const { scaleX = 1, scaleY = 1 } = transform?.matrix || {}; | ||
const width = box.marginBox.width / scaleX; | ||
const height = box.marginBox.height / scaleY; | ||
return { | ||
width, | ||
height, | ||
top: 0, | ||
left: 0, | ||
right: width, | ||
bottom: height, | ||
center: { | ||
x: width / 2, | ||
y: height / 2, | ||
}, | ||
x: 0, | ||
y: 0, | ||
}; | ||
}; | ||
/** | ||
@@ -54,6 +62,7 @@ * Get the scroll for a draggable inside an iframe | ||
const box = getBox(el); | ||
const transform = getTransform(iframe); | ||
const change = getScroll({ | ||
dragStartTime, | ||
container: resetToOrigin(viewportBox), // Reset to origin because we don't care about position of the iframe | ||
container: resetToOrigin(viewportBox, transform), // Reset to origin because we don't care about position of the iframe | ||
subject: draggable.client.marginBox, | ||
@@ -60,0 +69,0 @@ center: box.borderBox.center, |
@@ -257,5 +257,6 @@ import type { Position } from 'css-box-model'; | ||
combineTargetFor?: DraggableId | null, | ||
disableSecondaryAnimation?: boolean, | ||
): MapProps | null => { | ||
return combineTargetFor | ||
? getMemoizedProps(origin, combineTargetFor, true) | ||
? getMemoizedProps(origin, combineTargetFor, !disableSecondaryAnimation) | ||
: null; | ||
@@ -271,2 +272,3 @@ }; | ||
sourceDroppable?: DroppableDimension | null, | ||
disableSecondaryAnimation?: boolean, | ||
): MapProps | null => { | ||
@@ -285,3 +287,3 @@ const visualDisplacement: Displacement | null = | ||
if (!isAfterCriticalInVirtualList) { | ||
return getFallback(combineTargetFor); | ||
return getFallback(combineTargetFor, disableSecondaryAnimation); | ||
} | ||
@@ -306,3 +308,3 @@ | ||
combineTargetFor, | ||
true, | ||
!disableSecondaryAnimation, | ||
dimension, | ||
@@ -325,3 +327,3 @@ sourceDroppable, | ||
combineTargetFor, | ||
visualDisplacement.shouldAnimate, | ||
disableSecondaryAnimation ? false : visualDisplacement.shouldAnimate, | ||
dimension, | ||
@@ -356,2 +358,3 @@ sourceDroppable, | ||
sourceDroppable, | ||
ownProps.disableSecondaryAnimation, | ||
); | ||
@@ -380,2 +383,3 @@ } | ||
sourceDroppable, | ||
ownProps.disableSecondaryAnimation, | ||
); | ||
@@ -397,7 +401,24 @@ } | ||
const selector = (state: State, ownProps: OwnProps): MapProps => | ||
draggingSelector(state, ownProps) || | ||
secondarySelector(state, ownProps) || | ||
atRest; | ||
const selector = (state: State, ownProps: OwnProps): MapProps => { | ||
// Modify atRest based on props | ||
const atRestLocal = | ||
atRest.mapped.type === 'DRAGGING' | ||
? atRest | ||
: { | ||
...atRest, | ||
mapped: { | ||
...atRest.mapped, | ||
shouldAnimateDisplacement: ownProps.disableSecondaryAnimation | ||
? false | ||
: atRest.mapped.shouldAnimateDisplacement, | ||
}, | ||
}; | ||
return ( | ||
draggingSelector(state, ownProps) || | ||
secondarySelector(state, ownProps) || | ||
atRestLocal | ||
); | ||
}; | ||
return selector; | ||
@@ -404,0 +425,0 @@ }; |
@@ -171,2 +171,3 @@ import type { Position } from 'css-box-model'; | ||
shouldRespectForcePress?: boolean; | ||
disableSecondaryAnimation?: boolean; | ||
} | ||
@@ -173,0 +174,0 @@ |
@@ -20,19 +20,36 @@ import { querySelectorAll } from '../../query-selector-all'; | ||
let loaded = false; | ||
const getWin = (el: HTMLElement | Window) => { | ||
let win = el as Window | null; | ||
function bindEvent(win: Window, binding: EventBinding, options: EventOptions) { | ||
if ((el as HTMLElement).nodeName === 'IFRAME') { | ||
win = (el as HTMLIFrameElement).contentWindow; | ||
} | ||
return win; | ||
}; | ||
function bindEvent( | ||
el: HTMLElement | Window, | ||
binding: EventBinding, | ||
options: EventOptions, | ||
) { | ||
let timer: number | undefined; | ||
if (!loaded) { | ||
// Some browsers require us to defer binding events, i.e. Safari | ||
if ((el as HTMLElement).nodeName === 'IFRAME') { | ||
timer = setInterval(() => { | ||
if ((win as Window).document.readyState === 'complete') { | ||
win.addEventListener(binding.eventName, binding.fn, options); | ||
loaded = true; | ||
const currentWin = getWin(el); | ||
if (currentWin?.document.readyState === 'complete') { | ||
currentWin.addEventListener(binding.eventName, binding.fn, options); | ||
clearInterval(timer); | ||
} | ||
}, 100); | ||
} else { | ||
win.addEventListener(binding.eventName, binding.fn, options); | ||
return timer; | ||
} | ||
const win = getWin(el); | ||
win?.addEventListener(binding.eventName, binding.fn, options); | ||
return timer; | ||
@@ -50,17 +67,18 @@ } | ||
window.document, | ||
'iframe', | ||
'[data-rfd-iframe]', | ||
) as HTMLIFrameElement[]; | ||
const windows = [el, ...iframes.map((iframe) => iframe.contentWindow)]; | ||
const els = [el, ...iframes]; | ||
return windows.map((win) => { | ||
if (!win) return function unbind() {}; | ||
return els.map((currentEl) => { | ||
if (!currentEl) return function unbind() {}; | ||
const options = getOptions(sharedOptions, binding.options); | ||
const timer = bindEvent(win as Window, binding, options); | ||
const timer = bindEvent(currentEl, binding, options); | ||
return function unbind() { | ||
clearInterval(timer); | ||
win.removeEventListener(binding.eventName, binding.fn, options); | ||
const win = getWin(currentEl); | ||
win?.removeEventListener(binding.eventName, binding.fn, options); | ||
}; | ||
@@ -67,0 +85,0 @@ }); |
@@ -0,1 +1,2 @@ | ||
import { LRUCache } from 'lru-cache'; | ||
import type { DraggableId, ContextId } from '../../types'; | ||
@@ -7,2 +8,7 @@ import { dragHandle as dragHandleAttr } from '../data-attributes'; | ||
const dragHandleCache = new LRUCache<string, HTMLElement>({ | ||
max: 5000, | ||
ttl: 1000, | ||
}); | ||
export default function findDragHandle( | ||
@@ -15,2 +21,8 @@ contextId: ContextId, | ||
const cachedHandle = dragHandleCache.get(selector); | ||
if (cachedHandle) { | ||
return cachedHandle; | ||
} | ||
const possible = querySelectorAllIframe(selector); | ||
@@ -41,3 +53,5 @@ | ||
dragHandleCache.set(selector, handle); | ||
return handle; | ||
} |
@@ -0,1 +1,9 @@ | ||
import { LRUCache } from 'lru-cache'; | ||
import { querySelectorAll } from '../../query-selector-all'; | ||
const iframeCache = new LRUCache<string, HTMLIFrameElement[]>({ | ||
max: 1, | ||
ttl: 1000, | ||
}); | ||
/** | ||
@@ -6,12 +14,22 @@ * querySelectorAllIframe | ||
*/ | ||
export default function querySelectorAllIframe(selector: string) { | ||
let iframes = iframeCache.get('iframes'); | ||
import { querySelectorAll } from '../../query-selector-all'; | ||
if (!iframes) { | ||
iframes = querySelectorAll(document, 'iframe') as HTMLIFrameElement[]; | ||
export default function querySelectorAllIframe(selector: string) { | ||
const iframes = querySelectorAll(document, 'iframe') as HTMLIFrameElement[]; | ||
// Quicker than running the [data-rbd-frame] query | ||
iframes = iframes.filter((iframe) => | ||
iframe.hasAttribute('data-rfd-iframe'), | ||
); | ||
iframeCache.set('iframes', iframes); | ||
} | ||
const iframePossible = iframes.reduce<HTMLElement[]>( | ||
(acc, iframe) => [ | ||
...acc, | ||
...querySelectorAll(iframe.contentWindow!.document, selector), | ||
...(iframe.contentWindow?.document | ||
? querySelectorAll(iframe.contentWindow.document, selector) | ||
: []), | ||
], | ||
@@ -18,0 +36,0 @@ [], |
@@ -68,3 +68,5 @@ import memoizeOne from 'memoize-one'; | ||
querySelectorAll(document, `[${prefix}-iframe]`) as HTMLIFrameElement[] | ||
).map((iframe) => getHead(iframe.contentWindow!.document)), | ||
) | ||
.filter((iframe) => iframe.contentWindow?.document) | ||
.map((iframe) => getHead(iframe.contentWindow!.document)), | ||
]; | ||
@@ -71,0 +73,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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1425590
41559
10
252
+ Addedlru-cache@^10.2.0
+ Addedlru-cache@10.4.3(transitive)