add inital attempt at cursor position preservation

This commit is contained in:
Chris Kruining 2025-02-13 17:15:22 +11:00
parent 67b76e41c5
commit 69fd9a1753
No known key found for this signature in database
GPG key ID: EB894A3560CCCAD2
4 changed files with 43 additions and 495 deletions

503
bun.lock

File diff suppressed because it is too large Load diff

View file

@ -10,6 +10,7 @@
"@solid-primitives/destructure": "^0.2.0", "@solid-primitives/destructure": "^0.2.0",
"@solid-primitives/i18n": "^2.2.0", "@solid-primitives/i18n": "^2.2.0",
"@solid-primitives/scheduled": "^1.5.0", "@solid-primitives/scheduled": "^1.5.0",
"@solid-primitives/selection": "^0.1.0",
"@solid-primitives/storage": "^4.3.1", "@solid-primitives/storage": "^4.3.1",
"@solid-primitives/timer": "^1.4.0", "@solid-primitives/timer": "^1.4.0",
"@solidjs/meta": "^0.29.4", "@solidjs/meta": "^0.29.4",
@ -33,7 +34,6 @@
"@types/wicg-file-system-access": "^2023.10.5", "@types/wicg-file-system-access": "^2023.10.5",
"bun-types": "^1.2.2", "bun-types": "^1.2.2",
"jsdom": "^26.0.0", "jsdom": "^26.0.0",
"vite-plugin-pwa": "^0.21.1",
"vite-plugin-solid-svg": "^0.8.1", "vite-plugin-solid-svg": "^0.8.1",
"workbox-window": "^7.3.0" "workbox-window": "^7.3.0"
}, },

View file

@ -1,6 +1,7 @@
import { createEffect, createMemo, createSignal } from 'solid-js'; import { createEffect, createMemo, createSignal, untrack } from 'solid-js';
import { decode } from '~/utilities'; import { decode } from '~/utilities';
import { debounce } from '@solid-primitives/scheduled'; import { debounce } from '@solid-primitives/scheduled';
import { createSelection } from '@solid-primitives/selection';
import { defaultChecker as spellChecker } from './spellChecker'; import { defaultChecker as spellChecker } from './spellChecker';
import { defaultChecker as grammarChecker } from './grammarChecker'; import { defaultChecker as grammarChecker } from './grammarChecker';
import css from './textarea.module.css'; import css from './textarea.module.css';
@ -15,6 +16,7 @@ interface TextareaProps {
} }
export function Textarea(props: TextareaProps) { export function Textarea(props: TextareaProps) {
const [selection, setSelection] = createSelection();
const [value, setValue] = createSignal<string>(decode(props.value)); const [value, setValue] = createSignal<string>(decode(props.value));
const [element, setElement] = createSignal<HTMLTextAreaElement>(); const [element, setElement] = createSignal<HTMLTextAreaElement>();
@ -22,6 +24,23 @@ export function Textarea(props: TextareaProps) {
setValue(decode(props.value)); setValue(decode(props.value));
}); });
createEffect(() => {
// For tracking
value();
const root = untrack(() => element());
const [el, start, end] = untrack(() => selection());
if (el !== root) {
return;
}
// TODO :: this needs to be calculated based on the modification done
const offset = 1;
setSelection([el, start + offset, end + offset]);
});
const resize = () => { const resize = () => {
const el = element(); const el = element();
@ -43,7 +62,7 @@ export function Textarea(props: TextareaProps) {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
setValue(element()!.innerText.trim()); setValue(element()!.textContent!);
resize(); resize();
mutate(); mutate();

View file

@ -2,5 +2,13 @@
background-color: var(--surface-600); background-color: var(--surface-600);
color: var(--text-1); color: var(--text-1);
border: 1px solid var(--text-2); border: 1px solid var(--text-2);
border-radius: var(--radii-s); border-radius: var(--radii-m);
padding: var(--padding-s);
overflow: auto !important;
max-inline-size: 30em;
& * {
white-space: nowrap;
}
} }