More work on the new rich text editor...

This commit is contained in:
Scott Idem
2024-12-03 12:39:30 -05:00
parent 971ffbad02
commit 6d94583885
4 changed files with 309 additions and 361 deletions

View File

@@ -1,4 +1,7 @@
<script lang="ts">
import { fade } from 'svelte/transition'
import { cubicOut } from 'svelte/easing';
import { type Editor } from '@tiptap/core';
import Undo from './icons/undo.svelte';
import Redo from './icons/redo.svelte';
@@ -35,14 +38,14 @@ let show_button_kv_defaults: any = {
undo: true,
redo: true,
text: true,
text: false,
bold: true,
italic: true,
underline: true,
strikethrough: false,
align: false,
link: true,
link: false,
code: false,
blockquote: false,
subscript: false,
@@ -52,9 +55,9 @@ let show_button_kv_defaults: any = {
task_list: false,
image: false,
table: false,
text_color: true,
highlighter: true,
quick_color: true,
text_color: false,
highlighter: false,
quick_color: false,
search_replace: false,
};
console.log('show_button_kv', show_button_kv);
@@ -65,17 +68,36 @@ if (show_button_kv) {
}
</script>
<div class="flex w-full items-center overflow-auto border-b p-1 *:mx-1">
<div
transition:fade={{delay: 250, duration: 750, easing: cubicOut}}
class="
flex flex-row flex-wrap gap-0.5
w-full items-center justify-between
overflow-auto border-b p-1
transition-all duration-1000
"
>
<span
class:hidden={!show_button_kv.undo && !show_button_kv.redo}
>
{#if show_button_kv.undo}
<Undo {editor} />
{/if}
{#if show_button_kv.redo}
<Redo {editor} />
{/if}
</span>
<!-- <Separator orientation="vertical" class="h-fit" /> -->
<span
class:hidden={!show_button_kv.text}
>
{#if show_button_kv.text}
<Text {editor} />
{/if}
</span>
<span
class:hidden={!show_button_kv.bold && !show_button_kv.italic && !show_button_kv.underline && !show_button_kv.strikethrough}
>
{#if show_button_kv.bold}
<Bold {editor} />
{/if}
@@ -88,6 +110,10 @@ if (show_button_kv) {
{#if show_button_kv.strikethrough}
<Strikethrough {editor} />
{/if}
</span>
<span
class:hidden={!show_button_kv.align && !show_button_kv.link && !show_button_kv.code && !show_button_kv.blockquote && !show_button_kv.subscript && !show_button_kv.superscript && !show_button_kv.bullet_list && !show_button_kv.ordered_list && !show_button_kv.task_list && !show_button_kv.image && !show_button_kv.table}
>
{#if show_button_kv.align}
<Align {editor} />
{/if}
@@ -121,6 +147,11 @@ if (show_button_kv) {
{#if show_button_kv.table}
<Table {editor} />
{/if}
</span>
<span
class:hidden={!show_button_kv.text_color && !show_button_kv.highlighter && !show_button_kv.quick_color}
>
cxx
{#if show_button_kv.text_color}
<Textcolor {editor} />
{/if}
@@ -130,7 +161,12 @@ if (show_button_kv) {
{#if show_button_kv.quick_color}
<Quickcolor {editor} />
{/if}
</span>
<span
class:hidden={!show_button_kv.search_replace}
>
{#if show_button_kv.search_replace}
<SearchReplace {editor} />
{/if}
</span>
</div>

View File

@@ -41,19 +41,21 @@
interface Props {
class?: string;
content?: Content;
showToolbar?: boolean;
show_toolbar?: boolean;
// html_text?: string;
new_html?: string;
placeholder?: string;
show_button_kv?: any;
}
let { class:
className = '',
content = $bindable(''),
showToolbar = true,
show_toolbar = true,
// html_text = '',
new_html = $bindable(''),
placeholder = $bindable('Start typing...')
placeholder = $bindable('Start typing...'),
show_button_kv = $bindable({})
}: Props = $props();
let editor = $state<Editor>();
@@ -159,14 +161,16 @@
});
</script>
<div class={cn('flex flex-col rounded border', className)}>
{#if editor && showToolbar}
<EditorToolbar {editor} />
<div
class={cn('flex flex-col rounded border textarea editor', className)}
>
{#if editor && show_toolbar}
<EditorToolbar {editor} {show_button_kv} />
{/if}
<div
bind:this={element}
spellcheck="false"
class="tiptap h-full w-full overflow-auto relative">
class="tiptap overflow-auto relative">
<span
class="placeholder text-sm text-gray-400 italic absolute p-3"
contenteditable="false"

View File

@@ -37,11 +37,11 @@ import './element_tiptap_editor.scss';
export let html_text: string = '';
export let default_minimal: boolean = false;
export let show_menu: boolean = true;
export let show_toolbar: boolean = true;
export let placeholder: string = 'Type your text here...';
if (default_minimal) {
show_menu = false;
show_toolbar = false;
}
// export let html_text: string = `
@@ -79,43 +79,9 @@ let element: HTMLDivElement;
let editor: any;
// More default options should be defined later.
// minimal, basic, full
let show_button_kv_defaults: any = {
bold: true,
italic: true,
strike: true,
code: true,
paragraph: false,
heading__h1: false,
heading__h2: false,
heading__h3: false,
heading__h4: false,
heading__h5: false,
heading__h6: false,
bulletList: false,
orderedList: false,
codeBlock: false,
blockquote: false,
horizontalRule: false,
hardBreak: true,
link: false,
unsetLink: true,
unsetAllMarks: true,
undo: true,
redo: false,
};
export let show_button_kv: any;
if (show_button_kv) {
show_button_kv = { ...show_button_kv_defaults, ...show_button_kv };
} else {
show_button_kv = show_button_kv_defaults;
}
// export let new_json = editor?.getJSON();
export let new_html: string = '';
@@ -133,13 +99,10 @@ let mouse_leave_wait: number = 2000;
<!-- svelte-ignore a11y-no-static-element-interactions -->
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- class:py-1={show_menu} -->
{#if 1==3}
<div
on:click={() => {
if (default_minimal) {
editor.chain().focus().setParagraph().run();
show_menu = true;
show_toolbar = true;
}
}}
on:mouseleave={() => {
@@ -147,77 +110,30 @@ let mouse_leave_wait: number = 2000;
mouse_entered_timer = setTimeout(() => {
if (default_minimal) {
show_menu = false;
show_toolbar = false;
}
}, mouse_leave_wait);
// if (default_minimal) {
// show_menu = false;
// }
}}
on:mouseenter={() => {
clearTimeout(mouse_entered_timer);
mouse_entered_timer = setTimeout(() => {
if (default_minimal) {
show_menu = true;
show_toolbar = true;
}
}, mouse_enter_wait);
// if (default_minimal) {
// show_menu = true;
// }
}}
class="xxxeditor textarea p-1 transition-all duration-1000"
class:hidden={true}
class=""
>
<!-- && show_menu -->
<!-- class:h-0={!show_menu} -->
<!-- class:h-auto={show_menu} -->
<!-- class:opacity-0={!show_menu} -->
<!-- class:opacity-100={show_menu} -->
{#if editor && show_menu}
<div
transition:fade={{delay: 250, duration: 750, easing: cubicOut}}
class="
control-group button-group
bg-gray-200
border-b border-gray-400
p-1
transition-all duration-1000
flex flex-row flex-wrap gap-4
items-center justify-between
"
>
<!-- Nothing Here Anymore -->
</div>
{/if} <!-- show_menu -->
<!-- bg-slate-100 px-2 py-2 -->
<div
bind:this={element}
class="tiptap px-2 py-2 relative"
class:font-mono={show_menu}
>
<span
class="placeholder text-sm text-gray-400 italic absolute"
contenteditable="false"
hidden={editor?.getHTML() !== '<p></p>'}
>{placeholder}</span>
</div>
</div>
{/if}
<main class="my-10 flex w-full flex-col items-center justify-center">
<ShadEditor
class="editor textarea p-1 transition-all duration-1000"
class="p-1 transition-all duration-1000"
bind:content={html_text}
bind:new_html={new_html}
placeholder={placeholder}
show_toolbar={show_toolbar}
show_button_kv={show_button_kv}
/>
</main>
</div>
<style lang="scss">
// :global(.ProseMirror) {

View File

@@ -360,15 +360,11 @@ function send_staff_notification_email() {
default_minimal={true}
bind:html_text={$idaa_slct.post_obj.content}
show_button_kv={{
'heading__h1': true,
'heading__h2': false,
'heading__h3': false,
paragraph: false,
bulletList: true,
orderedList: true,
hardBreak: true,
text: true,
bullet_list: true,
ordered_list: true,
link: true,
unsetLink: true
unset_link: true
}}
bind:new_html={$idaa_slct.post_obj.content_new_html}
placeholder="Your post content here..."
@@ -378,15 +374,11 @@ function send_staff_notification_email() {
default_minimal={true}
bind:html_text={$idaa_slct.post_obj.content}
show_button_kv={{
'heading__h1': false,
'heading__h2': false,
'heading__h3': false,
paragraph: false,
bulletList: false,
orderedList: false,
hardBreak: false,
link: false,
unsetLink: false
// text: true,
// bullet_list: true,
// ordered_list: true,
// link: true,
// unset_link: true
}}
bind:new_html={$idaa_slct.post_obj.content_new_html}
placeholder="Your post content here..."