HoverState.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @flow strict-local
  8. * @format
  9. */
  10. 'use strict';
  11. import Platform from '../Utilities/Platform';
  12. let isEnabled = false;
  13. if (Platform.OS === 'web') {
  14. const canUseDOM = Boolean(
  15. typeof window !== 'undefined' &&
  16. window.document &&
  17. window.document.createElement,
  18. );
  19. if (canUseDOM) {
  20. /**
  21. * Web browsers emulate mouse events (and hover states) after touch events.
  22. * This code infers when the currently-in-use modality supports hover
  23. * (including for multi-modality devices) and considers "hover" to be enabled
  24. * if a mouse movement occurs more than 1 second after the last touch event.
  25. * This threshold is long enough to account for longer delays between the
  26. * browser firing touch and mouse events on low-powered devices.
  27. */
  28. const HOVER_THRESHOLD_MS = 1000;
  29. let lastTouchTimestamp = 0;
  30. const enableHover = () => {
  31. if (isEnabled || Date.now() - lastTouchTimestamp < HOVER_THRESHOLD_MS) {
  32. return;
  33. }
  34. isEnabled = true;
  35. };
  36. const disableHover = () => {
  37. lastTouchTimestamp = Date.now();
  38. if (isEnabled) {
  39. isEnabled = false;
  40. }
  41. };
  42. document.addEventListener('touchstart', disableHover, true);
  43. document.addEventListener('touchmove', disableHover, true);
  44. document.addEventListener('mousemove', enableHover, true);
  45. }
  46. }
  47. export function isHoverEnabled(): boolean {
  48. return isEnabled;
  49. }