{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { UIProps } from \"@yamada-ui/core\"\nimport type { HTMLAttributes, KeyboardEvent, MouseEvent, Ref } from \"react\"\nimport { useEventListeners } from \"@yamada-ui/use-event-listener\"\nimport { dataAttr, isTouchDevice, mergeRefs } from \"@yamada-ui/utils\"\nimport { useCallback, useState } from \"react\"\n\ntype Props<Y extends HTMLElement = HTMLElement> = Omit<\n  HTMLAttributes<Y>,\n  \"ref\" | \"size\" | keyof UIProps\n>\n\nexport type UseClickableProps<\n  Y extends HTMLElement = HTMLElement,\n  M extends Props<Y> = Props<Y>,\n> = {\n  /**\n   * The ref for the element.\n   */\n  ref?: Ref<Y>\n  /**\n   * Whether or not trigger click on pressing `Enter`.\n   *\n   * @default true\n   */\n  clickOnEnter?: boolean\n  /**\n   * Whether or not trigger click on pressing `Space`.\n   *\n   * @default true\n   */\n  clickOnSpace?: boolean\n  /**\n   * If `true`, the element will be disabled. It will set the `disabled` HTML attribute.\n   *\n   * @default false\n   */\n  disabled?: boolean\n  /**\n   * Disable the touch device behavior.\n   *\n   * @default true\n   */\n  disableTouchBehavior?: boolean\n  /**\n   * If `true` and isDisabled, the element will have only `aria-disabled` set to `true`.\n   *\n   * @default false\n   */\n  focusable?: boolean\n  /**\n   * Whether or not to focus the element when it is clicked.\n   * If `true`, the element will receive focus upon click.\n   *\n   * @default true\n   */\n  focusOnClick?: boolean\n  /**\n   * If `true`, the element will be disabled. It will set the `disabled` HTML attribute.\n   *\n   * @default false\n   *\n   * @deprecated Use `disabled` instead.\n   */\n  isDisabled?: boolean\n  /**\n   * If `true` and isDisabled, the element will have only `aria-disabled` set to `true`.\n   *\n   * @default false\n   *\n   * @deprecated Use `focusable` instead.\n   */\n  isFocusable?: boolean\n} & M\n\nconst isValidElement = (\n  ev: KeyboardEvent | KeyboardEvent[\"nativeEvent\"],\n): boolean => {\n  const { isContentEditable, tagName } = ev.target as HTMLElement\n\n  return tagName !== \"INPUT\" && tagName !== \"TEXTAREA\" && !isContentEditable\n}\n\nexport const useClickable = <\n  Y extends HTMLElement = HTMLElement,\n  M extends Props<Y> = Props<Y>,\n>(\n  {\n    ref,\n    clickOnEnter = true,\n    clickOnSpace = true,\n    isDisabled,\n    disabled = isDisabled,\n    disableTouchBehavior = true,\n    isFocusable,\n    focusable = isFocusable,\n    focusOnClick = true,\n    tabIndex: _tabIndex,\n    onClick,\n    onKeyDown,\n    onKeyUp,\n    onMouseDown,\n    onMouseLeave,\n    onMouseOver,\n    onMouseUp,\n    ...props\n  }: UseClickableProps<Y, M> = {} as UseClickableProps<Y, M>,\n) => {\n  const [button, setButton] = useState<boolean>(true)\n  const [pressed, setPressed] = useState<boolean>(false)\n\n  const listeners = useEventListeners()\n\n  const tabIndex = button ? _tabIndex : _tabIndex || 0\n  const trulyDisabled = disabled && !focusable\n\n  const refCb = (node: any) => {\n    if (!node) return\n\n    if (node.tagName !== \"BUTTON\") setButton(false)\n  }\n\n  const handleClick = useCallback(\n    (ev: MouseEvent<Y>) => {\n      if (disabled) {\n        ev.stopPropagation()\n        ev.preventDefault()\n\n        return\n      }\n\n      if (focusOnClick) ev.currentTarget.focus()\n      onClick?.(ev)\n    },\n    [disabled, focusOnClick, onClick],\n  )\n\n  const onDocumentKeyUp = useCallback(\n    (ev: KeyboardEvent<Y>) => {\n      if (pressed && isValidElement(ev)) {\n        ev.preventDefault()\n        ev.stopPropagation()\n\n        setPressed(false)\n\n        listeners.remove(document, \"keyup\", onDocumentKeyUp, false)\n      }\n    },\n    [pressed, listeners],\n  )\n\n  const handleKeyDown = useCallback(\n    (ev: KeyboardEvent<Y>) => {\n      onKeyDown?.(ev)\n\n      if (disabled || ev.defaultPrevented || ev.metaKey) return\n\n      if (!isValidElement(ev.nativeEvent) || button) return\n\n      if (clickOnSpace && ev.key === \" \") {\n        ev.preventDefault()\n        setPressed(true)\n      }\n\n      if (clickOnEnter && ev.key === \"Enter\") {\n        ev.preventDefault()\n        ev.currentTarget.click()\n      }\n\n      listeners.add(document, \"keyup\", onDocumentKeyUp, false)\n    },\n    [\n      disabled,\n      button,\n      onKeyDown,\n      clickOnEnter,\n      clickOnSpace,\n      listeners,\n      onDocumentKeyUp,\n    ],\n  )\n\n  const handleKeyUp = useCallback(\n    (ev: KeyboardEvent<Y>) => {\n      onKeyUp?.(ev)\n\n      if (disabled || ev.defaultPrevented || ev.metaKey) return\n\n      if (!isValidElement(ev.nativeEvent) || button) return\n\n      if (clickOnSpace && ev.key === \" \") {\n        ev.preventDefault()\n        setPressed(false)\n\n        ev.currentTarget.click()\n      }\n    },\n    [clickOnSpace, button, disabled, onKeyUp],\n  )\n\n  const onDocumentMouseUp = useCallback(\n    (ev: MouseEvent<Y>) => {\n      if (ev.button !== 0) return\n\n      setPressed(false)\n\n      listeners.remove(document, \"mouseup\", onDocumentMouseUp, false)\n    },\n    [listeners],\n  )\n\n  const handleMouseDown = useCallback(\n    (ev: MouseEvent<Y>) => {\n      if (ev.button !== 0) return\n\n      if (disabled) {\n        ev.stopPropagation()\n        ev.preventDefault()\n\n        return\n      }\n\n      if (!button) setPressed(true)\n\n      if (focusOnClick) ev.currentTarget.focus({ preventScroll: true })\n\n      listeners.add(document, \"mouseup\", onDocumentMouseUp, false)\n\n      onMouseDown?.(ev)\n    },\n    [disabled, button, focusOnClick, onMouseDown, listeners, onDocumentMouseUp],\n  )\n\n  const handleMouseUp = useCallback(\n    (ev: MouseEvent<Y>) => {\n      if (ev.button !== 0) return\n\n      if (!button) setPressed(false)\n\n      onMouseUp?.(ev)\n    },\n    [onMouseUp, button],\n  )\n\n  const handleMouseOver = useCallback(\n    (ev: MouseEvent<Y>) => {\n      if (disabled) {\n        ev.preventDefault()\n\n        return\n      }\n\n      if (disableTouchBehavior && isTouchDevice()) return\n\n      onMouseOver?.(ev)\n    },\n    [disabled, onMouseOver, disableTouchBehavior],\n  )\n\n  const handleMouseLeave = useCallback(\n    (ev: MouseEvent<Y>) => {\n      if (pressed) {\n        ev.preventDefault()\n\n        setPressed(false)\n      }\n\n      if (disableTouchBehavior && isTouchDevice()) return\n\n      onMouseLeave?.(ev)\n    },\n    [pressed, onMouseLeave, disableTouchBehavior],\n  )\n\n  if (button) {\n    return {\n      ...props,\n      ref: mergeRefs(ref, refCb),\n      type: \"button\",\n      \"aria-disabled\": trulyDisabled ? undefined : disabled,\n      disabled: trulyDisabled,\n      onClick: handleClick,\n      onKeyDown,\n      onKeyUp,\n      onMouseDown,\n      onMouseLeave,\n      onMouseOver,\n      onMouseUp,\n    }\n  } else {\n    return {\n      ...props,\n      ref: mergeRefs(ref, refCb),\n      \"aria-disabled\": disabled ? (\"true\" as const) : undefined,\n      \"data-active\": dataAttr(pressed),\n      role: \"button\",\n      tabIndex: trulyDisabled ? undefined : tabIndex,\n      onClick: handleClick,\n      onKeyDown: handleKeyDown,\n      onKeyUp: handleKeyUp,\n      onMouseDown: handleMouseDown,\n      onMouseLeave: handleMouseLeave,\n      onMouseOver: handleMouseOver,\n      onMouseUp: handleMouseUp,\n    }\n  }\n}\n\nexport type UseClickableReturn = ReturnType<typeof useClickable>\n"],"mappings":"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","names":[]}