Skip to content

Commit

Permalink
Merge pull request #457 from kreneskyp/code_editor_linewrap
Browse files Browse the repository at this point in the history
CodeEditor line numbers now account for line wrapping.
  • Loading branch information
kreneskyp committed Feb 24, 2024
2 parents 4590678 + 92afaa8 commit 0971c15
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 7 deletions.
43 changes: 39 additions & 4 deletions frontend/components/code_editor/CodeEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ export const CodeEditor = ({ value, language, onChange }) => {
const [editor] = useState(() => withHistory(withReact(createEditor())));
const _value = value || "";

const [lineHeights, setLineHeights] = useState([]); // State to store line heights

const updateLineHeight = (index, height) => {
setLineHeights((prevHeights) => {
const newHeights = [...prevHeights];
newHeights[index] = height;
return newHeights;
});
};

const decorate = useDecorate(editor);
const onKeyDown = useOnKeydown(editor);

Expand Down Expand Up @@ -79,6 +89,19 @@ export const CodeEditor = ({ value, language, onChange }) => {
[onChange]
);

const renderElement = React.useCallback(
(props) => (
<ElementWrapper
key={props.element.line}
{...props}
language={language}
heights={lineHeights}
updateLineHeight={updateLineHeight}
/>
),
[updateLineHeight]
);

return (
<Box
h={"100%"}
Expand All @@ -96,11 +119,11 @@ export const CodeEditor = ({ value, language, onChange }) => {
>
<SetNodeToDecorations />
<HStack spacing={0}>
<LineNumbers />
<LineNumbers lineHeights={lineHeights} />
<Box py={2} w={"100%"}>
<Editable
decorate={decorate}
renderElement={(props) => ElementWrapper(props, language)}
renderElement={renderElement}
renderLeaf={renderLeaf}
onKeyDown={onKeyDown}
/>
Expand All @@ -115,9 +138,10 @@ export const CodeEditor = ({ value, language, onChange }) => {
);
};

const ElementWrapper = (props, language) => {
const ElementWrapper = ({ language, heights, updateLineHeight, ...props }) => {
const { attributes, children, element } = props;
const editor = useSlateStatic();
const lineRef = React.useRef(null);

if (element.type === CodeBlockType) {
Transforms.setNodes(
Expand Down Expand Up @@ -145,10 +169,21 @@ const ElementWrapper = (props, language) => {
);
}

// update parent if code line size changes
React.useEffect(() => {
if (
element.type === CodeLineType &&
lineRef.current &&
heights[element.line] !== lineRef.current.offsetHeight
) {
updateLineHeight(element.line, lineRef.current.offsetHeight);
}
}, [element, children]);

if (element.type === CodeLineType) {
return (
<Box {...attributes} style={{ position: "relative" }}>
{children}
<div ref={lineRef}>{children}</div>
</Box>
);
}
Expand Down
7 changes: 4 additions & 3 deletions frontend/components/code_editor/LineNumbers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useSlate } from "slate-react";
import { Box } from "@chakra-ui/react";
import { useColorMode } from "@chakra-ui/react";

export const LineNumbers = () => {
export const LineNumbers = ({ lineHeights }) => {
const editor = useSlate();
const element = editor.children[0];
const lines = element.children || [];
Expand All @@ -20,6 +20,7 @@ export const LineNumbers = () => {
bg={bg}
px={1}
py={2}
pt={3}
fontSize="xs"
fontFamily="monospace"
color={color}
Expand All @@ -28,10 +29,10 @@ export const LineNumbers = () => {
<Box
key={index}
w="full"
h="21px"
h={lineHeights[index] ? `${lineHeights[index]}px` : "21px"}
m={0}
display="flex"
alignItems="end"
alignItems="start"
justifyContent="flex-end"
>
{index + 1}
Expand Down

0 comments on commit 0971c15

Please sign in to comment.