UNPKG

@yamada-ui/react

Version:

React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion

168 lines (164 loc) 4.65 kB
"use client"; import { mergeRefs } from "../../utils/ref.js"; import { utils_exports } from "../../utils/index.js"; import { useEventListeners } from "../use-event-listener/index.js"; import { useCallback, useState } from "react"; //#region src/hooks/use-clickable/index.ts const isValidElement$1 = (ev) => { const { isContentEditable, tagName } = ev.target; return tagName !== "INPUT" && tagName !== "TEXTAREA" && !isContentEditable; }; const useClickable = ({ ref, clickOnEnter = true, clickOnSpace = true, disabled, disableTouchBehavior = true, focusable, focusOnClick = true, tabIndex: tabIndexProp, onClick: onClickProp, onKeyDown: onKeyDownProp, onKeyUp: onKeyUpProp, onMouseDown: onMouseDownProp, onMouseLeave: onMouseLeaveProp, onMouseOver: onMouseOverProp, onMouseUp: onMouseUpProp,...props } = {}) => { const [button, setButton] = useState(true); const [pressed, setPressed] = useState(false); const listeners = useEventListeners(); const tabIndex = button ? tabIndexProp : tabIndexProp || 0; const trulyDisabled = disabled && !focusable; const refCb = (node) => { if (!node) return; if (node.tagName !== "BUTTON") setButton(false); }; const onClick = useCallback((ev) => { if (disabled) { ev.stopPropagation(); ev.preventDefault(); return; } if (focusOnClick) ev.currentTarget.focus(); onClickProp?.(ev); }, [ disabled, focusOnClick, onClickProp ]); const onDocumentKeyUp = useCallback((ev) => { if (pressed && isValidElement$1(ev)) { ev.preventDefault(); ev.stopPropagation(); setPressed(false); listeners.remove(document, "keyup", onDocumentKeyUp, false); } }, [pressed, listeners]); const onKeyDown = useCallback((ev) => { onKeyDownProp?.(ev); if (disabled || ev.defaultPrevented || ev.metaKey) return; if (!isValidElement$1(ev.nativeEvent) || button) return; if (clickOnSpace && ev.key === " ") { ev.preventDefault(); setPressed(true); } if (clickOnEnter && ev.key === "Enter") { ev.preventDefault(); ev.currentTarget.click(); } listeners.add(document, "keyup", onDocumentKeyUp, false); }, [ disabled, button, onKeyDownProp, clickOnEnter, clickOnSpace, listeners, onDocumentKeyUp ]); const onKeyUp = useCallback((ev) => { onKeyUpProp?.(ev); if (disabled || ev.defaultPrevented || ev.metaKey) return; if (!isValidElement$1(ev.nativeEvent) || button) return; if (clickOnSpace && ev.key === " ") { ev.preventDefault(); setPressed(false); ev.currentTarget.click(); } }, [ clickOnSpace, button, disabled, onKeyUpProp ]); const onDocumentMouseUp = useCallback((ev) => { if (ev.button !== 0) return; setPressed(false); listeners.remove(document, "mouseup", onDocumentMouseUp, false); }, [listeners]); const onMouseDown = useCallback((ev) => { if (ev.button !== 0) return; if (disabled) { ev.stopPropagation(); ev.preventDefault(); return; } if (!button) setPressed(true); if (focusOnClick) ev.currentTarget.focus({ preventScroll: true }); listeners.add(document, "mouseup", onDocumentMouseUp, false); onMouseDownProp?.(ev); }, [ disabled, button, onMouseDownProp, listeners, onDocumentMouseUp, focusOnClick ]); const onMouseUp = useCallback((ev) => { if (ev.button !== 0) return; if (!button) setPressed(false); onMouseUpProp?.(ev); }, [onMouseUpProp, button]); const onMouseOver = useCallback((ev) => { if (disabled) { ev.preventDefault(); return; } if (disableTouchBehavior && (0, utils_exports.isTouchDevice)()) return; onMouseOverProp?.(ev); }, [ disabled, onMouseOverProp, disableTouchBehavior ]); const onMouseLeave = useCallback((ev) => { if (pressed) { ev.preventDefault(); setPressed(false); } if (disableTouchBehavior && (0, utils_exports.isTouchDevice)()) return; onMouseLeaveProp?.(ev); }, [ pressed, onMouseLeaveProp, disableTouchBehavior ]); if (button) return { ...props, ref: mergeRefs(ref, refCb), type: "button", "aria-disabled": trulyDisabled ? void 0 : disabled, disabled: trulyDisabled, onClick, onKeyDown: onKeyDownProp, onKeyUp: onKeyUpProp, onMouseDown: onMouseDownProp, onMouseLeave: onMouseLeaveProp, onMouseOver: onMouseOverProp, onMouseUp: onMouseUpProp }; else return { ...props, ref: mergeRefs(ref, refCb), "aria-disabled": disabled ? "true" : void 0, "data-active": (0, utils_exports.dataAttr)(pressed), role: "button", tabIndex: trulyDisabled ? void 0 : tabIndex, onClick, onKeyDown, onKeyUp, onMouseDown, onMouseLeave, onMouseOver, onMouseUp }; }; //#endregion export { useClickable }; //# sourceMappingURL=index.js.map