Skip to content

Commit

Permalink
feat(useDraggable): Support trigger handle
Browse files Browse the repository at this point in the history
  • Loading branch information
imguolao committed Aug 26, 2022
1 parent df718df commit c0394bb
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/core/useDraggable/component.ts
Expand Up @@ -29,6 +29,7 @@ export const UseDraggable = defineComponent<UseDraggableProps>({
'stopPropagation',
'pointerTypes',
'as',
'handle',
] as unknown as undefined,
setup(props, { slots }) {
const target = ref()
Expand Down
21 changes: 21 additions & 0 deletions packages/core/useDraggable/demo.vue
Expand Up @@ -53,5 +53,26 @@ const { x, y, style } = useDraggable(el, {
{{ Math.round(x) }}, {{ Math.round(y) }}
</div>
</Draggable>

<Draggable
v-slot="{ x, y }"
p="x-4 y-2"
border="~ gray-400/30 rounded"
shadow="~ hover:lg"
class="fixed bg-$vp-c-bg select-none z-10"
:initial-value="{ x: innerWidth / 3.9, y: 240 }"
:prevent-default="true"
handle=".handle"
>
<div class="handle cursor-move">
👋 Drag here!
</div>
<div class="text-xs opacity-50">
Handle that triggers the drag event
</div>
<div class="text-sm opacity-50">
I am at {{ Math.round(x) }}, {{ Math.round(y) }}
</div>
</Draggable>
</div>
</template>
20 changes: 18 additions & 2 deletions packages/core/useDraggable/index.ts
@@ -1,6 +1,6 @@
import { computed, ref } from 'vue-demi'
import type { MaybeComputedRef } from '@vueuse/shared'
import { isClient, resolveUnref, toRefs } from '@vueuse/shared'
import { isClient, isString, resolveUnref, toRefs, tryOnMounted } from '@vueuse/shared'
import { useEventListener } from '../useEventListener'
import type { PointerType, Position } from '../types'
import { defaultWindow } from '../_configurable'
Expand Down Expand Up @@ -34,6 +34,11 @@ export interface UseDraggableOptions {
*/
draggingElement?: MaybeComputedRef<HTMLElement | SVGElement | Window | Document | null | undefined>

/**
* Handle that triggers the drag event
*/
handle?: MaybeComputedRef<HTMLElement | SVGElement | string | null | undefined>

/**
* Pointer types that listen to.
*
Expand Down Expand Up @@ -64,6 +69,16 @@ export interface UseDraggableOptions {
onEnd?: (position: Position, event: PointerEvent) => void
}

function normalizeHandle(handle: UseDraggableOptions['handle']) {
const unrefHandle = resolveUnref(handle)
if (isString(unrefHandle)) {
const newHandle = ref<HTMLElement | SVGAElement | null>(null)
tryOnMounted(() => newHandle.value = document.querySelector<HTMLElement | SVGAElement>(unrefHandle))
return newHandle
}
return handle as MaybeComputedRef<HTMLElement | SVGElement | null | undefined>
}

/**
* Make elements draggable.
*
Expand All @@ -73,6 +88,7 @@ export interface UseDraggableOptions {
*/
export function useDraggable(target: MaybeComputedRef<HTMLElement | SVGElement | null | undefined>, options: UseDraggableOptions = {}) {
const draggingElement = options.draggingElement ?? defaultWindow
const draggingHandle = normalizeHandle(options.handle) ?? target
const position = ref<Position>(resolveUnref(options.initialValue) ?? { x: 0, y: 0 })
const pressedDelta = ref<Position>()

Expand Down Expand Up @@ -127,7 +143,7 @@ export function useDraggable(target: MaybeComputedRef<HTMLElement | SVGElement |
}

if (isClient) {
useEventListener(target, 'pointerdown', start, true)
useEventListener(draggingHandle, 'pointerdown', start, true)
useEventListener(draggingElement, 'pointermove', move, true)
useEventListener(draggingElement, 'pointerup', end, true)
}
Expand Down

0 comments on commit c0394bb

Please sign in to comment.