Synchronize scrolling with textarea and preview

This commit is contained in:
thiloho
2024-08-17 16:05:14 +02:00
parent 6add151cd5
commit e41b963666
4 changed files with 50 additions and 7 deletions

View File

@@ -230,7 +230,7 @@ form label {
} }
form label:has(textarea) { form label:has(textarea) {
max-inline-size: 65ch; max-inline-size: 75ch;
} }
form .file-field { form .file-field {

View File

@@ -7,14 +7,23 @@
title, title,
children, children,
fullPreview = false, fullPreview = false,
previewContent previewContent,
previewScrollTop = 0
} = $props<{ } = $props<{
id: string; id: string;
title: string; title: string;
children: Snippet; children: Snippet;
fullPreview?: boolean; fullPreview?: boolean;
previewContent: string; previewContent: string;
previewScrollTop?: number;
}>(); }>();
let previewElement: HTMLDivElement;
$effect(() => {
const scrollHeight = previewElement.scrollHeight - previewElement.clientHeight;
previewElement.scrollTop = (previewScrollTop / 100) * scrollHeight;
});
</script> </script>
<input type="checkbox" id="toggle-mobile-preview" hidden /> <input type="checkbox" id="toggle-mobile-preview" hidden />
@@ -43,7 +52,7 @@
{@render children()} {@render children()}
</div> </div>
<div class="preview"> <div class="preview" bind:this={previewElement}>
{#if fullPreview} {#if fullPreview}
<iframe src={previewContent} title="Preview"></iframe> <iframe src={previewContent} title="Preview"></iframe>
{:else} {:else}

View File

@@ -8,6 +8,15 @@
import { API_BASE_PREFIX } from "$lib/utils"; import { API_BASE_PREFIX } from "$lib/utils";
const { data, form } = $props<{ data: PageServerData; form: ActionData }>(); const { data, form } = $props<{ data: PageServerData; form: ActionData }>();
let previewContent = $state(data.home.main_content);
let mainContentTextarea: HTMLTextAreaElement;
let textareaScrollTop = $state(0);
const updateScrollPercentage = () => {
const { scrollTop, scrollHeight, clientHeight } = mainContentTextarea;
textareaScrollTop = (scrollTop / (scrollHeight - clientHeight)) * 100;
};
</script> </script>
<SuccessOrError success={form?.success} message={form?.message} /> <SuccessOrError success={form?.success} message={form?.message} />
@@ -15,7 +24,8 @@
<WebsiteEditor <WebsiteEditor
id={data.website.id} id={data.website.id}
title={data.website.title} title={data.website.title}
previewContent={data.home.main_content} {previewContent}
previewScrollTop={textareaScrollTop}
> >
<section> <section>
<h2>Global</h2> <h2>Global</h2>
@@ -133,7 +143,14 @@
> >
<label> <label>
Main content: Main content:
<textarea name="main-content" rows="20" required>{data.home.main_content}</textarea> <textarea
name="main-content"
rows="20"
bind:value={previewContent}
bind:this={mainContentTextarea}
onscroll={updateScrollPercentage}
required>{data.home.main_content}</textarea
>
</label> </label>
<button type="submit">Submit</button> <button type="submit">Submit</button>

View File

@@ -8,6 +8,15 @@
import { API_BASE_PREFIX } from "$lib/utils"; import { API_BASE_PREFIX } from "$lib/utils";
const { data, form } = $props<{ data: PageServerData; form: ActionData }>(); const { data, form } = $props<{ data: PageServerData; form: ActionData }>();
let previewContent = $state(data.article.main_content);
let mainContentTextarea: HTMLTextAreaElement;
let textareaScrollTop = $state(0);
const updateScrollPercentage = () => {
const { scrollTop, scrollHeight, clientHeight } = mainContentTextarea;
textareaScrollTop = (scrollTop / (scrollHeight - clientHeight)) * 100;
};
</script> </script>
<SuccessOrError success={form?.success} message={form?.message} /> <SuccessOrError success={form?.success} message={form?.message} />
@@ -15,8 +24,9 @@
<WebsiteEditor <WebsiteEditor
id={data.website.id} id={data.website.id}
title={data.website.title} title={data.website.title}
previewContent={data.article.main_content || previewContent={previewContent ||
"Put some markdown content in main content to see a live preview here"} "Put some markdown content in main content to see a live preview here"}
previewScrollTop={textareaScrollTop}
> >
<section> <section>
<h2>Edit article</h2> <h2>Edit article</h2>
@@ -78,7 +88,14 @@
</div> </div>
<label> <label>
Main content: Main content:
<textarea name="main-content" rows="20" required>{data.article.main_content}</textarea> <textarea
name="main-content"
rows="20"
bind:value={previewContent}
bind:this={mainContentTextarea}
onscroll={updateScrollPercentage}
required>{data.article.main_content}</textarea
>
</label> </label>
<button type="submit">Submit</button> <button type="submit">Submit</button>