mirror of
https://github.com/thiloho/archtika.git
synced 2025-11-22 10:51:36 +01:00
Synchronize scrolling with textarea and preview
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user