UNPKG

json-joy

Version:

Collection of libraries for building collaborative editing apps.

140 lines 7.23 kB
import * as React from 'react'; import { rule } from 'nano-theme'; import useWindowSize from 'react-use/lib/useWindowSize'; import useWindowScroll from 'react-use/lib/useWindowScroll'; import { useDebugCtx } from '../context'; import { Anchor } from '../../../../json-crdt-extensions/peritext/rga/constants'; import { useSyncStore } from '../../../web/react/hooks'; import { CharOverlay } from './CharOverlay'; const blockClass = rule({ pos: 'relative', pe: 'none', us: 'none', w: '0px', h: '100%', va: 'bottom', }); export const RenderCaret = (props) => { const { children } = props; const ctx = useDebugCtx(); const enabled = useSyncStore(ctx.state.enabled); if (!enabled || !ctx.ctx?.dom) return children; return React.createElement(RenderDebugCaret, { ...props }); }; const RenderDebugCaret = (props) => { return (React.createElement("span", { className: blockClass }, props.children, React.createElement(DebugOverlay, { ...props }))); }; const characterOverlayStyles = { position: 'fixed', display: 'inline-block', visibility: 'hidden', backgroundColor: 'rgba(0, 0, 255, 0.1)', outline: '1px dashed blue', }; const eolCharacterOverlayStyles = { ...characterOverlayStyles, outline: '1px dotted blue', }; const eowCharacterOverlayStyles = { ...characterOverlayStyles, backgroundColor: 'rgba(127,127,127,.1)', outline: '0', }; const DebugOverlay = ({ point }) => { useWindowSize(); useWindowScroll(); const { ctx, state } = useDebugCtx(); const showCursorInfo = useSyncStore(state.showCursorInfo); const leftCharRef = React.useRef(null); const rightCharRef = React.useRef(null); const leftLineEndCharRef = React.useRef(null); const rightLineEndCharRef = React.useRef(null); const leftPrevLineEndCharRef = React.useRef(null); const rightPrevLineEndCharRef = React.useRef(null); const leftNextLineEndCharRef = React.useRef(null); const rightNextLineEndCharRef = React.useRef(null); const wordSkipLeftCharRef = React.useRef(null); const wordSkipRightCharRef = React.useRef(null); const prevLineCaretRef = React.useRef(null); const nextLineCaretRef = React.useRef(null); const anchorLeft = point.anchor === Anchor.After; React.useEffect(() => { leftCharRef.current?.(ctx.events.ui?.getPointRect(point, false)); rightCharRef.current?.(ctx.events.ui?.getPointRect(point, true)); const lineInfo = ctx.events.ui?.getLineInfo(point); leftLineEndCharRef.current?.(lineInfo?.[0][1]); rightLineEndCharRef.current?.(lineInfo?.[1][1]); if (lineInfo) { const prevLineInfo = ctx.events.ui?.getNextLineInfo(lineInfo, -1); const nextLineInfo = ctx.events.ui?.getNextLineInfo(lineInfo); leftPrevLineEndCharRef.current?.(prevLineInfo?.[0][1]); rightPrevLineEndCharRef.current?.(prevLineInfo?.[1][1]); leftNextLineEndCharRef.current?.(nextLineInfo?.[0][1]); rightNextLineEndCharRef.current?.(nextLineInfo?.[1][1]); } const wordJumpLeftPoint = ctx.peritext.editor.skip(point, -1, 'word'); if (wordJumpLeftPoint) wordSkipLeftCharRef.current?.(ctx.events.ui?.getPointRect?.(wordJumpLeftPoint, true)); const wordJumpRightPoint = ctx.peritext.editor.skip(point, 1, 'word'); if (wordJumpRightPoint) wordSkipRightCharRef.current?.(ctx.events.ui?.getPointRect?.(wordJumpRightPoint, false)); const pos = ctx.events.ui?.pointX(point); const currLine = ctx.events.ui?.getLineInfo(point); if (pos && currLine) { const targetX = pos[0]; const prevLine = ctx.events.ui?.getNextLineInfo(currLine, -1); const nextLine = ctx.events.ui?.getNextLineInfo(currLine); if (prevLine) { const prevLinePoint = ctx.events.ui?.findPointAtX(targetX, prevLine); if (point.anchor === Anchor.Before) prevLinePoint?.refBefore(); else prevLinePoint?.refAfter(); if (prevLinePoint) { const rect = ctx.events.ui?.api.getCharRect?.(prevLinePoint.id); if (rect) prevLineCaretRef.current?.(rect); } } if (nextLine) { const prevLinePoint = ctx.events.ui?.findPointAtX(targetX, nextLine); if (point.anchor === Anchor.Before) prevLinePoint?.refBefore(); else prevLinePoint?.refAfter(); if (prevLinePoint) { const rect = ctx.events.ui?.api.getCharRect?.(prevLinePoint.id); if (rect) nextLineCaretRef.current?.(rect); } } } }); if (!showCursorInfo) return null; return (React.createElement(React.Fragment, null, React.createElement(CharOverlay, { rectRef: leftCharRef, style: { ...characterOverlayStyles, backgroundColor: anchorLeft ? 'rgba(0,0,255,.2)' : 'rgba(0,0,255,.1)', outlineStyle: anchorLeft ? 'solid' : 'dashed', } }), React.createElement(CharOverlay, { rectRef: rightCharRef, style: { ...characterOverlayStyles, backgroundColor: !anchorLeft ? 'rgba(0,0,255,.2)' : 'rgba(0,0,255,.1)', outlineStyle: !anchorLeft ? 'solid' : 'dashed', } }), React.createElement(CharOverlay, { rectRef: leftLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderLeft: '2px solid blue' } }), React.createElement(CharOverlay, { rectRef: rightLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderRight: '2px solid blue' } }), React.createElement(CharOverlay, { rectRef: leftPrevLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderLeft: '2px solid rgba(127,127,127,.5)' } }), React.createElement(CharOverlay, { rectRef: rightPrevLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderRight: '2px solid rgba(127,127,127,.5)' } }), React.createElement(CharOverlay, { rectRef: leftNextLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderLeft: '2px solid rgba(127,127,127,.5)' } }), React.createElement(CharOverlay, { rectRef: rightNextLineEndCharRef, style: { ...eolCharacterOverlayStyles, borderRight: '2px solid rgba(127,127,127,.5)' } }), React.createElement(CharOverlay, { rectRef: wordSkipLeftCharRef, style: { ...eowCharacterOverlayStyles, borderLeft: '2px dotted rgba(127,127,127,.7)' } }), React.createElement(CharOverlay, { rectRef: wordSkipRightCharRef, style: { ...eowCharacterOverlayStyles, borderRight: '2px dotted rgba(127,127,127,.7)' } }), React.createElement(CharOverlay, { rectRef: prevLineCaretRef, style: { ...eowCharacterOverlayStyles, backgroundColor: 'rgba(127,127,127,.2)' } }), React.createElement(CharOverlay, { rectRef: nextLineCaretRef, style: { ...eowCharacterOverlayStyles, backgroundColor: 'rgba(127,127,127,.2)' } }))); }; //# sourceMappingURL=index.js.map