Skip to content

[🐞] onDblClick$ doesn't handle double tap #7197

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
patrickkmatias opened this issue Dec 26, 2024 · 5 comments
Open

[🐞] onDblClick$ doesn't handle double tap #7197

patrickkmatias opened this issue Dec 26, 2024 · 5 comments
Labels
STATUS-1: needs triage New issue which needs to be triaged TYPE: bug Something isn't working

Comments

@patrickkmatias
Copy link

Which component is affected?

Qwik Runtime

Describe the bug

onDblClick$ event handler doesn't handle double tap, making it useless on mobile devices.

on the other hand, onClick$ handle clicks and taps.

Reproduction

https://stackblitz.com/edit/github-vk5focuq?file=src%2Froutes%2Findex.tsx

Steps to reproduce

with the reproduction from stackblitz that I gave, open the preview in a new tab, and then:

  1. open dev tools
  2. emulate mobile devices (CTRL + Shift + M)
  3. double tap the button

System Info

System:
    OS: Windows 11 10.0.26100
    CPU: (12) x64 AMD Ryzen 5 5500U with Radeon Graphics
    Memory: 787.27 MB / 7.35 GB
  Binaries:
    Node: 22.12.0 - C:\Program Files\nodejs\node.EXE
    npm: 10.9.0 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Chromium (131.0.2903.99)
  npmPackages:
    @builder.io/qwik: ^1.9.0 => 1.9.0 
    @builder.io/qwik-city: ^1.9.0 => 1.9.0 
    typescript: 5.4.5 => 5.4.5 
    undici: * => 6.19.8 
    vite: ^5.4.11 => 5.4.11

Additional Information

No response

@patrickkmatias patrickkmatias added STATUS-1: needs triage New issue which needs to be triaged TYPE: bug Something isn't working labels Dec 26, 2024
@wmertens
Copy link
Member

None of the events do special handling, they're mapping to the browser events, so normally you would create the qrl separately and assign it to onDblTap$ as well.

Another thing Qwik doesn't do is change onChange to be onInput, like React does.

So I'm thinking this is working as expected?

@patrickkmatias
Copy link
Author

well, I changed it to onDblTap$ as you said and it didn't work... now it doesn't work on double tap neither double click.

@patrickkmatias
Copy link
Author

the test I did is available on the stackblitz reproduction that I've linked

maybe I'm calling it wrong? idk

@patrickkmatias
Copy link
Author

I'd like to document here if someone else find in the same trouble that I could workaround it creating a custom hook useDoubleClick() hook.

import type { QRL } from "@builder.io/qwik";
import { $, useSignal } from "@builder.io/qwik";

/**
 * Custom hook to handle both double-click and single-click events.
 * This is particularly useful for handling double-tap events on mobile devices,
 * which are currently not supported by Qwik's native onDblClick$ handler.
 * @see {@link https://github.com/QwikDev/qwik/issues/7197 GitHub issue tracking onDblClick$ mobile support}
 *
 * @param onDoubleClick - Handler function to be called when a double-click is detected
 * @param onSingleClick - Optional handler function to be called when a single-click is detected
 * @param threshold - Time in milliseconds to wait for a second click (default: 300ms)
 *
 * @returns A QRL function that can be directly used with onClick$
 *
 * @example
 * ```tsx
 * export const MyComponent = component$(() => {
 *   const onClick$ = useDoubleClick(
 *     $(() => console.log('Double clicked!')),
 *     $(() => console.log('Single clicked!'))
 *   );
 *
 *   return <button onClick$={onClick$}>Click me</button>;
 * });
 * ```
 */
export const useDoubleClick = (
  onDoubleClick: QRL<() => void>,
  onSingleClick?: QRL<() => void>,
  threshold = 300
) => {
  const lastClick = useSignal(0);

  return $(() => {
    const currentTime = new Date().getTime();
    const timeDiff = currentTime - lastClick.value;

    if (timeDiff < threshold) {
      onDoubleClick();
      lastClick.value = 0;
    } else {
      lastClick.value = currentTime;

      if (onSingleClick) {
        setTimeout(() => {
          if (lastClick.value === currentTime) {
            onSingleClick();
          }
        }, threshold);
      }
    }
  });
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
STATUS-1: needs triage New issue which needs to be triaged TYPE: bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants