长按按钮连续调用功能

问题描述 投票:0回答:1

我有一个显示值的自定义输入组件,它有 2 个用于增加或减少值的图标。但现在我希望能够在用户长按按钮时调用增量或减量函数,以便输入实时增加/减少。就像类型为数字的默认输入字段的工作方式一样。

输入看起来像这样

enter image description here

这是组件

import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'
import { cn } from '@/lib/utils'
import { useLongPress } from '@uidotdev/usehooks'

interface AdjustableQuantityProps extends React.InputHTMLAttributes<HTMLInputElement> {
  label?: string
  inputWrapperStyle?: string
  inputStyle?: string
  value: number | undefined
  valueSuffix?: string
  onChangeHandler: (value: number | undefined) => void
  onIncrementHandler?: (value: number | undefined) => void
  onDecrementHandler?: (value: number | undefined) => void
  min?: number
  max?: number
  hideZeroValue?: boolean
  enableLongPress?: boolean
}

const AdjustableQuantity: React.FC<AdjustableQuantityProps> = ({
  label = '',
  inputWrapperStyle = '',
  inputStyle = '',
  value,
  valueSuffix = '',
  onChangeHandler,
  onIncrementHandler,
  onDecrementHandler,
  min = 1,
  max = 100,
  hideZeroValue = false,
  enableLongPress = false,
  ...rest
}) => {
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const inputValue = e.target.value.replace(/[^0-9]/g, '')
    const numericValue = inputValue === '' ? undefined : Number(inputValue)
    onChangeHandler(numericValue)
  }

  const handleIncrement = () => {
    if (hideZeroValue && value === undefined) {
      onChangeHandler(0)
    } else if (value !== undefined && value < max) {
      onIncrementHandler ? onIncrementHandler(value) : onChangeHandler(value + 1)
    }
  }

  const handleDecrement = () => {
    if (hideZeroValue && value === 0) {
      onChangeHandler(undefined)
    } else if (value !== undefined && value > min) {
      onDecrementHandler ? onDecrementHandler(value) : onChangeHandler(value - 1)
    }
  }

  const longPressIncrement = useLongPress(() => handleIncrement(), {
    onStart: (event) => console.log('Press started'),
    onFinish: (event) => console.log('Press Finished'),
    onCancel: (event) => console.log('Press cancelled'),
    threshold: 500
  })

  // const longPressDecrement = useLongPress(() => handleDecrement(), {
  const longPressDecrement = useLongPress(() => handleDecrement(), {
    onStart: (event) => console.log('Press started'),
    onFinish: (event) => console.log('Press Finished'),
    onCancel: (event) => console.log('Press cancelled'),
    threshold: 500
  })

  return (
    <div className="flex items-center">
      {label && <p className="mr-2 text-14 capitalize">{label}</p>}

      <div
        className={cn(
          'mr-3 flex items-center justify-between rounded-[0.313rem] border border-tenzr-neutral-400 p-2 h-[2.25rem]',
          inputWrapperStyle
        )}
      >
        <input
          type="text"
          onChange={(e) => {
            if (hideZeroValue) {
              handleChange(e)
            } else {
              onChangeHandler(Number(e.target.value))
            }
          }}
          value={hideZeroValue && value === undefined ? '' : value}
          min={0}
          className={`flex w-1/5 items-center justify-center  bg-transparent focus:outline-none ${inputStyle}`}
          {...rest}
        />
        {valueSuffix}
        <div className="flex items-center space-x-2">
          <KeyboardArrowDownIcon
            {...(enableLongPress && longPressDecrement)}
            onClick={handleDecrement}
            className={`${
              (hideZeroValue && value === 0) || (value !== undefined && value > min)
                ? 'cursor-pointer'
                : 'cursor-not-allowed text-gray-300'
            }`}
          />
          <KeyboardArrowUpIcon
            {...(enableLongPress && longPressIncrement)}
            onClick={handleIncrement}
            className={`${
              (value === undefined && hideZeroValue) || (value !== undefined && value < max)
                ? 'cursor-pointer'
                : 'cursor-not-allowed text-gray-300'
            }`}
          />
        </div>
      </div>
    </div>
  )
}

export default AdjustableQuantity

目前该函数调用的是onLongpress,但结果没有继续更新。它只调用一次。

这就是组件的调用方式。

                value={weight}
                onChangeHandler={(value: number | undefined) => setWeight(value)}
                inputWrapperStyle="h-[2.5rem] w-[7.625rem] pl-4"
                inputStyle="!w-full"
                min={0}
                hideZeroValue={true}
                enableLongPress
              />
reactjs typescript long-press
1个回答
0
投票

您可以使用 RxJS 来实现连续按钮长按功能,如下所示。

const mdown = fromEvent(btn, 'mousedown');
const mup= fromEvent(btn, 'mouseup');

const longPress = mdown.pipe(
  mergeMap((e) => {
    return of(e).pipe(
      delay(2000),
      takeUntil(mup),
    );
  }),
);

longPress.subscribe(x => console.log("long press!"))
© www.soinside.com 2019 - 2024. All rights reserved.