UNPKG

react-dev-inspector

Version:

dev-tool for inspect react components and jump to local IDE for component code.

132 lines (131 loc) 5.42 kB
'use client'; import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime"; import { useState, useEffect, useRef, } from 'react'; import hotkeys from 'hotkeys-js'; import { setupHighlighter, getElementCodeInfo, gotoServerEditor, getElementInspect, } from './utils'; import { useLayoutEffect, useEffectEvent, useMousePosition, } from './hooks'; import { Overlay } from './Overlay'; /** * `v2.0.0` changes: * - make 'Ctrl + Shift + Alt + C' as default shortcut on Windows/Linux * - export `defaultHotkeys` */ export const defaultHotkeys = () => { var _a; return ((_a = navigator.platform) === null || _a === void 0 ? void 0 : _a.startsWith('Mac')) ? ['Ctrl', 'Shift', 'Command', 'C'] : ['Ctrl', 'Shift', 'Alt', 'C']; }; export const Inspector = (props) => { const { keys, onHoverElement, onClickElement, onInspectElement, active: controlledActive, onActiveChange, disableLaunchEditor, disable = (process.env.NODE_ENV !== 'development'), children, } = props; const [isActive, setActive] = useState(controlledActive !== null && controlledActive !== void 0 ? controlledActive : false); // sync state as controlled component useLayoutEffect(() => { if (controlledActive !== undefined) { setActive(controlledActive); } }, [controlledActive]); useEffect(() => { isActive ? startInspect() : stopInspect(); return stopInspect; }, [isActive]); // hotkeys-js params need string const hotkey = keys === null ? null : (keys !== null && keys !== void 0 ? keys : []).join('+'); /** inspector tooltip overlay */ const overlayRef = useRef(); const mouseRef = useMousePosition({ disable }); const activate = useEffectEvent(() => { onActiveChange === null || onActiveChange === void 0 ? void 0 : onActiveChange(true); if (controlledActive === undefined) { setActive(true); } }); const deactivate = useEffectEvent(() => { onActiveChange === null || onActiveChange === void 0 ? void 0 : onActiveChange(false); if (controlledActive === undefined) { setActive(false); } }); const startInspect = useEffectEvent(() => { if (overlayRef.current || disable) return; const overlay = new Overlay(); overlayRef.current = overlay; hotkeys(`esc`, deactivate); const stopCallback = setupHighlighter({ onPointerOver: handleHoverElement, onClick: handleClickElement, }); overlay.setRemoveCallback(stopCallback); // inspect element immediately at mouse point const initPoint = mouseRef.current; const initElement = document.elementFromPoint(initPoint.x, initPoint.y); if (initElement) handleHoverElement(initElement); }); const stopInspect = useEffectEvent(() => { var _a; (_a = overlayRef.current) === null || _a === void 0 ? void 0 : _a.remove(); overlayRef.current = undefined; hotkeys.unbind(`esc`, deactivate); }); const handleHoverElement = useEffectEvent((element) => { var _a; const overlay = overlayRef.current; const codeInfo = getElementCodeInfo(element); const relativePath = codeInfo === null || codeInfo === void 0 ? void 0 : codeInfo.relativePath; const absolutePath = codeInfo === null || codeInfo === void 0 ? void 0 : codeInfo.absolutePath; const { fiber, name, title } = getElementInspect(element); (_a = overlay === null || overlay === void 0 ? void 0 : overlay.inspect) === null || _a === void 0 ? void 0 : _a.call(overlay, [element], title, relativePath !== null && relativePath !== void 0 ? relativePath : absolutePath); onHoverElement === null || onHoverElement === void 0 ? void 0 : onHoverElement({ element, fiber, codeInfo, name, }); }); const handleClickElement = useEffectEvent((element) => { deactivate(); const codeInfo = getElementCodeInfo(element); const { fiber, name } = getElementInspect(element); onClickElement === null || onClickElement === void 0 ? void 0 : onClickElement({ element, fiber, codeInfo, name, }); if (fiber && codeInfo) { onInspectElement === null || onInspectElement === void 0 ? void 0 : onInspectElement({ element, fiber, codeInfo, name: name, }); if (!onInspectElement && !disableLaunchEditor) { gotoServerEditor(codeInfo); } } }); useEffect(() => { const handleHotKeys = () => { overlayRef.current ? deactivate() : activate(); }; const bindKey = (hotkey === null || disable) ? null : (hotkey || defaultHotkeys().join('+')); if (bindKey) { // https://github.com/jaywcjlove/hotkeys hotkeys(bindKey, handleHotKeys); return () => { hotkeys.unbind(bindKey, handleHotKeys); }; } }, [hotkey, disable]); return (_jsx(_Fragment, { children: children !== null && children !== void 0 ? children : null })); };