From dc049af1c5d3a1016406afec3237b85bad2211c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B0=D0=B2=D0=BB=D0=BE=D0=B2=D0=B8=D1=87=20=D0=9C?= =?UTF-8?q?=D0=B8=D1=85=D0=B0=D0=B8=D0=BB=20=D0=90=D0=BD=D1=82=D0=BE=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D0=B8=D1=87?= <87013925+PMAWorks@users.noreply.github.com> Date: Tue, 17 Dec 2024 17:05:45 +0300 Subject: [PATCH] feat(bundle): added empty row placeholder (#506) --- demo/components/Playground.tsx | 6 ++++++ src/bundle/types.ts | 12 ++++++++++++ src/bundle/useMarkdownEditor.ts | 1 + src/bundle/wysiwyg-preset.ts | 22 ++++++++++++++++++---- 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/demo/components/Playground.tsx b/demo/components/Playground.tsx index 3492b81f..b6c5708f 100644 --- a/demo/components/Playground.tsx +++ b/demo/components/Playground.tsx @@ -16,6 +16,7 @@ import { type RenderPreview, type ToolbarGroupData, type UseMarkdownEditorProps, + WysiwygPlaceholderOptions, logger, markupToolbarConfigs, useMarkdownEditor, @@ -79,6 +80,7 @@ export type PlaygroundProps = { breaks?: boolean; linkify?: boolean; linkifyTlds?: string | string[]; + placeholderOptions?: WysiwygPlaceholderOptions; sanitizeHtml?: boolean; prepareRawMarkup?: boolean; splitModeOrientation?: 'horizontal' | 'vertical' | false; @@ -139,6 +141,7 @@ export const Playground = React.memo((props) => { wysiwygCommandMenuConfig, markupConfigExtensions, markupToolbarConfig, + placeholderOptions, escapeConfig, enableSubmitInPreview, hidePreviewAfterSubmit, @@ -185,6 +188,9 @@ export const Playground = React.memo((props) => { needToSetDimensionsForUploadedImages, renderPreview: renderPreviewDefined ? renderPreview : undefined, fileUploadHandler, + wysiwygConfig: { + placeholderOptions: placeholderOptions, + }, experimental: { ...experimental, directiveSyntax, diff --git a/src/bundle/types.ts b/src/bundle/types.ts index 34d17136..b25ad335 100644 --- a/src/bundle/types.ts +++ b/src/bundle/types.ts @@ -26,6 +26,17 @@ export type RenderPreview = (params: RenderPreviewParams) => ReactNode; export type ParseInsertedUrlAsImage = (text: string) => {imageUrl: string; title?: string} | null; +export type WysiwygPlaceholderOptions = { + value?: string | (() => string); + /** Default – empty-doc + Values: + - 'empty-doc' – The placeholder will only be shown when the document is completely empty; + - 'empty-row-top-level' – The placeholder will be displayed in an empty line that is at the top level of the document structure; + - 'empty-row' – The placeholder will be shown in any empty line within the document, regardless of its nesting level. + */ + behavior?: 'empty-doc' | 'empty-row-top-level' | 'empty-row'; +}; + export type MarkdownEditorMdOptions = { html?: boolean; breaks?: boolean; @@ -148,6 +159,7 @@ export type MarkdownEditorWysiwygConfig = { extensions?: Extension; extensionOptions?: ExtensionsOptions; escapeConfig?: EscapeConfig; + placeholderOptions?: WysiwygPlaceholderOptions; }; // [major] TODO: remove generic type diff --git a/src/bundle/useMarkdownEditor.ts b/src/bundle/useMarkdownEditor.ts index b44cb463..6cdb1a7c 100644 --- a/src/bundle/useMarkdownEditor.ts +++ b/src/bundle/useMarkdownEditor.ts @@ -59,6 +59,7 @@ export function useMarkdownEditor( editor.emit('submit', null); return true; }, + placeholderOptions: wysiwygConfig.placeholderOptions, mdBreaks: breaks, fileUploadHandler: uploadFile, needToSetDimensionsForUploadedImages, diff --git a/src/bundle/wysiwyg-preset.ts b/src/bundle/wysiwyg-preset.ts index 42874148..af43bc4a 100644 --- a/src/bundle/wysiwyg-preset.ts +++ b/src/bundle/wysiwyg-preset.ts @@ -16,7 +16,7 @@ import type {FileUploadHandler} from '../utils/upload'; import {wCommandMenuConfigByPreset, wSelectionMenuConfigByPreset} from './config/wysiwyg'; import {emojiDefs} from './emoji'; -import type {MarkdownEditorPreset} from './types'; +import type {MarkdownEditorPreset, WysiwygPlaceholderOptions} from './types'; const DEFAULT_IGNORED_KEYS = ['Tab', 'Shift-Tab'] as const; @@ -27,6 +27,7 @@ export type BundlePresetOptions = ExtensionsOptions & preset: MarkdownEditorPreset; mdBreaks?: boolean; fileUploadHandler?: FileUploadHandler; + placeholderOptions?: WysiwygPlaceholderOptions; /** * If we need to set dimensions for uploaded images * @@ -63,9 +64,22 @@ export const BundlePreset: ExtensionAuto = (builder, opts) baseSchema: { paragraphKey: f.toPM(A.Text), paragraphPlaceholder: (node: Node, parent?: Node | null) => { - const isDocEmpty = - !node.text && parent?.type.name === BaseNode.Doc && parent.childCount === 1; - return isDocEmpty ? i18nPlaceholder('doc_empty') : null; + const {value, behavior} = opts.placeholderOptions || {}; + + const emptyEntries = { + 'empty-row': !node.text, + 'empty-row-top-level': !node.text && parent?.type.name === BaseNode.Doc, + 'empty-doc': + !node.text && parent?.type.name === BaseNode.Doc && parent.childCount === 1, + }; + + const showPlaceholder = emptyEntries[behavior || 'empty-doc']; + + if (!showPlaceholder) return null; + + return typeof value === 'function' + ? value() + : value ?? i18nPlaceholder('doc_empty'); }, ...opts.baseSchema, },