Skip to content

Commit

Permalink
Merge branch 'release/v0.22.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
holtwick committed Aug 7, 2024
2 parents a6b5308 + bbc21f1 commit 53338d4
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 46 deletions.
1 change: 1 addition & 0 deletions lib/basic/_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export interface OuiDraggableEvent {
deltaY: number
moveX: number
moveY: number
timeMS: number
// page: OuiDraggablePosition
// delta: OuiDraggablePosition
// pos: OuiDraggablePosition
Expand Down
48 changes: 48 additions & 0 deletions lib/basic/oui-draggable.demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import type { OuiDraggableEvent } from '@/lib'
import { OuiDemo, OuiDraggable, OuiInputNumber } from '@/lib'
const state = reactive({
x: 100,
y: 100,
})
const data = ref({})
function move(e: OuiDraggableEvent) {
data.value = e
state.x += e.deltaX
state.y += e.deltaY
}
</script>

<template>
<h2>Draggable</h2>

<OuiDraggable
class="app-draggable-box"
:style="{
left: `${state.x}px`,
top: `${state.y}px`,
}"
@move="move"
>
{{ data }}
</OuiDraggable>

<OuiDemo :state="state">
<OuiInputNumber v-model="state.x" title="X" />
<OuiInputNumber v-model="state.y" title="Y" />
</OuiDemo>
</template>

<style>
.app-draggable-box {
background: purple;
color: white;
position: absolute;
width: 200px;
height:200px;
}
</style>
64 changes: 44 additions & 20 deletions lib/basic/oui-draggable.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
<script lang="ts" setup>
import { useEventListener } from '@vueuse/core'
import { timestamp, useEventListener } from '@vueuse/core'
import { ref } from 'vue'
import type { LoggerInterface } from 'zeed'
import { Logger } from 'zeed'
import { Logger, getTimestamp } from 'zeed'
import { isInsideScrollable } from '../mobile/drag-util'
import type { OuiDraggableEvent } from './_types'
const props = defineProps<{
onlyTouch?: boolean
}>()
const emit = defineEmits<{
moveStart: [OuiDraggableEvent]
move: [OuiDraggableEvent]
Expand All @@ -15,6 +20,7 @@ const log: LoggerInterface = Logger('oui-draggable')
const el = ref()
let timeStart = 0
let dragging = false
let collapsed = false
let startX = 0
Expand All @@ -23,16 +29,17 @@ let lastX = 0
let lastY = 0
let deltaX = 0
let deltaY = 0
let lastEvent: OuiDraggableEvent | undefined
function translateMouseEvent(e: MouseEvent): OuiDraggableEvent {
const { pageX, pageY } = e
function translateTouchEvent(e: TouchEvent): OuiDraggableEvent {
const { pageX, pageY } = e?.touches?.[0] ?? e
deltaX = pageX - lastX
deltaY = pageY - lastY
lastX = pageX
lastY = pageY
const moveX = startX - pageX
const moveY = startY - pageY
const info = {
const info: OuiDraggableEvent = {
startX,
startY,
pageX,
Expand All @@ -41,42 +48,51 @@ function translateMouseEvent(e: MouseEvent): OuiDraggableEvent {
deltaY,
moveX,
moveY,
timeMS: getTimestamp() - timeStart,
}
log('event', info)
lastEvent = info
return info
}
function cancelEvent(e: MouseEvent) {
function cancelEvent(e: TouchEvent) {
// log('sep cancel')
e?.stopPropagation()
e?.preventDefault()
}
function onMouseDown(e: MouseEvent) {
function onMouseDown(e: TouchEvent) {
if (e.target && el.value && isInsideScrollable(e.target as any, el.value))
return
log('down')
const { pageX, pageY } = e
const { pageX, pageY } = e?.touches?.[0] ?? e
timeStart = getTimestamp()
dragging = true
startX = pageX
startY = pageY
lastX = pageX
lastY = pageY
emit('moveStart', translateMouseEvent(e))
emit('moveStart', translateTouchEvent(e))
bindEvents()
return cancelEvent(e)
}
function onMouseMove(e: MouseEvent) {
log('move')
function onMouseMove(e: TouchEvent) {
log('move', dragging, e)
if (!dragging)
return
emit('move', translateMouseEvent(e))
emit('move', translateTouchEvent(e))
return cancelEvent(e)
}
function onMouseUp(e: MouseEvent) {
function onMouseUp(e: TouchEvent) {
log('up')
dragging = false
emit('moveEnd', translateMouseEvent(e))
if (lastEvent)
lastEvent.timeMS = getTimestamp() - timeStart
emit('moveEnd', lastEvent ?? translateTouchEvent(e))
lastEvent = undefined
unbindEvents()
return cancelEvent(e)
}
Expand All @@ -87,20 +103,28 @@ function onDblClick() {
const mouseOptions = { passive: false }
useEventListener(el, 'mousedown', onMouseDown)
useEventListener(el, 'touchdown', onMouseDown)
useEventListener(el, 'dblclick', onDblClick)
if (!props.onlyTouch) {
useEventListener(el, 'mousedown', onMouseDown)
useEventListener(el, 'dblclick', onDblClick)
}
useEventListener(el, 'touchstart', onMouseDown)
let docListeners: any[] = []
// https://github.com/antoniandre/splitpanes/blob/master/src/components/splitpanes/splitpanes.vue
function bindEvents() {
docListeners = [
useEventListener(document, 'mousemove', onMouseMove, mouseOptions),
useEventListener(document, 'mouseup', onMouseUp),
useEventListener(document, 'touchmove', onMouseMove, mouseOptions),
useEventListener(document, 'touchend', onMouseUp),
]
if (!props.onlyTouch) {
docListeners.push(
useEventListener(document, 'mousemove', onMouseMove, mouseOptions),
useEventListener(document, 'mouseup', onMouseUp),
)
}
}
function unbindEvents() {
Expand All @@ -110,7 +134,7 @@ function unbindEvents() {
</script>

<template>
<div ref="el">
<div ref="el" data-noscroll="true">
<slot />
</div>
</template>
33 changes: 33 additions & 0 deletions lib/mobile/drag-util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type { LoggerInterface } from 'zeed'
import { Logger } from 'zeed'

const log: LoggerInterface = Logger('drag-util')

export function isInsideScrollable(el?: HTMLElement | null, childOf?: HTMLElement) {
// Figure out, if we are inside an element with custom scrolling

// log('isInsideScrollable', el, childOf, childOf?.contains(el))
while (el != null) {
if (childOf && (!childOf?.contains(el) || childOf.isSameNode(el)))
return false

if (el.dataset.noscroll === 'true') {
log('exit noscroll')
return true
// break
}
if (el.tagName === 'BODY') {
log('exit body')
return true
}
const { overflow } = window.getComputedStyle(el)
if (overflow.split(' ').some(o => o === 'auto' || o === 'scroll')) {
log('exit scroll', el.scrollTop, overflow)
// if (el.scrollTop <= 0)
// return false
return true
}
el = el.parentElement
}
return false
}
23 changes: 4 additions & 19 deletions lib/mobile/oui-mobile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Logger } from 'zeed'
import { useSingleton } from '../basic/singleton'
import './oui-mobile.styl'
import { isInsideScrollable } from './drag-util'
const props = defineProps<{
mode?: 'app' | 'body'
Expand Down Expand Up @@ -70,25 +71,9 @@ if (useSingleton('oui-mobile')) {
// if (virtualKeyboardActive === false)
// return
// Figure out, if we are inside an element with custom scrolling
let el = ev.target as HTMLElement | undefined | null
while (el != null) {
if (el.dataset.noscroll === 'true') {
log('exit noscroll')
break
}
if (el.tagName === 'BODY') {
log('exit body')
return
}
const { overflow } = window.getComputedStyle(el)
if (overflow.split(' ').some(o => o === 'auto' || o === 'scroll')) {
log('exit scroll', overflow)
return
}
el = el.parentElement
}
if (isInsideScrollable(ev.target as any))
return
log('prevent scroll')
// If not avoid scrolling
ev.preventDefault()
Expand Down
35 changes: 29 additions & 6 deletions lib/modal/oui-modal.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<script lang="ts" setup>
import { onKeyStroke, useScrollLock } from '@vueuse/core'
import { onBeforeUnmount, ref, watch } from 'vue'
import { onKeyStroke, useScrollLock, useWindowSize } from '@vueuse/core'
import { nextTick, onBeforeUnmount, ref, watch } from 'vue'
import type { OuiDraggableEvent } from '../basic'
import { OuiClose } from '../basic'
import OuiDraggable from '../basic/oui-draggable.vue'
import { vFocustrap } from './oui-modal.focustrap'
import './oui-modal.styl'
Expand Down Expand Up @@ -49,7 +51,7 @@ let scrollOffset: any
const scrollElement = document.scrollingElement as HTMLElement
function blockScrolling() {
// scrollOffset = window.pageYOffset
// scrollOffset = window.moveYOffset
// if (scrollElement) {
// scrollElement.style.overflow = 'hidden'
Expand Down Expand Up @@ -92,7 +94,6 @@ function didOpen() {
}
function triggerActiveClass(active: boolean = false) {
scrollLock.value = active
if (active)
document.documentElement.classList.add('oui-modal-active')
Expand All @@ -105,6 +106,21 @@ watch(_active, triggerActiveClass, { immediate: true })
onBeforeUnmount(doClose)
const name = 'oui-modal' // computed(() => String(attrs.class || 'oui-modal').split(/\s+/gim)?.[0])
//
const { height } = useWindowSize()
const dragY = ref(0)
async function checkClose(e: OuiDraggableEvent) {
// console.log('checkclose', dragY.value, e.timeMS, height.value / 3, e)
if (dragY.value > (height.value / 3) || (dragY.value > 40 && e.timeMS < 500))
doClose()
await nextTick()
dragY.value = 0
}
</script>

<template>
Expand Down Expand Up @@ -136,7 +152,14 @@ const name = 'oui-modal' // computed(() => String(attrs.class || 'oui-modal').sp
aria-label="Close"
@click="doCancel"
/>
<div v-focustrap class="_modal_container">
<OuiDraggable
v-focustrap
class="_modal_container"
only-touch
:style="{ transform: `translateY(${dragY}px)` }"
@move="e => dragY = -e.moveY"
@move-end="checkClose"
>
<button
v-if="close"
tooltip="Close"
Expand All @@ -161,7 +184,7 @@ const name = 'oui-modal' // computed(() => String(attrs.class || 'oui-modal').sp
<footer v-if="$slots.footer" class="oui-modal-footer footer _modal_footer">
<slot name="footer" />
</footer>
</div>
</OuiDraggable>
</div>
</Transition>
</Teleport>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "oui-kit",
"type": "module",
"version": "0.22.0",
"version": "0.22.1",
"author": {
"email": "dirk.holtwick@gmail.com",
"name": "Dirk Holtwick",
Expand Down

0 comments on commit 53338d4

Please sign in to comment.