Add option to wrap text (#20)

This commit is contained in:
Isaac - The456
2025-03-15 13:36:29 +00:00
committed by GitHub
parent 0d7cd64eef
commit 24025642f4
5 changed files with 58 additions and 9 deletions

View File

@@ -40,6 +40,12 @@ export default function Editor({
pref => pref >= 10 && pref <= 22
);
const [wordWrap, setWordWrap] = usePreference<boolean>(
'wordwrap',
true,
() => true
);
useEffect(() => {
if (contentType) {
setLanguage(contentType);
@@ -66,6 +72,8 @@ export default function Editor({
setReadOnly={setReadOnly}
theme={theme}
setTheme={setTheme}
wordWrap={wordWrap}
setWordWrap={setWordWrap}
zoom={zoom}
/>
<EditorTextArea
@@ -76,6 +84,7 @@ export default function Editor({
language={language}
fontSize={fontSize}
readOnly={readOnly}
wordWrap={wordWrap}
resetFunction={resetFunction}
/>
</ThemeProvider>

View File

@@ -19,6 +19,8 @@ export interface EditorControlsProps {
setReadOnly: (value: boolean) => void;
theme: keyof Themes;
setTheme: (value: keyof Themes) => void;
wordWrap: boolean;
setWordWrap: (value: boolean) => void;
zoom: (delta: number) => void;
}
@@ -31,6 +33,8 @@ export default function EditorControls({
setReadOnly,
theme,
setTheme,
wordWrap,
setWordWrap,
zoom,
}: EditorControlsProps) {
const [saving, setSaving] = useState<boolean>(false);
@@ -113,6 +117,9 @@ export default function EditorControls({
<Section>
<Button onClick={() => zoom(1)}>[+ </Button>
<Button onClick={() => zoom(-1)}> -]</Button>
<Button onClick={() => setWordWrap(!wordWrap)}>
[wrap:{wordWrap ? 'on' : 'off'}]
</Button>
<MenuButton
label="theme"
value={theme}
@@ -144,13 +151,15 @@ const Header = styled.header`
display: flex;
justify-content: space-between;
user-select: none;
overflow-x: auto;
white-space: nowrap;
`;
const Section = styled.div`
display: flex;
align-items: center;
@media (max-width: 470px) {
@media (max-width: 850px) {
.optional {
display: none;
}

View File

@@ -62,6 +62,7 @@ export interface EditorTextAreaProps {
language: string;
fontSize: number;
readOnly: boolean;
wordWrap: boolean;
resetFunction: MutableRefObject<ResetFunction | null>;
}
@@ -73,6 +74,7 @@ export default function EditorTextArea({
language,
fontSize,
readOnly,
wordWrap,
resetFunction,
}: EditorTextAreaProps) {
const [editor, setEditor] = useState<editor.IStandaloneCodeEditor>();
@@ -166,7 +168,7 @@ export default function EditorTextArea({
fontFamily: 'JetBrains Mono',
fontSize: fontSize,
fontLigatures: true,
wordWrap: 'on',
wordWrap: wordWrap ? 'on' : 'off',
renderLineHighlight: 'none',
renderValidationDecorations: 'off',
readOnly,

View File

@@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import styled from 'styled-components';
import Button from './Button';
@@ -16,6 +17,11 @@ export default function MenuButton<T extends string>({
setValue,
}: MenuButtonProps<T>) {
const [open, setOpen] = useState<boolean>(false);
const [menuPosition, setMenuPosition] = useState<{
top: number;
left: number;
}>({ top: 0, left: 0 });
const buttonRef = useRef<HTMLDivElement | null>(null);
// close the menu when a click is made elsewhere
useEffect(() => {
@@ -26,6 +32,16 @@ export default function MenuButton<T extends string>({
function toggleOpen(e: React.MouseEvent) {
e.stopPropagation();
if (!buttonRef.current) {
return;
}
if (!open) {
const rect = buttonRef.current.getBoundingClientRect();
setMenuPosition({
top: rect.bottom + window.scrollY,
left: rect.left + window.scrollX,
});
}
setOpen(!open);
}
@@ -63,22 +79,35 @@ export default function MenuButton<T extends string>({
}
return (
<Button onClick={toggleOpen}>
[<span>{label}: </span>
{value}]{open && <Menu>{items}</Menu>}
</Button>
<>
<Button onClick={toggleOpen} ref={buttonRef}>
[<span>{label}: </span>
{value}]
</Button>
{open &&
createPortal(
<Menu style={{ top: menuPosition.top, left: menuPosition.left }}>
{items}
</Menu>,
document.body
)}
</>
);
}
const Menu = styled.ul`
position: absolute;
top: 2em;
margin: 0;
padding: 0;
list-style: none;
background-color: ${props => props.theme.highlight};
max-height: calc(100vh - 2em);
overflow: auto;
z-index: 20;
> li {
cursor: pointer;
}
> li.title {
text-align: center;