This commit is contained in:
2026-03-03 05:36:56 +01:00
parent d1ae498a2f
commit 57f1ecf5c3
7 changed files with 217 additions and 20 deletions
+21 -7
View File
@@ -24,6 +24,7 @@ export type TinyMCEEditorProps<KeyType extends string> = {
showLabel?: boolean;
useParentCSS?: boolean;
placeholder?: string;
refreshDependencyArray?: any[];
};
/**
@@ -32,7 +33,7 @@ export type TinyMCEEditorProps<KeyType extends string> = {
*/
export default function TinyMCEEditor<KeyType extends string>({
options,
editorRef,
editorRef: passedEditorRef,
setEditor: passedSetEditor,
wrapperProps,
defaultValue,
@@ -43,10 +44,12 @@ export default function TinyMCEEditor<KeyType extends string>({
showLabel,
useParentCSS,
placeholder,
refreshDependencyArray,
}: TinyMCEEditorProps<KeyType>) {
const { tinyMCE } = useTinyMCE();
const editorComponentRef = React.useRef<HTMLDivElement>(null);
const editorRef = passedEditorRef || React.useRef<Editor>(null);
const EDITOR_VALUE_CHANGE_TIMEOUT = 500;
@@ -97,7 +100,10 @@ export default function TinyMCEEditor<KeyType extends string>({
"body { font-family:Helvetica,Arial,sans-serif; font-size:14px; background-color: transparent }",
init_instance_callback: (editor) => {
setEditor(editor as any);
if (editorRef) editorRef.current = editor as any;
if (editorRef) {
editorRef.current = editor;
passedSetEditor?.(editor);
}
if (defaultValue) editor.setContent(defaultValue);
setReady(true);
@@ -140,7 +146,15 @@ export default function TinyMCEEditor<KeyType extends string>({
: undefined;
instance?.remove();
};
}, [tinyMCE, themeReady, refresh]);
}, [tinyMCE, themeReady, refresh, ...(refreshDependencyArray || [])]);
React.useEffect(() => {
const instance = editorRef.current;
if (instance) {
instance.setContent(defaultValue || "");
}
}, [defaultValue]);
return (
<div
@@ -148,7 +162,7 @@ export default function TinyMCEEditor<KeyType extends string>({
className={twMerge(
"relative w-full [&_.tox-tinymce]:!border-none",
"bg-background-light dark:bg-background-dark",
wrapperWrapperProps?.className
wrapperWrapperProps?.className,
)}
onInput={(e) => {
console.log(`Input Detected`);
@@ -159,7 +173,7 @@ export default function TinyMCEEditor<KeyType extends string>({
className={twMerge(
"absolute z-10 -top-[7px] left-[10px] px-2 text-xs",
"bg-background-light dark:bg-background-dark text-gray-500",
"dark:text-white/80 rounded"
"dark:text-white/80 rounded",
)}
htmlFor={id}
>
@@ -170,7 +184,7 @@ export default function TinyMCEEditor<KeyType extends string>({
{...borderProps}
className={twMerge(
"dark:border-white/30 p-0 pt-2",
borderProps?.className
borderProps?.className,
)}
>
<div
@@ -183,7 +197,7 @@ export default function TinyMCEEditor<KeyType extends string>({
}}
className={twMerge(
"bg-slate-200 dark:bg-slate-700 rounded-sm w-full",
"twui-rte-wrapper"
"twui-rte-wrapper",
)}
id={id}
></div>
+5 -1
View File
@@ -3,6 +3,7 @@ import React from "react";
type Params = {
initialLoading?: boolean;
initialReady?: boolean;
initialOpen?: boolean;
};
export type UseStatusStatusType = {
@@ -13,10 +14,11 @@ export type UseStatusStatusType = {
export default function useStatus(params?: Params) {
const [refresh, setRefresh] = React.useState(0);
const [loading, setLoading] = React.useState(
params?.initialLoading || false
params?.initialLoading || false,
);
const [status, setStatus] = React.useState<UseStatusStatusType>({});
const [ready, setReady] = React.useState(params?.initialReady || false);
const [open, setOpen] = React.useState(params?.initialOpen || false);
return {
refresh,
@@ -27,5 +29,7 @@ export default function useStatus(params?: Params) {
setStatus,
ready,
setReady,
open,
setOpen,
};
}
+3 -3
View File
@@ -1,4 +1,4 @@
import {
import React, {
AnchorHTMLAttributes,
ButtonHTMLAttributes,
ComponentProps,
@@ -35,8 +35,8 @@ export type TWUIButtonProps = DetailedHTMLProps<
AnchorHTMLAttributes<HTMLAnchorElement>,
HTMLAnchorElement
>;
beforeIcon?: TWUILucideIconName | JSX.Element;
afterIcon?: TWUILucideIconName | JSX.Element;
beforeIcon?: TWUILucideIconName | React.JSX.Element;
afterIcon?: TWUILucideIconName | React.JSX.Element;
buttonContentProps?: DetailedHTMLProps<
HTMLAttributes<HTMLDivElement>,
HTMLDivElement
+19 -3
View File
@@ -1,4 +1,4 @@
import React, { ComponentProps } from "react";
import React, { ComponentProps, useRef } from "react";
import { twMerge } from "tailwind-merge";
import MarkdownEditorPreviewComponent from "./MarkdownEditorPreviewComponent";
import MarkdownEditorComponent from "./MarkdownEditorComponent";
@@ -6,6 +6,7 @@ import MarkdownEditorSelectorButtons from "./MarkdownEditorSelectorButtons";
import Row from "../../layout/Row";
import Stack from "../../layout/Stack";
import AceEditor from "../../editors/AceEditor";
import useStatus from "../../hooks/useStatus";
type Props = {
value?: string;
@@ -29,17 +30,30 @@ export default function MarkdownEditor({
const [value, setValue] = React.useState<any>(existingValue || ``);
const [sideBySide, setSideBySide] = React.useState(
defaultSideBySide || false
defaultSideBySide || false,
);
const [preview, setPreview] = React.useState(false);
const { refresh, setRefresh } = useStatus();
const updatingFromExtValueRef = useRef(false);
const maxHeight = existingMaxHeight || "600px";
React.useEffect(() => {
if (updatingFromExtValueRef.current) return;
setExistingValue?.(value);
changeHandler?.(value);
}, [value]);
React.useEffect(() => {
if (!existingValue) return;
updatingFromExtValueRef.current = true;
setValue(existingValue);
setTimeout(() => {
updatingFromExtValueRef.current = false;
setRefresh((prev) => prev + 1);
}, 500);
}, [existingValue]);
return (
<Stack className="w-full items-stretch">
{!noToggleButtons && (
@@ -52,13 +66,14 @@ export default function MarkdownEditor({
<Row
className={twMerge(
`w-full grid xl:grid-cols-2 gap-6 max-h-[${maxHeight}]`,
"overflow-auto"
"overflow-auto",
)}
>
<MarkdownEditorComponent
setValue={setValue}
value={value}
maxHeight={maxHeight}
refreshDepArr={[refresh]}
{...editorProps}
/>
<MarkdownEditorPreviewComponent
@@ -80,6 +95,7 @@ export default function MarkdownEditor({
setValue={setValue}
value={value}
maxHeight={maxHeight}
refreshDepArr={[refresh]}
{...editorProps}
/>
)}