Skip to content

Commit

Permalink
fix(NumberField): increment reset if value is from min
Browse files Browse the repository at this point in the history
  • Loading branch information
zernonia committed Jun 24, 2024
1 parent 1742575 commit b292ebc
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 35 deletions.
20 changes: 5 additions & 15 deletions packages/radix-vue/src/NumberField/NumberFieldDecrement.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
<script lang="ts">
import type { PrimitiveProps } from '@/Primitive'
import { injectNumberFieldRootContext } from './NumberFieldRoot.vue'
import { useMousePressed } from '@vueuse/core'
import { usePressedHold } from './utils'
import { computed, watch } from 'vue'
import { computed, ref, watch } from 'vue'
export interface NumberFieldDecrementProps extends PrimitiveProps {
disabled?: boolean
Expand All @@ -18,23 +17,14 @@ const props = withDefaults(defineProps<NumberFieldDecrementProps>(), {
})
const rootContext = injectNumberFieldRootContext()
const { primitiveElement, currentElement } = usePrimitiveElement()
const { handlePressStart, handlePressEnd, onTrigger } = usePressedHold()
const isDisabled = computed(() => rootContext.disabled?.value || props.disabled || rootContext.isDecreaseDisabled.value)
const { pressed: isPressed } = useMousePressed({ target: currentElement })
const { primitiveElement, currentElement } = usePrimitiveElement()
const { isPressed, onTrigger } = usePressedHold({ target: currentElement, disabled: isDisabled })
onTrigger(() => {
rootContext.handleDecrease()
})
watch(isPressed, () => {
if (isPressed.value)
handlePressStart()
else
handlePressEnd()
})
const isDisabled = computed(() => rootContext.disabled?.value || props.disabled || rootContext.isDecreaseDisabled.value)
</script>

<template>
Expand All @@ -50,7 +40,7 @@ const isDisabled = computed(() => rootContext.disabled?.value || props.disabled
:disabled="isDisabled ? '' : undefined"
:data-disabled="isDisabled ? '' : undefined"
:data-pressed="isPressed ? 'true' : undefined"
@mousedown.left.prevent
@contextmenu.prevent
>
<slot />
</Primitive>
Expand Down
18 changes: 4 additions & 14 deletions packages/radix-vue/src/NumberField/NumberFieldIncrement.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<script lang="ts">
import type { PrimitiveProps } from '@/Primitive'
import { injectNumberFieldRootContext } from './NumberFieldRoot.vue'
import { useMousePressed } from '@vueuse/core'
import { usePressedHold } from './utils'
import { computed, watch } from 'vue'
Expand All @@ -18,23 +17,14 @@ const props = withDefaults(defineProps<NumberFieldIncrementProps>(), {
})
const rootContext = injectNumberFieldRootContext()
const { primitiveElement, currentElement } = usePrimitiveElement()
const { handlePressStart, handlePressEnd, onTrigger } = usePressedHold()
const isDisabled = computed(() => rootContext.disabled?.value || props.disabled || rootContext.isIncreaseDisabled.value)
const { pressed: isPressed } = useMousePressed({ target: currentElement })
const { primitiveElement, currentElement } = usePrimitiveElement()
const { isPressed, onTrigger } = usePressedHold({ target: currentElement, disabled: isDisabled })
onTrigger(() => {
rootContext.handleIncrease()
})
watch(isPressed, () => {
if (isPressed.value)
handlePressStart()
else
handlePressEnd()
})
const isDisabled = computed(() => rootContext.disabled?.value || props.disabled || rootContext.isIncreaseDisabled.value)
</script>

<template>
Expand All @@ -50,7 +40,7 @@ const isDisabled = computed(() => rootContext.disabled?.value || props.disabled
:disabled="isDisabled ? '' : undefined"
:data-disabled="isDisabled ? '' : undefined"
:data-pressed="isPressed ? 'true' : undefined"
@mousedown.left.prevent
@contextmenu.prevent
>
<slot />
</Primitive>
Expand Down
40 changes: 34 additions & 6 deletions packages/radix-vue/src/NumberField/utils.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import { NumberFormatter, NumberParser } from '@internationalized/number'
import { type MaybeComputedElementRef, unrefElement, useEventListener } from '@vueuse/core'
import { createEventHook, reactiveComputed } from '@vueuse/shared'
import { type Ref, ref } from 'vue'
import { type Ref, computed, ref } from 'vue'

export function usePressedHold() {
export function usePressedHold(options: { target?: MaybeComputedElementRef, disabled: Ref<boolean> }) {
const { disabled } = options
const timeout = ref<number>()
const triggerHook = createEventHook()

const resetTimeout = () => window.clearTimeout(timeout.value)

const onIncrementPressStart = (delay: number) => {
resetTimeout()
if (disabled.value)
return

triggerHook.trigger()

timeout.value = window.setTimeout(() => {
// TODO: add conditional
onIncrementPressStart(60)
}, delay)
}
Expand All @@ -26,9 +29,34 @@ export function usePressedHold() {
resetTimeout()
}

// Handle press event, modified version of useMousePressed
const isPressed = ref(false)
const target = computed(() => unrefElement(options.target) || window)

const onPressStart = (event: PointerEvent) => {
// Only handle left clicks, and ignore events that bubbled through portals.
if (event.button !== 0 || isPressed.value)
return

event.preventDefault()
isPressed.value = true
handlePressStart()
}

const onPressRelease = () => {
isPressed.value = false
handlePressEnd()
}

useEventListener(target, 'pointerdown', onPressStart)

if (window) {
useEventListener(window, 'pointerup', onPressRelease)
useEventListener(window, 'pointercancel', onPressRelease)
}

return {
handlePressStart,
handlePressEnd,
isPressed,
onTrigger: triggerHook.on,
}
}
Expand Down

0 comments on commit b292ebc

Please sign in to comment.