UNPKG

reka-ui

Version:

Vue port for Radix UI Primitives.

97 lines (76 loc) 3.19 kB
import type { MaybeComputedElementRef } from '@vueuse/core' import type { Ref } from 'vue' import { NumberFormatter, NumberParser } from '@internationalized/number' import { unrefElement, useEventListener } from '@vueuse/core' import { createEventHook, isClient, reactiveComputed } from '@vueuse/shared' import { computed, ref } from 'vue' 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(() => { onIncrementPressStart(60) }, delay) } const handlePressStart = () => { onIncrementPressStart(400) } const handlePressEnd = () => { resetTimeout() } // Handle press event, modified version of useMousePressed const isPressed = ref(false) const target = computed(() => unrefElement(options.target)) 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() } if (isClient) { useEventListener(target || window, 'pointerdown', onPressStart) useEventListener(window, 'pointerup', onPressRelease) useEventListener(window, 'pointercancel', onPressRelease) } return { isPressed, onTrigger: triggerHook.on, } } export function useNumberFormatter(locale: Ref<string>, options: Ref<Intl.NumberFormatOptions | undefined> = ref({})) { return reactiveComputed(() => new NumberFormatter(locale.value, options.value)) } export function useNumberParser(locale: Ref<string>, options: Ref<Intl.NumberFormatOptions | undefined> = ref({})) { return reactiveComputed(() => new NumberParser(locale.value, options.value)) } export function handleDecimalOperation(operator: '-' | '+', value1: number, value2: number): number { let result = operator === '+' ? value1 + value2 : value1 - value2 // Check if we have decimals if (value1 % 1 !== 0 || value2 % 1 !== 0) { const value1Decimal = value1.toString().split('.') const value2Decimal = value2.toString().split('.') const value1DecimalLength = (value1Decimal[1] && value1Decimal[1].length) || 0 const value2DecimalLength = (value2Decimal[1] && value2Decimal[1].length) || 0 const multiplier = 10 ** Math.max(value1DecimalLength, value2DecimalLength) // Transform the decimals to integers based on the precision value1 = Math.round(value1 * multiplier) value2 = Math.round(value2 * multiplier) // Perform the operation on integers values to make sure we don't get a fancy decimal value result = operator === '+' ? value1 + value2 : value1 - value2 // Transform the integer result back to decimal result /= multiplier } return result }