Comparing version 0.4.0 to 0.5.0
import * as eventti from 'eventti'; | ||
import { EventListenerId, Emitter, Events } from 'eventti'; | ||
import * as tikki from 'tikki'; | ||
import { Phase, AutoTicker, FrameCallback } from 'tikki'; | ||
import { AutoTicker, Phase, FrameCallback } from 'tikki'; | ||
declare const SensorEventType: { | ||
readonly start: "start"; | ||
readonly move: "move"; | ||
readonly cancel: "cancel"; | ||
readonly end: "end"; | ||
readonly destroy: "destroy"; | ||
readonly Start: "start"; | ||
readonly Move: "move"; | ||
readonly Cancel: "cancel"; | ||
readonly End: "end"; | ||
readonly Destroy: "destroy"; | ||
}; | ||
type SensorEventType = (typeof SensorEventType)[keyof typeof SensorEventType]; | ||
interface SensorStartEvent { | ||
type: typeof SensorEventType.start; | ||
type: typeof SensorEventType.Start; | ||
x: number; | ||
@@ -19,3 +20,3 @@ y: number; | ||
interface SensorMoveEvent { | ||
type: typeof SensorEventType.move; | ||
type: typeof SensorEventType.Move; | ||
x: number; | ||
@@ -25,3 +26,3 @@ y: number; | ||
interface SensorCancelEvent { | ||
type: typeof SensorEventType.cancel; | ||
type: typeof SensorEventType.Cancel; | ||
x: number; | ||
@@ -31,3 +32,3 @@ y: number; | ||
interface SensorEndEvent { | ||
type: typeof SensorEventType.end; | ||
type: typeof SensorEventType.End; | ||
x: number; | ||
@@ -37,3 +38,3 @@ y: number; | ||
interface SensorDestroyEvent { | ||
type: typeof SensorEventType.destroy; | ||
type: typeof SensorEventType.Destroy; | ||
} | ||
@@ -306,2 +307,15 @@ interface SensorEvents { | ||
declare class ObjectCache<Key extends any, Value extends any> { | ||
private cache; | ||
private validation; | ||
constructor(); | ||
set(key: Key, value: Value): void; | ||
get(key: Key): Value | undefined; | ||
has(key: Key): boolean; | ||
delete(key: Key): void; | ||
isValid(key: Key): boolean; | ||
invalidate(key?: Key): void; | ||
clear(): void; | ||
} | ||
declare class DraggableDragItem<S extends Sensor[] = Sensor[], E extends S[number]['events'] = S[number]['events']> { | ||
@@ -316,11 +330,23 @@ data: { | ||
readonly dragOffsetContainer: HTMLElement | SVGSVGElement | Window | Document; | ||
readonly initialTransform: string; | ||
readonly frozenProps: CSSProperties | null; | ||
readonly unfrozenProps: CSSProperties | null; | ||
readonly elementTransformOrigin: { | ||
x: number; | ||
y: number; | ||
z: number; | ||
}; | ||
readonly elementTransformMatrix: DOMMatrix; | ||
readonly frozenStyles: CSSProperties | null; | ||
readonly unfrozenStyles: CSSProperties | null; | ||
readonly clientRect: Rect; | ||
readonly position: Point; | ||
readonly _updateDiff: Point; | ||
readonly _moveDiff: Point; | ||
readonly _containerDiff: Point; | ||
readonly containerOffset: Point; | ||
readonly alignmentOffset: Point; | ||
protected _moveDiff: Point; | ||
protected _alignDiff: Point; | ||
protected _matrixCache: ObjectCache<HTMLElement | SVGSVGElement, [DOMMatrix, DOMMatrix]>; | ||
protected _clientOffsetCache: ObjectCache<HTMLElement | SVGSVGElement | Window | Document, Point>; | ||
constructor(element: HTMLElement | SVGSVGElement, draggable: Draggable<S, E>); | ||
protected _updateContainerMatrices(): void; | ||
protected _updateContainerOffset(): void; | ||
getContainerMatrix(): [DOMMatrix, DOMMatrix]; | ||
getDragContainerMatrix(): [DOMMatrix, DOMMatrix]; | ||
updateSize(dimensions?: { | ||
@@ -334,8 +360,10 @@ width: number; | ||
readonly sensor: S[number]; | ||
readonly isEnded: boolean; | ||
readonly event: E['start'] | E['move']; | ||
readonly prevEvent: E['start'] | E['move']; | ||
readonly startEvent: E['start'] | E['move']; | ||
readonly prevMoveEvent: E['start'] | E['move']; | ||
readonly moveEvent: E['start'] | E['move']; | ||
readonly endEvent: E['end'] | E['cancel'] | E['destroy'] | null; | ||
readonly items: DraggableDragItem[]; | ||
readonly isEnded: boolean; | ||
protected _matrixCache: ObjectCache<HTMLElement | SVGSVGElement, [DOMMatrix, DOMMatrix]>; | ||
protected _clientOffsetCache: ObjectCache<HTMLElement | SVGSVGElement | Window | Document, Point>; | ||
constructor(sensor: S[number], startEvent: E['start'] | E['move']); | ||
@@ -345,12 +373,34 @@ } | ||
declare enum DragStartPhase { | ||
NONE = 0, | ||
INIT = 1, | ||
START_PREPARE = 2, | ||
FINISH_APPLY = 3 | ||
None = 0, | ||
Init = 1, | ||
StartPrepare = 2, | ||
FinishApply = 3 | ||
} | ||
declare enum DraggableStartPredicateState { | ||
PENDING = 0, | ||
RESOLVED = 1, | ||
REJECTED = 2 | ||
Pending = 0, | ||
Resolved = 1, | ||
Rejected = 2 | ||
} | ||
declare const DraggableModifierPhase: { | ||
readonly Start: "start"; | ||
readonly Move: "move"; | ||
readonly End: "end"; | ||
}; | ||
type DraggableModifierPhase = (typeof DraggableModifierPhase)[keyof typeof DraggableModifierPhase]; | ||
declare const DraggableApplyPositionPhase: { | ||
readonly Start: "start"; | ||
readonly StartAlign: "start-align"; | ||
readonly Move: "move"; | ||
readonly Align: "align"; | ||
readonly End: "end"; | ||
readonly EndAlign: "end-align"; | ||
}; | ||
type DraggableApplyPositionPhase = (typeof DraggableApplyPositionPhase)[keyof typeof DraggableApplyPositionPhase]; | ||
type DraggableModifierData<S extends Sensor[], E extends S[number]['events']> = { | ||
draggable: Draggable<S, E>; | ||
drag: DraggableDrag<S, E>; | ||
item: DraggableDragItem<S, E>; | ||
phase: DraggableModifierPhase; | ||
}; | ||
type DraggableModifier<S extends Sensor[], E extends S[number]['events']> = (change: Point, data: DraggableModifierData<S, E>) => Point; | ||
interface DraggableSettings<S extends Sensor[], E extends S[number]['events']> { | ||
@@ -363,40 +413,25 @@ container: HTMLElement | null; | ||
}) => boolean | undefined; | ||
getElements: (data: { | ||
elements: (data: { | ||
draggable: Draggable<S, E>; | ||
sensor: S[number]; | ||
startEvent: E['start'] | E['move']; | ||
drag: DraggableDrag<S, E>; | ||
}) => (HTMLElement | SVGSVGElement)[] | null; | ||
releaseElements: (data: { | ||
frozenStyles: (data: { | ||
draggable: Draggable<S, E>; | ||
sensor: S[number]; | ||
elements: (HTMLElement | SVGSVGElement)[]; | ||
}) => void; | ||
getFrozenProps: (data: { | ||
draggable: Draggable<S, E>; | ||
sensor: S[number]; | ||
drag: DraggableDrag<S, E>; | ||
item: DraggableDragItem<S, E>; | ||
style: CSSStyleDeclaration; | ||
}) => CSSProperties | (keyof CSSProperties)[] | null; | ||
getStartPosition: (data: { | ||
positionModifiers: DraggableModifier<S, E>[]; | ||
applyPosition: (data: { | ||
draggable: Draggable<S, E>; | ||
sensor: S[number]; | ||
drag: DraggableDrag<S, E>; | ||
item: DraggableDragItem<S, E>; | ||
style: CSSStyleDeclaration; | ||
}) => Point; | ||
setPosition: (data: { | ||
draggable: Draggable<S, E>; | ||
sensor: S[number]; | ||
phase: 'start' | 'move' | 'end'; | ||
item: DraggableDragItem<S, E>; | ||
x: number; | ||
y: number; | ||
phase: DraggableApplyPositionPhase; | ||
}) => void; | ||
getPositionChange: (data: { | ||
draggable: Draggable<S, E>; | ||
sensor: S[number]; | ||
item: DraggableDragItem<S, E>; | ||
event: E['start'] | E['move']; | ||
prevEvent: E['start'] | E['move']; | ||
startEvent: E['start'] | E['move']; | ||
}) => Point; | ||
onPrepareStart?: (drag: DraggableDrag<S, E>, draggable: Draggable<S, E>) => void; | ||
onStart?: (drag: DraggableDrag<S, E>, draggable: Draggable<S, E>) => void; | ||
onPrepareMove?: (drag: DraggableDrag<S, E>, draggable: Draggable<S, E>) => void; | ||
onMove?: (drag: DraggableDrag<S, E>, draggable: Draggable<S, E>) => void; | ||
onEnd?: (drag: DraggableDrag<S, E>, draggable: Draggable<S, E>) => void; | ||
onDestroy?: (draggable: Draggable<S, E>) => void; | ||
} | ||
@@ -408,10 +443,20 @@ interface DraggablePlugin { | ||
type DraggablePluginMap = Record<string, DraggablePlugin | undefined>; | ||
declare const DraggableEventType: { | ||
readonly PrepareStart: "preparestart"; | ||
readonly Start: "start"; | ||
readonly PrepareMove: "preparemove"; | ||
readonly Move: "move"; | ||
readonly End: "end"; | ||
readonly Destroy: "destroy"; | ||
}; | ||
type DraggableEventType = (typeof DraggableEventType)[keyof typeof DraggableEventType]; | ||
interface DraggableEventCallbacks<E extends SensorEvents> { | ||
preparestart(event: E['start'] | E['move']): void; | ||
start(event: E['start'] | E['move']): void; | ||
preparemove(event: E['move']): void; | ||
move(event: E['move']): void; | ||
end(event: E['end'] | E['cancel'] | E['destroy'] | null): void; | ||
destroy(): void; | ||
[DraggableEventType.PrepareStart]: (event: E['start'] | E['move']) => void; | ||
[DraggableEventType.Start]: (event: E['start'] | E['move']) => void; | ||
[DraggableEventType.PrepareMove]: (event: E['move']) => void; | ||
[DraggableEventType.Move]: (event: E['move']) => void; | ||
[DraggableEventType.End]: (event: E['end'] | E['cancel'] | E['destroy'] | null) => void; | ||
[DraggableEventType.Destroy]: () => void; | ||
} | ||
declare const DraggableDefaultSettings: DraggableSettings<any, any>; | ||
declare class Draggable<S extends Sensor[] = Sensor[], E extends S[number]['events'] = S[number]['events'], P extends DraggablePluginMap = {}> { | ||
@@ -435,3 +480,3 @@ readonly sensors: S; | ||
protected _moveId: symbol; | ||
protected _updateId: symbol; | ||
protected _alignId: symbol; | ||
constructor(sensors: S, options?: Partial<DraggableSettings<S, E>>); | ||
@@ -447,4 +492,5 @@ protected _parseSettings(options?: Partial<this['settings']>, defaults?: this['settings']): this['settings']; | ||
protected _applyMove(): void; | ||
protected _preparePositionUpdate(): void; | ||
protected _applyPositionUpdate(): void; | ||
protected _prepareAlign(): void; | ||
protected _applyAlign(): void; | ||
_applyModifiers(phase: DraggableModifierPhase, changeX: number, changeY: number): void; | ||
on<T extends keyof DraggableEventCallbacks<E>>(type: T, listener: DraggableEventCallbacks<E>[T], listenerId?: EventListenerId): EventListenerId; | ||
@@ -455,3 +501,3 @@ off<T extends keyof DraggableEventCallbacks<E>>(type: T, listenerId: EventListenerId): void; | ||
stop(): void; | ||
updatePosition(instant?: boolean): void; | ||
align(instant?: boolean): void; | ||
updateSettings(options?: Partial<this['settings']>): void; | ||
@@ -462,2 +508,11 @@ use<SS extends S, EE extends SS[number]['events'], PP extends P>(plugin: (draggable: this) => Draggable<SS, EE, PP>): Draggable<SS, EE, PP>; | ||
declare function createPointerSensorStartPredicate<S extends (Sensor | PointerSensor)[] = (Sensor | PointerSensor)[], D extends Draggable<S> = Draggable<S>>(options?: { | ||
touchTimeout?: number; | ||
fallback?: D['settings']['startPredicate']; | ||
}): D["settings"]["startPredicate"]; | ||
declare function createSnapModifier<S extends Sensor[], E extends S[number]['events']>(cellWidth: number, cellHeight: number): DraggableModifier<S, E>; | ||
declare function createContainmentModifier<S extends Sensor[], E extends S[number]['events']>(getContainerRect: (data: DraggableModifierData<S, E>) => Rect, trackSensorDrift?: boolean | ((data: DraggableModifierData<S, E>) => boolean)): DraggableModifier<S, E>; | ||
declare class Pool<T> { | ||
@@ -529,4 +584,2 @@ protected _data: T[]; | ||
readonly onStop?: AutoScrollItemEventCallback | null; | ||
readonly onPrepareScrollEffect?: AutoScrollItemEffectCallback | null; | ||
readonly onApplyScrollEffect?: AutoScrollItemEffectCallback | null; | ||
} | ||
@@ -538,6 +591,2 @@ interface AutoScrollSettings { | ||
} | ||
interface AutoScrollEventCallbacks { | ||
beforescroll(): void; | ||
afterscroll(): void; | ||
} | ||
interface AutoScrollItemTarget { | ||
@@ -615,6 +664,2 @@ element: Window | Element; | ||
protected _actionPool: Pool<AutoScrollAction>; | ||
protected _emitter: Emitter<{ | ||
beforescroll: () => void; | ||
afterscroll: () => void; | ||
}>; | ||
constructor(options?: AutoScrollOptions); | ||
@@ -634,4 +679,2 @@ protected _frameRead(time: number): void; | ||
protected _applyActions(): void; | ||
on<T extends keyof AutoScrollEventCallbacks>(type: T, listener: AutoScrollEventCallbacks[T], listenerId?: EventListenerId): EventListenerId; | ||
off<T extends keyof AutoScrollEventCallbacks>(type: T, listenerId: EventListenerId): void; | ||
addItem(item: AutoScrollItem): void; | ||
@@ -662,4 +705,2 @@ removeItem(item: AutoScrollItem): void; | ||
get onStop(): AutoScrollItemEventCallback | null; | ||
onPrepareScrollEffect(): void; | ||
onApplyScrollEffect(): void; | ||
} | ||
@@ -694,21 +735,9 @@ interface DraggableAutoScrollSettings<S extends Sensor[], E extends S[number]['events']> { | ||
declare let tickerReadPhase: Phase; | ||
declare let tickerWritePhase: Phase; | ||
declare const tickerPhases: { | ||
read: symbol; | ||
write: symbol; | ||
}; | ||
declare let ticker: AutoTicker<eventti.EventName, tikki.AutoTickerDefaultFrameCallback>; | ||
declare function setTicker(newTicker: AutoTicker<Phase, FrameCallback>, readPhase: Phase, writePhase: Phase): void; | ||
declare function setTicker(newTicker: AutoTicker<Phase, FrameCallback>, phases: typeof tickerPhases): void; | ||
declare function createPointerSensorStartPredicate<S extends (Sensor | PointerSensor)[] = (Sensor | PointerSensor)[], D extends Draggable<S> = Draggable<S>>(options?: { | ||
timeout?: number; | ||
fallback?: D['settings']['startPredicate']; | ||
}): D["settings"]["startPredicate"]; | ||
declare function createSnapModifier<S extends Sensor[], E extends S[number]['events']>(gridWidth: number, gridHeight: number): ({ item, event, startEvent, }: { | ||
item: DraggableDragItem<S, E>; | ||
event: E['start'] | E['move']; | ||
startEvent: E['start'] | E['move']; | ||
}) => { | ||
x: number; | ||
y: number; | ||
}; | ||
export { AUTO_SCROLL_AXIS, AUTO_SCROLL_AXIS_DIRECTION, AUTO_SCROLL_DIRECTION, AutoScroll, type AutoScrollEventCallbacks, type AutoScrollItem, type AutoScrollItemEffectCallback, type AutoScrollItemEventCallback, type AutoScrollItemSpeedCallback, type AutoScrollItemTarget, type AutoScrollOptions, type AutoScrollSettings, BaseMotionSensor, type BaseMotionSensorDragData, type BaseMotionSensorEvents, type BaseMotionSensorTickEvent, BaseSensor, type BaseSensorDragData, Draggable, DraggableAutoScroll, type DraggableAutoScrollOptions, type DraggableAutoScrollSettings, type DraggableEventCallbacks, type DraggablePlugin, type DraggablePluginMap, type DraggableSettings, KeyboardMotionSensor, type KeyboardMotionSensorEvents, type KeyboardMotionSensorSettings, KeyboardSensor, type KeyboardSensorCancelEvent, type KeyboardSensorDestroyEvent, type KeyboardSensorEndEvent, type KeyboardSensorEvents, type KeyboardSensorMoveEvent, type KeyboardSensorPredicate, type KeyboardSensorSettings, type KeyboardSensorStartEvent, PointerSensor, type PointerSensorCancelEvent, type PointerSensorDestroyEvent, type PointerSensorDragData, type PointerSensorEndEvent, type PointerSensorEvents, type PointerSensorMoveEvent, type PointerSensorSettings, type PointerSensorStartEvent, type Sensor, type SensorCancelEvent, type SensorDestroyEvent, type SensorEndEvent, SensorEventType, type SensorEvents, type SensorMoveEvent, type SensorStartEvent, autoScroll, autoScrollPlugin, autoScrollSmoothSpeed, createPointerSensorStartPredicate, createSnapModifier, keyboardMotionSensorDefaults, keyboardSensorDefaults, setTicker, ticker, tickerReadPhase, tickerWritePhase }; | ||
export { AUTO_SCROLL_AXIS, AUTO_SCROLL_AXIS_DIRECTION, AUTO_SCROLL_DIRECTION, AutoScroll, type AutoScrollItem, type AutoScrollItemEffectCallback, type AutoScrollItemEventCallback, type AutoScrollItemSpeedCallback, type AutoScrollItemTarget, type AutoScrollOptions, type AutoScrollSettings, BaseMotionSensor, type BaseMotionSensorDragData, type BaseMotionSensorEvents, type BaseMotionSensorTickEvent, BaseSensor, type BaseSensorDragData, Draggable, DraggableApplyPositionPhase, DraggableAutoScroll, type DraggableAutoScrollOptions, type DraggableAutoScrollSettings, DraggableDefaultSettings, type DraggableEventCallbacks, DraggableEventType, type DraggableModifier, type DraggableModifierData, DraggableModifierPhase, type DraggablePlugin, type DraggablePluginMap, type DraggableSettings, KeyboardMotionSensor, type KeyboardMotionSensorEvents, type KeyboardMotionSensorSettings, KeyboardSensor, type KeyboardSensorCancelEvent, type KeyboardSensorDestroyEvent, type KeyboardSensorEndEvent, type KeyboardSensorEvents, type KeyboardSensorMoveEvent, type KeyboardSensorPredicate, type KeyboardSensorSettings, type KeyboardSensorStartEvent, PointerSensor, type PointerSensorCancelEvent, type PointerSensorDestroyEvent, type PointerSensorDragData, type PointerSensorEndEvent, type PointerSensorEvents, type PointerSensorMoveEvent, type PointerSensorSettings, type PointerSensorStartEvent, type Sensor, type SensorCancelEvent, type SensorDestroyEvent, type SensorEndEvent, SensorEventType, type SensorEvents, type SensorMoveEvent, type SensorStartEvent, autoScroll, autoScrollPlugin, autoScrollSmoothSpeed, createContainmentModifier, createPointerSensorStartPredicate, createSnapModifier, keyboardMotionSensorDefaults, keyboardSensorDefaults, setTicker, ticker, tickerPhases }; |
@@ -1,1 +0,1 @@ | ||
var b={start:"start",move:"move",cancel:"cancel",end:"end",destroy:"destroy"};import{Emitter as st}from"eventti";var V=class{constructor(){this.drag=null,this.isDestroyed=!1,this._emitter=new st}_createDragData(e){return{x:e.x,y:e.y}}_updateDragData(e){this.drag&&(this.drag.x=e.x,this.drag.y=e.y)}_resetDragData(){this.drag=null}_start(e){this.isDestroyed||this.drag||(this.drag=this._createDragData(e),this._emitter.emit(b.start,e))}_move(e){this.drag&&(this._updateDragData(e),this._emitter.emit(b.move,e))}_end(e){this.drag&&(this._updateDragData(e),this._emitter.emit(b.end,e),this._resetDragData())}_cancel(e){this.drag&&(this._updateDragData(e),this._emitter.emit(b.cancel,e),this._resetDragData())}on(e,t,n){return this._emitter.on(e,t,n)}off(e,t){this._emitter.off(e,t)}cancel(){this.drag&&this._cancel({type:b.cancel,x:this.drag.x,y:this.drag.y})}destroy(){this.isDestroyed||(this.isDestroyed=!0,this.cancel(),this._emitter.emit(b.destroy,{type:b.destroy}),this._emitter.off())}};import{AutoTicker as at}from"tikki";var v=Symbol(),x=Symbol(),m=new at({phases:[v,x]});function Vt(r,e,t){v=e,x=t,m=r}var Q=class extends V{constructor(){super(),this.drag=null,this._direction={x:0,y:0},this._speed=0,this._tick=this._tick.bind(this)}_createDragData(e){return{...super._createDragData(e),time:0,deltaTime:0}}_start(e){this.isDestroyed||this.drag||(super._start(e),m.on(v,this._tick,this._tick))}_end(e){this.drag&&(m.off(v,this._tick),super._end(e))}_cancel(e){this.drag&&(m.off(v,this._tick),super._cancel(e))}_tick(e){if(this.drag)if(e&&this.drag.time){this.drag.deltaTime=e-this.drag.time,this.drag.time=e;let t={type:"tick",time:this.drag.time,deltaTime:this.drag.deltaTime};if(this._emitter.emit("tick",t),!this.drag)return;let n=this._speed*(this.drag.deltaTime/1e3),i=this._direction.x*n,o=this._direction.y*n;(i||o)&&this._move({type:"move",x:this.drag.x+i,y:this.drag.y+o})}else this.drag.time=e,this.drag.deltaTime=0}};import{Emitter as lt}from"eventti";function me(r,e){if("pointerId"in r)return r.pointerId===e?r:null;if("changedTouches"in r){let t=0;for(;t<r.changedTouches.length;t++)if(r.changedTouches[t].identifier===e)return r.changedTouches[t];return null}return r}function Ve(r){return"pointerType"in r?r.pointerType:"touches"in r?"touch":"mouse"}function Ne(r){return"pointerId"in r?r.pointerId:"changedTouches"in r?r.changedTouches[0]?r.changedTouches[0].identifier:null:-1}var pe=typeof window<"u"&&typeof window.document<"u",Z=(()=>{let r=!1;try{let e=Object.defineProperty({},"passive",{get:function(){r=!0}});window.addEventListener("testPassive",null,e),window.removeEventListener("testPassive",null,e)}catch{}return r})(),qe=pe&&"ontouchstart"in window,Xe=pe&&!!window.PointerEvent,Ft=!!(pe&&navigator.vendor&&navigator.vendor.indexOf("Apple")>-1&&navigator.userAgent&&navigator.userAgent.indexOf("CriOS")==-1&&navigator.userAgent.indexOf("FxiOS")==-1);function fe(r={}){let{capture:e=!0,passive:t=!0}=r;return Z?{capture:e,passive:t}:{capture:e}}function ge(r){return r==="auto"||r===void 0?Xe?"pointer":qe?"touch":"mouse":r}var ct={start:"pointerdown",move:"pointermove",cancel:"pointercancel",end:"pointerup"},dt={start:"touchstart",move:"touchmove",cancel:"touchcancel",end:"touchend"},ht={start:"mousedown",move:"mousemove",cancel:"",end:"mouseup"},N={pointer:ct,touch:dt,mouse:ht},q=class{constructor(e,t={}){let{listenerOptions:n={},sourceEvents:i="auto",startPredicate:o=s=>!("button"in s&&s.button>0)}=t;this.element=e,this.drag=null,this.isDestroyed=!1,this._areWindowListenersBound=!1,this._startPredicate=o,this._listenerOptions=fe(n),this._sourceEvents=ge(i),this._emitter=new lt,this._onStart=this._onStart.bind(this),this._onMove=this._onMove.bind(this),this._onCancel=this._onCancel.bind(this),this._onEnd=this._onEnd.bind(this),e.addEventListener(N[this._sourceEvents].start,this._onStart,this._listenerOptions)}_getTrackedPointerEventData(e){return this.drag?me(e,this.drag.pointerId):null}_onStart(e){if(this.isDestroyed||this.drag||!this._startPredicate(e))return;let t=Ne(e);if(t===null)return;let n=me(e,t);if(n===null)return;let i={pointerId:t,pointerType:Ve(e),x:n.clientX,y:n.clientY};this.drag=i;let o={...i,type:b.start,srcEvent:e,target:n.target};this._emitter.emit(o.type,o),this.drag&&this._bindWindowListeners()}_onMove(e){if(!this.drag)return;let t=this._getTrackedPointerEventData(e);if(!t)return;this.drag.x=t.clientX,this.drag.y=t.clientY;let n={type:b.move,srcEvent:e,target:t.target,...this.drag};this._emitter.emit(n.type,n)}_onCancel(e){if(!this.drag)return;let t=this._getTrackedPointerEventData(e);if(!t)return;this.drag.x=t.clientX,this.drag.y=t.clientY;let n={type:b.cancel,srcEvent:e,target:t.target,...this.drag};this._emitter.emit(n.type,n),this._resetDrag()}_onEnd(e){if(!this.drag)return;let t=this._getTrackedPointerEventData(e);if(!t)return;this.drag.x=t.clientX,this.drag.y=t.clientY;let n={type:b.end,srcEvent:e,target:t.target,...this.drag};this._emitter.emit(n.type,n),this._resetDrag()}_bindWindowListeners(){if(this._areWindowListenersBound)return;let{move:e,end:t,cancel:n}=N[this._sourceEvents];window.addEventListener(e,this._onMove,this._listenerOptions),window.addEventListener(t,this._onEnd,this._listenerOptions),n&&window.addEventListener(n,this._onCancel,this._listenerOptions),this._areWindowListenersBound=!0}_unbindWindowListeners(){if(this._areWindowListenersBound){let{move:e,end:t,cancel:n}=N[this._sourceEvents];window.removeEventListener(e,this._onMove,this._listenerOptions),window.removeEventListener(t,this._onEnd,this._listenerOptions),n&&window.removeEventListener(n,this._onCancel,this._listenerOptions),this._areWindowListenersBound=!1}}_resetDrag(){this.drag=null,this._unbindWindowListeners()}cancel(){if(!this.drag)return;let e={type:b.cancel,srcEvent:null,target:null,...this.drag};this._emitter.emit(e.type,e),this._resetDrag()}updateSettings(e){if(this.isDestroyed)return;let{listenerOptions:t,sourceEvents:n,startPredicate:i}=e,o=ge(n),s=fe(t);i&&this._startPredicate!==i&&(this._startPredicate=i),(t&&(this._listenerOptions.capture!==s.capture||this._listenerOptions.passive===s.passive)||n&&this._sourceEvents!==o)&&(this.element.removeEventListener(N[this._sourceEvents].start,this._onStart,this._listenerOptions),this._unbindWindowListeners(),this.cancel(),n&&(this._sourceEvents=o),t&&s&&(this._listenerOptions=s),this.element.addEventListener(N[this._sourceEvents].start,this._onStart,this._listenerOptions))}on(e,t,n){return this._emitter.on(e,t,n)}off(e,t){this._emitter.off(e,t)}destroy(){this.isDestroyed||(this.isDestroyed=!0,this.cancel(),this._emitter.emit(b.destroy,{type:b.destroy}),this._emitter.off(),this.element.removeEventListener(N[this._sourceEvents].start,this._onStart,this._listenerOptions))}};var K={moveDistance:25,cancelOnBlur:!0,cancelOnVisibilityChange:!0,startPredicate:(r,e)=>{if(e.element&&(r.key==="Enter"||r.key===" ")&&document.activeElement===e.element){let{x:t,y:n}=e.element.getBoundingClientRect();return{x:t,y:n}}return null},movePredicate:(r,e)=>{if(!e.drag)return null;switch(r.key){case"ArrowLeft":return{x:e.drag.x-e.moveDistance.x,y:e.drag.y};case"ArrowRight":return{x:e.drag.x+e.moveDistance.x,y:e.drag.y};case"ArrowUp":return{x:e.drag.x,y:e.drag.y-e.moveDistance.y};case"ArrowDown":return{x:e.drag.x,y:e.drag.y+e.moveDistance.y};default:return null}},cancelPredicate:(r,e)=>{if(e.drag&&r.key==="Escape"){let{x:t,y:n}=e.drag;return{x:t,y:n}}return null},endPredicate:(r,e)=>{if(e.drag&&(r.key==="Enter"||r.key===" ")){let{x:t,y:n}=e.drag;return{x:t,y:n}}return null}},Ye=class extends V{constructor(e,t={}){super();let{moveDistance:n=K.moveDistance,cancelOnBlur:i=K.cancelOnBlur,cancelOnVisibilityChange:o=K.cancelOnVisibilityChange,startPredicate:s=K.startPredicate,movePredicate:a=K.movePredicate,cancelPredicate:c=K.cancelPredicate,endPredicate:l=K.endPredicate}=t;this.element=e,this.moveDistance=typeof n=="number"?{x:n,y:n}:{...n},this._cancelOnBlur=i,this._cancelOnVisibilityChange=o,this._startPredicate=s,this._movePredicate=a,this._cancelPredicate=c,this._endPredicate=l,this._onKeyDown=this._onKeyDown.bind(this),this._internalCancel=this._internalCancel.bind(this),this._blurCancelHandler=this._blurCancelHandler.bind(this),document.addEventListener("keydown",this._onKeyDown),i&&e?.addEventListener("blur",this._blurCancelHandler),o&&document.addEventListener("visibilitychange",this._internalCancel)}_internalCancel(){this.cancel()}_blurCancelHandler(){queueMicrotask(()=>{document.activeElement!==this.element&&this.cancel()})}_onKeyDown(e){if(!this.drag){let o=this._startPredicate(e,this);o&&(e.preventDefault(),this._start({type:"start",x:o.x,y:o.y,srcEvent:e}));return}let t=this._cancelPredicate(e,this);if(t){e.preventDefault(),this._cancel({type:"cancel",x:t.x,y:t.y,srcEvent:e});return}let n=this._endPredicate(e,this);if(n){e.preventDefault(),this._end({type:"end",x:n.x,y:n.y,srcEvent:e});return}let i=this._movePredicate(e,this);if(i){e.preventDefault(),this._move({type:"move",x:i.x,y:i.y,srcEvent:e});return}}updateSettings(e={}){let{moveDistance:t,cancelOnBlur:n,cancelOnVisibilityChange:i,startPredicate:o,movePredicate:s,cancelPredicate:a,endPredicate:c}=e;t!==void 0&&(typeof t=="number"?this.moveDistance.x=this.moveDistance.y=t:(this.moveDistance.x=t.x,this.moveDistance.y=t.y)),n!==void 0&&this._cancelOnBlur!==n&&(this._cancelOnBlur=n,n?this.element?.addEventListener("blur",this._blurCancelHandler):this.element?.removeEventListener("blur",this._blurCancelHandler)),i!==void 0&&this._cancelOnVisibilityChange!==i&&(this._cancelOnVisibilityChange=i,i?document.addEventListener("visibilitychange",this._internalCancel):document.removeEventListener("visibilitychange",this._internalCancel)),o&&(this._startPredicate=o),s&&(this._movePredicate=s),a&&(this._cancelPredicate=a),c&&(this._endPredicate=c)}destroy(){this.isDestroyed||(super.destroy(),document.removeEventListener("keydown",this._onKeyDown),this._cancelOnBlur&&this.element?.removeEventListener("blur",this._blurCancelHandler),this._cancelOnVisibilityChange&&document.removeEventListener("visibilitychange",this._internalCancel))}};var ut=["start","cancel","end","moveLeft","moveRight","moveUp","moveDown"];function ee(r,e){if(!r.size||!e.size)return 1/0;let t=1/0;for(let n of r){let i=e.get(n);i!==void 0&&i<t&&(t=i)}return t}var I={startKeys:[" ","Enter"],moveLeftKeys:["ArrowLeft"],moveRightKeys:["ArrowRight"],moveUpKeys:["ArrowUp"],moveDownKeys:["ArrowDown"],cancelKeys:["Escape"],endKeys:[" ","Enter"],cancelOnBlur:!0,cancelOnVisibilityChange:!0,computeSpeed:()=>500,startPredicate:(r,e)=>{if(e.element&&document.activeElement===e.element){let{left:t,top:n}=e.element.getBoundingClientRect();return{x:t,y:n}}return null}},Ue=class extends Q{constructor(e,t={}){super();let{startPredicate:n=I.startPredicate,computeSpeed:i=I.computeSpeed,cancelOnVisibilityChange:o=I.cancelOnVisibilityChange,cancelOnBlur:s=I.cancelOnBlur,startKeys:a=I.startKeys,moveLeftKeys:c=I.moveLeftKeys,moveRightKeys:l=I.moveRightKeys,moveUpKeys:d=I.moveUpKeys,moveDownKeys:u=I.moveDownKeys,cancelKeys:y=I.cancelKeys,endKeys:g=I.endKeys}=t;this.element=e,this._startKeys=new Set(a),this._cancelKeys=new Set(y),this._endKeys=new Set(g),this._moveLeftKeys=new Set(c),this._moveRightKeys=new Set(l),this._moveUpKeys=new Set(d),this._moveDownKeys=new Set(u),this._moveKeys=new Set([...c,...l,...d,...u]),this._moveKeyTimestamps=new Map,this._cancelOnBlur=s,this._cancelOnVisibilityChange=o,this._computeSpeed=i,this._startPredicate=n,this._onKeyDown=this._onKeyDown.bind(this),this._onKeyUp=this._onKeyUp.bind(this),this._onTick=this._onTick.bind(this),this._internalCancel=this._internalCancel.bind(this),this._blurCancelHandler=this._blurCancelHandler.bind(this),this.on("tick",this._onTick,this._onTick),document.addEventListener("keydown",this._onKeyDown),document.addEventListener("keyup",this._onKeyUp),s&&e?.addEventListener("blur",this._blurCancelHandler),o&&document.addEventListener("visibilitychange",this._internalCancel)}_end(e){this.drag&&(this._moveKeyTimestamps.clear(),this._direction.x=0,this._direction.y=0,super._end(e))}_cancel(e){this.drag&&(this._moveKeyTimestamps.clear(),this._direction.x=0,this._direction.y=0,super._cancel(e))}_internalCancel(){this.cancel()}_blurCancelHandler(){queueMicrotask(()=>{document.activeElement!==this.element&&this.cancel()})}_updateDirection(){let e=ee(this._moveLeftKeys,this._moveKeyTimestamps),t=ee(this._moveRightKeys,this._moveKeyTimestamps),n=ee(this._moveUpKeys,this._moveKeyTimestamps),i=ee(this._moveDownKeys,this._moveKeyTimestamps),o=e===t?0:e<t?-1:1,s=n===i?0:n<i?-1:1;if(!(o===0||s===0)){let a=1/(Math.sqrt(o*o+s*s)||1);o*=a,s*=a}this._direction.x=o,this._direction.y=s}_onTick(){this._speed=this._computeSpeed(this)}_onKeyUp(e){this._moveKeyTimestamps.get(e.key)&&(this._moveKeyTimestamps.delete(e.key),this._updateDirection())}_onKeyDown(e){if(!this.drag){if(this._startKeys.has(e.key)){let t=this._startPredicate(e,this);t&&(e.preventDefault(),this._start({type:"start",x:t.x,y:t.y}))}return}if(this._cancelKeys.has(e.key)){e.preventDefault(),this._internalCancel();return}if(this._endKeys.has(e.key)){e.preventDefault(),this._end({type:"end",x:this.drag.x,y:this.drag.y});return}if(this._moveKeys.has(e.key)){e.preventDefault(),this._moveKeyTimestamps.get(e.key)||(this._moveKeyTimestamps.set(e.key,Date.now()),this._updateDirection());return}}updateSettings(e={}){let t=!1,{cancelOnBlur:n,cancelOnVisibilityChange:i,startPredicate:o,computeSpeed:s}=e;if(n!==void 0&&this._cancelOnBlur!==n&&(this._cancelOnBlur=n,n?this.element?.addEventListener("blur",this._blurCancelHandler):this.element?.removeEventListener("blur",this._blurCancelHandler)),i!==void 0&&this._cancelOnVisibilityChange!==i&&(this._cancelOnVisibilityChange=i,i?document.addEventListener("visibilitychange",this._internalCancel):document.removeEventListener("visibilitychange",this._internalCancel)),o!==void 0&&(this._startPredicate=o),s!==void 0&&(this._computeSpeed=s),ut.forEach((a,c)=>{let l=`${a}Keys`,d=e[l];d!==void 0&&(this[`_${l}`]=new Set(d),c>=3&&(t=!0))}),t){let a=[...this._moveLeftKeys,...this._moveRightKeys,...this._moveUpKeys,...this._moveDownKeys];[...this._moveKeys].every((l,d)=>a[d]===l)||(this._moveKeys=new Set(a),this._moveKeyTimestamps.clear(),this._updateDirection())}}destroy(){this.isDestroyed||(super.destroy(),this.off("tick",this._onTick),document.removeEventListener("keydown",this._onKeyDown),document.removeEventListener("keyup",this._onKeyUp),this._cancelOnBlur&&this.element?.removeEventListener("blur",this._blurCancelHandler),this._cancelOnVisibilityChange&&document.removeEventListener("visibilitychange",this._internalCancel))}};import{Emitter as gt}from"eventti";var te=class{constructor(e,t){this.sensor=e,this.isEnded=!1,this.event=t,this.prevEvent=t,this.startEvent=t,this.endEvent=null,this.items=[]}};import{getOffsetContainer as ze}from"mezr";var Be=new WeakMap;function ne(r){let e=Be.get(r)?.deref();return e||(e=window.getComputedStyle(r,null),Be.set(r,new WeakRef(e))),e}import{getOffset as He}from"mezr";function re(r,e,t={left:0,top:0}){if(t.left=0,t.top=0,r===e)return t;let n=He([r,"padding"]),i=He([e,"padding"]);return t.left=i.left-n.left,t.top=i.top-n.top,t}var mt={left:0,top:0},pt="matrix(1, 0, 0, 1, 0, 0)",ft="matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)",ie=class{constructor(e,t){if(!e.isConnected)throw new Error("Element is not connected");let n=t.drag?.sensor;if(!n)throw new Error("Sensor is not defined");let i=this,o=ne(e),s=e.getBoundingClientRect();this.data={},this.element=e,this.frozenProps=null,this.unfrozenProps=null,this.position={x:0,y:0},this._updateDiff={x:0,y:0},this._moveDiff={x:0,y:0},this._containerDiff={x:0,y:0};let a=e.parentElement;if(!a)throw new Error("Element does not have a parent element.");this.elementContainer=a;let c=ze(e);if(!c)throw new Error("Offset container could not be computed for the element!");this.elementOffsetContainer=c;let l=t.settings.container||a;this.dragContainer=l;let d=l===a?c:ze(e,{container:l});if(!d)throw new Error("Drag offset container could not be computed for the element!");this.dragOffsetContainer=d;{let{width:_,height:p,x:S,y:D}=s;this.clientRect={width:_,height:p,x:S,y:D}}if(c!==d){let{left:_,top:p}=re(d,c,mt);this._containerDiff.x=_,this._containerDiff.y=p}let{transform:u}=o;u&&u!=="none"&&u!==pt&&u!==ft?this.initialTransform=u:this.initialTransform="";let{x:y,y:g}=t.settings.getStartPosition({draggable:t,sensor:n,item:i,style:o});this.position.x=y,this.position.y=g;let E=t.settings.getFrozenProps({draggable:t,sensor:n,item:i,style:o});if(Array.isArray(E))if(E.length){let _={};for(let p of E)_[p]=o[p];this.frozenProps=_}else this.frozenProps=null;else this.frozenProps=E;if(this.frozenProps){let _={};for(let p in this.frozenProps)this.frozenProps.hasOwnProperty(p)&&(_[p]=e.style[p]);this.unfrozenProps=_}}updateSize(e){if(e)this.clientRect.width=e.width,this.clientRect.height=e.height;else{let t=this.element.getBoundingClientRect();this.clientRect.width=t.width,this.clientRect.height=t.height}}};function Se(r,e){let t=document.activeElement,n=r.contains(t);e.append(r),n&&document.activeElement!==t&&t.focus({preventScroll:!0})}var Fe=Z?{capture:!0,passive:!0}:!0,St={left:0,top:0},Ee={x:0,y:0};function Et(){return{container:null,startPredicate:()=>!0,getElements:()=>null,releaseElements:()=>null,getFrozenProps:()=>null,getStartPosition:()=>({x:0,y:0}),setPosition:({item:r,x:e,y:t})=>{r.element.style.transform=`translate(${e}px, ${t}px) ${r.initialTransform}`},getPositionChange:({event:r,prevEvent:e})=>(Ee.x=r.x-e.x,Ee.y=r.y-e.y,Ee)}}var Ge=class{constructor(e,t={}){this.sensors=e,this.settings=this._parseSettings(t),this.plugins={},this.drag=null,this.isDestroyed=!1,this._sensorData=new Map,this._emitter=new gt,this._startPhase=0,this._startId=Symbol(),this._moveId=Symbol(),this._updateId=Symbol(),this._onMove=this._onMove.bind(this),this._onScroll=this._onScroll.bind(this),this._onEnd=this._onEnd.bind(this),this._prepareStart=this._prepareStart.bind(this),this._applyStart=this._applyStart.bind(this),this._prepareMove=this._prepareMove.bind(this),this._applyMove=this._applyMove.bind(this),this._preparePositionUpdate=this._preparePositionUpdate.bind(this),this._applyPositionUpdate=this._applyPositionUpdate.bind(this),this.sensors.forEach(n=>{this._sensorData.set(n,{predicateState:0,predicateEvent:null,onMove:s=>this._onMove(s,n),onEnd:s=>this._onEnd(s,n)});let{onMove:i,onEnd:o}=this._sensorData.get(n);n.on("start",i,i),n.on("move",i,i),n.on("cancel",o,o),n.on("end",o,o),n.on("destroy",o,o)})}_parseSettings(e,t=Et()){let{container:n=t.container,startPredicate:i=t.startPredicate,getElements:o=t.getElements,releaseElements:s=t.releaseElements,getFrozenProps:a=t.getFrozenProps,getStartPosition:c=t.getStartPosition,setPosition:l=t.setPosition,getPositionChange:d=t.getPositionChange}=e||{};return{container:n,startPredicate:i,getElements:o,releaseElements:s,getFrozenProps:a,getStartPosition:c,setPosition:l,getPositionChange:d}}_emit(e,...t){this._emitter.emit(e,...t)}_onMove(e,t){let n=this._sensorData.get(t);if(n)switch(n.predicateState){case 0:{n.predicateEvent=e;let i=this.settings.startPredicate({draggable:this,sensor:t,event:e});i===!0?this.resolveStartPredicate(t):i===!1&&this.rejectStartPredicate(t);break}case 1:{this.drag&&(this.drag.event=e,m.once(v,this._prepareMove,this._moveId),m.once(x,this._applyMove,this._moveId));break}}}_onScroll(){this.updatePosition()}_onEnd(e,t){let n=this._sensorData.get(t);n&&(this.drag?n.predicateState===1&&(this.drag.endEvent=e,this._sensorData.forEach(i=>{i.predicateState=0,i.predicateEvent=null}),this.stop()):(n.predicateState=0,n.predicateEvent=null))}_prepareStart(){let e=this.drag;if(!e)return;this._startPhase=2;let t=this.settings.getElements({draggable:this,sensor:e.sensor,startEvent:e.startEvent})||[];e.items=t.map(n=>new ie(n,this)),this._emit("preparestart",e.startEvent)}_applyStart(){let e=this.drag;if(e){for(let t of e.items)t.dragContainer!==t.elementContainer&&(t.position.x+=t._containerDiff.x,t.position.y+=t._containerDiff.y,Se(t.element,t.dragContainer)),t.frozenProps&&Object.assign(t.element.style,t.frozenProps),this.settings.setPosition({phase:"start",draggable:this,sensor:e.sensor,item:t,x:t.position.x,y:t.position.y});window.addEventListener("scroll",this._onScroll,Fe),this._startPhase=3,this._emit("start",e.startEvent)}}_prepareMove(){let e=this.drag;if(!e)return;let{event:t,prevEvent:n,startEvent:i,sensor:o}=e;if(t!==n){for(let s of e.items){let{x:a,y:c}=this.settings.getPositionChange({draggable:this,sensor:o,item:s,event:t,prevEvent:n,startEvent:i});a&&(s.position.x+=a,s.clientRect.x+=a,s._moveDiff.x+=a),c&&(s.position.y+=c,s.clientRect.y+=c,s._moveDiff.y+=c)}e.prevEvent=t,this._emit("preparemove",t)}}_applyMove(){let e=this.drag;if(e){for(let t of e.items)t._moveDiff.x=0,t._moveDiff.y=0,this.settings.setPosition({phase:"move",draggable:this,sensor:e.sensor,item:t,x:t.position.x,y:t.position.y});e.event&&this._emit("move",e.event)}}_preparePositionUpdate(){let{drag:e}=this;if(e)for(let t of e.items){if(t.elementOffsetContainer!==t.dragOffsetContainer){let{left:l,top:d}=re(t.dragOffsetContainer,t.elementOffsetContainer,St);t._containerDiff.x=l,t._containerDiff.y=d}let{left:n,top:i,width:o,height:s}=t.element.getBoundingClientRect(),a=t.clientRect.x-t._moveDiff.x-n;t.position.x=t.position.x-t._updateDiff.x+a,t._updateDiff.x=a;let c=t.clientRect.y-t._moveDiff.y-i;t.position.y=t.position.y-t._updateDiff.y+c,t._updateDiff.y=c,t.clientRect.width=o,t.clientRect.height=s}}_applyPositionUpdate(){let{drag:e}=this;if(e)for(let t of e.items)t._updateDiff.x=0,t._updateDiff.y=0,this.settings.setPosition({phase:"move",draggable:this,sensor:e.sensor,item:t,x:t.position.x,y:t.position.y})}on(e,t,n){return this._emitter.on(e,t,n)}off(e,t){this._emitter.off(e,t)}resolveStartPredicate(e,t){let n=this._sensorData.get(e);if(!n)return;let i=t||n.predicateEvent;n.predicateState===0&&i&&(this._startPhase=1,n.predicateState=1,n.predicateEvent=null,this.drag=new te(e,i),this._sensorData.forEach((o,s)=>{s!==e&&(o.predicateState=2,o.predicateEvent=null)}),m.once(v,this._prepareStart,this._startId),m.once(x,this._applyStart,this._startId))}rejectStartPredicate(e){let t=this._sensorData.get(e);t?.predicateState===0&&(t.predicateState=2,t.predicateEvent=null)}stop(){let e=this.drag;if(!e||e.isEnded)return;if(this._startPhase===2){this.off("start",this._startId),this.on("start",()=>this.stop(),this._startId);return}this._startPhase=0,e.isEnded=!0,m.off(v,this._startId),m.off(x,this._startId),m.off(v,this._moveId),m.off(x,this._moveId),m.off(v,this._updateId),m.off(x,this._updateId),window.removeEventListener("scroll",this._onScroll,Fe);let t=[];for(let n of e.items){if(t.push(n.element),n.elementContainer!==n.dragContainer&&(n.position.x-=n._containerDiff.x,n.position.y-=n._containerDiff.y,n._containerDiff.x=0,n._containerDiff.y=0,Se(n.element,n.elementContainer)),n.unfrozenProps)for(let i in n.unfrozenProps)n.element.style[i]=n.unfrozenProps[i]||"";this.settings.setPosition({phase:"end",draggable:this,sensor:e.sensor,item:n,x:n.position.x,y:n.position.y})}t.length&&this.settings.releaseElements({draggable:this,sensor:e.sensor,elements:t}),this._emit("end",e.endEvent),this.drag=null}updatePosition(e=!1){this.drag&&(e?(this._preparePositionUpdate(),this._applyPositionUpdate()):(m.once(v,this._preparePositionUpdate,this._updateId),m.once(x,this._applyPositionUpdate,this._updateId)))}updateSettings(e={}){this.settings=this._parseSettings(e,this.settings)}use(e){return e(this)}destroy(){this.isDestroyed||(this.isDestroyed=!0,this.stop(),this._sensorData.forEach(({onMove:e,onEnd:t},n)=>{n.off("start",e),n.off("move",e),n.off("cancel",t),n.off("end",t),n.off("destroy",t)}),this._sensorData.clear(),this._emit("destroy"),this._emitter.off())}};import{Emitter as xt}from"eventti";var z=class{constructor(e,t){this._data=[],this._createObject=e,this._onPut=t}pick(){return this._data.length?this._data.pop():this._createObject()}put(e){this._data.indexOf(e)===-1&&(this._onPut&&this._onPut(e),this._data.push(e))}reset(){this._data.length=0}};import{getDistance as vt}from"mezr";function F(r,e={width:0,height:0,x:0,y:0,left:0,top:0,right:0,bottom:0}){return r&&(e.width=r.width,e.height=r.height,e.x=r.x,e.y=r.y,e.left=r.x,e.top=r.y,e.right=r.x+r.width,e.bottom=r.y+r.height),e}var _t=F(),yt=F();function je(r,e){return vt(F(r,_t),F(e,yt))}function $e(r,e,t={width:0,height:0,x:0,y:0}){let n=Math.max(r.x,e.x),i=Math.min(r.x+r.width,e.x+e.width);if(i<=n)return null;let o=Math.max(r.y,e.y),s=Math.min(r.y+r.height,e.y+e.height);return s<=o?null:(t.x=n,t.y=o,t.width=i-n,t.height=s-o,t)}function Je(r,e){let t=$e(r,e);return t?t.width*t.height:0}function ve(r,e){let t=Je(r,e);if(!t)return 0;let n=Math.min(r.width,e.width)*Math.min(r.height,e.height);return t/n*100}import{getRect as bt}from"mezr";function _e(...r){let{width:e,height:t,left:n,top:i}=bt(...r);return{width:e,height:t,x:n,y:i}}function w(r){return r instanceof Window}function ye(r){return w(r)||r===document.documentElement||r===document.body?window:r}function X(r){return w(r)?r.pageXOffset:r.scrollLeft}function be(r){return w(r)&&(r=document.documentElement),r.scrollWidth-r.clientWidth}function Y(r){return w(r)?r.pageYOffset:r.scrollTop}function xe(r){return w(r)&&(r=document.documentElement),r.scrollHeight-r.clientHeight}function De(r,e){return!(r.x+r.width<=e.x||e.x+e.width<=r.x||r.y+r.height<=e.y||e.y+e.height<=r.y)}var Qe={width:0,height:0,x:0,y:0},Ze=50,A={direction:"none",threshold:0,distance:0,value:0,maxValue:0,duration:0,speed:0,deltaTime:0,isEnding:!1},h={x:1,y:2},M={forward:4,reverse:8},oe={none:0,left:h.x|M.reverse,right:h.x|M.forward},G={none:0,up:h.y|M.reverse,down:h.y|M.forward},f={...oe,...G};function Pe(r){switch(r){case oe.none:case G.none:return"none";case oe.left:return"left";case oe.right:return"right";case G.up:return"up";case G.down:return"down";default:throw new Error(`Unknown direction value: ${r}`)}}function et(r,e,t){let{left:n=0,right:i=0,top:o=0,bottom:s=0}=e;return n=Math.max(0,n),i=Math.max(0,i),o=Math.max(0,o),s=Math.max(0,s),t.width=r.width+n+i,t.height=r.height+o+s,t.x=r.x-n,t.y=r.y-o,t}function se(r,e){return Math.ceil(r)>=Math.floor(e)}function Te(r,e){return Math.min(e/2,r)}function Ie(r,e,t,n){return Math.max(0,t+r*2+n*e-n)/2}var we=class{constructor(){this.positionX=0,this.positionY=0,this.directionX=f.none,this.directionY=f.none,this.overlapCheckRequestTime=0}},Ae=class{constructor(){this.element=null,this.requestX=null,this.requestY=null,this.scrollLeft=0,this.scrollTop=0}reset(){this.requestX&&(this.requestX.action=null),this.requestY&&(this.requestY.action=null),this.element=null,this.requestX=null,this.requestY=null,this.scrollLeft=0,this.scrollTop=0}addRequest(e){h.x&e.direction?(this.requestX&&this.removeRequest(this.requestX),this.requestX=e):(this.requestY&&this.removeRequest(this.requestY),this.requestY=e),e.action=this}removeRequest(e){this.requestX===e?(this.requestX=null,e.action=null):this.requestY===e&&(this.requestY=null,e.action=null)}computeScrollValues(){this.element&&(this.scrollLeft=this.requestX?this.requestX.value:X(this.element),this.scrollTop=this.requestY?this.requestY.value:Y(this.element))}scroll(){this.element&&(this.element.scrollTo?this.element.scrollTo(this.scrollLeft,this.scrollTop):(this.element.scrollLeft=this.scrollLeft,this.element.scrollTop=this.scrollTop))}},Ce=class{constructor(){this.item=null,this.element=null,this.isActive=!1,this.isEnding=!1,this.direction=0,this.value=NaN,this.maxValue=0,this.threshold=0,this.distance=0,this.deltaTime=0,this.speed=0,this.duration=0,this.action=null}reset(){this.isActive&&this.onStop(),this.item=null,this.element=null,this.isActive=!1,this.isEnding=!1,this.direction=0,this.value=NaN,this.maxValue=0,this.threshold=0,this.distance=0,this.deltaTime=0,this.speed=0,this.duration=0,this.action=null}hasReachedEnd(){return M.forward&this.direction?se(this.value,this.maxValue):this.value<=0}computeCurrentScrollValue(){return this.element?this.value!==this.value?h.x&this.direction?X(this.element):Y(this.element):Math.max(0,Math.min(this.value,this.maxValue)):0}computeNextScrollValue(){let e=this.speed*(this.deltaTime/1e3),t=M.forward&this.direction?this.value+e:this.value-e;return Math.max(0,Math.min(t,this.maxValue))}computeSpeed(){if(!this.item||!this.element)return 0;let{speed:e}=this.item;return typeof e=="function"?(A.direction=Pe(this.direction),A.threshold=this.threshold,A.distance=this.distance,A.value=this.value,A.maxValue=this.maxValue,A.duration=this.duration,A.speed=this.speed,A.deltaTime=this.deltaTime,A.isEnding=this.isEnding,e(this.element,A)):e}tick(e){return this.isActive||(this.isActive=!0,this.onStart()),this.deltaTime=e,this.value=this.computeCurrentScrollValue(),this.speed=this.computeSpeed(),this.value=this.computeNextScrollValue(),this.duration+=e,this.value}onStart(){if(!this.item||!this.element)return;let{onStart:e}=this.item;typeof e=="function"&&e(this.element,Pe(this.direction))}onStop(){if(!this.item||!this.element)return;let{onStop:e}=this.item;typeof e=="function"&&e(this.element,Pe(this.direction))}};function tt(r=500,e=.5,t=.25){let n=r*(e>0?1/e:1/0),i=r*(t>0?1/t:1/0);return function(o,s){let a=0;if(!s.isEnding)if(s.threshold>0){let d=s.threshold-Math.max(0,s.distance);a=r/s.threshold*d}else a=r;let c=s.speed;if(c===a)return a;let l=a;return c<a?(l=c+n*(s.deltaTime/1e3),Math.min(a,l)):(l=c-i*(s.deltaTime/1e3),Math.max(a,l))}}var ae=class{constructor(e={}){let{overlapCheckInterval:t=150}=e;this.items=[],this.settings={overlapCheckInterval:t},this._actions=[],this._isDestroyed=!1,this._isTicking=!1,this._tickTime=0,this._tickDeltaTime=0,this._requests={[h.x]:new Map,[h.y]:new Map},this._itemData=new Map,this._requestPool=new z(()=>new Ce,n=>n.reset()),this._actionPool=new z(()=>new Ae,n=>n.reset()),this._emitter=new xt,this._frameRead=this._frameRead.bind(this),this._frameWrite=this._frameWrite.bind(this)}_frameRead(e){this._isDestroyed||(e&&this._tickTime?(this._tickDeltaTime=e-this._tickTime,this._tickTime=e,this._updateItems(),this._updateRequests(),this._updateActions()):(this._tickTime=e,this._tickDeltaTime=0))}_frameWrite(){this._isDestroyed||this._applyActions()}_startTicking(){this._isTicking||(this._isTicking=!0,m.on(v,this._frameRead,this._frameRead),m.on(x,this._frameWrite,this._frameWrite))}_stopTicking(){this._isTicking&&(this._isTicking=!1,this._tickTime=0,this._tickDeltaTime=0,m.off(v,this._frameRead),m.off(x,this._frameWrite))}_requestItemScroll(e,t,n,i,o,s,a){let c=this._requests[t],l=c.get(e);l?(l.element!==n||l.direction!==i)&&l.reset():(l=this._requestPool.pick(),c.set(e,l)),l.item=e,l.element=n,l.direction=i,l.threshold=o,l.distance=s,l.maxValue=a}_cancelItemScroll(e,t){let n=this._requests[t],i=n.get(e);i&&(i.action&&i.action.removeRequest(i),this._requestPool.put(i),n.delete(e))}_checkItemOverlap(e,t,n){let{inertAreaSize:i,targets:o,clientRect:s}=e;if(!o.length){t&&this._cancelItemScroll(e,h.x),n&&this._cancelItemScroll(e,h.y);return}let a=this._itemData.get(e),c=a?.directionX,l=a?.directionY;if(!c&&!l){t&&this._cancelItemScroll(e,h.x),n&&this._cancelItemScroll(e,h.y);return}let d=null,u=-1/0,y=0,g=-1/0,E=f.none,_=0,p=0,S=null,D=-1/0,U=0,B=-1/0,ce=f.none,Ke=0,Me=0,de=0;for(;de<o.length;de++){let C=o[de],We=typeof C.threshold=="number"?C.threshold:Ze,he=!!(t&&c&&C.axis!=="y"),ue=!!(n&&l&&C.axis!=="x"),R=C.priority||0;if((!he||R<u)&&(!ue||R<D))continue;let O=ye(C.element||C),$=he?be(O):-1,J=ue?xe(O):-1;if($<=0&&J<=0)continue;let P=_e([O,"padding"],window),W=ve(s,P)||-1/0;if(W===-1/0)if(C.padding&&De(s,et(P,C.padding,Qe)))W=-(je(s,P)||0);else continue;if(he&&R>=u&&$>0&&(R>u||W>g)){let T=0,k=f.none,L=Te(We,P.width),H=Ie(L,i,s.width,P.width);c===f.right?(T=P.x+P.width+H-(s.x+s.width),T<=L&&!se(X(O),$)&&(k=f.right)):c===f.left&&(T=s.x-(P.x-H),T<=L&&X(O)>0&&(k=f.left)),k&&(d=O,u=R,y=L,g=W,E=k,_=T,p=$)}if(ue&&R>=D&&J>0&&(R>D||W>B)){let T=0,k=G.none,L=Te(We,P.height),H=Ie(L,i,s.height,P.height);l===f.down?(T=P.y+P.height+H-(s.y+s.height),T<=L&&!se(Y(O),J)&&(k=f.down)):l===f.up&&(T=s.y-(P.y-H),T<=L&&Y(O)>0&&(k=f.up)),k&&(S=O,D=R,U=L,B=W,ce=k,Ke=T,Me=J)}}t&&(d&&E?this._requestItemScroll(e,h.x,d,E,y,_,p):this._cancelItemScroll(e,h.x)),n&&(S&&ce?this._requestItemScroll(e,h.y,S,ce,U,Ke,Me):this._cancelItemScroll(e,h.y))}_updateScrollRequest(e){let t=e.item,{inertAreaSize:n,smoothStop:i,targets:o,clientRect:s}=t,a=null,c=0;for(;c<o.length;c++){let l=o[c],d=ye(l.element||l);if(d!==e.element)continue;let u=!!(h.x&e.direction);if(u){if(l.axis==="y")continue}else if(l.axis==="x")continue;let y=u?be(d):xe(d);if(y<=0)break;let g=_e([d,"padding"],window);if((ve(s,g)||-1/0)===-1/0){let B=l.scrollPadding||l.padding;if(!(B&&De(s,et(g,B,Qe))))break}let _=typeof l.threshold=="number"?l.threshold:Ze,p=Te(_,u?g.width:g.height),S=Ie(p,n,u?s.width:s.height,u?g.width:g.height),D=0;if(e.direction===f.left?D=s.x-(g.x-S):e.direction===f.right?D=g.x+g.width+S-(s.x+s.width):e.direction===f.up?D=s.y-(g.y-S):D=g.y+g.height+S-(s.y+s.height),D>p)break;let U=u?X(d):Y(d);if(a=M.forward&e.direction?se(U,y):U<=0,a)break;return e.maxValue=y,e.threshold=p,e.distance=D,e.isEnding=!1,!0}return i===!0&&e.speed>0?(a===null&&(a=e.hasReachedEnd()),e.isEnding=!a):e.isEnding=!1,e.isEnding}_updateItems(){for(let e=0;e<this.items.length;e++){let t=this.items[e],n=this._itemData.get(t),{x:i,y:o}=t.position,s=n.positionX,a=n.positionY;i===s&&o===a||(n.directionX=i>s?f.right:i<s?f.left:n.directionX,n.directionY=o>a?f.down:o<a?f.up:n.directionY,n.positionX=i,n.positionY=o,n.overlapCheckRequestTime===0&&(n.overlapCheckRequestTime=this._tickTime))}}_updateRequests(){let e=this.items,t=this._requests[h.x],n=this._requests[h.y],i=0;for(;i<e.length;i++){let o=e[i],s=this._itemData.get(o),a=s.overlapCheckRequestTime,c=a>0&&this._tickTime-a>this.settings.overlapCheckInterval,l=!0,d=t.get(o);d&&d.isActive&&(l=!this._updateScrollRequest(d),l&&(c=!0,this._cancelItemScroll(o,h.x)));let u=!0,y=n.get(o);y&&y.isActive&&(u=!this._updateScrollRequest(y),u&&(c=!0,this._cancelItemScroll(o,h.y))),c&&(s.overlapCheckRequestTime=0,this._checkItemOverlap(o,l,u))}}_requestAction(e,t){let n=t===h.x,i=null,o=0;for(;o<this._actions.length;o++){if(i=this._actions[o],e.element!==i.element){i=null;continue}if(n?i.requestX:i.requestY){this._cancelItemScroll(e.item,t);return}break}i||(i=this._actionPool.pick()),i.element=e.element,i.addRequest(e),e.tick(this._tickDeltaTime),this._actions.push(i)}_updateActions(){let e=0;for(e=0;e<this.items.length;e++){let t=this.items[e],n=this._requests[h.x].get(t),i=this._requests[h.y].get(t);n&&this._requestAction(n,h.x),i&&this._requestAction(i,h.y)}for(e=0;e<this._actions.length;e++)this._actions[e].computeScrollValues()}_applyActions(){if(!this._actions.length)return;this._emitter.emit("beforescroll");let e=0;for(e=0;e<this._actions.length;e++)this._actions[e].scroll(),this._actionPool.put(this._actions[e]);this._actions.length=0;let t;for(e=0;e<this.items.length;e++)t=this.items[e],t.onPrepareScrollEffect&&t.onPrepareScrollEffect();for(e=0;e<this.items.length;e++)t=this.items[e],t.onApplyScrollEffect&&t.onApplyScrollEffect();this._emitter.emit("afterscroll")}on(e,t,n){return this._emitter.on(e,t,n)}off(e,t){this._emitter.off(e,t)}addItem(e){if(this._isDestroyed||this._itemData.has(e))return;let{x:t,y:n}=e.position,i=new we;i.positionX=t,i.positionY=n,i.directionX=f.none,i.directionY=f.none,i.overlapCheckRequestTime=this._tickTime,this._itemData.set(e,i),this.items.push(e),this._isTicking||this._startTicking()}removeItem(e){if(this._isDestroyed)return;let t=this.items.indexOf(e);t!==-1&&(this._requests[h.x].get(e)&&(this._cancelItemScroll(e,h.x),this._requests[h.x].delete(e)),this._requests[h.y].get(e)&&(this._cancelItemScroll(e,h.y),this._requests[h.y].delete(e)),this._itemData.delete(e),this.items.splice(t,1),this._isTicking&&!this.items.length&&this._stopTicking())}isDestroyed(){return this._isDestroyed}isItemScrollingX(e){return!!this._requests[h.x].get(e)?.isActive}isItemScrollingY(e){return!!this._requests[h.y].get(e)?.isActive}isItemScrolling(e){return this.isItemScrollingX(e)||this.isItemScrollingY(e)}updateSettings(e={}){let{overlapCheckInterval:t=this.settings.overlapCheckInterval}=e;this.settings.overlapCheckInterval=t}destroy(){if(this._isDestroyed)return;let e=this.items.slice(0),t=0;for(;t<e.length;t++)this.removeItem(e[t]);this._actions.length=0,this._requestPool.reset(),this._actionPool.reset(),this._emitter.off(),this._isDestroyed=!0}};var Oe=new ae;var ke={x:0,y:0},j={width:0,height:0,x:0,y:0};function Dt(){return{targets:[],inertAreaSize:.2,speed:tt(),smoothStop:!1,getPosition:r=>{let{drag:e}=r,t=e?.items[0];if(t)return t.position;let n=e&&(e.event||e.startEvent);return ke.x=n?n.x:0,ke.y=n?n.y:0,ke},getClientRect:r=>{let{drag:e}=r,t=e?.items[0];if(t&&t.element)return t.clientRect;let n=e&&(e.event||e.startEvent);return j.width=n?50:0,j.height=n?50:0,j.x=n?n.x-25:0,j.y=n?n.y-25:0,j},onStart:null,onStop:null}}var Le=class{constructor(e,t){this._draggableAutoScroll=e,this._draggable=t,this._position={x:0,y:0},this._clientRect={width:0,height:0,x:0,y:0}}_getSettings(){return this._draggableAutoScroll.settings}get targets(){let{targets:e}=this._getSettings();return typeof e=="function"&&(e=e(this._draggable)),e}get position(){let e=this._position,{getPosition:t}=this._getSettings();return typeof t=="function"?Object.assign(e,t(this._draggable)):(e.x=0,e.y=0),e}get clientRect(){let e=this._clientRect,{getClientRect:t}=this._getSettings();return typeof t=="function"?Object.assign(e,t(this._draggable)):(e.width=0,e.height=0,e.x=0,e.y=0),e}get inertAreaSize(){return this._getSettings().inertAreaSize}get smoothStop(){return this._getSettings().smoothStop}get speed(){return this._getSettings().speed}get onStart(){return this._getSettings().onStart}get onStop(){return this._getSettings().onStop}onPrepareScrollEffect(){let e=this._draggable._updateId;m.off(v,e),m.off(x,e),this._draggable._preparePositionUpdate()}onApplyScrollEffect(){this._draggable._applyPositionUpdate()}},Re=class{constructor(e,t={}){this.name="autoscroll",this.version="0.0.3",this.settings=this._parseSettings(t),this._autoScrollProxy=null,e.on("start",()=>{this._autoScrollProxy||(this._autoScrollProxy=new Le(this,e),Oe.addItem(this._autoScrollProxy))}),e.on("end",()=>{this._autoScrollProxy&&(Oe.removeItem(this._autoScrollProxy),this._autoScrollProxy=null)})}_parseSettings(e,t=Dt()){let{targets:n=t.targets,inertAreaSize:i=t.inertAreaSize,speed:o=t.speed,smoothStop:s=t.smoothStop,getPosition:a=t.getPosition,getClientRect:c=t.getClientRect,onStart:l=t.onStart,onStop:d=t.onStop}=e||{};return{targets:n,inertAreaSize:i,speed:o,smoothStop:s,getPosition:a,getClientRect:c,onStart:l,onStop:d}}updateSettings(e={}){this.settings=this._parseSettings(e,this.settings)}};function kr(r){return e=>{let t=new Re(e,r),n=e;return n.plugins[t.name]=t,n}}var nt=new Set(["auto","scroll","overlay"]);function le(r){let e=ne(r);return!!(nt.has(e.overflowY)||nt.has(e.overflowX))}function rt(r){return r instanceof Document}function it(r,e=[]){let t=r?.parentNode;for(;t&&!rt(t);)t instanceof Element?(le(t)&&e.push(t),t=t.parentNode):t instanceof ShadowRoot?t=t.host:t=t.parentNode;return e.push(window),e}function Pt(r){let e=[];return le(r)&&e.push(r),it(r,e),e}function Br(r={}){let e,t=0,n=null,i,{timeout:o=250,fallback:s=()=>!0}=r,a=d=>d.preventDefault(),c=d=>{if(t){if(e){d.cancelable&&d.preventDefault();return}e===void 0&&(d.cancelable&&d.timeStamp-t>o?(e=!0,d.preventDefault()):e=!1)}};return d=>{if(!(d.sensor instanceof q))return s(d);let{draggable:u,sensor:y,event:g}=d,E=g;if(E.pointerType==="touch"){if(E.type==="start"&&(E.srcEvent.type==="pointerdown"||E.srcEvent.type==="touchstart")){n=E.target;let _=n?Pt(n):[];_.forEach(S=>{S.addEventListener("touchmove",c,{passive:!1,capture:!0})});let p=()=>{t&&(u.off("end",p),u.sensors.forEach(S=>{S instanceof q&&S.off("end",p)}),n?.removeEventListener("contextmenu",a),_.forEach(S=>{S.removeEventListener("touchmove",c,{capture:!0})}),t=0,e=void 0,n=null,i=void window.clearTimeout(i))};e=void 0,t=E.srcEvent.timeStamp,n?.addEventListener("contextmenu",a),u.on("end",p),u.sensors.forEach(S=>{S instanceof q&&S.off("end",p)}),o>0&&(i=window.setTimeout(()=>{u.resolveStartPredicate(y),e=!0,i=void 0},o))}return e}return E.type==="start"&&!E.srcEvent.button}}function Tt(r,e){return Math.round(r/e)*e}function ot(r,e,t){let n=t-e,i=Math.abs(n);if(i>=r){let o=i%r;return Tt(n>0?n-o:n+o,r)}return 0}function zr(r,e){return function({item:n,event:i,startEvent:o}){let{__snapX__:s=o.x,__snapY__:a=o.y}=n.data,c=ot(r,s,i.x),l=ot(e,a,i.y);return c&&(n.data.__snapX__=s+c),l&&(n.data.__snapY__=a+l),{x:c,y:l}}}export{h as AUTO_SCROLL_AXIS,M as AUTO_SCROLL_AXIS_DIRECTION,f as AUTO_SCROLL_DIRECTION,ae as AutoScroll,Q as BaseMotionSensor,V as BaseSensor,Ge as Draggable,Re as DraggableAutoScroll,Ue as KeyboardMotionSensor,Ye as KeyboardSensor,q as PointerSensor,b as SensorEventType,Oe as autoScroll,kr as autoScrollPlugin,tt as autoScrollSmoothSpeed,Br as createPointerSensorStartPredicate,zr as createSnapModifier,I as keyboardMotionSensorDefaults,K as keyboardSensorDefaults,Vt as setTicker,m as ticker,v as tickerReadPhase,x as tickerWritePhase}; | ||
var m={Start:"start",Move:"move",Cancel:"cancel",End:"end",Destroy:"destroy"};import{Emitter as xt}from"eventti";var H=class{constructor(){this.drag=null,this.isDestroyed=!1,this._emitter=new xt}_createDragData(e){return{x:e.x,y:e.y}}_updateDragData(e){this.drag&&(this.drag.x=e.x,this.drag.y=e.y)}_resetDragData(){this.drag=null}_start(e){this.isDestroyed||this.drag||(this.drag=this._createDragData(e),this._emitter.emit(m.Start,e))}_move(e){this.drag&&(this._updateDragData(e),this._emitter.emit(m.Move,e))}_end(e){this.drag&&(this._updateDragData(e),this._emitter.emit(m.End,e),this._resetDragData())}_cancel(e){this.drag&&(this._updateDragData(e),this._emitter.emit(m.Cancel,e),this._resetDragData())}on(e,t,n){return this._emitter.on(e,t,n)}off(e,t){this._emitter.off(e,t)}cancel(){this.drag&&this._cancel({type:m.Cancel,x:this.drag.x,y:this.drag.y})}destroy(){this.isDestroyed||(this.isDestroyed=!0,this.cancel(),this._emitter.emit(m.Destroy,{type:m.Destroy}),this._emitter.off())}};import{AutoTicker as Dt}from"tikki";var g={read:Symbol(),write:Symbol()},S=new Dt({phases:[g.read,g.write]});function nn(r,e){S=r,Object.assign(g,e)}var le=class extends H{constructor(){super(),this.drag=null,this._direction={x:0,y:0},this._speed=0,this._tick=this._tick.bind(this)}_createDragData(e){return{...super._createDragData(e),time:0,deltaTime:0}}_start(e){this.isDestroyed||this.drag||(super._start(e),S.on(g.read,this._tick,this._tick))}_end(e){this.drag&&(S.off(g.read,this._tick),super._end(e))}_cancel(e){this.drag&&(S.off(g.read,this._tick),super._cancel(e))}_tick(e){if(this.drag)if(e&&this.drag.time){this.drag.deltaTime=e-this.drag.time,this.drag.time=e;let t={type:"tick",time:this.drag.time,deltaTime:this.drag.deltaTime};if(this._emitter.emit("tick",t),!this.drag)return;let n=this._speed*(this.drag.deltaTime/1e3),i=this._direction.x*n,o=this._direction.y*n;(i||o)&&this._move({type:m.Move,x:this.drag.x+i,y:this.drag.y+o})}else this.drag.time=e,this.drag.deltaTime=0}};import{Emitter as Pt}from"eventti";function De(r,e){if("pointerId"in r)return r.pointerId===e?r:null;if("changedTouches"in r){let t=0;for(;t<r.changedTouches.length;t++)if(r.changedTouches[t].identifier===e)return r.changedTouches[t];return null}return r}function $e(r){return"pointerType"in r?r.pointerType:"touches"in r?"touch":"mouse"}function Ze(r){return"pointerId"in r?r.pointerId:"changedTouches"in r?r.changedTouches[0]?r.changedTouches[0].identifier:null:-1}var Pe=typeof window<"u"&&typeof window.document<"u",ce=(()=>{let r=!1;try{let e=Object.defineProperty({},"passive",{get:function(){r=!0}});window.addEventListener("testPassive",null,e),window.removeEventListener("testPassive",null,e)}catch{}return r})(),Je=Pe&&"ontouchstart"in window,Qe=Pe&&!!window.PointerEvent,fn=!!(Pe&&navigator.vendor&&navigator.vendor.indexOf("Apple")>-1&&navigator.userAgent&&navigator.userAgent.indexOf("CriOS")==-1&&navigator.userAgent.indexOf("FxiOS")==-1);function Te(r={}){let{capture:e=!0,passive:t=!0}=r;return ce?{capture:e,passive:t}:{capture:e}}function Me(r){return r==="auto"||r===void 0?Qe?"pointer":Je?"touch":"mouse":r}var Tt={start:"pointerdown",move:"pointermove",cancel:"pointercancel",end:"pointerup"},Mt={start:"touchstart",move:"touchmove",cancel:"touchcancel",end:"touchend"},wt={start:"mousedown",move:"mousemove",cancel:"",end:"mouseup"},U={pointer:Tt,touch:Mt,mouse:wt},V=class{constructor(e,t={}){let{listenerOptions:n={},sourceEvents:i="auto",startPredicate:o=s=>!("button"in s&&s.button>0)}=t;this.element=e,this.drag=null,this.isDestroyed=!1,this._areWindowListenersBound=!1,this._startPredicate=o,this._listenerOptions=Te(n),this._sourceEvents=Me(i),this._emitter=new Pt,this._onStart=this._onStart.bind(this),this._onMove=this._onMove.bind(this),this._onCancel=this._onCancel.bind(this),this._onEnd=this._onEnd.bind(this),e.addEventListener(U[this._sourceEvents].start,this._onStart,this._listenerOptions)}_getTrackedPointerEventData(e){return this.drag?De(e,this.drag.pointerId):null}_onStart(e){if(this.isDestroyed||this.drag||!this._startPredicate(e))return;let t=Ze(e);if(t===null)return;let n=De(e,t);if(n===null)return;let i={pointerId:t,pointerType:$e(e),x:n.clientX,y:n.clientY};this.drag=i;let o={...i,type:m.Start,srcEvent:e,target:n.target};this._emitter.emit(o.type,o),this.drag&&this._bindWindowListeners()}_onMove(e){if(!this.drag)return;let t=this._getTrackedPointerEventData(e);if(!t)return;this.drag.x=t.clientX,this.drag.y=t.clientY;let n={type:m.Move,srcEvent:e,target:t.target,...this.drag};this._emitter.emit(n.type,n)}_onCancel(e){if(!this.drag)return;let t=this._getTrackedPointerEventData(e);if(!t)return;this.drag.x=t.clientX,this.drag.y=t.clientY;let n={type:m.Cancel,srcEvent:e,target:t.target,...this.drag};this._emitter.emit(n.type,n),this._resetDrag()}_onEnd(e){if(!this.drag)return;let t=this._getTrackedPointerEventData(e);if(!t)return;this.drag.x=t.clientX,this.drag.y=t.clientY;let n={type:m.End,srcEvent:e,target:t.target,...this.drag};this._emitter.emit(n.type,n),this._resetDrag()}_bindWindowListeners(){if(this._areWindowListenersBound)return;let{move:e,end:t,cancel:n}=U[this._sourceEvents];window.addEventListener(e,this._onMove,this._listenerOptions),window.addEventListener(t,this._onEnd,this._listenerOptions),n&&window.addEventListener(n,this._onCancel,this._listenerOptions),this._areWindowListenersBound=!0}_unbindWindowListeners(){if(this._areWindowListenersBound){let{move:e,end:t,cancel:n}=U[this._sourceEvents];window.removeEventListener(e,this._onMove,this._listenerOptions),window.removeEventListener(t,this._onEnd,this._listenerOptions),n&&window.removeEventListener(n,this._onCancel,this._listenerOptions),this._areWindowListenersBound=!1}}_resetDrag(){this.drag=null,this._unbindWindowListeners()}cancel(){if(!this.drag)return;let e={type:m.Cancel,srcEvent:null,target:null,...this.drag};this._emitter.emit(e.type,e),this._resetDrag()}updateSettings(e){if(this.isDestroyed)return;let{listenerOptions:t,sourceEvents:n,startPredicate:i}=e,o=Me(n),s=Te(t);i&&this._startPredicate!==i&&(this._startPredicate=i),(t&&(this._listenerOptions.capture!==s.capture||this._listenerOptions.passive===s.passive)||n&&this._sourceEvents!==o)&&(this.element.removeEventListener(U[this._sourceEvents].start,this._onStart,this._listenerOptions),this._unbindWindowListeners(),this.cancel(),n&&(this._sourceEvents=o),t&&s&&(this._listenerOptions=s),this.element.addEventListener(U[this._sourceEvents].start,this._onStart,this._listenerOptions))}on(e,t,n){return this._emitter.on(e,t,n)}off(e,t){this._emitter.off(e,t)}destroy(){this.isDestroyed||(this.isDestroyed=!0,this.cancel(),this._emitter.emit(m.Destroy,{type:m.Destroy}),this._emitter.off(),this.element.removeEventListener(U[this._sourceEvents].start,this._onStart,this._listenerOptions))}};var q={moveDistance:25,cancelOnBlur:!0,cancelOnVisibilityChange:!0,startPredicate:(r,e)=>{if(e.element&&(r.key==="Enter"||r.key===" ")&&document.activeElement===e.element){let{x:t,y:n}=e.element.getBoundingClientRect();return{x:t,y:n}}return null},movePredicate:(r,e)=>{if(!e.drag)return null;switch(r.key){case"ArrowLeft":return{x:e.drag.x-e.moveDistance.x,y:e.drag.y};case"ArrowRight":return{x:e.drag.x+e.moveDistance.x,y:e.drag.y};case"ArrowUp":return{x:e.drag.x,y:e.drag.y-e.moveDistance.y};case"ArrowDown":return{x:e.drag.x,y:e.drag.y+e.moveDistance.y};default:return null}},cancelPredicate:(r,e)=>{if(e.drag&&r.key==="Escape"){let{x:t,y:n}=e.drag;return{x:t,y:n}}return null},endPredicate:(r,e)=>{if(e.drag&&(r.key==="Enter"||r.key===" ")){let{x:t,y:n}=e.drag;return{x:t,y:n}}return null}},et=class extends H{constructor(e,t={}){super();let{moveDistance:n=q.moveDistance,cancelOnBlur:i=q.cancelOnBlur,cancelOnVisibilityChange:o=q.cancelOnVisibilityChange,startPredicate:s=q.startPredicate,movePredicate:a=q.movePredicate,cancelPredicate:c=q.cancelPredicate,endPredicate:l=q.endPredicate}=t;this.element=e,this.moveDistance=typeof n=="number"?{x:n,y:n}:{...n},this._cancelOnBlur=i,this._cancelOnVisibilityChange=o,this._startPredicate=s,this._movePredicate=a,this._cancelPredicate=c,this._endPredicate=l,this._onKeyDown=this._onKeyDown.bind(this),this._internalCancel=this._internalCancel.bind(this),this._blurCancelHandler=this._blurCancelHandler.bind(this),document.addEventListener("keydown",this._onKeyDown),i&&e?.addEventListener("blur",this._blurCancelHandler),o&&document.addEventListener("visibilitychange",this._internalCancel)}_internalCancel(){this.cancel()}_blurCancelHandler(){queueMicrotask(()=>{document.activeElement!==this.element&&this.cancel()})}_onKeyDown(e){if(!this.drag){let o=this._startPredicate(e,this);o&&(e.preventDefault(),this._start({type:m.Start,x:o.x,y:o.y,srcEvent:e}));return}let t=this._cancelPredicate(e,this);if(t){e.preventDefault(),this._cancel({type:m.Cancel,x:t.x,y:t.y,srcEvent:e});return}let n=this._endPredicate(e,this);if(n){e.preventDefault(),this._end({type:m.End,x:n.x,y:n.y,srcEvent:e});return}let i=this._movePredicate(e,this);if(i){e.preventDefault(),this._move({type:m.Move,x:i.x,y:i.y,srcEvent:e});return}}updateSettings(e={}){let{moveDistance:t,cancelOnBlur:n,cancelOnVisibilityChange:i,startPredicate:o,movePredicate:s,cancelPredicate:a,endPredicate:c}=e;t!==void 0&&(typeof t=="number"?this.moveDistance.x=this.moveDistance.y=t:(this.moveDistance.x=t.x,this.moveDistance.y=t.y)),n!==void 0&&this._cancelOnBlur!==n&&(this._cancelOnBlur=n,n?this.element?.addEventListener("blur",this._blurCancelHandler):this.element?.removeEventListener("blur",this._blurCancelHandler)),i!==void 0&&this._cancelOnVisibilityChange!==i&&(this._cancelOnVisibilityChange=i,i?document.addEventListener("visibilitychange",this._internalCancel):document.removeEventListener("visibilitychange",this._internalCancel)),o&&(this._startPredicate=o),s&&(this._movePredicate=s),a&&(this._cancelPredicate=a),c&&(this._endPredicate=c)}destroy(){this.isDestroyed||(super.destroy(),document.removeEventListener("keydown",this._onKeyDown),this._cancelOnBlur&&this.element?.removeEventListener("blur",this._blurCancelHandler),this._cancelOnVisibilityChange&&document.removeEventListener("visibilitychange",this._internalCancel))}};var Ct=["start","cancel","end","moveLeft","moveRight","moveUp","moveDown"];function de(r,e){if(!r.size||!e.size)return 1/0;let t=1/0;for(let n of r){let i=e.get(n);i!==void 0&&i<t&&(t=i)}return t}var T={startKeys:[" ","Enter"],moveLeftKeys:["ArrowLeft"],moveRightKeys:["ArrowRight"],moveUpKeys:["ArrowUp"],moveDownKeys:["ArrowDown"],cancelKeys:["Escape"],endKeys:[" ","Enter"],cancelOnBlur:!0,cancelOnVisibilityChange:!0,computeSpeed:()=>500,startPredicate:(r,e)=>{if(e.element&&document.activeElement===e.element){let{left:t,top:n}=e.element.getBoundingClientRect();return{x:t,y:n}}return null}},tt=class extends le{constructor(e,t={}){super();let{startPredicate:n=T.startPredicate,computeSpeed:i=T.computeSpeed,cancelOnVisibilityChange:o=T.cancelOnVisibilityChange,cancelOnBlur:s=T.cancelOnBlur,startKeys:a=T.startKeys,moveLeftKeys:c=T.moveLeftKeys,moveRightKeys:l=T.moveRightKeys,moveUpKeys:d=T.moveUpKeys,moveDownKeys:h=T.moveDownKeys,cancelKeys:p=T.cancelKeys,endKeys:u=T.endKeys}=t;this.element=e,this._startKeys=new Set(a),this._cancelKeys=new Set(p),this._endKeys=new Set(u),this._moveLeftKeys=new Set(c),this._moveRightKeys=new Set(l),this._moveUpKeys=new Set(d),this._moveDownKeys=new Set(h),this._moveKeys=new Set([...c,...l,...d,...h]),this._moveKeyTimestamps=new Map,this._cancelOnBlur=s,this._cancelOnVisibilityChange=o,this._computeSpeed=i,this._startPredicate=n,this._onKeyDown=this._onKeyDown.bind(this),this._onKeyUp=this._onKeyUp.bind(this),this._onTick=this._onTick.bind(this),this._internalCancel=this._internalCancel.bind(this),this._blurCancelHandler=this._blurCancelHandler.bind(this),this.on("tick",this._onTick,this._onTick),document.addEventListener("keydown",this._onKeyDown),document.addEventListener("keyup",this._onKeyUp),s&&e?.addEventListener("blur",this._blurCancelHandler),o&&document.addEventListener("visibilitychange",this._internalCancel)}_end(e){this.drag&&(this._moveKeyTimestamps.clear(),this._direction.x=0,this._direction.y=0,super._end(e))}_cancel(e){this.drag&&(this._moveKeyTimestamps.clear(),this._direction.x=0,this._direction.y=0,super._cancel(e))}_internalCancel(){this.cancel()}_blurCancelHandler(){queueMicrotask(()=>{document.activeElement!==this.element&&this.cancel()})}_updateDirection(){let e=de(this._moveLeftKeys,this._moveKeyTimestamps),t=de(this._moveRightKeys,this._moveKeyTimestamps),n=de(this._moveUpKeys,this._moveKeyTimestamps),i=de(this._moveDownKeys,this._moveKeyTimestamps),o=e===t?0:e<t?-1:1,s=n===i?0:n<i?-1:1;if(!(o===0||s===0)){let a=1/(Math.sqrt(o*o+s*s)||1);o*=a,s*=a}this._direction.x=o,this._direction.y=s}_onTick(){this._speed=this._computeSpeed(this)}_onKeyUp(e){this._moveKeyTimestamps.get(e.key)&&(this._moveKeyTimestamps.delete(e.key),this._updateDirection())}_onKeyDown(e){if(!this.drag){if(this._startKeys.has(e.key)){let t=this._startPredicate(e,this);t&&(e.preventDefault(),this._start({type:m.Start,x:t.x,y:t.y}))}return}if(this._cancelKeys.has(e.key)){e.preventDefault(),this._internalCancel();return}if(this._endKeys.has(e.key)){e.preventDefault(),this._end({type:m.End,x:this.drag.x,y:this.drag.y});return}if(this._moveKeys.has(e.key)){e.preventDefault(),this._moveKeyTimestamps.get(e.key)||(this._moveKeyTimestamps.set(e.key,Date.now()),this._updateDirection());return}}updateSettings(e={}){let t=!1,{cancelOnBlur:n,cancelOnVisibilityChange:i,startPredicate:o,computeSpeed:s}=e;if(n!==void 0&&this._cancelOnBlur!==n&&(this._cancelOnBlur=n,n?this.element?.addEventListener("blur",this._blurCancelHandler):this.element?.removeEventListener("blur",this._blurCancelHandler)),i!==void 0&&this._cancelOnVisibilityChange!==i&&(this._cancelOnVisibilityChange=i,i?document.addEventListener("visibilitychange",this._internalCancel):document.removeEventListener("visibilitychange",this._internalCancel)),o!==void 0&&(this._startPredicate=o),s!==void 0&&(this._computeSpeed=s),Ct.forEach((a,c)=>{let l=`${a}Keys`,d=e[l];d!==void 0&&(this[`_${l}`]=new Set(d),c>=3&&(t=!0))}),t){let a=[...this._moveLeftKeys,...this._moveRightKeys,...this._moveUpKeys,...this._moveDownKeys];[...this._moveKeys].every((l,d)=>a[d]===l)||(this._moveKeys=new Set(a),this._moveKeyTimestamps.clear(),this._updateDirection())}}destroy(){this.isDestroyed||(super.destroy(),this.off("tick",this._onTick),document.removeEventListener("keydown",this._onKeyDown),document.removeEventListener("keyup",this._onKeyUp),this._cancelOnBlur&&this.element?.removeEventListener("blur",this._blurCancelHandler),this._cancelOnVisibilityChange&&document.removeEventListener("visibilitychange",this._internalCancel))}};import{Emitter as Lt}from"eventti";var ee=class{constructor(){this.cache=new Map;this.validation=new Map;this.cache=new Map,this.validation=new Map}set(e,t){this.cache.set(e,t),this.validation.set(e,void 0)}get(e){return this.cache.get(e)}has(e){return this.cache.has(e)}delete(e){this.cache.delete(e),this.validation.delete(e)}isValid(e){return this.validation.has(e)}invalidate(e){e===void 0?this.validation.clear():this.validation.delete(e)}clear(){this.cache.clear(),this.validation.clear()}};var he=class{constructor(e,t){this.sensor=e,this.startEvent=t,this.prevMoveEvent=t,this.moveEvent=t,this.endEvent=null,this.items=[],this.isEnded=!1,this._matrixCache=new ee,this._clientOffsetCache=new ee}};import{getOffsetContainer as at}from"mezr";var nt=new WeakMap;function W(r){let e=nt.get(r)?.deref();return e||(e=window.getComputedStyle(r,null),nt.set(r,new WeakRef(e))),e}function X(r,e={x:0,y:0}){if(e.x=0,e.y=0,r instanceof Window)return e;if(r instanceof Document)return e.x=window.scrollX*-1,e.y=window.scrollY*-1,e;let{x:t,y:n}=r.getBoundingClientRect(),i=W(r);return e.x=t+(parseFloat(i.borderLeftWidth)||0),e.y=n+(parseFloat(i.borderTopWidth)||0),e}function we(r){return typeof r=="object"&&r!==null&&"x"in r&&"y"in r}var Ot={x:0,y:0},At={x:0,y:0};function rt(r,e,t={x:0,y:0}){let n=we(r)?r:X(r,Ot),i=we(e)?e:X(e,At);return t.x=i.x-n.x,t.y=i.y-n.y,t}function me(r){let e=r.split(" "),t="",n="",i="";return e.length===1?t=n=e[0]:e.length===2?[t,n]=e:[t,n,i]=e,{x:parseFloat(t)||0,y:parseFloat(n)||0,z:parseFloat(i)||0}}var It="scale(1, 1)";function z(r){return r.setMatrixValue(It)}var Y=new DOMMatrix;function it(r,e=new DOMMatrix){let t=r;for(z(e);t;){let{transform:n,transformOrigin:i}=W(t);if(n&&n!=="none"&&(Y.setMatrixValue(n),!Y.isIdentity)){let{x:o,y:s,z:a}=me(i);a===0?Y.setMatrixValue(`translate(${o}px, ${s}px) ${Y} translate(${o*-1}px, ${s*-1}px)`):Y.setMatrixValue(`translate3d(${o}px, ${s}px, ${a}px) ${Y} translate3d(${o*-1}px, ${s*-1}px, ${a*-1}px)`),e.preMultiplySelf(Y)}t=t.parentElement}return e}function ot(r,e,t=!1){let{style:n}=r;for(let i in e)n.setProperty(i,e[i],t?"important":"")}function st(){let r=document.createElement("div");return r.classList.add("dragdoll-measure"),ot(r,{display:"block",position:"absolute",inset:"0px",padding:"0px",margin:"0px",border:"none",opacity:"0",transform:"none","transform-origin":"0 0",transition:"none",animation:"none","pointer-events":"none"},!0),r}function te(r){return r.m11!==1||r.m12!==0||r.m13!==0||r.m14!==0||r.m21!==0||r.m22!==1||r.m23!==0||r.m24!==0||r.m31!==0||r.m32!==0||r.m33!==1||r.m34!==0||r.m43!==0||r.m44!==1}var pe=st(),ue=class{constructor(e,t){if(!e.isConnected)throw new Error("Element is not connected");let{drag:n}=t;if(!n)throw new Error("Drag is not defined");let i=W(e),o=e.getBoundingClientRect();this.data={},this.element=e,this.elementTransformOrigin=me(i.transformOrigin),this.elementTransformMatrix=new DOMMatrix().setMatrixValue(i.transform),this.frozenStyles=null,this.unfrozenStyles=null,this.position={x:0,y:0},this.containerOffset={x:0,y:0},this.alignmentOffset={x:0,y:0},this._moveDiff={x:0,y:0},this._alignDiff={x:0,y:0},this._matrixCache=n._matrixCache,this._clientOffsetCache=n._clientOffsetCache;let s=e.parentElement;if(!s)throw new Error("Dragged element does not have a parent element.");this.elementContainer=s;let a=t.settings.container||s;if(this.dragContainer=a,s!==a){let{position:h}=i;if(h!=="fixed"&&h!=="absolute")throw new Error(`Dragged element has "${h}" position, but only "fixed" or "absolute" are allowed when using a custom drag container.`)}let c=at(e)||e;this.elementOffsetContainer=c;let l=a===s?c:at(e,{container:a});this.dragOffsetContainer=l;{let{width:h,height:p,x:u,y}=o;this.clientRect={width:h,height:p,x:u,y}}this._updateContainerMatrices(),this._updateContainerOffset();let d=t.settings.frozenStyles({draggable:t,drag:n,item:this,style:i});if(Array.isArray(d))if(d.length){let h={};for(let p of d)h[p]=i[p];this.frozenStyles=h}else this.frozenStyles=null;else this.frozenStyles=d;if(this.frozenStyles){let h={};for(let p in this.frozenStyles)this.frozenStyles.hasOwnProperty(p)&&(h[p]=e.style[p]);this.unfrozenStyles=h}}_updateContainerMatrices(){[this.elementContainer,this.dragContainer].forEach(e=>{if(!this._matrixCache.isValid(e)){let t=this._matrixCache.get(e)||[new DOMMatrix,new DOMMatrix],[n,i]=t;it(e,n),i.setMatrixValue(n.toString()).invertSelf(),this._matrixCache.set(e,t)}})}_updateContainerOffset(){let{elementOffsetContainer:e,elementContainer:t,dragOffsetContainer:n,dragContainer:i,containerOffset:o,_clientOffsetCache:s,_matrixCache:a}=this;if(e!==n){let[c,l]=[[i,n],[t,e]].map(([d,h])=>{let p=s.get(h)||{x:0,y:0};if(!s.isValid(h)){let u=a.get(d);h instanceof HTMLElement&&u&&!u[0].isIdentity?te(u[0])?(pe.style.setProperty("transform",u[1].toString(),"important"),h.append(pe),X(pe,p),pe.remove()):(X(h,p),p.x-=u[0].m41,p.y-=u[0].m42):X(h,p)}return s.set(h,p),p});rt(c,l,o)}else o.x=0,o.y=0}getContainerMatrix(){return this._matrixCache.get(this.elementContainer)}getDragContainerMatrix(){return this._matrixCache.get(this.dragContainer)}updateSize(e){if(e)this.clientRect.width=e.width,this.clientRect.height=e.height;else{let{width:t,height:n}=this.element.getBoundingClientRect();this.clientRect.width=t,this.clientRect.height=n}}};function Ce(r,e,t){let n=document.activeElement,i=r.contains(n);t&&t.append(r),e.append(t||r),i&&document.activeElement!==n&&n.focus({preventScroll:!0})}function ne(r,e=0){let t=Math.pow(10,e);return Math.round((r+Number.EPSILON)*t)/t}function lt(r,e){return r.isIdentity&&e.isIdentity?!0:r.is2D&&e.is2D?r.a===e.a&&r.b===e.b&&r.c===e.c&&r.d===e.d&&r.e===e.e&&r.f===e.f:r.m11===e.m11&&r.m12===e.m12&&r.m13===e.m13&&r.m14===e.m14&&r.m21===e.m21&&r.m22===e.m22&&r.m23===e.m23&&r.m24===e.m24&&r.m31===e.m31&&r.m32===e.m32&&r.m33===e.m33&&r.m34===e.m34&&r.m41===e.m41&&r.m42===e.m42&&r.m43===e.m43&&r.m44===e.m44}var ct=ce?{capture:!0,passive:!0}:!0,Rt={x:0,y:0},w=new DOMMatrix,fe=new DOMMatrix;var Oe={Start:"start",Move:"move",End:"end"},G={Start:"start",StartAlign:"start-align",Move:"move",Align:"align",End:"end",EndAlign:"end-align"},_={PrepareStart:"preparestart",Start:"start",PrepareMove:"preparemove",Move:"move",End:"end",Destroy:"destroy"},kt={container:null,startPredicate:()=>!0,elements:()=>null,frozenStyles:()=>null,applyPosition:({item:r,phase:e})=>{let t=e==="end"||e==="end-align",[n,i]=r.getContainerMatrix(),[o,s]=r.getDragContainerMatrix(),{position:a,alignmentOffset:c,containerOffset:l,elementTransformMatrix:d,elementTransformOrigin:h}=r,{x:p,y:u,z:y}=h,M=!d.isIdentity&&(p!==0||u!==0||y!==0),b=a.x+c.x+l.x,v=a.y+c.y+l.y;z(w),M&&(y===0?w.translateSelf(-p,-u):w.translateSelf(-p,-u,-y)),t?i.isIdentity||w.multiplySelf(i):s.isIdentity||w.multiplySelf(s),z(fe).translateSelf(b,v),w.multiplySelf(fe),n.isIdentity||w.multiplySelf(n),M&&(z(fe).translateSelf(p,u,y),w.multiplySelf(fe)),d.isIdentity||w.multiplySelf(d),r.element.style.transform=`${w}`},positionModifiers:[]},dt=class{constructor(e,t={}){this.sensors=e,this.settings=this._parseSettings(t),this.plugins={},this.drag=null,this.isDestroyed=!1,this._sensorData=new Map,this._emitter=new Lt,this._startPhase=0,this._startId=Symbol(),this._moveId=Symbol(),this._alignId=Symbol(),this._onMove=this._onMove.bind(this),this._onScroll=this._onScroll.bind(this),this._onEnd=this._onEnd.bind(this),this._prepareStart=this._prepareStart.bind(this),this._applyStart=this._applyStart.bind(this),this._prepareMove=this._prepareMove.bind(this),this._applyMove=this._applyMove.bind(this),this._prepareAlign=this._prepareAlign.bind(this),this._applyAlign=this._applyAlign.bind(this),this.sensors.forEach(n=>{this._sensorData.set(n,{predicateState:0,predicateEvent:null,onMove:s=>this._onMove(s,n),onEnd:s=>this._onEnd(s,n)});let{onMove:i,onEnd:o}=this._sensorData.get(n);n.on(m.Start,i,i),n.on(m.Move,i,i),n.on(m.Cancel,o,o),n.on(m.End,o,o),n.on(m.Destroy,o,o)})}_parseSettings(e,t=kt){let{container:n=t.container,startPredicate:i=t.startPredicate,elements:o=t.elements,frozenStyles:s=t.frozenStyles,positionModifiers:a=t.positionModifiers,applyPosition:c=t.applyPosition,onPrepareStart:l=t.onPrepareStart,onStart:d=t.onStart,onPrepareMove:h=t.onPrepareMove,onMove:p=t.onMove,onEnd:u=t.onEnd,onDestroy:y=t.onDestroy}=e||{};return{container:n,startPredicate:i,elements:o,frozenStyles:s,positionModifiers:a,applyPosition:c,onPrepareStart:l,onStart:d,onPrepareMove:h,onMove:p,onEnd:u,onDestroy:y}}_emit(e,...t){this._emitter.emit(e,...t)}_onMove(e,t){let n=this._sensorData.get(t);if(n)switch(n.predicateState){case 0:{n.predicateEvent=e;let i=this.settings.startPredicate({draggable:this,sensor:t,event:e});i===!0?this.resolveStartPredicate(t):i===!1&&this.rejectStartPredicate(t);break}case 1:{this.drag&&(this.drag.moveEvent=e,S.once(g.read,this._prepareMove,this._moveId),S.once(g.write,this._applyMove,this._moveId));break}}}_onScroll(){this.align()}_onEnd(e,t){let n=this._sensorData.get(t);n&&(this.drag?n.predicateState===1&&(this.drag.endEvent=e,this._sensorData.forEach(i=>{i.predicateState=0,i.predicateEvent=null}),this.stop()):(n.predicateState=0,n.predicateEvent=null))}_prepareStart(){let e=this.drag;if(!e)return;this._startPhase=2;let t=this.settings.elements({draggable:this,drag:e})||[];e.items=t.map(n=>new ue(n,this)),this._applyModifiers(Oe.Start,0,0),this._emit(_.PrepareStart,e.startEvent),this.settings.onPrepareStart?.(e,this)}_applyStart(){let e=this.drag;if(e){for(let t of e.items)t.dragContainer!==t.elementContainer&&Ce(t.element,t.dragContainer),t.frozenStyles&&Object.assign(t.element.style,t.frozenStyles),this.settings.applyPosition({phase:G.Start,draggable:this,drag:e,item:t});for(let t of e.items){let n=t.getContainerMatrix()[0],i=t.getDragContainerMatrix()[0];if(lt(n,i)||!te(n)&&!te(i))continue;let o=t.element.getBoundingClientRect(),{alignmentOffset:s}=t;s.x+=ne(t.clientRect.x-o.x,3),s.y+=ne(t.clientRect.y-o.y,3)}for(let t of e.items){let{alignmentOffset:n}=t;(n.x!==0||n.y!==0)&&this.settings.applyPosition({phase:G.StartAlign,draggable:this,drag:e,item:t})}window.addEventListener("scroll",this._onScroll,ct),this._startPhase=3,this._emit(_.Start,e.startEvent),this.settings.onStart?.(e,this)}}_prepareMove(){let e=this.drag;if(!e)return;let{moveEvent:t,prevMoveEvent:n}=e;t!==n&&(this._applyModifiers(Oe.Move,t.x-n.x,t.y-n.y),this._emit(_.PrepareMove,t),this.settings.onPrepareMove?.(e,this),e.prevMoveEvent=t)}_applyMove(){let e=this.drag;if(e){for(let t of e.items)t._moveDiff.x=0,t._moveDiff.y=0,this.settings.applyPosition({phase:G.Move,draggable:this,drag:e,item:t});this._emit(_.Move,e.moveEvent),this.settings.onMove?.(e,this)}}_prepareAlign(){let{drag:e}=this;if(e)for(let t of e.items){let{x:n,y:i}=t.element.getBoundingClientRect(),o=t.clientRect.x-t._moveDiff.x-n;t.alignmentOffset.x=t.alignmentOffset.x-t._alignDiff.x+o,t._alignDiff.x=o;let s=t.clientRect.y-t._moveDiff.y-i;t.alignmentOffset.y=t.alignmentOffset.y-t._alignDiff.y+s,t._alignDiff.y=s}}_applyAlign(){let{drag:e}=this;if(e)for(let t of e.items)t._alignDiff.x=0,t._alignDiff.y=0,this.settings.applyPosition({phase:G.Align,draggable:this,drag:e,item:t})}_applyModifiers(e,t,n){let{drag:i}=this;if(!i)return;let{positionModifiers:o}=this.settings;for(let s of i.items){let a=Rt;a.x=t,a.y=n;for(let c of o)a=c(a,{draggable:this,drag:i,item:s,phase:e});s.position.x+=a.x,s.position.y+=a.y,s.clientRect.x+=a.x,s.clientRect.y+=a.y,e==="move"&&(s._moveDiff.x+=a.x,s._moveDiff.y+=a.y)}}on(e,t,n){return this._emitter.on(e,t,n)}off(e,t){this._emitter.off(e,t)}resolveStartPredicate(e,t){let n=this._sensorData.get(e);if(!n)return;let i=t||n.predicateEvent;n.predicateState===0&&i&&(this._startPhase=1,n.predicateState=1,n.predicateEvent=null,this.drag=new he(e,i),this._sensorData.forEach((o,s)=>{s!==e&&(o.predicateState=2,o.predicateEvent=null)}),S.once(g.read,this._prepareStart,this._startId),S.once(g.write,this._applyStart,this._startId))}rejectStartPredicate(e){let t=this._sensorData.get(e);t?.predicateState===0&&(t.predicateState=2,t.predicateEvent=null)}stop(){let e=this.drag;if(!(!e||e.isEnded)){if(this._startPhase===2){this.off(_.Start,this._startId),this.on(_.Start,()=>this.stop(),this._startId);return}this._startPhase=0,e.isEnded=!0,S.off(g.read,this._startId),S.off(g.write,this._startId),S.off(g.read,this._moveId),S.off(g.write,this._moveId),S.off(g.read,this._alignId),S.off(g.write,this._alignId),window.removeEventListener("scroll",this._onScroll,ct),this._applyModifiers(Oe.End,0,0);for(let t of e.items){if(t.elementContainer!==t.dragContainer&&(Ce(t.element,t.elementContainer),t.alignmentOffset.x=0,t.alignmentOffset.y=0,t.containerOffset.x=0,t.containerOffset.y=0),t.unfrozenStyles)for(let n in t.unfrozenStyles)t.element.style[n]=t.unfrozenStyles[n]||"";this.settings.applyPosition({phase:G.End,draggable:this,drag:e,item:t})}for(let t of e.items)if(t.elementContainer!==t.dragContainer){let n=t.element.getBoundingClientRect();t.alignmentOffset.x=ne(t.clientRect.x-n.x,3),t.alignmentOffset.y=ne(t.clientRect.y-n.y,3)}for(let t of e.items)t.elementContainer!==t.dragContainer&&(t.alignmentOffset.x!==0||t.alignmentOffset.y!==0)&&this.settings.applyPosition({phase:G.EndAlign,draggable:this,drag:e,item:t});this._emit(_.End,e.endEvent),this.settings.onEnd?.(e,this),this.drag=null}}align(e=!1){this.drag&&(e?(this._prepareAlign(),this._applyAlign()):(S.once(g.read,this._prepareAlign,this._alignId),S.once(g.write,this._applyAlign,this._alignId)))}updateSettings(e={}){this.settings=this._parseSettings(e,this.settings)}use(e){return e(this)}destroy(){this.isDestroyed||(this.isDestroyed=!0,this.stop(),this._sensorData.forEach(({onMove:e,onEnd:t},n)=>{n.off(m.Start,e),n.off(m.Move,e),n.off(m.Cancel,t),n.off(m.End,t),n.off(m.Destroy,t)}),this._sensorData.clear(),this._emit(_.Destroy),this.settings.onDestroy?.(this),this._emitter.off())}};var ht=new Set(["auto","scroll","overlay"]);function ge(r){let e=W(r);return!!(ht.has(e.overflowY)||ht.has(e.overflowX))}function mt(r){return r instanceof Document}function pt(r,e=[]){let t=r?.parentNode;for(;t&&!mt(t);)t instanceof Element?(ge(t)&&e.push(t),t=t.parentNode):t instanceof ShadowRoot?t=t.host:t=t.parentNode;return e.push(window),e}function Kt(r){let e=[];return ge(r)&&e.push(r),pt(r,e),e}function ii(r={}){let e,t=0,n=null,i,{touchTimeout:o=250,fallback:s=()=>!0}=r,a=d=>d.preventDefault(),c=d=>{if(t){if(e){d.cancelable&&d.preventDefault();return}e===void 0&&(d.cancelable&&d.timeStamp-t>o?(e=!0,d.preventDefault()):e=!1)}};return d=>{if(!(d.sensor instanceof V))return s(d);let{draggable:h,sensor:p,event:u}=d,y=u;if(y.pointerType==="touch"){if(y.type===m.Start&&(y.srcEvent.type==="pointerdown"||y.srcEvent.type==="touchstart")){n=y.target;let M=n?Kt(n):[];M.forEach(v=>{v.addEventListener("touchmove",c,{passive:!1,capture:!0})});let b=()=>{t&&(h.off(_.End,b),h.sensors.forEach(v=>{v instanceof V&&v.off(m.End,b)}),n?.removeEventListener("contextmenu",a),M.forEach(v=>{v.removeEventListener("touchmove",c,{capture:!0})}),t=0,e=void 0,n=null,i=void window.clearTimeout(i))};e=void 0,t=y.srcEvent.timeStamp,n?.addEventListener("contextmenu",a),h.on(_.End,b),h.sensors.forEach(v=>{v instanceof V&&v.on(m.End,b)}),o>0&&(i=window.setTimeout(()=>{h.resolveStartPredicate(p),e=!0,i=void 0},o))}return e}return y.type===m.Start&&!y.srcEvent.button}}function Vt(r,e){return Math.round(r/e)*e}function ut(r,e,t){let n=t-e,i=Math.abs(n);if(i>=r){let o=i%r;return Vt(n>0?n-o:n+o,r)}return 0}function si(r,e){return function(n,{item:i}){let o=i.data.__snap__||(i.data.__snap__={snapX:0,snapY:0,sensorX:0,sensorY:0});o.sensorX+=n.x,o.sensorY+=n.y;let s=ut(r,o.snapX,o.sensorX),a=ut(e,o.snapY,o.sensorY);return o.snapX+=s,o.snapY+=a,n.x=s,n.y=a,n}}function C(r,e={width:0,height:0,x:0,y:0,left:0,top:0,right:0,bottom:0}){return r&&(e.width=r.width,e.height=r.height,e.x=r.x,e.y=r.y,e.left=r.x,e.top=r.y,e.right=r.x+r.width,e.bottom=r.y+r.height),e}var Wt=C(),qt=C(),j={change:0,drift:0};function ft(r,e,t,n,i,o,s){let a=o,c=i;if(o>0){if(a=Math.min(Math.max(n-e,0),o),s)if(i<0){let l=Math.min(-i,o);c=i+l,a=Math.max(0,a-l)}else c=i+(o-a)}else if(o<0&&(a=Math.max(Math.min(t-r,0),o),s))if(i>0){let l=Math.max(-i,o);c=i+l,a=Math.min(0,a-l)}else c=i+(o-a);j.change=a,j.drift=c}function hi(r,e=({drag:t})=>t.sensor instanceof V){return function(n,i){let o=C(r(i),Wt),s=C(i.item.clientRect,qt),a=i.item.data,c=a.__containment__||{drift:{x:0,y:0},trackDrift:!1};a.__containment__||(c.trackDrift=typeof e=="function"?e(i):e,a.__containment__=c);let{drift:l,trackDrift:d}=c;return n.x&&(ft(s.left,s.right,o.left,o.right,l.x,n.x,d),l.x=j.drift,n.x=j.change),n.y&&(ft(s.top,s.bottom,o.top,o.bottom,l.y,n.y,d),l.y=j.drift,n.y=j.change),n}}var re=class{constructor(e,t){this._data=[],this._createObject=e,this._onPut=t}pick(){return this._data.length?this._data.pop():this._createObject()}put(e){this._data.indexOf(e)===-1&&(this._onPut&&this._onPut(e),this._data.push(e))}reset(){this._data.length=0}};import{getDistance as Xt}from"mezr";var Yt=C(),Bt=C();function gt(r,e){return Xt(C(r,Yt),C(e,Bt))}function St(r,e,t={width:0,height:0,x:0,y:0}){let n=Math.max(r.x,e.x),i=Math.min(r.x+r.width,e.x+e.width);if(i<=n)return null;let o=Math.max(r.y,e.y),s=Math.min(r.y+r.height,e.y+e.height);return s<=o?null:(t.x=n,t.y=o,t.width=i-n,t.height=s-o,t)}function yt(r,e){let t=St(r,e);return t?t.width*t.height:0}function Ae(r,e){let t=yt(r,e);if(!t)return 0;let n=Math.min(r.width,e.width)*Math.min(r.height,e.height);return t/n*100}import{getRect as Nt}from"mezr";function Ie(...r){let{width:e,height:t,left:n,top:i}=Nt(...r);return{width:e,height:t,x:n,y:i}}function O(r){return r instanceof Window}function Le(r){return O(r)||r===document.documentElement||r===document.body?window:r}function F(r){return O(r)?r.scrollX:r.scrollLeft}function Re(r){return O(r)&&(r=document.documentElement),r.scrollWidth-r.clientWidth}function $(r){return O(r)?r.scrollY:r.scrollTop}function ke(r){return O(r)&&(r=document.documentElement),r.scrollHeight-r.clientHeight}function Ke(r,e){return!(r.x+r.width<=e.x||e.x+e.width<=r.x||r.y+r.height<=e.y||e.y+e.height<=r.y)}var Et={width:0,height:0,x:0,y:0},vt=50,A={direction:"none",threshold:0,distance:0,value:0,maxValue:0,duration:0,speed:0,deltaTime:0,isEnding:!1},f={x:1,y:2},B={forward:4,reverse:8},Se={none:0,left:f.x|B.reverse,right:f.x|B.forward},ie={none:0,up:f.y|B.reverse,down:f.y|B.forward},E={...Se,...ie};function Ve(r){switch(r){case Se.none:case ie.none:return"none";case Se.left:return"left";case Se.right:return"right";case ie.up:return"up";case ie.down:return"down";default:throw new Error(`Unknown direction value: ${r}`)}}function _t(r,e,t){let{left:n=0,right:i=0,top:o=0,bottom:s=0}=e;return n=Math.max(0,n),i=Math.max(0,i),o=Math.max(0,o),s=Math.max(0,s),t.width=r.width+n+i,t.height=r.height+o+s,t.x=r.x-n,t.y=r.y-o,t}function ye(r,e){return Math.ceil(r)>=Math.floor(e)}function We(r,e){return Math.min(e/2,r)}function qe(r,e,t,n){return Math.max(0,t+r*2+n*e-n)/2}var Xe=class{constructor(){this.positionX=0,this.positionY=0,this.directionX=E.none,this.directionY=E.none,this.overlapCheckRequestTime=0}},Ye=class{constructor(){this.element=null,this.requestX=null,this.requestY=null,this.scrollLeft=0,this.scrollTop=0}reset(){this.requestX&&(this.requestX.action=null),this.requestY&&(this.requestY.action=null),this.element=null,this.requestX=null,this.requestY=null,this.scrollLeft=0,this.scrollTop=0}addRequest(e){f.x&e.direction?(this.requestX&&this.removeRequest(this.requestX),this.requestX=e):(this.requestY&&this.removeRequest(this.requestY),this.requestY=e),e.action=this}removeRequest(e){this.requestX===e?(this.requestX=null,e.action=null):this.requestY===e&&(this.requestY=null,e.action=null)}computeScrollValues(){this.element&&(this.scrollLeft=this.requestX?this.requestX.value:F(this.element),this.scrollTop=this.requestY?this.requestY.value:$(this.element))}scroll(){this.element&&(this.element.scrollTo?this.element.scrollTo(this.scrollLeft,this.scrollTop):(this.element.scrollLeft=this.scrollLeft,this.element.scrollTop=this.scrollTop))}},Be=class{constructor(){this.item=null,this.element=null,this.isActive=!1,this.isEnding=!1,this.direction=0,this.value=NaN,this.maxValue=0,this.threshold=0,this.distance=0,this.deltaTime=0,this.speed=0,this.duration=0,this.action=null}reset(){this.isActive&&this.onStop(),this.item=null,this.element=null,this.isActive=!1,this.isEnding=!1,this.direction=0,this.value=NaN,this.maxValue=0,this.threshold=0,this.distance=0,this.deltaTime=0,this.speed=0,this.duration=0,this.action=null}hasReachedEnd(){return B.forward&this.direction?ye(this.value,this.maxValue):this.value<=0}computeCurrentScrollValue(){return this.element?this.value!==this.value?f.x&this.direction?F(this.element):$(this.element):Math.max(0,Math.min(this.value,this.maxValue)):0}computeNextScrollValue(){let e=this.speed*(this.deltaTime/1e3),t=B.forward&this.direction?this.value+e:this.value-e;return Math.max(0,Math.min(t,this.maxValue))}computeSpeed(){if(!this.item||!this.element)return 0;let{speed:e}=this.item;return typeof e=="function"?(A.direction=Ve(this.direction),A.threshold=this.threshold,A.distance=this.distance,A.value=this.value,A.maxValue=this.maxValue,A.duration=this.duration,A.speed=this.speed,A.deltaTime=this.deltaTime,A.isEnding=this.isEnding,e(this.element,A)):e}tick(e){return this.isActive||(this.isActive=!0,this.onStart()),this.deltaTime=e,this.value=this.computeCurrentScrollValue(),this.speed=this.computeSpeed(),this.value=this.computeNextScrollValue(),this.duration+=e,this.value}onStart(){if(!this.item||!this.element)return;let{onStart:e}=this.item;typeof e=="function"&&e(this.element,Ve(this.direction))}onStop(){if(!this.item||!this.element)return;let{onStop:e}=this.item;typeof e=="function"&&e(this.element,Ve(this.direction))}};function bt(r=500,e=.5,t=.25){let n=r*(e>0?1/e:1/0),i=r*(t>0?1/t:1/0);return function(o,s){let a=0;if(!s.isEnding)if(s.threshold>0){let d=s.threshold-Math.max(0,s.distance);a=r/s.threshold*d}else a=r;let c=s.speed;if(c===a)return a;let l=a;return c<a?(l=c+n*(s.deltaTime/1e3),Math.min(a,l)):(l=c-i*(s.deltaTime/1e3),Math.max(a,l))}}var Ee=class{constructor(e={}){let{overlapCheckInterval:t=150}=e;this.items=[],this.settings={overlapCheckInterval:t},this._actions=[],this._isDestroyed=!1,this._isTicking=!1,this._tickTime=0,this._tickDeltaTime=0,this._requests={[f.x]:new Map,[f.y]:new Map},this._itemData=new Map,this._requestPool=new re(()=>new Be,n=>n.reset()),this._actionPool=new re(()=>new Ye,n=>n.reset()),this._frameRead=this._frameRead.bind(this),this._frameWrite=this._frameWrite.bind(this)}_frameRead(e){this._isDestroyed||(e&&this._tickTime?(this._tickDeltaTime=e-this._tickTime,this._tickTime=e,this._updateItems(),this._updateRequests(),this._updateActions()):(this._tickTime=e,this._tickDeltaTime=0))}_frameWrite(){this._isDestroyed||this._applyActions()}_startTicking(){this._isTicking||(this._isTicking=!0,S.on(g.read,this._frameRead,this._frameRead),S.on(g.write,this._frameWrite,this._frameWrite))}_stopTicking(){this._isTicking&&(this._isTicking=!1,this._tickTime=0,this._tickDeltaTime=0,S.off(g.read,this._frameRead),S.off(g.write,this._frameWrite))}_requestItemScroll(e,t,n,i,o,s,a){let c=this._requests[t],l=c.get(e);l?(l.element!==n||l.direction!==i)&&l.reset():(l=this._requestPool.pick(),c.set(e,l)),l.item=e,l.element=n,l.direction=i,l.threshold=o,l.distance=s,l.maxValue=a}_cancelItemScroll(e,t){let n=this._requests[t],i=n.get(e);i&&(i.action&&i.action.removeRequest(i),this._requestPool.put(i),n.delete(e))}_checkItemOverlap(e,t,n){let{inertAreaSize:i,targets:o,clientRect:s}=e;if(!o.length){t&&this._cancelItemScroll(e,f.x),n&&this._cancelItemScroll(e,f.y);return}let a=this._itemData.get(e),c=a?.directionX,l=a?.directionY;if(!c&&!l){t&&this._cancelItemScroll(e,f.x),n&&this._cancelItemScroll(e,f.y);return}let d=null,h=-1/0,p=0,u=-1/0,y=E.none,M=0,b=0,v=null,D=-1/0,Z=0,J=-1/0,ve=E.none,Ge=0,je=0,_e=0;for(;_e<o.length;_e++){let I=o[_e],Fe=typeof I.threshold=="number"?I.threshold:vt,be=!!(t&&c&&I.axis!=="y"),xe=!!(n&&l&&I.axis!=="x"),K=I.priority||0;if((!be||K<h)&&(!xe||K<D))continue;let L=Le(I.element||I),se=be?Re(L):-1,ae=xe?ke(L):-1;if(se<=0&&ae<=0)continue;let x=Ie([L,"padding"],window),N=Ae(s,x)||-1/0;if(N===-1/0)if(I.padding&&Ke(s,_t(x,I.padding,Et)))N=-(gt(s,x)||0);else continue;if(be&&K>=h&&se>0&&(K>h||N>u)){let P=0,R=E.none,k=We(Fe,x.width),Q=qe(k,i,s.width,x.width);c===E.right?(P=x.x+x.width+Q-(s.x+s.width),P<=k&&!ye(F(L),se)&&(R=E.right)):c===E.left&&(P=s.x-(x.x-Q),P<=k&&F(L)>0&&(R=E.left)),R&&(d=L,h=K,p=k,u=N,y=R,M=P,b=se)}if(xe&&K>=D&&ae>0&&(K>D||N>J)){let P=0,R=ie.none,k=We(Fe,x.height),Q=qe(k,i,s.height,x.height);l===E.down?(P=x.y+x.height+Q-(s.y+s.height),P<=k&&!ye($(L),ae)&&(R=E.down)):l===E.up&&(P=s.y-(x.y-Q),P<=k&&$(L)>0&&(R=E.up)),R&&(v=L,D=K,Z=k,J=N,ve=R,Ge=P,je=ae)}}t&&(d&&y?this._requestItemScroll(e,f.x,d,y,p,M,b):this._cancelItemScroll(e,f.x)),n&&(v&&ve?this._requestItemScroll(e,f.y,v,ve,Z,Ge,je):this._cancelItemScroll(e,f.y))}_updateScrollRequest(e){let t=e.item,{inertAreaSize:n,smoothStop:i,targets:o,clientRect:s}=t,a=null,c=0;for(;c<o.length;c++){let l=o[c],d=Le(l.element||l);if(d!==e.element)continue;let h=!!(f.x&e.direction);if(h){if(l.axis==="y")continue}else if(l.axis==="x")continue;let p=h?Re(d):ke(d);if(p<=0)break;let u=Ie([d,"padding"],window);if((Ae(s,u)||-1/0)===-1/0){let J=l.scrollPadding||l.padding;if(!(J&&Ke(s,_t(u,J,Et))))break}let M=typeof l.threshold=="number"?l.threshold:vt,b=We(M,h?u.width:u.height),v=qe(b,n,h?s.width:s.height,h?u.width:u.height),D=0;if(e.direction===E.left?D=s.x-(u.x-v):e.direction===E.right?D=u.x+u.width+v-(s.x+s.width):e.direction===E.up?D=s.y-(u.y-v):D=u.y+u.height+v-(s.y+s.height),D>b)break;let Z=h?F(d):$(d);if(a=B.forward&e.direction?ye(Z,p):Z<=0,a)break;return e.maxValue=p,e.threshold=b,e.distance=D,e.isEnding=!1,!0}return i===!0&&e.speed>0?(a===null&&(a=e.hasReachedEnd()),e.isEnding=!a):e.isEnding=!1,e.isEnding}_updateItems(){for(let e=0;e<this.items.length;e++){let t=this.items[e],n=this._itemData.get(t),{x:i,y:o}=t.position,s=n.positionX,a=n.positionY;i===s&&o===a||(n.directionX=i>s?E.right:i<s?E.left:n.directionX,n.directionY=o>a?E.down:o<a?E.up:n.directionY,n.positionX=i,n.positionY=o,n.overlapCheckRequestTime===0&&(n.overlapCheckRequestTime=this._tickTime))}}_updateRequests(){let e=this.items,t=this._requests[f.x],n=this._requests[f.y],i=0;for(;i<e.length;i++){let o=e[i],s=this._itemData.get(o),a=s.overlapCheckRequestTime,c=a>0&&this._tickTime-a>this.settings.overlapCheckInterval,l=!0,d=t.get(o);d&&d.isActive&&(l=!this._updateScrollRequest(d),l&&(c=!0,this._cancelItemScroll(o,f.x)));let h=!0,p=n.get(o);p&&p.isActive&&(h=!this._updateScrollRequest(p),h&&(c=!0,this._cancelItemScroll(o,f.y))),c&&(s.overlapCheckRequestTime=0,this._checkItemOverlap(o,l,h))}}_requestAction(e,t){let n=t===f.x,i=null,o=0;for(;o<this._actions.length;o++){if(i=this._actions[o],e.element!==i.element){i=null;continue}if(n?i.requestX:i.requestY){this._cancelItemScroll(e.item,t);return}break}i||(i=this._actionPool.pick()),i.element=e.element,i.addRequest(e),e.tick(this._tickDeltaTime),this._actions.push(i)}_updateActions(){let e=0;for(e=0;e<this.items.length;e++){let t=this.items[e],n=this._requests[f.x].get(t),i=this._requests[f.y].get(t);n&&this._requestAction(n,f.x),i&&this._requestAction(i,f.y)}for(e=0;e<this._actions.length;e++)this._actions[e].computeScrollValues()}_applyActions(){if(!this._actions.length)return;let e=0;for(e=0;e<this._actions.length;e++)this._actions[e].scroll(),this._actionPool.put(this._actions[e]);this._actions.length=0}addItem(e){if(this._isDestroyed||this._itemData.has(e))return;let{x:t,y:n}=e.position,i=new Xe;i.positionX=t,i.positionY=n,i.directionX=E.none,i.directionY=E.none,i.overlapCheckRequestTime=this._tickTime,this._itemData.set(e,i),this.items.push(e),this._isTicking||this._startTicking()}removeItem(e){if(this._isDestroyed)return;let t=this.items.indexOf(e);t!==-1&&(this._requests[f.x].get(e)&&(this._cancelItemScroll(e,f.x),this._requests[f.x].delete(e)),this._requests[f.y].get(e)&&(this._cancelItemScroll(e,f.y),this._requests[f.y].delete(e)),this._itemData.delete(e),this.items.splice(t,1),this._isTicking&&!this.items.length&&this._stopTicking())}isDestroyed(){return this._isDestroyed}isItemScrollingX(e){return!!this._requests[f.x].get(e)?.isActive}isItemScrollingY(e){return!!this._requests[f.y].get(e)?.isActive}isItemScrolling(e){return this.isItemScrollingX(e)||this.isItemScrollingY(e)}updateSettings(e={}){let{overlapCheckInterval:t=this.settings.overlapCheckInterval}=e;this.settings.overlapCheckInterval=t}destroy(){if(this._isDestroyed)return;let e=this.items.slice(0),t=0;for(;t<e.length;t++)this.removeItem(e[t]);this._actions.length=0,this._requestPool.reset(),this._actionPool.reset(),this._isDestroyed=!0}};var Ne=new Ee;var He={x:0,y:0},oe={width:0,height:0,x:0,y:0};function Ht(){return{targets:[],inertAreaSize:.2,speed:bt(),smoothStop:!1,getPosition:r=>{let{drag:e}=r,t=e?.items[0];if(t)return t.position;let n=e&&(e.moveEvent||e.startEvent);return He.x=n?n.x:0,He.y=n?n.y:0,He},getClientRect:r=>{let{drag:e}=r,t=e?.items[0];if(t&&t.element)return t.clientRect;let n=e&&(e.moveEvent||e.startEvent);return oe.width=n?50:0,oe.height=n?50:0,oe.x=n?n.x-25:0,oe.y=n?n.y-25:0,oe},onStart:null,onStop:null}}var Ue=class{constructor(e,t){this._draggableAutoScroll=e,this._draggable=t,this._position={x:0,y:0},this._clientRect={width:0,height:0,x:0,y:0}}_getSettings(){return this._draggableAutoScroll.settings}get targets(){let{targets:e}=this._getSettings();return typeof e=="function"&&(e=e(this._draggable)),e}get position(){let e=this._position,{getPosition:t}=this._getSettings();return typeof t=="function"?Object.assign(e,t(this._draggable)):(e.x=0,e.y=0),e}get clientRect(){let e=this._clientRect,{getClientRect:t}=this._getSettings();return typeof t=="function"?Object.assign(e,t(this._draggable)):(e.width=0,e.height=0,e.x=0,e.y=0),e}get inertAreaSize(){return this._getSettings().inertAreaSize}get smoothStop(){return this._getSettings().smoothStop}get speed(){return this._getSettings().speed}get onStart(){return this._getSettings().onStart}get onStop(){return this._getSettings().onStop}},ze=class{constructor(e,t={}){this.name="autoscroll",this.version="0.0.3",this.settings=this._parseSettings(t),this._autoScrollProxy=null,e.on(_.Start,()=>{this._autoScrollProxy||(this._autoScrollProxy=new Ue(this,e),Ne.addItem(this._autoScrollProxy))}),e.on(_.End,()=>{this._autoScrollProxy&&(Ne.removeItem(this._autoScrollProxy),this._autoScrollProxy=null)})}_parseSettings(e,t=Ht()){let{targets:n=t.targets,inertAreaSize:i=t.inertAreaSize,speed:o=t.speed,smoothStop:s=t.smoothStop,getPosition:a=t.getPosition,getClientRect:c=t.getClientRect,onStart:l=t.onStart,onStop:d=t.onStop}=e||{};return{targets:n,inertAreaSize:i,speed:o,smoothStop:s,getPosition:a,getClientRect:c,onStart:l,onStop:d}}updateSettings(e={}){this.settings=this._parseSettings(e,this.settings)}};function oo(r){return e=>{let t=new ze(e,r),n=e;return n.plugins[t.name]=t,n}}export{f as AUTO_SCROLL_AXIS,B as AUTO_SCROLL_AXIS_DIRECTION,E as AUTO_SCROLL_DIRECTION,Ee as AutoScroll,le as BaseMotionSensor,H as BaseSensor,dt as Draggable,G as DraggableApplyPositionPhase,ze as DraggableAutoScroll,kt as DraggableDefaultSettings,_ as DraggableEventType,Oe as DraggableModifierPhase,tt as KeyboardMotionSensor,et as KeyboardSensor,V as PointerSensor,m as SensorEventType,Ne as autoScroll,oo as autoScrollPlugin,bt as autoScrollSmoothSpeed,hi as createContainmentModifier,ii as createPointerSensorStartPredicate,si as createSnapModifier,T as keyboardMotionSensorDefaults,q as keyboardSensorDefaults,nn as setTicker,S as ticker,g as tickerPhases}; |
{ | ||
"name": "dragdoll", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"description": "Modular and extensible drag & drop system.", | ||
@@ -42,10 +42,10 @@ "keywords": [ | ||
"scripts": { | ||
"build": "npm run del-dist && npm run ts-check && npm run build-lib && npm run build-tests && npm run build-examples && npm run format && npm run size", | ||
"build": "npm run clean-build && npm run ts-check && npm run build-lib && npm run build-tests && npm run build-examples && npm run format && npm run size", | ||
"build-lib": "tsup --config ./tsup.config.lib.ts", | ||
"build-tests": "tsup --config ./tsup.config.tests.ts", | ||
"build-examples": "node ./scripts/build-examples.mjs", | ||
"clean-build": "rimraf ./dist && rimraf ./tests/dist && rimraf ./docs/public/examples", | ||
"docs-build": "vitepress build docs", | ||
"docs-dev": "npm run build && vitepress dev docs", | ||
"docs-serve": "vitepress serve docs", | ||
"del-dist": "rimraf ./dist && rimraf ./tests/dist && rimraf ./docs/public/examples", | ||
"format": "prettier --write --no-error-on-unmatched-pattern \"./**/*\"", | ||
@@ -61,5 +61,5 @@ "format-check": "prettier --check --no-error-on-unmatched-pattern \"./**/*\"", | ||
"@parcel/config-default": "2.12.0", | ||
"@types/chai": "4.3.14", | ||
"@types/mocha": "10.0.6", | ||
"chai": "5.1.0", | ||
"@types/chai": "4.3.19", | ||
"@types/mocha": "10.0.7", | ||
"chai": "5.1.1", | ||
"cpy-cli": "5.0.0", | ||
@@ -69,4 +69,4 @@ "dotenv": "16.4.5", | ||
"gzip-size-cli": "5.1.0", | ||
"jsdom": "24.0.0", | ||
"karma": "6.4.3", | ||
"jsdom": "25.0.0", | ||
"karma": "6.4.4", | ||
"karma-browserstack-launcher": "1.6.0", | ||
@@ -78,11 +78,11 @@ "karma-chrome-launcher": "3.2.0", | ||
"mezr": "1.1.0", | ||
"mocha": "10.4.0", | ||
"mocha": "10.7.3", | ||
"parcel": "2.12.0", | ||
"prettier": "3.2.5", | ||
"rimraf": "5.0.5", | ||
"prettier": "3.3.3", | ||
"rimraf": "6.0.1", | ||
"tikki": "3.0.1", | ||
"tsup": "8.0.2", | ||
"typescript": "5.4.5", | ||
"vitepress": "1.1.3", | ||
"vue": "3.4.25" | ||
"tsup": "8.2.4", | ||
"typescript": "5.5.4", | ||
"vitepress": "1.3.4", | ||
"vue": "3.4.38" | ||
}, | ||
@@ -89,0 +89,0 @@ "peerDependencies": { |
@@ -5,3 +5,3 @@ <h1 align="center"> | ||
DragDoll is a modular and highly extensible drag & drop system written in TypeScript. It's originally based on [Muuri's](https://github.com/haltu/muuri) internal drag & drop system, but fully redesigned to be used as a general purpose drag & drop system. | ||
DragDoll is a modular and highly extensible drag system written in TypeScript. It's originally based on [Muuri's](https://github.com/haltu/muuri) internal drag system, but fully redesigned to be used as a general purpose drag system. | ||
@@ -16,2 +16,6 @@ 📡 **Sweet Sensors** | ||
🪄 **Magical Transforms** | ||
Transformed (2D) elements can be dragged normally, finally. Rotate, scale, skew and translate to your heart's content. | ||
🧘 **Blissful DX** | ||
@@ -21,6 +25,2 @@ | ||
🎁 **Tiny and Modular** | ||
Weighs around 11kB gzipped all in all, but you can use only the bits and pieces you need. | ||
🍦 **Vanilla Flavour** | ||
@@ -27,0 +27,0 @@ |
@@ -1,3 +0,1 @@ | ||
import { Emitter, EventListenerId } from 'eventti'; | ||
import { Point, Rect } from '../types.js'; | ||
@@ -7,3 +5,3 @@ | ||
import { ticker, tickerReadPhase, tickerWritePhase } from '../singletons/ticker.js'; | ||
import { ticker, tickerPhases } from '../singletons/ticker.js'; | ||
@@ -168,4 +166,2 @@ import { getDistance } from '../utils/get-distance.js'; | ||
readonly onStop?: AutoScrollItemEventCallback | null; | ||
readonly onPrepareScrollEffect?: AutoScrollItemEffectCallback | null; | ||
readonly onApplyScrollEffect?: AutoScrollItemEffectCallback | null; | ||
} | ||
@@ -179,7 +175,2 @@ | ||
export interface AutoScrollEventCallbacks { | ||
beforescroll(): void; | ||
afterscroll(): void; | ||
} | ||
export interface AutoScrollItemTarget { | ||
@@ -483,6 +474,2 @@ element: Window | Element; | ||
protected _actionPool: Pool<AutoScrollAction>; | ||
protected _emitter: Emitter<{ | ||
beforescroll: () => void; | ||
afterscroll: () => void; | ||
}>; | ||
@@ -516,4 +503,2 @@ constructor(options: AutoScrollOptions = {}) { | ||
this._emitter = new Emitter(); | ||
this._frameRead = this._frameRead.bind(this); | ||
@@ -545,4 +530,4 @@ this._frameWrite = this._frameWrite.bind(this); | ||
this._isTicking = true; | ||
ticker.on(tickerReadPhase, this._frameRead, this._frameRead); | ||
ticker.on(tickerWritePhase, this._frameWrite, this._frameWrite); | ||
ticker.on(tickerPhases.read, this._frameRead, this._frameRead); | ||
ticker.on(tickerPhases.write, this._frameWrite, this._frameWrite); | ||
} | ||
@@ -555,4 +540,4 @@ | ||
this._tickDeltaTime = 0; | ||
ticker.off(tickerReadPhase, this._frameRead); | ||
ticker.off(tickerWritePhase, this._frameWrite); | ||
ticker.off(tickerPhases.read, this._frameRead); | ||
ticker.off(tickerPhases.write, this._frameWrite); | ||
} | ||
@@ -1038,10 +1023,4 @@ | ||
// TODO: Would be nice to emit also the elements that will be scrolled, | ||
// to which direction they will be scrolled and how much they will be | ||
// scrolled. | ||
this._emitter.emit('beforescroll'); | ||
// Scroll all the required elements. | ||
let i = 0; | ||
// Scroll all the required elements. | ||
for (i = 0; i < this._actions.length; i++) { | ||
@@ -1054,41 +1033,4 @@ this._actions[i].scroll(); | ||
this._actions.length = 0; | ||
// Call after scroll callbacks for all items that were scrolled. | ||
let item: AutoScrollItem; | ||
for (i = 0; i < this.items.length; i++) { | ||
item = this.items[i]; | ||
if (item.onPrepareScrollEffect) { | ||
item.onPrepareScrollEffect(); | ||
} | ||
} | ||
for (i = 0; i < this.items.length; i++) { | ||
item = this.items[i]; | ||
if (item.onApplyScrollEffect) { | ||
item.onApplyScrollEffect(); | ||
} | ||
} | ||
// TODO: Would be nice to emit also the elements that were scrolled, | ||
// to which direction they were scrolled and how much they were scrolled. | ||
this._emitter.emit('afterscroll'); | ||
} | ||
/** | ||
* Bind a listener. | ||
*/ | ||
on<T extends keyof AutoScrollEventCallbacks>( | ||
type: T, | ||
listener: AutoScrollEventCallbacks[T], | ||
listenerId?: EventListenerId, | ||
): EventListenerId { | ||
return this._emitter.on(type, listener, listenerId); | ||
} | ||
/** | ||
* Unbind a listener. | ||
*/ | ||
off<T extends keyof AutoScrollEventCallbacks>(type: T, listenerId: EventListenerId): void { | ||
this._emitter.off(type, listenerId); | ||
} | ||
addItem(item: AutoScrollItem) { | ||
@@ -1168,3 +1110,2 @@ if (this._isDestroyed || this._itemData.has(item)) return; | ||
this._actionPool.reset(); | ||
this._emitter.off(); | ||
@@ -1171,0 +1112,0 @@ this._isDestroyed = true; |
@@ -7,14 +7,22 @@ import { getOffsetContainer } from 'mezr'; | ||
import { getStyle } from 'utils/get-style.js'; | ||
import { getStyle } from '../utils/get-style.js'; | ||
import { getOffsetDiff } from 'utils/get-offset-diff.js'; | ||
import { getClientOffset } from '../utils/get-client-offset.js'; | ||
import { getOffsetDiff } from '../utils/get-offset-diff.js'; | ||
import { getWorldTransformMatrix } from '../utils/get-world-transform-matrix.js'; | ||
import { createMeasureElement } from '../utils/create-measure-element.js'; | ||
import { isMatrixWarped } from '../utils/is-matrix-warped.js'; | ||
import { parseTransformOrigin } from '../utils/parse-transform-origin.js'; | ||
import type { Draggable } from './draggable.js'; | ||
const OFFSET_DIFF = { left: 0, top: 0 }; | ||
import type { ObjectCache } from '../utils/object-cache.js'; | ||
const IDENTITY_MATRIX = 'matrix(1, 0, 0, 1, 0, 0)'; | ||
const MEASURE_ELEMENT = createMeasureElement(); | ||
const IDENTITY_MATRIX_3D = 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)'; | ||
export class DraggableDragItem< | ||
@@ -30,10 +38,14 @@ S extends Sensor[] = Sensor[], | ||
readonly dragOffsetContainer: HTMLElement | SVGSVGElement | Window | Document; | ||
readonly initialTransform: string; | ||
readonly frozenProps: CSSProperties | null; | ||
readonly unfrozenProps: CSSProperties | null; | ||
readonly elementTransformOrigin: { x: number; y: number; z: number }; | ||
readonly elementTransformMatrix: DOMMatrix; | ||
readonly frozenStyles: CSSProperties | null; | ||
readonly unfrozenStyles: CSSProperties | null; | ||
readonly clientRect: Rect; | ||
readonly position: Point; | ||
readonly _updateDiff: Point; | ||
readonly _moveDiff: Point; | ||
readonly _containerDiff: Point; | ||
readonly containerOffset: Point; | ||
readonly alignmentOffset: Point; | ||
protected _moveDiff: Point; | ||
protected _alignDiff: Point; | ||
protected _matrixCache: ObjectCache<HTMLElement | SVGSVGElement, [DOMMatrix, DOMMatrix]>; | ||
protected _clientOffsetCache: ObjectCache<HTMLElement | SVGSVGElement | Window | Document, Point>; | ||
@@ -47,9 +59,8 @@ constructor(element: HTMLElement | SVGSVGElement, draggable: Draggable<S, E>) { | ||
// Make sure sensor is defined. | ||
const sensor = draggable.drag?.sensor; | ||
if (!sensor) { | ||
throw new Error('Sensor is not defined'); | ||
// Make sure drag is defined. | ||
const { drag } = draggable; | ||
if (!drag) { | ||
throw new Error('Drag is not defined'); | ||
} | ||
const item = this; | ||
const style = getStyle(element); | ||
@@ -60,8 +71,13 @@ const clientRect = element.getBoundingClientRect(); | ||
this.element = element; | ||
this.frozenProps = null; | ||
this.unfrozenProps = null; | ||
this.elementTransformOrigin = parseTransformOrigin(style.transformOrigin); | ||
this.elementTransformMatrix = new DOMMatrix().setMatrixValue(style.transform); | ||
this.frozenStyles = null; | ||
this.unfrozenStyles = null; | ||
this.position = { x: 0, y: 0 }; | ||
this._updateDiff = { x: 0, y: 0 }; | ||
this.containerOffset = { x: 0, y: 0 }; | ||
this.alignmentOffset = { x: 0, y: 0 }; | ||
this._moveDiff = { x: 0, y: 0 }; | ||
this._containerDiff = { x: 0, y: 0 }; | ||
this._alignDiff = { x: 0, y: 0 }; | ||
this._matrixCache = drag['_matrixCache']; | ||
this._clientOffsetCache = drag['_clientOffsetCache']; | ||
@@ -71,13 +87,6 @@ // Use element's parent element as the element container. | ||
if (!elementContainer) { | ||
throw new Error('Element does not have a parent element.'); | ||
throw new Error('Dragged element does not have a parent element.'); | ||
} | ||
this.elementContainer = elementContainer; | ||
// Compute element's offset container. | ||
const elementOffsetContainer = getOffsetContainer(element); | ||
if (!elementOffsetContainer) { | ||
throw new Error('Offset container could not be computed for the element!'); | ||
} | ||
this.elementOffsetContainer = elementOffsetContainer; | ||
// Get element's drag parent, default to element's parent element. | ||
@@ -87,2 +96,17 @@ const dragContainer = draggable.settings.container || elementContainer; | ||
// Make sure that the element is fixed or absolute positioned if there | ||
// is a drag container. | ||
if (elementContainer !== dragContainer) { | ||
const { position } = style; | ||
if (position !== 'fixed' && position !== 'absolute') { | ||
throw new Error( | ||
`Dragged element has "${position}" position, but only "fixed" or "absolute" are allowed when using a custom drag container.`, | ||
); | ||
} | ||
} | ||
// Compute element's offset container. | ||
const elementOffsetContainer = getOffsetContainer(element) || element; | ||
this.elementOffsetContainer = elementOffsetContainer; | ||
// Get drag container's offset container. | ||
@@ -92,9 +116,6 @@ const dragOffsetContainer = | ||
? elementOffsetContainer | ||
: getOffsetContainer(element, { container: dragContainer }); | ||
if (!dragOffsetContainer) { | ||
throw new Error('Drag offset container could not be computed for the element!'); | ||
} | ||
: getOffsetContainer(element, { container: dragContainer })!; | ||
this.dragOffsetContainer = dragOffsetContainer; | ||
// Store element's client rect. | ||
// Compute element's client rect. | ||
{ | ||
@@ -105,56 +126,25 @@ const { width, height, x, y } = clientRect; | ||
// If element's offset container is different than drag container's | ||
// offset container let's compute the offset between the offset containers. | ||
if (elementOffsetContainer !== dragOffsetContainer) { | ||
const { left, top } = getOffsetDiff(dragOffsetContainer, elementOffsetContainer, OFFSET_DIFF); | ||
this._containerDiff.x = left; | ||
this._containerDiff.y = top; | ||
} | ||
// Compute container matrices and offset. | ||
this._updateContainerMatrices(); | ||
this._updateContainerOffset(); | ||
// Store element's initial transform. | ||
const { transform } = style; | ||
if ( | ||
transform && | ||
transform !== 'none' && | ||
transform !== IDENTITY_MATRIX && | ||
transform !== IDENTITY_MATRIX_3D | ||
) { | ||
this.initialTransform = transform; | ||
} else { | ||
this.initialTransform = ''; | ||
} | ||
// Get element's initial position. This position is relative to the | ||
// properties the user is using to move the element. For example, if the | ||
// user is using the `translate` transform to move the element then the | ||
// initial position will be relative to the `translate` transform and the | ||
// position here should reflect the transform value delta. | ||
const { x, y } = draggable.settings.getStartPosition({ | ||
draggable, | ||
sensor, | ||
item, | ||
style, | ||
}); | ||
this.position.x = x; | ||
this.position.y = y; | ||
// Get element's frozen props. | ||
const frozenProps = draggable.settings.getFrozenProps({ | ||
const frozenStyles = draggable.settings.frozenStyles({ | ||
draggable, | ||
sensor, | ||
item, | ||
drag, | ||
item: this, | ||
style, | ||
}); | ||
if (Array.isArray(frozenProps)) { | ||
if (frozenProps.length) { | ||
if (Array.isArray(frozenStyles)) { | ||
if (frozenStyles.length) { | ||
const props: CSSProperties = {}; | ||
for (const prop of frozenProps) { | ||
for (const prop of frozenStyles) { | ||
props[prop] = style[prop]; | ||
} | ||
this.frozenProps = props; | ||
this.frozenStyles = props; | ||
} else { | ||
this.frozenProps = null; | ||
this.frozenStyles = null; | ||
} | ||
} else { | ||
this.frozenProps = frozenProps; | ||
this.frozenStyles = frozenStyles; | ||
} | ||
@@ -165,13 +155,106 @@ | ||
// drag process is over. | ||
if (this.frozenProps) { | ||
const unfrozenProps: CSSProperties = {}; | ||
for (const key in this.frozenProps) { | ||
if (this.frozenProps.hasOwnProperty(key)) { | ||
unfrozenProps[key] = element.style[key]; | ||
if (this.frozenStyles) { | ||
const unfrozenStyles: CSSProperties = {}; | ||
for (const key in this.frozenStyles) { | ||
if (this.frozenStyles.hasOwnProperty(key)) { | ||
unfrozenStyles[key] = element.style[key]; | ||
} | ||
} | ||
this.unfrozenProps = unfrozenProps; | ||
this.unfrozenStyles = unfrozenStyles; | ||
} | ||
} | ||
protected _updateContainerMatrices() { | ||
[this.elementContainer, this.dragContainer].forEach((container) => { | ||
if (!this._matrixCache.isValid(container)) { | ||
const matrices = this._matrixCache.get(container) || [new DOMMatrix(), new DOMMatrix()]; | ||
const [matrix, inverseMatrix] = matrices; | ||
getWorldTransformMatrix(container, matrix); | ||
inverseMatrix.setMatrixValue(matrix.toString()).invertSelf(); | ||
this._matrixCache.set(container, matrices); | ||
} | ||
}); | ||
} | ||
protected _updateContainerOffset() { | ||
const { | ||
elementOffsetContainer, | ||
elementContainer, | ||
dragOffsetContainer, | ||
dragContainer, | ||
containerOffset, | ||
_clientOffsetCache, | ||
_matrixCache, | ||
} = this; | ||
// If element's offset container is different than drag container's | ||
// offset container let's compute the offset between the offset containers. | ||
if (elementOffsetContainer !== dragOffsetContainer) { | ||
// Get the client offsets for the element and drag containers. | ||
const [dragOffset, elementOffset] = ( | ||
[ | ||
[dragContainer, dragOffsetContainer], | ||
[elementContainer, elementOffsetContainer], | ||
] as const | ||
).map(([container, offsetContainer]) => { | ||
// Get the client offset from the cache or create a new one. | ||
const offset = _clientOffsetCache.get(offsetContainer) || { x: 0, y: 0 }; | ||
// If the client offset is not cached let's compute it. | ||
if (!_clientOffsetCache.isValid(offsetContainer)) { | ||
// Get the world transform matrices. | ||
const matrices = _matrixCache.get(container); | ||
// If the offset container is a valid HTMLElement and the matrix is | ||
// not an identity matrix we need to do some extra work. | ||
if (offsetContainer instanceof HTMLElement && matrices && !matrices[0].isIdentity) { | ||
// If the matrix is scaled, rotated, skewed or 3d translated we | ||
// (unfortunately) need to add a temporary measure element to | ||
// compute the untransformed offset from the window's top-left | ||
// corner. If there was a way to compute the offset without | ||
// manipulating the DOM, we would definitely do that, but | ||
// unfortunately, there seems to be no way to do that accurately | ||
// with subpixel precision. | ||
if (isMatrixWarped(matrices[0])) { | ||
MEASURE_ELEMENT.style.setProperty('transform', matrices[1].toString(), 'important'); | ||
offsetContainer.append(MEASURE_ELEMENT); | ||
getClientOffset(MEASURE_ELEMENT, offset); | ||
MEASURE_ELEMENT.remove(); | ||
} | ||
// If the matrix only contains a 2d translation we can compute the | ||
// client offset normally and subtract the translation values from | ||
// the offset. | ||
else { | ||
getClientOffset(offsetContainer, offset); | ||
offset.x -= matrices[0].m41; | ||
offset.y -= matrices[0].m42; | ||
} | ||
} | ||
// In all other cases, let's compute the client offset normally. | ||
else { | ||
getClientOffset(offsetContainer, offset); | ||
} | ||
} | ||
// Cache the client offset. | ||
_clientOffsetCache.set(offsetContainer, offset); | ||
return offset; | ||
}); | ||
getOffsetDiff(dragOffset, elementOffset, containerOffset); | ||
} else { | ||
containerOffset.x = 0; | ||
containerOffset.y = 0; | ||
} | ||
} | ||
getContainerMatrix() { | ||
return this._matrixCache.get(this.elementContainer)!; | ||
} | ||
getDragContainerMatrix() { | ||
return this._matrixCache.get(this.dragContainer)!; | ||
} | ||
updateSize(dimensions?: { width: number; height: number }) { | ||
@@ -182,7 +265,7 @@ if (dimensions) { | ||
} else { | ||
const rect = this.element.getBoundingClientRect(); | ||
this.clientRect.width = rect.width; | ||
this.clientRect.height = rect.height; | ||
const { width, height } = this.element.getBoundingClientRect(); | ||
this.clientRect.width = width; | ||
this.clientRect.height = height; | ||
} | ||
} | ||
} |
@@ -5,20 +5,28 @@ import { Sensor } from '../sensors/sensor.js'; | ||
import { ObjectCache } from '../utils/object-cache.js'; | ||
import { Point } from '../types.js'; | ||
export class DraggableDrag<S extends Sensor[], E extends S[number]['events']> { | ||
readonly sensor: S[number]; | ||
readonly isEnded: boolean; | ||
readonly event: E['start'] | E['move']; | ||
readonly prevEvent: E['start'] | E['move']; | ||
readonly startEvent: E['start'] | E['move']; | ||
readonly prevMoveEvent: E['start'] | E['move']; | ||
readonly moveEvent: E['start'] | E['move']; | ||
readonly endEvent: E['end'] | E['cancel'] | E['destroy'] | null; | ||
readonly items: DraggableDragItem[]; | ||
readonly isEnded: boolean; | ||
protected _matrixCache: ObjectCache<HTMLElement | SVGSVGElement, [DOMMatrix, DOMMatrix]>; | ||
protected _clientOffsetCache: ObjectCache<HTMLElement | SVGSVGElement | Window | Document, Point>; | ||
constructor(sensor: S[number], startEvent: E['start'] | E['move']) { | ||
this.sensor = sensor; | ||
this.isEnded = false; | ||
this.event = startEvent; | ||
this.prevEvent = startEvent; | ||
this.startEvent = startEvent; | ||
this.prevMoveEvent = startEvent; | ||
this.moveEvent = startEvent; | ||
this.endEvent = null; | ||
this.items = []; | ||
this.isEnded = false; | ||
this._matrixCache = new ObjectCache(); | ||
this._clientOffsetCache = new ObjectCache(); | ||
} | ||
} |
@@ -5,3 +5,3 @@ import { HAS_PASSIVE_EVENTS } from '../constants.js'; | ||
import { Sensor, SensorEvents } from '../sensors/sensor.js'; | ||
import { Sensor, SensorEvents, SensorEventType } from '../sensors/sensor.js'; | ||
@@ -12,8 +12,14 @@ import { DraggableDrag } from './draggable-drag.js'; | ||
import { ticker, tickerReadPhase, tickerWritePhase } from '../singletons/ticker.js'; | ||
import { ticker, tickerPhases } from '../singletons/ticker.js'; | ||
import { appendElement } from 'utils/append-element.js'; | ||
import { appendElement } from '../utils/append-element.js'; | ||
import { getOffsetDiff } from '../utils/get-offset-diff.js'; | ||
import { roundNumber } from '../utils/round-number.js'; | ||
import { resetMatrix } from '../utils/reset-matrix.js'; | ||
import { areMatricesEqual } from '../utils/are-matrices-equal.js'; | ||
import { isMatrixWarped } from '../utils/is-matrix-warped.js'; | ||
import { Writeable, CSSProperties, Point } from '../types.js'; | ||
@@ -23,43 +29,54 @@ | ||
const OFFSET_DIFF = { left: 0, top: 0 }; | ||
const POSITION_CHANGE = { x: 0, y: 0 }; | ||
const ELEMENT_MATRIX = new DOMMatrix(); | ||
const TEMP_MATRIX = new DOMMatrix(); | ||
enum DragStartPhase { | ||
NONE = 0, | ||
INIT = 1, | ||
START_PREPARE = 2, | ||
FINISH_APPLY = 3, | ||
None = 0, | ||
Init = 1, | ||
StartPrepare = 2, | ||
FinishApply = 3, | ||
} | ||
enum DraggableStartPredicateState { | ||
PENDING = 0, | ||
RESOLVED = 1, | ||
REJECTED = 2, | ||
Pending = 0, | ||
Resolved = 1, | ||
Rejected = 2, | ||
} | ||
function getDefaultSettings<S extends Sensor[], E extends S[number]['events']>(): DraggableSettings< | ||
S, | ||
E | ||
> { | ||
return { | ||
container: null, | ||
startPredicate: () => true, | ||
getElements: () => null, | ||
releaseElements: () => null, | ||
getFrozenProps: () => null, | ||
getStartPosition: () => { | ||
return { x: 0, y: 0 }; | ||
}, | ||
setPosition: ({ item, x, y }) => { | ||
item.element.style.transform = `translate(${x}px, ${y}px) ${item.initialTransform}`; | ||
}, | ||
getPositionChange: ({ event, prevEvent }) => { | ||
POSITION_CHANGE.x = event.x - prevEvent.x; | ||
POSITION_CHANGE.y = event.y - prevEvent.y; | ||
return POSITION_CHANGE; | ||
}, | ||
}; | ||
} | ||
export const DraggableModifierPhase = { | ||
Start: 'start', | ||
Move: 'move', | ||
End: 'end', | ||
} as const; | ||
export type DraggableModifierPhase = | ||
(typeof DraggableModifierPhase)[keyof typeof DraggableModifierPhase]; | ||
export const DraggableApplyPositionPhase = { | ||
Start: 'start', | ||
StartAlign: 'start-align', | ||
Move: 'move', | ||
Align: 'align', | ||
End: 'end', | ||
EndAlign: 'end-align', | ||
} as const; | ||
export type DraggableApplyPositionPhase = | ||
(typeof DraggableApplyPositionPhase)[keyof typeof DraggableApplyPositionPhase]; | ||
export type DraggableModifierData<S extends Sensor[], E extends S[number]['events']> = { | ||
draggable: Draggable<S, E>; | ||
drag: DraggableDrag<S, E>; | ||
item: DraggableDragItem<S, E>; | ||
phase: DraggableModifierPhase; | ||
}; | ||
export type DraggableModifier<S extends Sensor[], E extends S[number]['events']> = ( | ||
change: Point, | ||
data: DraggableModifierData<S, E>, | ||
) => Point; | ||
export interface DraggableSettings<S extends Sensor[], E extends S[number]['events']> { | ||
@@ -72,40 +89,25 @@ container: HTMLElement | null; | ||
}) => boolean | undefined; | ||
getElements: (data: { | ||
elements: (data: { | ||
draggable: Draggable<S, E>; | ||
sensor: S[number]; | ||
startEvent: E['start'] | E['move']; | ||
drag: DraggableDrag<S, E>; | ||
}) => (HTMLElement | SVGSVGElement)[] | null; | ||
releaseElements: (data: { | ||
frozenStyles: (data: { | ||
draggable: Draggable<S, E>; | ||
sensor: S[number]; | ||
elements: (HTMLElement | SVGSVGElement)[]; | ||
}) => void; | ||
getFrozenProps: (data: { | ||
draggable: Draggable<S, E>; | ||
sensor: S[number]; | ||
drag: DraggableDrag<S, E>; | ||
item: DraggableDragItem<S, E>; | ||
style: CSSStyleDeclaration; | ||
}) => CSSProperties | (keyof CSSProperties)[] | null; | ||
getStartPosition: (data: { | ||
positionModifiers: DraggableModifier<S, E>[]; | ||
applyPosition: (data: { | ||
draggable: Draggable<S, E>; | ||
sensor: S[number]; | ||
drag: DraggableDrag<S, E>; | ||
item: DraggableDragItem<S, E>; | ||
style: CSSStyleDeclaration; | ||
}) => Point; | ||
setPosition: (data: { | ||
draggable: Draggable<S, E>; | ||
sensor: S[number]; | ||
phase: 'start' | 'move' | 'end'; | ||
item: DraggableDragItem<S, E>; | ||
x: number; | ||
y: number; | ||
phase: DraggableApplyPositionPhase; | ||
}) => void; | ||
getPositionChange: (data: { | ||
draggable: Draggable<S, E>; | ||
sensor: S[number]; | ||
item: DraggableDragItem<S, E>; | ||
event: E['start'] | E['move']; | ||
prevEvent: E['start'] | E['move']; | ||
startEvent: E['start'] | E['move']; | ||
}) => Point; | ||
onPrepareStart?: (drag: DraggableDrag<S, E>, draggable: Draggable<S, E>) => void; | ||
onStart?: (drag: DraggableDrag<S, E>, draggable: Draggable<S, E>) => void; | ||
onPrepareMove?: (drag: DraggableDrag<S, E>, draggable: Draggable<S, E>) => void; | ||
onMove?: (drag: DraggableDrag<S, E>, draggable: Draggable<S, E>) => void; | ||
onEnd?: (drag: DraggableDrag<S, E>, draggable: Draggable<S, E>) => void; | ||
onDestroy?: (draggable: Draggable<S, E>) => void; | ||
} | ||
@@ -120,11 +122,99 @@ | ||
export const DraggableEventType = { | ||
PrepareStart: 'preparestart', | ||
Start: 'start', | ||
PrepareMove: 'preparemove', | ||
Move: 'move', | ||
End: 'end', | ||
Destroy: 'destroy', | ||
} as const; | ||
export type DraggableEventType = (typeof DraggableEventType)[keyof typeof DraggableEventType]; | ||
export interface DraggableEventCallbacks<E extends SensorEvents> { | ||
preparestart(event: E['start'] | E['move']): void; | ||
start(event: E['start'] | E['move']): void; | ||
preparemove(event: E['move']): void; | ||
move(event: E['move']): void; | ||
end(event: E['end'] | E['cancel'] | E['destroy'] | null): void; | ||
destroy(): void; | ||
[DraggableEventType.PrepareStart]: (event: E['start'] | E['move']) => void; | ||
[DraggableEventType.Start]: (event: E['start'] | E['move']) => void; | ||
[DraggableEventType.PrepareMove]: (event: E['move']) => void; | ||
[DraggableEventType.Move]: (event: E['move']) => void; | ||
[DraggableEventType.End]: (event: E['end'] | E['cancel'] | E['destroy'] | null) => void; | ||
[DraggableEventType.Destroy]: () => void; | ||
} | ||
export const DraggableDefaultSettings: DraggableSettings<any, any> = { | ||
container: null, | ||
startPredicate: () => true, | ||
elements: () => null, | ||
frozenStyles: () => null, | ||
applyPosition: ({ item, phase }) => { | ||
const isEndPhase = phase === 'end' || phase === 'end-align'; | ||
const [containerMatrix, inverseContainerMatrix] = item.getContainerMatrix(); | ||
const [_dragContainerMatrix, inverseDragContainerMatrix] = item.getDragContainerMatrix(); | ||
const { | ||
position, | ||
alignmentOffset, | ||
containerOffset, | ||
elementTransformMatrix, | ||
elementTransformOrigin, | ||
} = item; | ||
const { x: oX, y: oY, z: oZ } = elementTransformOrigin; | ||
const needsOriginOffset = | ||
!elementTransformMatrix.isIdentity && (oX !== 0 || oY !== 0 || oZ !== 0); | ||
const tX = position.x + alignmentOffset.x + containerOffset.x; | ||
const tY = position.y + alignmentOffset.y + containerOffset.y; | ||
// Reset the matrix to identity. | ||
resetMatrix(ELEMENT_MATRIX); | ||
// First of all negate the element's transform origin. | ||
if (needsOriginOffset) { | ||
if (oZ === 0) { | ||
ELEMENT_MATRIX.translateSelf(-oX, -oY); | ||
} else { | ||
ELEMENT_MATRIX.translateSelf(-oX, -oY, -oZ); | ||
} | ||
} | ||
// Invert the current container's matrix, so we can apply the | ||
// translation in world space coordinates. If this is the end phase the | ||
// element will have been appended back to the original container if | ||
// there was a drag container defined. Otherwise the element will be | ||
// appended to the drag container (if defined). | ||
if (isEndPhase) { | ||
if (!inverseContainerMatrix.isIdentity) { | ||
ELEMENT_MATRIX.multiplySelf(inverseContainerMatrix); | ||
} | ||
} else { | ||
if (!inverseDragContainerMatrix.isIdentity) { | ||
ELEMENT_MATRIX.multiplySelf(inverseDragContainerMatrix); | ||
} | ||
} | ||
// Apply the translation (in world space coordinates). | ||
resetMatrix(TEMP_MATRIX).translateSelf(tX, tY); | ||
ELEMENT_MATRIX.multiplySelf(TEMP_MATRIX); | ||
// Apply the element's original container's world matrix so we can apply | ||
// the element's original transform as if it was in the original | ||
// container's local space coordinates. | ||
if (!containerMatrix.isIdentity) { | ||
ELEMENT_MATRIX.multiplySelf(containerMatrix); | ||
} | ||
// Undo the transform origin negation. | ||
if (needsOriginOffset) { | ||
resetMatrix(TEMP_MATRIX).translateSelf(oX, oY, oZ); | ||
ELEMENT_MATRIX.multiplySelf(TEMP_MATRIX); | ||
} | ||
// Apply the element's original transform. | ||
if (!elementTransformMatrix.isIdentity) { | ||
ELEMENT_MATRIX.multiplySelf(elementTransformMatrix); | ||
} | ||
// Apply the matrix to the element. | ||
item.element.style.transform = `${ELEMENT_MATRIX}`; | ||
}, | ||
positionModifiers: [], | ||
} as const; | ||
export class Draggable< | ||
@@ -155,3 +245,3 @@ S extends Sensor[] = Sensor[], | ||
protected _moveId: symbol; | ||
protected _updateId: symbol; | ||
protected _alignId: symbol; | ||
@@ -167,6 +257,6 @@ constructor(sensors: S, options: Partial<DraggableSettings<S, E>> = {}) { | ||
this._emitter = new Emitter(); | ||
this._startPhase = DragStartPhase.NONE; | ||
this._startPhase = DragStartPhase.None; | ||
this._startId = Symbol(); | ||
this._moveId = Symbol(); | ||
this._updateId = Symbol(); | ||
this._alignId = Symbol(); | ||
@@ -181,4 +271,4 @@ // Bind methods (that need binding). | ||
this._applyMove = this._applyMove.bind(this); | ||
this._preparePositionUpdate = this._preparePositionUpdate.bind(this); | ||
this._applyPositionUpdate = this._applyPositionUpdate.bind(this); | ||
this._prepareAlign = this._prepareAlign.bind(this); | ||
this._applyAlign = this._applyAlign.bind(this); | ||
@@ -188,3 +278,3 @@ // Bind drag sensor events. | ||
this._sensorData.set(sensor, { | ||
predicateState: DraggableStartPredicateState.PENDING, | ||
predicateState: DraggableStartPredicateState.Pending, | ||
predicateEvent: null, | ||
@@ -195,7 +285,7 @@ onMove: (e) => this._onMove(e, sensor), | ||
const { onMove, onEnd } = this._sensorData.get(sensor)!; | ||
sensor.on('start', onMove, onMove); | ||
sensor.on('move', onMove, onMove); | ||
sensor.on('cancel', onEnd, onEnd); | ||
sensor.on('end', onEnd, onEnd); | ||
sensor.on('destroy', onEnd, onEnd); | ||
sensor.on(SensorEventType.Start, onMove, onMove); | ||
sensor.on(SensorEventType.Move, onMove, onMove); | ||
sensor.on(SensorEventType.Cancel, onEnd, onEnd); | ||
sensor.on(SensorEventType.End, onEnd, onEnd); | ||
sensor.on(SensorEventType.Destroy, onEnd, onEnd); | ||
}); | ||
@@ -206,3 +296,3 @@ } | ||
options?: Partial<this['settings']>, | ||
defaults: this['settings'] = getDefaultSettings(), | ||
defaults: this['settings'] = DraggableDefaultSettings, | ||
): this['settings'] { | ||
@@ -212,8 +302,12 @@ const { | ||
startPredicate = defaults.startPredicate, | ||
getElements = defaults.getElements, | ||
releaseElements = defaults.releaseElements, | ||
getFrozenProps = defaults.getFrozenProps, | ||
getStartPosition = defaults.getStartPosition, | ||
setPosition = defaults.setPosition, | ||
getPositionChange = defaults.getPositionChange, | ||
elements = defaults.elements, | ||
frozenStyles = defaults.frozenStyles, | ||
positionModifiers = defaults.positionModifiers, | ||
applyPosition = defaults.applyPosition, | ||
onPrepareStart = defaults.onPrepareStart, | ||
onStart = defaults.onStart, | ||
onPrepareMove = defaults.onPrepareMove, | ||
onMove = defaults.onMove, | ||
onEnd = defaults.onEnd, | ||
onDestroy = defaults.onDestroy, | ||
} = options || {}; | ||
@@ -224,8 +318,12 @@ | ||
startPredicate, | ||
getElements, | ||
releaseElements, | ||
getFrozenProps, | ||
getStartPosition, | ||
setPosition, | ||
getPositionChange, | ||
elements, | ||
frozenStyles, | ||
positionModifiers, | ||
applyPosition, | ||
onPrepareStart, | ||
onStart, | ||
onPrepareMove, | ||
onMove, | ||
onEnd, | ||
onDestroy, | ||
}; | ||
@@ -246,3 +344,3 @@ } | ||
switch (sensorData.predicateState) { | ||
case DraggableStartPredicateState.PENDING: { | ||
case DraggableStartPredicateState.Pending: { | ||
sensorData.predicateEvent = e; | ||
@@ -267,8 +365,8 @@ | ||
} | ||
case DraggableStartPredicateState.RESOLVED: { | ||
case DraggableStartPredicateState.Resolved: { | ||
// Move the element if dragging is active. | ||
if (this.drag) { | ||
(this.drag as Writeable<DraggableDrag<S, E>>).event = e; | ||
ticker.once(tickerReadPhase, this._prepareMove, this._moveId); | ||
ticker.once(tickerWritePhase, this._applyMove, this._moveId); | ||
(this.drag as Writeable<typeof this.drag>).moveEvent = e; | ||
ticker.once(tickerPhases.read, this._prepareMove, this._moveId); | ||
ticker.once(tickerPhases.write, this._applyMove, this._moveId); | ||
} | ||
@@ -281,3 +379,3 @@ break; | ||
protected _onScroll() { | ||
this.updatePosition(); | ||
this.align(); | ||
} | ||
@@ -292,11 +390,11 @@ | ||
if (!this.drag) { | ||
sensorData.predicateState = DraggableStartPredicateState.PENDING; | ||
sensorData.predicateState = DraggableStartPredicateState.Pending; | ||
sensorData.predicateEvent = null; | ||
} | ||
// Otherwise, if drag is active AND the sensor is the one that triggered the | ||
// drag process, let's reset all sensors' start preidcate states. | ||
else if (sensorData.predicateState === DraggableStartPredicateState.RESOLVED) { | ||
(this.drag as Writeable<DraggableDrag<S, E>>).endEvent = e; | ||
// drag process, let's reset all sensors' start predicate states. | ||
else if (sensorData.predicateState === DraggableStartPredicateState.Resolved) { | ||
(this.drag as Writeable<typeof this.drag>).endEvent = e; | ||
this._sensorData.forEach((data) => { | ||
data.predicateState = DraggableStartPredicateState.PENDING; | ||
data.predicateState = DraggableStartPredicateState.Pending; | ||
data.predicateEvent = null; | ||
@@ -309,36 +407,39 @@ }); | ||
protected _prepareStart() { | ||
const drag: Writeable<DraggableDrag<S, E>> | null = this.drag; | ||
const drag = this.drag; | ||
if (!drag) return; | ||
// Update start phase. | ||
this._startPhase = DragStartPhase.START_PREPARE; | ||
this._startPhase = DragStartPhase.StartPrepare; | ||
// Get elements that we'll need to move with the drag. | ||
// NB: It is okay if there are no elements and thus no items. The drag | ||
// process will process as usual, but nothing is moving by default. | ||
// process will process as usual, but no elements will be moved. | ||
const elements = | ||
this.settings.getElements({ | ||
this.settings.elements({ | ||
draggable: this, | ||
sensor: drag.sensor, | ||
startEvent: drag.startEvent, | ||
drag, | ||
}) || []; | ||
// Create drag items. | ||
drag.items = elements.map((element) => { | ||
(drag as Writeable<typeof drag>).items = elements.map((element) => { | ||
return new DraggableDragItem(element, this); | ||
}); | ||
// Apply modifiers for the start phase. | ||
this._applyModifiers(DraggableModifierPhase.Start, 0, 0); | ||
// Emit preparestart event. | ||
this._emit('preparestart', drag.startEvent); | ||
this._emit(DraggableEventType.PrepareStart, drag.startEvent); | ||
// Call onPrepareStart callback. | ||
this.settings.onPrepareStart?.(drag, this); | ||
} | ||
protected _applyStart() { | ||
const drag: Writeable<DraggableDrag<S, E>> | null = this.drag; | ||
const drag = this.drag; | ||
if (!drag) return; | ||
for (const item of drag.items as Writeable<DraggableDragItem<S, E>>[]) { | ||
for (const item of drag.items) { | ||
// Append element within the container element if such is provided. | ||
if (item.dragContainer !== item.elementContainer) { | ||
item.position.x += item._containerDiff.x; | ||
item.position.y += item._containerDiff.y; | ||
appendElement(item.element, item.dragContainer); | ||
@@ -348,17 +449,53 @@ } | ||
// Freeze element's props if such are provided. | ||
if (item.frozenProps) { | ||
Object.assign(item.element.style, item.frozenProps); | ||
if (item.frozenStyles) { | ||
Object.assign(item.element.style, item.frozenStyles); | ||
} | ||
// Set the element's start position. | ||
this.settings.setPosition({ | ||
phase: 'start', | ||
// Set element's start position. | ||
this.settings.applyPosition({ | ||
phase: DraggableApplyPositionPhase.Start, | ||
draggable: this, | ||
sensor: drag.sensor, | ||
item: item as DraggableDragItem<S, E>, | ||
x: item.position.x, | ||
y: item.position.y, | ||
drag, | ||
item, | ||
}); | ||
} | ||
// Compute the start offset (if needed). | ||
for (const item of drag.items) { | ||
const containerMatrix = item.getContainerMatrix()[0]; | ||
const dragContainerMatrix = item.getDragContainerMatrix()[0]; | ||
// If both container matrices are equal, we can skip the computation. | ||
if (areMatricesEqual(containerMatrix, dragContainerMatrix)) { | ||
continue; | ||
} | ||
// We can also skip computation if both matrices contain only 2D | ||
// translations. | ||
if (!isMatrixWarped(containerMatrix) && !isMatrixWarped(dragContainerMatrix)) { | ||
continue; | ||
} | ||
const rect = item.element.getBoundingClientRect(); | ||
const { alignmentOffset } = item; | ||
// Round the align diff to nearest 3rd decimal to avoid applying it if the | ||
// value is so small that it's not visible. | ||
alignmentOffset.x += roundNumber(item.clientRect.x - rect.x, 3); | ||
alignmentOffset.y += roundNumber(item.clientRect.y - rect.y, 3); | ||
} | ||
// Apply start offset (if needed). | ||
for (const item of drag.items) { | ||
const { alignmentOffset } = item; | ||
if (alignmentOffset.x !== 0 || alignmentOffset.y !== 0) { | ||
this.settings.applyPosition({ | ||
phase: DraggableApplyPositionPhase.StartAlign, | ||
draggable: this, | ||
drag, | ||
item, | ||
}); | ||
} | ||
} | ||
// Bind scroll listeners. | ||
@@ -368,10 +505,13 @@ window.addEventListener('scroll', this._onScroll, SCROLL_LISTENER_OPTIONS); | ||
// Update start phase. | ||
this._startPhase = DragStartPhase.FINISH_APPLY; | ||
this._startPhase = DragStartPhase.FinishApply; | ||
// Emit start event. | ||
this._emit('start', drag.startEvent); | ||
this._emit(DraggableEventType.Start, drag.startEvent); | ||
// Call onStart callback. | ||
this.settings.onStart?.(drag, this); | ||
} | ||
protected _prepareMove() { | ||
const drag: Writeable<DraggableDrag<S, E>> | null = this.drag; | ||
const drag = this.drag; | ||
if (!drag) return; | ||
@@ -381,54 +521,36 @@ | ||
// difference between the clientX/Y values. | ||
const { event, prevEvent, startEvent, sensor } = drag; | ||
if (event === prevEvent) return; | ||
const { moveEvent, prevMoveEvent } = drag; | ||
if (moveEvent === prevMoveEvent) return; | ||
for (const item of drag.items as Writeable<DraggableDragItem<S, E>>[]) { | ||
// Compute how much x and y needs to be transformed. | ||
const { x: changeX, y: changeY } = this.settings.getPositionChange({ | ||
draggable: this, | ||
sensor, | ||
item: item as DraggableDragItem<S, E>, | ||
event, | ||
prevEvent, | ||
startEvent, | ||
}); | ||
// Apply modifiers for the move phase. | ||
this._applyModifiers( | ||
DraggableModifierPhase.Move, | ||
moveEvent.x - prevMoveEvent.x, | ||
moveEvent.y - prevMoveEvent.y, | ||
); | ||
// Update horizontal position data. | ||
if (changeX) { | ||
item.position.x += changeX; | ||
item.clientRect.x += changeX; | ||
item._moveDiff.x += changeX; | ||
} | ||
// Emit preparemove event. | ||
this._emit(DraggableEventType.PrepareMove, moveEvent as E['move']); | ||
// Update vertical position data. | ||
if (changeY) { | ||
item.position.y += changeY; | ||
item.clientRect.y += changeY; | ||
item._moveDiff.y += changeY; | ||
} | ||
} | ||
// Call onPrepareMove callback. | ||
this.settings.onPrepareMove?.(drag, this); | ||
// Store next event as previous event. | ||
(drag as Writeable<DraggableDrag<S, E>>).prevEvent = event; | ||
// Emit preparemove event. | ||
this._emit('preparemove', event as E['move']); | ||
// Store next move event as previous move event. | ||
(drag as Writeable<typeof drag>).prevMoveEvent = moveEvent; | ||
} | ||
protected _applyMove() { | ||
const drag: Writeable<DraggableDrag<S, E>> | null = this.drag; | ||
const drag = this.drag; | ||
if (!drag) return; | ||
// Reset movement diff and move the element. | ||
for (const item of drag.items as Writeable<DraggableDragItem<S, E>>[]) { | ||
item._moveDiff.x = 0; | ||
item._moveDiff.y = 0; | ||
for (const item of drag.items) { | ||
item['_moveDiff'].x = 0; | ||
item['_moveDiff'].y = 0; | ||
this.settings.setPosition({ | ||
phase: 'move', | ||
this.settings.applyPosition({ | ||
phase: DraggableApplyPositionPhase.Move, | ||
draggable: this, | ||
sensor: drag.sensor, | ||
item: item as DraggableDragItem<S, E>, | ||
x: item.position.x, | ||
y: item.position.y, | ||
drag, | ||
item, | ||
}); | ||
@@ -438,59 +560,45 @@ } | ||
// Emit move event. | ||
if (drag.event) { | ||
this._emit('move', drag.event as E['move']); | ||
} | ||
this._emit(DraggableEventType.Move, drag.moveEvent as E['move']); | ||
// Call onMove callback. | ||
this.settings.onMove?.(drag, this); | ||
} | ||
protected _preparePositionUpdate() { | ||
protected _prepareAlign() { | ||
const { drag } = this; | ||
if (!drag) return; | ||
for (const item of drag.items as Writeable<DraggableDragItem<S, E>>[]) { | ||
// Update container diff. | ||
if (item.elementOffsetContainer !== item.dragOffsetContainer) { | ||
const { left, top } = getOffsetDiff( | ||
item.dragOffsetContainer, | ||
item.elementOffsetContainer, | ||
OFFSET_DIFF, | ||
); | ||
item._containerDiff.x = left; | ||
item._containerDiff.y = top; | ||
} | ||
for (const item of drag.items) { | ||
const { x, y } = item.element.getBoundingClientRect(); | ||
const { left, top, width, height } = item.element.getBoundingClientRect(); | ||
// Note that we INTENTIONALLY DO NOT UPDATE THE CLIENT RECT COORDINATES | ||
// here. The point of this method is to update the POSITION of the | ||
// draggable item based on how much the client rect has drifted so that | ||
// the element is visually repostioned to the correct place. | ||
// Update horizontal position data. | ||
const updateDiffX = item.clientRect.x - item._moveDiff.x - left; | ||
item.position.x = item.position.x - item._updateDiff.x + updateDiffX; | ||
item._updateDiff.x = updateDiffX; | ||
const alignDiffX = item.clientRect.x - item['_moveDiff'].x - x; | ||
item.alignmentOffset.x = item.alignmentOffset.x - item['_alignDiff'].x + alignDiffX; | ||
item['_alignDiff'].x = alignDiffX; | ||
// Update vertical position data. | ||
const updateDiffY = item.clientRect.y - item._moveDiff.y - top; | ||
item.position.y = item.position.y - item._updateDiff.y + updateDiffY; | ||
item._updateDiff.y = updateDiffY; | ||
// Update item client size. This is not necessary for the drag process, | ||
// but since we're computing the bounding client rect, we might as well | ||
// update the size in the process. The size is used by the auto-scroll | ||
// plugin and possibly some other third-party plugins. | ||
item.clientRect.width = width; | ||
item.clientRect.height = height; | ||
const alignDiffY = item.clientRect.y - item['_moveDiff'].y - y; | ||
item.alignmentOffset.y = item.alignmentOffset.y - item['_alignDiff'].y + alignDiffY; | ||
item['_alignDiff'].y = alignDiffY; | ||
} | ||
} | ||
protected _applyPositionUpdate() { | ||
protected _applyAlign() { | ||
const { drag } = this; | ||
if (!drag) return; | ||
for (const item of drag.items as Writeable<DraggableDragItem<S, E>>[]) { | ||
item._updateDiff.x = 0; | ||
item._updateDiff.y = 0; | ||
for (const item of drag.items) { | ||
item['_alignDiff'].x = 0; | ||
item['_alignDiff'].y = 0; | ||
this.settings.setPosition({ | ||
phase: 'move', | ||
this.settings.applyPosition({ | ||
phase: DraggableApplyPositionPhase.Align, | ||
draggable: this, | ||
sensor: drag.sensor, | ||
item: item as DraggableDragItem<S, E>, | ||
x: item.position.x, | ||
y: item.position.y, | ||
drag, | ||
item, | ||
}); | ||
@@ -500,2 +608,30 @@ } | ||
_applyModifiers(phase: DraggableModifierPhase, changeX: number, changeY: number) { | ||
const { drag } = this; | ||
if (!drag) return; | ||
const { positionModifiers } = this.settings; | ||
for (const item of drag.items) { | ||
let positionChange = POSITION_CHANGE; | ||
positionChange.x = changeX; | ||
positionChange.y = changeY; | ||
for (const modifier of positionModifiers) { | ||
positionChange = modifier(positionChange, { | ||
draggable: this, | ||
drag, | ||
item, | ||
phase, | ||
}); | ||
} | ||
item.position.x += positionChange.x; | ||
item.position.y += positionChange.y; | ||
item.clientRect.x += positionChange.x; | ||
item.clientRect.y += positionChange.y; | ||
if (phase === 'move') { | ||
item['_moveDiff'].x += positionChange.x; | ||
item['_moveDiff'].y += positionChange.y; | ||
} | ||
} | ||
} | ||
on<T extends keyof DraggableEventCallbacks<E>>( | ||
@@ -519,8 +655,8 @@ type: T, | ||
if (sensorData.predicateState === DraggableStartPredicateState.PENDING && startEvent) { | ||
if (sensorData.predicateState === DraggableStartPredicateState.Pending && startEvent) { | ||
// Update start phase. | ||
this._startPhase = DragStartPhase.INIT; | ||
this._startPhase = DragStartPhase.Init; | ||
// Resolve the provided sensor's start predicate. | ||
sensorData.predicateState = DraggableStartPredicateState.RESOLVED; | ||
sensorData.predicateState = DraggableStartPredicateState.Resolved; | ||
sensorData.predicateEvent = null; | ||
@@ -533,3 +669,3 @@ | ||
if (s === sensor) return; | ||
data.predicateState = DraggableStartPredicateState.REJECTED; | ||
data.predicateState = DraggableStartPredicateState.Rejected; | ||
data.predicateEvent = null; | ||
@@ -539,4 +675,4 @@ }); | ||
// Queue drag start. | ||
ticker.once(tickerReadPhase, this._prepareStart, this._startId); | ||
ticker.once(tickerWritePhase, this._applyStart, this._startId); | ||
ticker.once(tickerPhases.read, this._prepareStart, this._startId); | ||
ticker.once(tickerPhases.write, this._applyStart, this._startId); | ||
} | ||
@@ -547,4 +683,4 @@ } | ||
const sensorData = this._sensorData.get(sensor); | ||
if (sensorData?.predicateState === DraggableStartPredicateState.PENDING) { | ||
sensorData.predicateState = DraggableStartPredicateState.REJECTED; | ||
if (sensorData?.predicateState === DraggableStartPredicateState.Pending) { | ||
sensorData.predicateState = DraggableStartPredicateState.Rejected; | ||
sensorData.predicateEvent = null; | ||
@@ -555,3 +691,3 @@ } | ||
stop() { | ||
const drag: Writeable<DraggableDrag<S, E>> | null = this.drag; | ||
const drag = this.drag; | ||
if (!drag || drag.isEnded) return; | ||
@@ -564,5 +700,5 @@ | ||
// NB: We reuse the `_startId` symbol to queue the stop procedure. | ||
if (this._startPhase === DragStartPhase.START_PREPARE) { | ||
this.off('start', this._startId); | ||
this.on('start', () => this.stop(), this._startId); | ||
if (this._startPhase === DragStartPhase.StartPrepare) { | ||
this.off(DraggableEventType.Start, this._startId); | ||
this.on(DraggableEventType.Start, () => this.stop(), this._startId); | ||
return; | ||
@@ -572,14 +708,14 @@ } | ||
// Reset drag start phase. | ||
this._startPhase = DragStartPhase.NONE; | ||
this._startPhase = DragStartPhase.None; | ||
// Mark drag process as ended. | ||
drag.isEnded = true; | ||
(drag as Writeable<typeof drag>).isEnded = true; | ||
// Cancel all queued ticks. | ||
ticker.off(tickerReadPhase, this._startId); | ||
ticker.off(tickerWritePhase, this._startId); | ||
ticker.off(tickerReadPhase, this._moveId); | ||
ticker.off(tickerWritePhase, this._moveId); | ||
ticker.off(tickerReadPhase, this._updateId); | ||
ticker.off(tickerWritePhase, this._updateId); | ||
ticker.off(tickerPhases.read, this._startId); | ||
ticker.off(tickerPhases.write, this._startId); | ||
ticker.off(tickerPhases.read, this._moveId); | ||
ticker.off(tickerPhases.write, this._moveId); | ||
ticker.off(tickerPhases.read, this._alignId); | ||
ticker.off(tickerPhases.write, this._alignId); | ||
@@ -589,46 +725,69 @@ // Unbind scroll listener. | ||
// Move elements within the root container and collect all elements | ||
// to an elements array. | ||
const elements: (HTMLElement | SVGSVGElement)[] = []; | ||
for (const item of drag.items as Writeable<DraggableDragItem<S, E>>[]) { | ||
elements.push(item.element); | ||
// Apply modifiers for the end phase. | ||
this._applyModifiers(DraggableModifierPhase.End, 0, 0); | ||
for (const item of drag.items) { | ||
// Move elements within the root container if they were moved to a | ||
// different container during the drag process. Also reset alignment | ||
// and container offsets for those elements. | ||
if (item.elementContainer !== item.dragContainer) { | ||
item.position.x -= item._containerDiff.x; | ||
item.position.y -= item._containerDiff.y; | ||
item._containerDiff.x = 0; | ||
item._containerDiff.y = 0; | ||
appendElement(item.element, item.elementContainer); | ||
item.alignmentOffset.x = 0; | ||
item.alignmentOffset.y = 0; | ||
item.containerOffset.x = 0; | ||
item.containerOffset.y = 0; | ||
} | ||
// Unfreeze element's props if such are provided. | ||
if (item.unfrozenProps) { | ||
for (const key in item.unfrozenProps) { | ||
item.element.style[key] = item.unfrozenProps[key] || ''; | ||
if (item.unfrozenStyles) { | ||
for (const key in item.unfrozenStyles) { | ||
item.element.style[key] = item.unfrozenStyles[key] || ''; | ||
} | ||
} | ||
// Set final position after drag. | ||
this.settings.setPosition({ | ||
phase: 'end', | ||
// Set (maybe) final position after drag. | ||
this.settings.applyPosition({ | ||
phase: DraggableApplyPositionPhase.End, | ||
draggable: this, | ||
sensor: drag.sensor, | ||
item: item as DraggableDragItem<S, E>, | ||
x: item.position.x, | ||
y: item.position.y, | ||
drag, | ||
item, | ||
}); | ||
} | ||
// Call "releaseElements" callback. | ||
if (elements.length) { | ||
this.settings.releaseElements({ | ||
draggable: this, | ||
sensor: drag.sensor!, | ||
elements, | ||
}); | ||
// Make sure that all elements that were reparented during the drag process | ||
// are actually aligned with the item's cached client rect data. NB: This | ||
// procedure causes a reflow, but it's necessary to ensure that the elements | ||
// are visually aligned correctly. We do the DOM reading in a separate loop | ||
// to avoid layout thrashing more than necessary. | ||
for (const item of drag.items) { | ||
if (item.elementContainer !== item.dragContainer) { | ||
const itemRect = item.element.getBoundingClientRect(); | ||
// Round the align diff to nearest 3rd decimal to avoid applying it if | ||
// the value is so small that it's not visible. | ||
item.alignmentOffset.x = roundNumber(item.clientRect.x - itemRect.x, 3); | ||
item.alignmentOffset.y = roundNumber(item.clientRect.y - itemRect.y, 3); | ||
} | ||
} | ||
// Apply final alignment to all the elements that need it. | ||
for (const item of drag.items) { | ||
if ( | ||
item.elementContainer !== item.dragContainer && | ||
(item.alignmentOffset.x !== 0 || item.alignmentOffset.y !== 0) | ||
) { | ||
this.settings.applyPosition({ | ||
phase: DraggableApplyPositionPhase.EndAlign, | ||
draggable: this, | ||
drag, | ||
item, | ||
}); | ||
} | ||
} | ||
// Emit end event. | ||
this._emit('end', drag.endEvent); | ||
this._emit(DraggableEventType.End, drag.endEvent); | ||
// Call onEnd callback. | ||
this.settings.onEnd?.(drag, this); | ||
// Reset drag data. | ||
@@ -638,10 +797,10 @@ (this as Writeable<this>).drag = null; | ||
updatePosition(instant = false) { | ||
align(instant = false) { | ||
if (!this.drag) return; | ||
if (instant) { | ||
this._preparePositionUpdate(); | ||
this._applyPositionUpdate(); | ||
this._prepareAlign(); | ||
this._applyAlign(); | ||
} else { | ||
ticker.once(tickerReadPhase, this._preparePositionUpdate, this._updateId); | ||
ticker.once(tickerWritePhase, this._applyPositionUpdate, this._updateId); | ||
ticker.once(tickerPhases.read, this._prepareAlign, this._alignId); | ||
ticker.once(tickerPhases.write, this._applyAlign, this._alignId); | ||
} | ||
@@ -667,7 +826,7 @@ } | ||
this._sensorData.forEach(({ onMove, onEnd }, sensor) => { | ||
sensor.off('start', onMove); | ||
sensor.off('move', onMove); | ||
sensor.off('cancel', onEnd); | ||
sensor.off('end', onEnd); | ||
sensor.off('destroy', onEnd); | ||
sensor.off(SensorEventType.Start, onMove); | ||
sensor.off(SensorEventType.Move, onMove); | ||
sensor.off(SensorEventType.Cancel, onEnd); | ||
sensor.off(SensorEventType.End, onEnd); | ||
sensor.off(SensorEventType.Destroy, onEnd); | ||
}); | ||
@@ -677,6 +836,8 @@ | ||
this._emit('destroy'); | ||
this._emit(DraggableEventType.Destroy); | ||
this.settings.onDestroy?.(this); | ||
this._emitter.off(); | ||
} | ||
} |
@@ -1,5 +0,3 @@ | ||
import { ticker, tickerReadPhase, tickerWritePhase } from '../../singletons/ticker.js'; | ||
import { Draggable, DraggableEventType, DraggablePluginMap } from '../draggable.js'; | ||
import { Draggable, DraggablePluginMap } from '../draggable.js'; | ||
import { Sensor } from '../../sensors/sensor.js'; | ||
@@ -44,3 +42,3 @@ | ||
// Fallback to the sensor's clientX/clientY values. | ||
const e = drag && (drag.event || drag.startEvent); | ||
const e = drag && (drag.moveEvent || drag.startEvent); | ||
AUTOSCROLL_POSITION.x = e ? e.x : 0; | ||
@@ -61,3 +59,3 @@ AUTOSCROLL_POSITION.y = e ? e.y : 0; | ||
// 50x50px. | ||
const e = drag && (drag.event || drag.startEvent); | ||
const e = drag && (drag.moveEvent || drag.startEvent); | ||
AUTOSCROLL_CLIENT_RECT.width = e ? 50 : 0; | ||
@@ -146,13 +144,2 @@ AUTOSCROLL_CLIENT_RECT.height = e ? 50 : 0; | ||
} | ||
onPrepareScrollEffect() { | ||
const updateId = this._draggable['_updateId']; | ||
ticker.off(tickerReadPhase, updateId); | ||
ticker.off(tickerWritePhase, updateId); | ||
this._draggable['_preparePositionUpdate'](); | ||
} | ||
onApplyScrollEffect() { | ||
this._draggable['_applyPositionUpdate'](); | ||
} | ||
} | ||
@@ -190,3 +177,3 @@ | ||
draggable.on('start', () => { | ||
draggable.on(DraggableEventType.Start, () => { | ||
if (!this._autoScrollProxy) { | ||
@@ -198,3 +185,3 @@ this._autoScrollProxy = new DraggableAutoScrollProxy(this, draggable); | ||
draggable.on('end', () => { | ||
draggable.on(DraggableEventType.End, () => { | ||
if (this._autoScrollProxy) { | ||
@@ -201,0 +188,0 @@ autoScroll.removeItem(this._autoScrollProxy); |
@@ -15,2 +15,8 @@ export * from './sensors/sensor.js'; | ||
export * from './draggable/helpers/create-pointer-sensor-start-predicate.js'; | ||
export * from './draggable/modifiers/create-snap-modifier.js'; | ||
export * from './draggable/modifiers/create-containment-modifier.js'; | ||
export * from './draggable/plugins/auto-scroll-plugin.js'; | ||
@@ -23,5 +29,1 @@ | ||
export * from './singletons/ticker.js'; | ||
export * from './utils/create-pointer-sensor-start-predicate.js'; | ||
export * from './utils/create-snap-modifier.js'; |
@@ -1,2 +0,2 @@ | ||
import { Sensor, SensorEvents } from './sensor.js'; | ||
import { Sensor, SensorEvents, SensorEventType } from './sensor.js'; | ||
@@ -7,3 +7,3 @@ import { BaseSensor, BaseSensorDragData } from './base-sensor.js'; | ||
import { ticker, tickerReadPhase } from '../singletons/ticker.js'; | ||
import { ticker, tickerPhases } from '../singletons/ticker.js'; | ||
@@ -54,3 +54,3 @@ export interface BaseMotionSensorTickEvent { | ||
super._start(data); | ||
ticker.on(tickerReadPhase, this._tick, this._tick); | ||
ticker.on(tickerPhases.read, this._tick, this._tick); | ||
} | ||
@@ -60,3 +60,3 @@ | ||
if (!this.drag) return; | ||
ticker.off(tickerReadPhase, this._tick); | ||
ticker.off(tickerPhases.read, this._tick); | ||
super._end(data); | ||
@@ -67,3 +67,3 @@ } | ||
if (!this.drag) return; | ||
ticker.off(tickerReadPhase, this._tick); | ||
ticker.off(tickerPhases.read, this._tick); | ||
super._cancel(data); | ||
@@ -101,3 +101,3 @@ } | ||
this._move({ | ||
type: 'move', | ||
type: SensorEventType.Move, | ||
x: this.drag.x + deltaX, | ||
@@ -104,0 +104,0 @@ y: this.drag.y + deltaY, |
@@ -44,3 +44,3 @@ import { Emitter, Events, EventListenerId } from 'eventti'; | ||
(this as Writeable<this>).drag = this._createDragData(data); | ||
this._emitter.emit(SensorEventType.start, data); | ||
this._emitter.emit(SensorEventType.Start, data); | ||
} | ||
@@ -51,3 +51,3 @@ | ||
this._updateDragData(data); | ||
this._emitter.emit(SensorEventType.move, data); | ||
this._emitter.emit(SensorEventType.Move, data); | ||
} | ||
@@ -58,3 +58,3 @@ | ||
this._updateDragData(data); | ||
this._emitter.emit(SensorEventType.end, data); | ||
this._emitter.emit(SensorEventType.End, data); | ||
this._resetDragData(); | ||
@@ -66,3 +66,3 @@ } | ||
this._updateDragData(data); | ||
this._emitter.emit(SensorEventType.cancel, data); | ||
this._emitter.emit(SensorEventType.Cancel, data); | ||
this._resetDragData(); | ||
@@ -86,3 +86,3 @@ } | ||
this._cancel({ | ||
type: SensorEventType.cancel, | ||
type: SensorEventType.Cancel, | ||
x: this.drag.x, | ||
@@ -97,4 +97,4 @@ y: this.drag.y, | ||
this.cancel(); | ||
this._emitter.emit(SensorEventType.destroy, { | ||
type: SensorEventType.destroy, | ||
this._emitter.emit(SensorEventType.Destroy, { | ||
type: SensorEventType.Destroy, | ||
}); | ||
@@ -101,0 +101,0 @@ this._emitter.off(); |
@@ -1,2 +0,2 @@ | ||
import { Sensor } from './sensor.js'; | ||
import { Sensor, SensorEventType } from './sensor.js'; | ||
@@ -211,3 +211,3 @@ import { BaseMotionSensor, BaseMotionSensorEvents } from './base-motion-sensor.js'; | ||
this._start({ | ||
type: 'start', | ||
type: SensorEventType.Start, | ||
x: startPosition.x, | ||
@@ -232,3 +232,3 @@ y: startPosition.y, | ||
this._end({ | ||
type: 'end', | ||
type: SensorEventType.End, | ||
x: this.drag.x, | ||
@@ -235,0 +235,0 @@ y: this.drag.y, |
@@ -8,2 +8,3 @@ import { | ||
SensorDestroyEvent, | ||
SensorEventType, | ||
} from './sensor.js'; | ||
@@ -194,3 +195,3 @@ | ||
this._start({ | ||
type: 'start', | ||
type: SensorEventType.Start, | ||
x: startPosition.x, | ||
@@ -209,3 +210,3 @@ y: startPosition.y, | ||
this._cancel({ | ||
type: 'cancel', | ||
type: SensorEventType.Cancel, | ||
x: cancelPosition.x, | ||
@@ -223,3 +224,3 @@ y: cancelPosition.y, | ||
this._end({ | ||
type: 'end', | ||
type: SensorEventType.End, | ||
x: endPosition.x, | ||
@@ -237,3 +238,3 @@ y: endPosition.y, | ||
this._move({ | ||
type: 'move', | ||
type: SensorEventType.Move, | ||
x: movePosition.x, | ||
@@ -240,0 +241,0 @@ y: movePosition.y, |
@@ -222,3 +222,3 @@ import { Emitter, Events, EventListenerId } from 'eventti'; | ||
...dragData, | ||
type: SensorEventType.start, | ||
type: SensorEventType.Start, | ||
srcEvent: e, | ||
@@ -249,3 +249,3 @@ target: pointerEventData.target, | ||
const eventData: PointerSensorMoveEvent = { | ||
type: SensorEventType.move, | ||
type: SensorEventType.Move, | ||
srcEvent: e, | ||
@@ -272,3 +272,3 @@ target: pointerEventData.target, | ||
const eventData: PointerSensorCancelEvent = { | ||
type: SensorEventType.cancel, | ||
type: SensorEventType.Cancel, | ||
srcEvent: e, | ||
@@ -297,3 +297,3 @@ target: pointerEventData.target, | ||
const eventData: PointerSensorEndEvent = { | ||
type: SensorEventType.end, | ||
type: SensorEventType.End, | ||
srcEvent: e, | ||
@@ -353,3 +353,3 @@ target: pointerEventData.target, | ||
const eventData: PointerSensorCancelEvent = { | ||
type: SensorEventType.cancel, | ||
type: SensorEventType.Cancel, | ||
srcEvent: null, | ||
@@ -448,4 +448,4 @@ target: null, | ||
// Emit destroy event. | ||
this._emitter.emit(SensorEventType.destroy, { | ||
type: SensorEventType.destroy, | ||
this._emitter.emit(SensorEventType.Destroy, { | ||
type: SensorEventType.Destroy, | ||
}); | ||
@@ -452,0 +452,0 @@ |
import type { EventListenerId } from 'eventti'; | ||
export const SensorEventType = { | ||
start: 'start', | ||
move: 'move', | ||
cancel: 'cancel', | ||
end: 'end', | ||
destroy: 'destroy', | ||
Start: 'start', | ||
Move: 'move', | ||
Cancel: 'cancel', | ||
End: 'end', | ||
Destroy: 'destroy', | ||
} as const; | ||
export type SensorEventType = (typeof SensorEventType)[keyof typeof SensorEventType]; | ||
export interface SensorStartEvent { | ||
type: typeof SensorEventType.start; | ||
type: typeof SensorEventType.Start; | ||
x: number; | ||
@@ -18,3 +20,3 @@ y: number; | ||
export interface SensorMoveEvent { | ||
type: typeof SensorEventType.move; | ||
type: typeof SensorEventType.Move; | ||
x: number; | ||
@@ -25,3 +27,3 @@ y: number; | ||
export interface SensorCancelEvent { | ||
type: typeof SensorEventType.cancel; | ||
type: typeof SensorEventType.Cancel; | ||
x: number; | ||
@@ -32,3 +34,3 @@ y: number; | ||
export interface SensorEndEvent { | ||
type: typeof SensorEventType.end; | ||
type: typeof SensorEventType.End; | ||
x: number; | ||
@@ -39,3 +41,3 @@ y: number; | ||
export interface SensorDestroyEvent { | ||
type: typeof SensorEventType.destroy; | ||
type: typeof SensorEventType.Destroy; | ||
} | ||
@@ -42,0 +44,0 @@ |
import { AutoTicker, Phase, FrameCallback } from 'tikki'; | ||
export let tickerReadPhase: Phase = Symbol(); | ||
export const tickerPhases = { | ||
read: Symbol(), | ||
write: Symbol(), | ||
}; | ||
export let tickerWritePhase: Phase = Symbol(); | ||
export let ticker = new AutoTicker<Phase>({ | ||
phases: [tickerPhases.read, tickerPhases.write], | ||
}); | ||
export let ticker = new AutoTicker<Phase>({ phases: [tickerReadPhase, tickerWritePhase] }); | ||
export function setTicker( | ||
newTicker: AutoTicker<Phase, FrameCallback>, | ||
readPhase: Phase, | ||
writePhase: Phase, | ||
phases: typeof tickerPhases, | ||
) { | ||
tickerReadPhase = readPhase; | ||
tickerWritePhase = writePhase; | ||
ticker = newTicker; | ||
Object.assign(tickerPhases, phases); | ||
} |
// A special append method which doesn't lose focus when appending an element. | ||
export function appendElement(element: HTMLElement | SVGSVGElement, container: HTMLElement) { | ||
export function appendElement( | ||
element: HTMLElement | SVGSVGElement, | ||
container: HTMLElement, | ||
innerContainer?: HTMLElement | null, | ||
) { | ||
const focusedElement = document.activeElement; | ||
const containsFocus = element.contains(focusedElement); | ||
container.append(element); | ||
if (innerContainer) innerContainer.append(element); | ||
container.append(innerContainer || element); | ||
if (containsFocus && document.activeElement !== focusedElement) { | ||
@@ -7,0 +12,0 @@ (focusedElement as HTMLElement).focus({ preventScroll: true }); |
@@ -1,3 +0,8 @@ | ||
import { getOffset } from 'mezr'; | ||
import { Point } from 'types.js'; | ||
import { getClientOffset } from './get-client-offset.js'; | ||
import { isPoint } from './is-point.js'; | ||
const OFFSET_A = { x: 0, y: 0 }; | ||
const OFFSET_B = { x: 0, y: 0 }; | ||
/** | ||
@@ -7,19 +12,11 @@ * Calculate the offset difference two elements. | ||
export function getOffsetDiff( | ||
elemA: Element | Window | Document, | ||
elemB: Element | Window | Document, | ||
result: { left: number; top: number } = { left: 0, top: 0 }, | ||
elemA: HTMLElement | SVGSVGElement | Window | Document | Point, | ||
elemB: HTMLElement | SVGSVGElement | Window | Document | Point, | ||
result: Point = { x: 0, y: 0 }, | ||
) { | ||
result.left = 0; | ||
result.top = 0; | ||
// If elements are same let's return early. | ||
if (elemA === elemB) return result; | ||
// Finally, let's calculate the offset diff. | ||
const offsetA = getOffset([elemA, 'padding']); | ||
const offsetB = getOffset([elemB, 'padding']); | ||
result.left = offsetB.left - offsetA.left; | ||
result.top = offsetB.top - offsetA.top; | ||
const offsetA = isPoint(elemA) ? elemA : getClientOffset(elemA, OFFSET_A); | ||
const offsetB = isPoint(elemB) ? elemB : getClientOffset(elemB, OFFSET_B); | ||
result.x = offsetB.x - offsetA.x; | ||
result.y = offsetB.y - offsetA.y; | ||
return result; | ||
} |
@@ -1,2 +0,2 @@ | ||
import { getRect as _getRect } from 'mezr'; | ||
import { getRect as mezrGetRect } from 'mezr'; | ||
@@ -8,5 +8,5 @@ import { Rect } from '../types.js'; | ||
*/ | ||
export function getRect(...args: Parameters<typeof _getRect>): Rect { | ||
const { width, height, left: x, top: y } = _getRect(...args); | ||
export function getRect(...args: Parameters<typeof mezrGetRect>): Rect { | ||
const { width, height, left: x, top: y } = mezrGetRect(...args); | ||
return { width, height, x, y }; | ||
} |
import { isWindow } from './is-window.js'; | ||
export function getScrollLeft(element: Element | Window) { | ||
return isWindow(element) ? element.pageXOffset : element.scrollLeft; | ||
return isWindow(element) ? element.scrollX : element.scrollLeft; | ||
} |
import { isWindow } from './is-window.js'; | ||
export function getScrollTop(element: Element | Window) { | ||
return isWindow(element) ? element.pageYOffset : element.scrollTop; | ||
return isWindow(element) ? element.scrollY : element.scrollTop; | ||
} |
@@ -8,4 +8,3 @@ const STYLE_DECLARATION_CACHE: WeakMap<Element, WeakRef<CSSStyleDeclaration>> = new WeakMap(); | ||
export function getStyle(element: Element) { | ||
let styleDeclaration: CSSStyleDeclaration | undefined = | ||
STYLE_DECLARATION_CACHE.get(element)?.deref(); | ||
let styleDeclaration = STYLE_DECLARATION_CACHE.get(element)?.deref(); | ||
@@ -12,0 +11,0 @@ if (!styleDeclaration) { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
303579
63
5167