From 8c55f06659cfc75572087f06bf2f1df2c08c2193 Mon Sep 17 00:00:00 2001 From: Petyo Ivanov Date: Sun, 16 Feb 2025 09:21:07 +0200 Subject: [PATCH] feat: on change includes a parameter to indicate the reason for change --- src/MDXEditor.tsx | 3 ++- src/plugins/core/index.ts | 19 +++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/MDXEditor.tsx b/src/MDXEditor.tsx index 126d78a..1e34d3c 100644 --- a/src/MDXEditor.tsx +++ b/src/MDXEditor.tsx @@ -246,8 +246,9 @@ export interface MDXEditorProps { /** * Triggered when the editor value changes. The callback is not throttled, you can use any throttling mechanism * if you intend to do auto-saving. + * @param initialMarkdownNormalize - set to true if the change is triggered when the initial markdown is set. This can happen due to variety of reasons - for example, additional whitespace, bullet symbols different than the configured ones, etc. */ - onChange?: (markdown: string) => void + onChange?: (markdown: string, initialMarkdownNormalize: boolean) => void /** * Triggered when the markdown parser encounters an error. The payload includes the invalid source and the error message. */ diff --git a/src/plugins/core/index.ts b/src/plugins/core/index.ts index 1604b72..9bc0326 100644 --- a/src/plugins/core/index.ts +++ b/src/plugins/core/index.ts @@ -215,10 +215,16 @@ export const initialMarkdown$ = Cell('') */ export const markdown$ = Cell('') +export const initialMarkdownNormalize$ = Cell(false) /** @internal */ const markdownSignal$ = Signal((r) => { r.link(markdown$, markdownSignal$) - r.link(initialMarkdown$, markdown$) + r.sub(initialMarkdown$, (md) => { + r.pubIn({ + [initialMarkdownNormalize$]: true, + [markdown$]: md + }) + }) }) const mutableMarkdownSignal$ = Signal((r) => { @@ -546,6 +552,7 @@ export const createRootEditorSubscription$ = Appender(rootEditorSubscriptions$, }) r.pub(markdown$, theNewMarkdownValue.trim()) + r.pub(initialMarkdownNormalize$, false) }) }, (rootEditor) => { @@ -857,7 +864,7 @@ export const corePlugin = realmPlugin<{ spellCheck: boolean placeholder?: React.ReactNode autoFocus: boolean | { defaultSelection?: 'rootStart' | 'rootEnd'; preventScroll?: boolean | undefined } - onChange: (markdown: string) => void + onChange: (markdown: string, initialMarkdownNormalize: boolean) => void onBlur?: (e: FocusEvent) => void onError?: (payload: { error: string; source: string }) => void toMarkdownOptions: NonNullable @@ -902,7 +909,9 @@ export const corePlugin = realmPlugin<{ }) r.singletonSub(markdownErrorSignal$, params?.onError) - r.singletonSub(mutableMarkdownSignal$, params?.onChange) + r.singletonSub(mutableMarkdownSignal$, (value) => { + params?.onChange(value, r.getValue(initialMarkdownNormalize$)) + }) r.singletonSub(onBlur$, params?.onBlur) // Use the JSX extension to parse HTML @@ -961,7 +970,9 @@ export const corePlugin = realmPlugin<{ [readOnly$]: params?.readOnly }) - realm.singletonSub(mutableMarkdownSignal$, params?.onChange) + realm.singletonSub(mutableMarkdownSignal$, (value) => { + params?.onChange(value, realm.getValue(initialMarkdownNormalize$)) + }) realm.singletonSub(onBlur$, params?.onBlur) realm.singletonSub(markdownErrorSignal$, params?.onError) }