revert textarea component to conenteditable
This commit is contained in:
parent
925ea142fb
commit
c6c7240fee
3 changed files with 30 additions and 11 deletions
|
@ -1,8 +1,8 @@
|
|||
import { createEffect, createSignal, on } from 'solid-js';
|
||||
import { getTextNodes } from '@solid-primitives/selection';
|
||||
import { createEditContext } from '~/features/editor';
|
||||
import { createEffect, createSignal, on, onMount } from 'solid-js';
|
||||
import { createSelection, getTextNodes } from '@solid-primitives/selection';
|
||||
import { createSource } from '~/features/source';
|
||||
import css from './textarea.module.css';
|
||||
import { debounce } from '@solid-primitives/scheduled';
|
||||
|
||||
interface TextareaProps {
|
||||
class?: string;
|
||||
|
@ -16,13 +16,31 @@ interface TextareaProps {
|
|||
}
|
||||
|
||||
export function Textarea(props: TextareaProps) {
|
||||
const [selection, setSelection] = createSelection();
|
||||
const [editorRef, setEditorRef] = createSignal<HTMLElement>();
|
||||
|
||||
const source = createSource(() => props.value);
|
||||
const [text] = createEditContext(editorRef, () => source.out);
|
||||
|
||||
createEffect(() => {
|
||||
source.out = text();
|
||||
const mutate = debounce(() => {
|
||||
const [, start, end] = selection();
|
||||
const ref = editorRef();
|
||||
|
||||
if (ref) {
|
||||
source.out = ref.innerHTML;
|
||||
|
||||
ref.style.height = `1px`;
|
||||
ref.style.height = `${2 + ref.scrollHeight}px`;
|
||||
|
||||
setSelection([ref, start, end]);
|
||||
}
|
||||
}, 300);
|
||||
|
||||
onMount(() => {
|
||||
new MutationObserver(mutate).observe(editorRef()!, {
|
||||
subtree: true,
|
||||
childList: true,
|
||||
characterData: true,
|
||||
});
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
|
@ -42,12 +60,13 @@ export function Textarea(props: TextareaProps) {
|
|||
}));
|
||||
|
||||
return <div
|
||||
contentEditable
|
||||
ref={setEditorRef}
|
||||
class={`${css.textarea} ${props.class}`}
|
||||
title={props.title ?? ''}
|
||||
dir="auto"
|
||||
lang={props.lang}
|
||||
innerHTML={text()}
|
||||
innerHTML={source.out}
|
||||
data-placeholder={props.placeholder ?? ''}
|
||||
on:keydown={e => e.stopPropagation()}
|
||||
on:pointerdown={e => e.stopPropagation()}
|
||||
|
|
|
@ -103,7 +103,7 @@ export function createSource(value: Accessor<string>): Source {
|
|||
});
|
||||
|
||||
createEffect(() => {
|
||||
setStore('metadata', 'queryResults', findMatches(store.plain, store.query).toArray());
|
||||
setStore('metadata', 'queryResults', findMatches(store.plain, store.query));
|
||||
});
|
||||
|
||||
return src;
|
||||
|
|
|
@ -37,11 +37,11 @@ export default function Formatter(props: {}) {
|
|||
|
||||
return <div class={css.root}>
|
||||
<textarea oninput={onInput} title="markdown">{value()}</textarea>
|
||||
<Editor value={value()} oninput={setValue}>
|
||||
{/* <Editor value={value()} oninput={setValue}>
|
||||
<SearchAndReplace />
|
||||
</Editor>
|
||||
</Editor> */}
|
||||
|
||||
{/* <Textarea class={css.textarea} title="html" value={value()} oninput={setValue} lang="en-GB" /> */}
|
||||
<Textarea class={css.textarea} title="html" value={value()} oninput={setValue} lang="en-GB" />
|
||||
</div>;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue