Skip to content

Commit

Permalink
Add continuous counter update to VaCounter close #2108 (#3247)
Browse files Browse the repository at this point in the history
* Continous update of the counter when keep clicked

* Refactor elements to span multiple lines with one attribute per line

* Refactor: Moved logic to compostables

* chore: eslint fixes

* chore: refactor useLongPress composable

* fix(counter): correctly use useLongPress composable

* fix(counter): add long-press-delay prop

---------

Co-authored-by: Maksim Nedoshev <m0ksem1337@gmail.com>
  • Loading branch information
Skander999 and m0ksem authored Apr 11, 2023
1 parent 9e89b58 commit aacb851
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 15 deletions.
2 changes: 1 addition & 1 deletion packages/ui/build/common-config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { componentVBindFix } from './plugins/component-v-bind-fix';
import { componentVBindFix } from './plugins/component-v-bind-fix'
import { readFileSync, lstatSync, readdirSync } from 'fs'
import vue from '@vitejs/plugin-vue'
import { resolve as resolver } from 'path'
Expand Down
50 changes: 36 additions & 14 deletions packages/ui/src/components/va-counter/VaCounter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
@keydown.left.prevent="decreaseCount"
>
<template v-if="$props.buttons" #prepend="slotScope">
<div class="va-counter__prepend-wrapper"
<div
class="va-counter__prepend-wrapper"
:style="{ marginRight: marginComputed }"
@mousedown.prevent="focus"
>
Expand All @@ -20,7 +21,7 @@
class="va-counter__button-decrease"
:aria-label="tp($props.ariaDecreaseLabel)"
v-bind="decreaseButtonProps"
@click="decreaseCount"
ref="decreaseButtonRef"
/>
</slot>
</div>
Expand All @@ -32,13 +33,17 @@
@mousedown.prevent="focus"
>
<slot name="decreaseAction" v-bind="{ ...slotScope, decreaseCount }">
<va-button v-bind="decreaseIconProps" />
<va-button
v-bind="decreaseIconProps"
ref="decreaseButtonRef"
/>
</slot>
</div>
</template>

<template v-if="$props.buttons" #append="slotScope">
<div class="va-counter__append-wrapper"
<div
class="va-counter__append-wrapper"
:style="{ marginLeft: marginComputed }"
@mousedown.prevent="focus"
>
Expand All @@ -47,7 +52,7 @@
class="va-counter__button-increase"
:aria-label="tp($props.ariaIncreaseLabel)"
v-bind="increaseButtonProps"
@click="increaseCount"
ref="increaseButtonRef"
/>
</slot>
</div>
Expand All @@ -59,18 +64,20 @@
@mousedown.prevent="focus"
>
<slot name="increaseAction" v-bind="{ ...slotScope, increaseCount }">
<va-button v-bind="increaseIconProps" />
<va-button
v-bind="increaseIconProps"
ref="increaseButtonRef"
/>
</slot>
</div>
</template>

<template v-if="$slots.content" #default="slotScope">
<div
ref="input"
tabindex="0"
class="va-counter__content-wrapper"
>
<slot name="content" v-bind="{ ...slotScope, value: Number(valueComputed) }" />
<div ref="input" tabindex="0" class="va-counter__content-wrapper">
<slot
name="content"
v-bind="{ ...slotScope, value: Number(valueComputed) }"
/>
</div>
</template>

Expand All @@ -84,7 +91,7 @@
:value="valueComputed"
@input="setCountInput"
@change="setCountChange"
>
/>
</va-input-wrapper>
</template>

Expand All @@ -97,6 +104,7 @@ import {
InputHTMLAttributes,
PropType,
ComputedRef,
toRef,
} from 'vue'
import omit from 'lodash/omit'
import pick from 'lodash/pick'
Expand All @@ -110,6 +118,8 @@ import {
useStateful, useStatefulProps,
useColors,
useTranslation,
useLongPress,
useTemplateRef,
} from '../../composables'
import useCounterPropsValidation from './hooks/useCounterPropsValidation'
Expand Down Expand Up @@ -159,6 +169,7 @@ export default defineComponent({
rounded: { type: Boolean, default: false },
margins: { type: [String, Number], default: '4px' },
textColor: { type: String, default: undefined },
longPressDelay: { type: Number, default: 500 },
ariaLabel: { type: String, default: '$t:counterValue' },
ariaDecreaseLabel: { type: String, default: '$t:decreaseCounter' },
Expand Down Expand Up @@ -190,7 +201,7 @@ export default defineComponent({
valueComputed.value = Number((target as HTMLInputElement | null)?.value)
}
const setCountChange = ({ target } : Event) => {
const setCountChange = ({ target }: Event) => {
calculateCounterValue(Number((target as HTMLInputElement | null)?.value))
}
Expand Down Expand Up @@ -252,6 +263,16 @@ export default defineComponent({
calculateCounterValue(Number(valueComputed.value) + step.value)
}
useLongPress(useTemplateRef('decreaseButtonRef'), {
onUpdate: decreaseCount,
delay: toRef(props, 'longPressDelay'),
})
useLongPress(useTemplateRef('increaseButtonRef'), {
onUpdate: increaseCount,
delay: toRef(props, 'longPressDelay'),
})
const { getColor } = useColors()
const colorComputed = computed(() => getColor(props.color))
Expand Down Expand Up @@ -453,6 +474,7 @@ export default defineComponent({
-webkit-appearance: none;
margin: 0;
}
// Firefox
&[type=number] {
-moz-appearance: textfield;
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/composables/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export * from './useIntersectionObserver'
export * from './useIsMounted'
export * from './useKeyboardOnlyFocus'
export * from './useLoading'
export * from './useLongPress'
export * from './useMaxSelections'
export * from './useModalLevel'
export * from './useObjectRefs'
Expand Down
36 changes: 36 additions & 0 deletions packages/ui/src/composables/useLongPress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Ref, ShallowRef, unref } from 'vue'
import { useEvent } from './useEvent'
import { MaybeElement, useHTMLElement } from '.'

type MaybeRef<T> = Ref<T> | T

interface LongPressOptions {
onStart: () => void;
onEnd: () => void;
onUpdate: () => void;
delay?: MaybeRef<number>;
interval?: number;
}

export function useLongPress (el: ShallowRef<HTMLElement | undefined>, options: Partial<LongPressOptions>) {
let timeoutId = -1
let intervalId = -1

const handleMouseDown = () => {
options.onStart?.()
timeoutId = setTimeout(() => {
intervalId = setInterval(() => options.onUpdate?.(), options.interval || 100) as any
}, unref(options.delay) || 500) as unknown as number
}

const handleMouseUp = () => {
clearTimeout(timeoutId)
clearInterval(intervalId)
options.onEnd?.()
}

const htmlElement = useHTMLElement(el)

useEvent('mousedown', handleMouseDown, htmlElement)
useEvent('mouseup', handleMouseUp, htmlElement)
}

0 comments on commit aacb851

Please sign in to comment.