📄 index.ts¶
📊 Analysis Summary¶
| Metric | Count |
|---|---|
| 🔧 Functions | 7 |
| 📦 Imports | 10 |
| 📊 Variables & Constants | 1 |
| 🟢 Vue Composition API | 2 |
| 📐 Interfaces | 1 |
| 📑 Type Aliases | 1 |
📚 Table of Contents¶
🛠️ File Location:¶
📂 packages/core/useDraggable/index.ts
📦 Imports¶
| Name | Source |
|---|---|
MaybeRefOrGetter |
vue |
PointerType |
../types |
Position |
../types |
isClient |
@vueuse/shared |
toRefs |
@vueuse/shared |
computed |
vue |
deepRef |
vue |
toValue |
vue |
defaultWindow |
../_configurable |
useEventListener |
../useEventListener |
Variables & Constants¶
| Name | Type | Kind | Value | Exported |
|---|---|---|---|---|
pos |
{ x: number; y: number; } |
const | `{ | |
| x: e.clientX - (container ? targetRect.left - containerRect!.left + container.scrollLeft : targetRect.left), | ||||
| y: e.clientY - (container ? targetRect.top - containerRect!.top + container.scrollTop : targetRect.top), | ||||
| }` | ✗ |
Vue Composition API¶
| Name | Type | Reactive Variables | Composables |
|---|---|---|---|
computed |
computed | none | none |
computed |
computed | none | none |
Functions¶
useDraggable(target: MaybeRefOrGetter<HTMLElement | SVGElement | null | undefined>, options: UseDraggableOptions): any¶
Code
export function useDraggable(
target: MaybeRefOrGetter<HTMLElement | SVGElement | null | undefined>,
options: UseDraggableOptions = {},
) {
const {
pointerTypes,
preventDefault,
stopPropagation,
exact,
onMove,
onEnd,
onStart,
initialValue,
axis = 'both',
draggingElement = defaultWindow,
containerElement,
handle: draggingHandle = target,
buttons = [0],
} = options
const position = deepRef<Position>(
toValue(initialValue) ?? { x: 0, y: 0 },
)
const pressedDelta = deepRef<Position>()
const filterEvent = (e: PointerEvent) => {
if (pointerTypes)
return pointerTypes.includes(e.pointerType as PointerType)
return true
}
const handleEvent = (e: PointerEvent) => {
if (toValue(preventDefault))
e.preventDefault()
if (toValue(stopPropagation))
e.stopPropagation()
}
const start = (e: PointerEvent) => {
if (!toValue(buttons).includes(e.button))
return
if (toValue(options.disabled) || !filterEvent(e))
return
if (toValue(exact) && e.target !== toValue(target))
return
const container = toValue(containerElement)
const containerRect = container?.getBoundingClientRect?.()
const targetRect = toValue(target)!.getBoundingClientRect()
const pos = {
x: e.clientX - (container ? targetRect.left - containerRect!.left + container.scrollLeft : targetRect.left),
y: e.clientY - (container ? targetRect.top - containerRect!.top + container.scrollTop : targetRect.top),
}
if (onStart?.(pos, e) === false)
return
pressedDelta.value = pos
handleEvent(e)
}
const move = (e: PointerEvent) => {
if (toValue(options.disabled) || !filterEvent(e))
return
if (!pressedDelta.value)
return
const container = toValue(containerElement)
const targetRect = toValue(target)!.getBoundingClientRect()
let { x, y } = position.value
if (axis === 'x' || axis === 'both') {
x = e.clientX - pressedDelta.value.x
if (container)
x = Math.min(Math.max(0, x), container.scrollWidth - targetRect!.width)
}
if (axis === 'y' || axis === 'both') {
y = e.clientY - pressedDelta.value.y
if (container)
y = Math.min(Math.max(0, y), container.scrollHeight - targetRect!.height)
}
position.value = {
x,
y,
}
onMove?.(position.value, e)
handleEvent(e)
}
const end = (e: PointerEvent) => {
if (toValue(options.disabled) || !filterEvent(e))
return
if (!pressedDelta.value)
return
pressedDelta.value = undefined
onEnd?.(position.value, e)
handleEvent(e)
}
if (isClient) {
const config = () => ({
capture: options.capture ?? true,
passive: !toValue(preventDefault),
})
useEventListener(draggingHandle, 'pointerdown', start, config)
useEventListener(draggingElement, 'pointermove', move, config)
useEventListener(draggingElement, 'pointerup', end, config)
}
return {
...toRefs(position),
position,
isDragging: computed(() => !!pressedDelta.value),
style: computed(
() => `left:${position.value.x}px;top:${position.value.y}px;`,
),
}
}
-
JSDoc:
-
Parameters:
target: MaybeRefOrGetter<HTMLElement | SVGElement | null | undefined>options: UseDraggableOptions- Return Type:
any - Calls:
deepRef (from vue)toValue (from vue)pointerTypes.includese.preventDefaulte.stopPropagationtoValue(buttons).includesfilterEventcontainer?.getBoundingClientRecttoValue(target)!.getBoundingClientRectonStarthandleEventMath.minMath.maxonMoveonEnduseEventListener (from ../useEventListener)toRefs (from @vueuse/shared)computed (from vue)
filterEvent(e: PointerEvent): boolean¶
Code
- Parameters:
e: PointerEvent- Return Type:
boolean - Calls:
pointerTypes.includes
handleEvent(e: PointerEvent): void¶
Code
- Parameters:
e: PointerEvent- Return Type:
void - Calls:
toValue (from vue)e.preventDefaulte.stopPropagation
start(e: PointerEvent): void¶
Code
(e: PointerEvent) => {
if (!toValue(buttons).includes(e.button))
return
if (toValue(options.disabled) || !filterEvent(e))
return
if (toValue(exact) && e.target !== toValue(target))
return
const container = toValue(containerElement)
const containerRect = container?.getBoundingClientRect?.()
const targetRect = toValue(target)!.getBoundingClientRect()
const pos = {
x: e.clientX - (container ? targetRect.left - containerRect!.left + container.scrollLeft : targetRect.left),
y: e.clientY - (container ? targetRect.top - containerRect!.top + container.scrollTop : targetRect.top),
}
if (onStart?.(pos, e) === false)
return
pressedDelta.value = pos
handleEvent(e)
}
- Parameters:
e: PointerEvent- Return Type:
void - Calls:
toValue(buttons).includestoValue (from vue)filterEventcontainer?.getBoundingClientRecttoValue(target)!.getBoundingClientRectonStarthandleEvent
move(e: PointerEvent): void¶
Code
(e: PointerEvent) => {
if (toValue(options.disabled) || !filterEvent(e))
return
if (!pressedDelta.value)
return
const container = toValue(containerElement)
const targetRect = toValue(target)!.getBoundingClientRect()
let { x, y } = position.value
if (axis === 'x' || axis === 'both') {
x = e.clientX - pressedDelta.value.x
if (container)
x = Math.min(Math.max(0, x), container.scrollWidth - targetRect!.width)
}
if (axis === 'y' || axis === 'both') {
y = e.clientY - pressedDelta.value.y
if (container)
y = Math.min(Math.max(0, y), container.scrollHeight - targetRect!.height)
}
position.value = {
x,
y,
}
onMove?.(position.value, e)
handleEvent(e)
}
- Parameters:
e: PointerEvent- Return Type:
void - Calls:
toValue (from vue)filterEventtoValue(target)!.getBoundingClientRectMath.minMath.maxonMovehandleEvent
end(e: PointerEvent): void¶
Code
- Parameters:
e: PointerEvent- Return Type:
void - Calls:
toValue (from vue)filterEventonEndhandleEvent
config(): { capture: boolean; passive: boolean; }¶
- Return Type:
{ capture: boolean; passive: boolean; }
Interfaces¶
UseDraggableOptions¶
Interface Code
export interface UseDraggableOptions {
/**
* Only start the dragging when click on the element directly
*
* @default false
*/
exact?: MaybeRefOrGetter<boolean>
/**
* Prevent events defaults
*
* @default false
*/
preventDefault?: MaybeRefOrGetter<boolean>
/**
* Prevent events propagation
*
* @default false
*/
stopPropagation?: MaybeRefOrGetter<boolean>
/**
* Whether dispatch events in capturing phase
*
* @default true
*/
capture?: boolean
/**
* Element to attach `pointermove` and `pointerup` events to.
*
* @default window
*/
draggingElement?: MaybeRefOrGetter<HTMLElement | SVGElement | Window | Document | null | undefined>
/**
* Element for calculating bounds (If not set, it will use the event's target).
*
* @default undefined
*/
containerElement?: MaybeRefOrGetter<HTMLElement | SVGElement | null | undefined>
/**
* Handle that triggers the drag event
*
* @default target
*/
handle?: MaybeRefOrGetter<HTMLElement | SVGElement | null | undefined>
/**
* Pointer types that listen to.
*
* @default ['mouse', 'touch', 'pen']
*/
pointerTypes?: PointerType[]
/**
* Initial position of the element.
*
* @default { x: 0, y: 0 }
*/
initialValue?: MaybeRefOrGetter<Position>
/**
* Callback when the dragging starts. Return `false` to prevent dragging.
*/
onStart?: (position: Position, event: PointerEvent) => void | false
/**
* Callback during dragging.
*/
onMove?: (position: Position, event: PointerEvent) => void
/**
* Callback when dragging end.
*/
onEnd?: (position: Position, event: PointerEvent) => void
/**
* Axis to drag on.
*
* @default 'both'
*/
axis?: 'x' | 'y' | 'both'
/**
* Disabled drag and drop.
*
* @default false
*/
disabled?: MaybeRefOrGetter<boolean>
/**
* Mouse buttons that are allowed to trigger drag events.
*
* - `0`: Main button, usually the left button or the un-initialized state
* - `1`: Auxiliary button, usually the wheel button or the middle button (if present)
* - `2`: Secondary button, usually the right button
* - `3`: Fourth button, typically the Browser Back button
* - `4`: Fifth button, typically the Browser Forward button
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button#value
* @default [0]
*/
buttons?: MaybeRefOrGetter<number[]>
}
Properties¶
| Name | Type | Optional | Description |
|---|---|---|---|
exact |
MaybeRefOrGetter<boolean> |
✓ | |
preventDefault |
MaybeRefOrGetter<boolean> |
✓ | |
stopPropagation |
MaybeRefOrGetter<boolean> |
✓ | |
capture |
boolean |
✓ | |
draggingElement |
MaybeRefOrGetter<HTMLElement | SVGElement | Window | Document | null | undefined> |
✓ | |
containerElement |
MaybeRefOrGetter<HTMLElement | SVGElement | null | undefined> |
✓ | |
handle |
MaybeRefOrGetter<HTMLElement | SVGElement | null | undefined> |
✓ | |
pointerTypes |
PointerType[] |
✓ | |
initialValue |
MaybeRefOrGetter<Position> |
✓ | |
onStart |
(position: Position, event: PointerEvent) => void | false |
✓ | |
onMove |
(position: Position, event: PointerEvent) => void |
✓ | |
onEnd |
(position: Position, event: PointerEvent) => void |
✓ | |
axis |
'x' | 'y' | 'both' |
✓ | |
disabled |
MaybeRefOrGetter<boolean> |
✓ | |
buttons |
MaybeRefOrGetter<number[]> |
✓ |