UNPKG

@yamada-ui/use-clickable

Version:

Yamada UI useClickable custom hook

214 lines (213 loc) • 6.5 kB
"use client" "use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { useClickable: () => useClickable }); module.exports = __toCommonJS(index_exports); var import_use_event_listener = require("@yamada-ui/use-event-listener"); var import_utils = require("@yamada-ui/utils"); var import_react = require("react"); var isValidElement = (ev) => { const { isContentEditable, tagName } = ev.target; return tagName !== "INPUT" && tagName !== "TEXTAREA" && !isContentEditable; }; var useClickable = ({ ref, clickOnEnter = true, clickOnSpace = true, isDisabled, disabled = isDisabled, disableTouchBehavior = true, isFocusable, focusable = isFocusable, focusOnClick = true, tabIndex: _tabIndex, onClick, onKeyDown, onKeyUp, onMouseDown, onMouseLeave, onMouseOver, onMouseUp, ...props } = {}) => { const [button, setButton] = (0, import_react.useState)(true); const [pressed, setPressed] = (0, import_react.useState)(false); const listeners = (0, import_use_event_listener.useEventListeners)(); const tabIndex = button ? _tabIndex : _tabIndex || 0; const trulyDisabled = disabled && !focusable; const refCb = (node) => { if (!node) return; if (node.tagName !== "BUTTON") setButton(false); }; const handleClick = (0, import_react.useCallback)( (ev) => { if (disabled) { ev.stopPropagation(); ev.preventDefault(); return; } if (focusOnClick) ev.currentTarget.focus(); onClick == null ? void 0 : onClick(ev); }, [disabled, focusOnClick, onClick] ); const onDocumentKeyUp = (0, import_react.useCallback)( (ev) => { if (pressed && isValidElement(ev)) { ev.preventDefault(); ev.stopPropagation(); setPressed(false); listeners.remove(document, "keyup", onDocumentKeyUp, false); } }, [pressed, listeners] ); const handleKeyDown = (0, import_react.useCallback)( (ev) => { onKeyDown == null ? void 0 : onKeyDown(ev); if (disabled || ev.defaultPrevented || ev.metaKey) return; if (!isValidElement(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, onKeyDown, clickOnEnter, clickOnSpace, listeners, onDocumentKeyUp ] ); const handleKeyUp = (0, import_react.useCallback)( (ev) => { onKeyUp == null ? void 0 : onKeyUp(ev); if (disabled || ev.defaultPrevented || ev.metaKey) return; if (!isValidElement(ev.nativeEvent) || button) return; if (clickOnSpace && ev.key === " ") { ev.preventDefault(); setPressed(false); ev.currentTarget.click(); } }, [clickOnSpace, button, disabled, onKeyUp] ); const onDocumentMouseUp = (0, import_react.useCallback)( (ev) => { if (ev.button !== 0) return; setPressed(false); listeners.remove(document, "mouseup", onDocumentMouseUp, false); }, [listeners] ); const handleMouseDown = (0, import_react.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); onMouseDown == null ? void 0 : onMouseDown(ev); }, [disabled, button, focusOnClick, onMouseDown, listeners, onDocumentMouseUp] ); const handleMouseUp = (0, import_react.useCallback)( (ev) => { if (ev.button !== 0) return; if (!button) setPressed(false); onMouseUp == null ? void 0 : onMouseUp(ev); }, [onMouseUp, button] ); const handleMouseOver = (0, import_react.useCallback)( (ev) => { if (disabled) { ev.preventDefault(); return; } if (disableTouchBehavior && (0, import_utils.isTouchDevice)()) return; onMouseOver == null ? void 0 : onMouseOver(ev); }, [disabled, onMouseOver, disableTouchBehavior] ); const handleMouseLeave = (0, import_react.useCallback)( (ev) => { if (pressed) { ev.preventDefault(); setPressed(false); } if (disableTouchBehavior && (0, import_utils.isTouchDevice)()) return; onMouseLeave == null ? void 0 : onMouseLeave(ev); }, [pressed, onMouseLeave, disableTouchBehavior] ); if (button) { return { ...props, ref: (0, import_utils.mergeRefs)(ref, refCb), type: "button", "aria-disabled": trulyDisabled ? void 0 : disabled, disabled: trulyDisabled, onClick: handleClick, onKeyDown, onKeyUp, onMouseDown, onMouseLeave, onMouseOver, onMouseUp }; } else { return { ...props, ref: (0, import_utils.mergeRefs)(ref, refCb), "aria-disabled": disabled ? "true" : void 0, "data-active": (0, import_utils.dataAttr)(pressed), role: "button", tabIndex: trulyDisabled ? void 0 : tabIndex, onClick: handleClick, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, onMouseDown: handleMouseDown, onMouseLeave: handleMouseLeave, onMouseOver: handleMouseOver, onMouseUp: handleMouseUp }; } }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { useClickable }); //# sourceMappingURL=index.js.map