All Downloads are FREE. Search and download functionalities are using the official Maven repository.

japgolly.scalajs.react.events.scala Maven / Gradle / Ivy

package japgolly.scalajs.react

import japgolly.scalajs.react.util.Effect.Sync
import japgolly.scalajs.react.util.{DefaultEffects => D}
import org.scalajs.dom
import org.scalajs.dom.html

trait ReactEventTypes {

  final type            ReactEventFrom[+N <: dom.Node] = facade.            SyntheticEvent[N]
  final type   ReactAnimationEventFrom[+N <: dom.Node] = facade.   SyntheticAnimationEvent[N]
  final type   ReactClipboardEventFrom[+N <: dom.Node] = facade.   SyntheticClipboardEvent[N]
  final type ReactCompositionEventFrom[+N <: dom.Node] = facade. SyntheticCompositionEvent[N]
  final type        ReactDragEventFrom[+N <: dom.Node] = facade.        SyntheticDragEvent[N]
  final type       ReactFocusEventFrom[+N <: dom.Node] = facade.       SyntheticFocusEvent[N]
  final type        ReactFormEventFrom[+N <: dom.Node] = facade.        SyntheticFormEvent[N]
  final type    ReactKeyboardEventFrom[+N <: dom.Node] = facade.    SyntheticKeyboardEvent[N]
  final type       ReactMouseEventFrom[+N <: dom.Node] = facade.       SyntheticMouseEvent[N]
  final type     ReactPointerEventFrom[+N <: dom.Node] = facade.     SyntheticPointerEvent[N]
  final type       ReactTouchEventFrom[+N <: dom.Node] = facade.       SyntheticTouchEvent[N]
  final type  ReactTransitionEventFrom[+N <: dom.Node] = facade.  SyntheticTransitionEvent[N]
  final type          ReactUIEventFrom[+N <: dom.Node] = facade.          SyntheticUIEvent[N]
  final type       ReactWheelEventFrom[+N <: dom.Node] = facade.       SyntheticWheelEvent[N]

  final type            ReactEvent =            ReactEventFrom[dom.Node]
  final type   ReactAnimationEvent =   ReactAnimationEventFrom[dom.Node]
  final type   ReactClipboardEvent =   ReactClipboardEventFrom[dom.Node]
  final type ReactCompositionEvent = ReactCompositionEventFrom[dom.Node]
  final type        ReactDragEvent =        ReactDragEventFrom[dom.Node]
  final type       ReactFocusEvent =       ReactFocusEventFrom[dom.Node]
  final type        ReactFormEvent =        ReactFormEventFrom[dom.Node]
  final type    ReactKeyboardEvent =    ReactKeyboardEventFrom[dom.Node]
  final type       ReactMouseEvent =       ReactMouseEventFrom[dom.Node]
  final type     ReactPointerEvent =     ReactPointerEventFrom[dom.Node]
  final type       ReactTouchEvent =       ReactTouchEventFrom[dom.Node]
  final type  ReactTransitionEvent =  ReactTransitionEventFrom[dom.Node]
  final type          ReactUIEvent =          ReactUIEventFrom[dom.Node]
  final type       ReactWheelEvent =       ReactWheelEventFrom[dom.Node]

  final type            ReactEventFromHtml =            ReactEventFrom[html.Element]
  final type   ReactAnimationEventFromHtml =   ReactAnimationEventFrom[html.Element]
  final type   ReactClipboardEventFromHtml =   ReactClipboardEventFrom[html.Element]
  final type ReactCompositionEventFromHtml = ReactCompositionEventFrom[html.Element]
  final type        ReactDragEventFromHtml =        ReactDragEventFrom[html.Element]
  final type       ReactFocusEventFromHtml =       ReactFocusEventFrom[html.Element]
  final type        ReactFormEventFromHtml =        ReactFormEventFrom[html.Element]
  final type    ReactKeyboardEventFromHtml =    ReactKeyboardEventFrom[html.Element]
  final type       ReactMouseEventFromHtml =       ReactMouseEventFrom[html.Element]
  final type     ReactPointerEventFromHtml =     ReactPointerEventFrom[html.Element]
  final type       ReactTouchEventFromHtml =       ReactTouchEventFrom[html.Element]
  final type  ReactTransitionEventFromHtml =  ReactTransitionEventFrom[html.Element]
  final type          ReactUIEventFromHtml =          ReactUIEventFrom[html.Element]
  final type       ReactWheelEventFromHtml =       ReactWheelEventFrom[html.Element]

  final type            ReactEventFromInput =            ReactEventFrom[html.Input]
  final type   ReactAnimationEventFromInput =   ReactAnimationEventFrom[html.Input]
  final type   ReactClipboardEventFromInput =   ReactClipboardEventFrom[html.Input]
  final type ReactCompositionEventFromInput = ReactCompositionEventFrom[html.Input]
  final type        ReactDragEventFromInput =        ReactDragEventFrom[html.Input]
  final type       ReactFocusEventFromInput =       ReactFocusEventFrom[html.Input]
  final type        ReactFormEventFromInput =        ReactFormEventFrom[html.Input]
  final type    ReactKeyboardEventFromInput =    ReactKeyboardEventFrom[html.Input]
  final type       ReactMouseEventFromInput =       ReactMouseEventFrom[html.Input]
  final type     ReactPointerEventFromInput =     ReactPointerEventFrom[html.Input]
  final type       ReactTouchEventFromInput =       ReactTouchEventFrom[html.Input]
  final type  ReactTransitionEventFromInput =  ReactTransitionEventFrom[html.Input]
  final type          ReactUIEventFromInput =          ReactUIEventFrom[html.Input]
  final type       ReactWheelEventFromInput =       ReactWheelEventFrom[html.Input]

  final type            ReactEventFromTextArea =            ReactEventFrom[html.TextArea]
  final type   ReactAnimationEventFromTextArea =   ReactAnimationEventFrom[html.TextArea]
  final type   ReactClipboardEventFromTextArea =   ReactClipboardEventFrom[html.TextArea]
  final type ReactCompositionEventFromTextArea = ReactCompositionEventFrom[html.TextArea]
  final type        ReactDragEventFromTextArea =        ReactDragEventFrom[html.TextArea]
  final type       ReactFocusEventFromTextArea =       ReactFocusEventFrom[html.TextArea]
  final type        ReactFormEventFromTextArea =        ReactFormEventFrom[html.TextArea]
  final type    ReactKeyboardEventFromTextArea =    ReactKeyboardEventFrom[html.TextArea]
  final type       ReactMouseEventFromTextArea =       ReactMouseEventFrom[html.TextArea]
  final type     ReactPointerEventFromTextArea =     ReactPointerEventFrom[html.TextArea]
  final type       ReactTouchEventFromTextArea =       ReactTouchEventFrom[html.TextArea]
  final type  ReactTransitionEventFromTextArea =  ReactTransitionEventFrom[html.TextArea]
  final type          ReactUIEventFromTextArea =          ReactUIEventFrom[html.TextArea]
  final type       ReactWheelEventFromTextArea =       ReactWheelEventFrom[html.TextArea]

  @inline final implicit def toReactExt_DomEvent(e: dom.Event): ReactExt_DomEvent[D.Sync] =
    new ReactExt_DomEvent(e)(D.Sync)

  @inline final implicit def toReactExt_ReactEvent[E <: ReactEvent](e: E): ReactExt_ReactEvent[D.Sync, E] =
    new ReactExt_ReactEvent(e)(D.Sync)

  @inline final implicit def toReactExt_ReactKeyboardEvent[N <: dom.Node](e: ReactKeyboardEventFrom[N]): ReactExt_ReactKeyboardEvent[N] =
    new ReactExt_ReactKeyboardEvent(e)
}

final class ReactExt_DomEvent[F[_]](private val e: dom.Event)(implicit F: Sync[F]) {
  /**
   * Stops the default action of an element from happening.
   * For example: Prevent a submit button from submitting a form Prevent a link from following the URL
   */
  def preventDefaultCB: F[Unit] =
    F.delay(e.preventDefault())

  /**
   * Stops the bubbling of an event to parent elements, preventing any parent event handlers from being executed.
   */
  def stopPropagationCB: F[Unit] =
    F.delay(e.stopPropagation())
}

final class ReactExt_ReactEvent[F[_], E <: facade.SyntheticEvent[dom.Node]](private val e: E)(implicit F: Sync[F]) {
  /**
   * Stops the default action of an element from happening.
   * For example: Prevent a submit button from submitting a form Prevent a link from following the URL
   */
  def preventDefaultCB: F[Unit] =
    F.delay(e.preventDefault())

  /**
   * Stops the bubbling of an event to parent elements, preventing any parent event handlers from being executed.
   */
  def stopPropagationCB: F[Unit] =
    F.delay(e.stopPropagation())

  /**
   * If you want to access the event properties in an asynchronous way (eg. in a `modState(…)` function),
   * React will have recycled the event by the time the asynchronous call executes.
   *
   * This convenience function extracts a value from the event synchronously (i.e. now!) and so that it is
   * available to the asynchronous code.
   */
  @inline def extract[A, B](getNow: E => A)(useAsync: A => B): B = {
    val a = getNow(e)
    useAsync(a)
  }
}

final class ReactExt_ReactKeyboardEvent[N <: dom.Node](private val e: facade.SyntheticKeyboardEvent[N]) extends AnyVal {

  /**
   * Checks the state of all pressed modifier keys.
   *
   * `e.pressedModifierKeys()` returns `true` if no modifier keys are currently pressed.
   *
   * `e.pressedModifierKeys(altKey = true)` returns `true` if alt is the only modifier key currently pressed.
   */
  def pressedModifierKeys(altKey  : Boolean = false,
                          ctrlKey : Boolean = false,
                          metaKey : Boolean = false,
                          shiftKey: Boolean = false): Boolean =
    e.altKey   == altKey   &&
    e.ctrlKey  == ctrlKey  &&
    e.metaKey  == metaKey  &&
    e.shiftKey == shiftKey
}

object ReactMouseEvent {
  /**
   * Would this mouse event (if applied to a link), open it in a new tab?
   */
  def targetsNewTab_?(e: facade.SyntheticMouseEvent[dom.Node]): Boolean = {
    e.metaKey || e.ctrlKey || // Ctrl-click opens new tab
    e.button == 1             // Middle-click opens new tab
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy