UNPKG

prism-react-editor

Version:

Lightweight, extensible code editor component for React apps

116 lines (115 loc) 3.67 kB
"use client"; import { jsx } from "react/jsx-runtime"; import { useRef, useLayoutEffect, useMemo } from "react"; import { k as createTemplate } from "../local-Cq-4Fajb.js"; import { u as useStableRef } from "../core-Dm5I6BkG.js"; const getIndentGuides = (code, tabSize) => { const lines = code.split("\n"); const l = lines.length; const stack = []; const results = []; for (let prevIndent = 0, emptyPos = -1, i = 0, p = 0; ; i++) { let last = i == l; let line = lines[i]; let pos = last ? 0 : line.search(/\S/); let indent = 0; let j = 0; if (pos < 0) { if (emptyPos < 0) emptyPos = i; } else { for (; j < pos; ) { indent += line[j++] == " " ? tabSize - indent % tabSize : 1; } if (indent) indent = Math.ceil(indent / tabSize); for (j = indent; j < prevIndent; j++) { stack[j][2] = (emptyPos < 0 || j == indent && !last ? i : emptyPos) - stack[j][0]; } for (j = prevIndent; j < indent; ) { results[p++] = stack[j] = [emptyPos < 0 || j > prevIndent ? i : emptyPos, j++, 0]; } emptyPos = -1; prevIndent = indent; } if (last) break; } return results; }; const guideTemplate = /* @__PURE__ */ createTemplate( "<div style=width:1px;position:absolute;background:var(--bg-guide-indent)>" ); const IndentGuides = ({ editor }) => { let prevLength = 0; let lineIndentMap; let active; const container = useRef(null); const lines = []; const indents = []; const update = (code) => { lineIndentMap = []; const tabSize = editor.props.tabSize || 2; const newIndents = getIndentGuides(code, tabSize); const l = newIndents.length; for (let i = 0, prev = [], next = newIndents[0]; next; i++) { const style = (lines[i] ||= guideTemplate()).style; const [top, left, height] = next; const old = indents[i]; next = newIndents[i + 1]; if (top != old?.[0]) style.top = top + "00%"; if (left != old?.[1]) style.left = left + "00%"; if (height != old?.[2]) style.height = height + "00%"; const isSingleIndent = prev[0] != top && next?.[0] != top, isSingleOutdent = prev[0] + prev[1] != top + height && next?.[0] + next?.[1] != top + height; for (let j = -isSingleIndent, l2 = height + isSingleOutdent; j < l2; j++) lineIndentMap[j + top] = i; prev = indents[i] = newIndents[i]; } for (let i = l; i < prevLength; ) lines[i++].remove(); container.current.append(...lines.slice(prevLength, prevLength = l)); }; const updateActive = () => { const newActive = lines[lineIndentMap[editor.activeLine - 1]]; if (newActive != active) { if (active) active.className = ""; if (newActive) newActive.className = "active-indent"; active = newActive; } }; const props = editor.props; const noWrap = !props.wordWrap; useLayoutEffect( useStableRef(() => { const value = editor.value; const cleanup1 = editor.on("update", update); const cleanup2 = editor.on("selectionChange", updateActive); if (value) { update(value); updateActive(); } return () => { cleanup1(); cleanup2(); }; }), [props.tabSize] ); return useMemo(() => { return /* @__PURE__ */ jsx( "div", { ref: container, className: "guide-indents", style: { left: "var(--padding-left)", bottom: "auto", right: "auto", display: noWrap ? "" : "none" }, children: " " } ); }, [noWrap]); }; export { IndentGuides, getIndentGuides }; //# sourceMappingURL=guides.js.map