Skip to content

Commit dc049af

Browse files
authored
feat(bundle): added empty row placeholder (#506)
1 parent 4355519 commit dc049af

File tree

4 files changed

+37
-4
lines changed

4 files changed

+37
-4
lines changed

demo/components/Playground.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
type RenderPreview,
1717
type ToolbarGroupData,
1818
type UseMarkdownEditorProps,
19+
WysiwygPlaceholderOptions,
1920
logger,
2021
markupToolbarConfigs,
2122
useMarkdownEditor,
@@ -79,6 +80,7 @@ export type PlaygroundProps = {
7980
breaks?: boolean;
8081
linkify?: boolean;
8182
linkifyTlds?: string | string[];
83+
placeholderOptions?: WysiwygPlaceholderOptions;
8284
sanitizeHtml?: boolean;
8385
prepareRawMarkup?: boolean;
8486
splitModeOrientation?: 'horizontal' | 'vertical' | false;
@@ -139,6 +141,7 @@ export const Playground = React.memo<PlaygroundProps>((props) => {
139141
wysiwygCommandMenuConfig,
140142
markupConfigExtensions,
141143
markupToolbarConfig,
144+
placeholderOptions,
142145
escapeConfig,
143146
enableSubmitInPreview,
144147
hidePreviewAfterSubmit,
@@ -185,6 +188,9 @@ export const Playground = React.memo<PlaygroundProps>((props) => {
185188
needToSetDimensionsForUploadedImages,
186189
renderPreview: renderPreviewDefined ? renderPreview : undefined,
187190
fileUploadHandler,
191+
wysiwygConfig: {
192+
placeholderOptions: placeholderOptions,
193+
},
188194
experimental: {
189195
...experimental,
190196
directiveSyntax,

src/bundle/types.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ export type RenderPreview = (params: RenderPreviewParams) => ReactNode;
2626

2727
export type ParseInsertedUrlAsImage = (text: string) => {imageUrl: string; title?: string} | null;
2828

29+
export type WysiwygPlaceholderOptions = {
30+
value?: string | (() => string);
31+
/** Default – empty-doc
32+
Values:
33+
- 'empty-doc' – The placeholder will only be shown when the document is completely empty;
34+
- 'empty-row-top-level' – The placeholder will be displayed in an empty line that is at the top level of the document structure;
35+
- 'empty-row' – The placeholder will be shown in any empty line within the document, regardless of its nesting level.
36+
*/
37+
behavior?: 'empty-doc' | 'empty-row-top-level' | 'empty-row';
38+
};
39+
2940
export type MarkdownEditorMdOptions = {
3041
html?: boolean;
3142
breaks?: boolean;
@@ -148,6 +159,7 @@ export type MarkdownEditorWysiwygConfig = {
148159
extensions?: Extension;
149160
extensionOptions?: ExtensionsOptions;
150161
escapeConfig?: EscapeConfig;
162+
placeholderOptions?: WysiwygPlaceholderOptions;
151163
};
152164

153165
// [major] TODO: remove generic type

src/bundle/useMarkdownEditor.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export function useMarkdownEditor<T extends object = {}>(
5959
editor.emit('submit', null);
6060
return true;
6161
},
62+
placeholderOptions: wysiwygConfig.placeholderOptions,
6263
mdBreaks: breaks,
6364
fileUploadHandler: uploadFile,
6465
needToSetDimensionsForUploadedImages,

src/bundle/wysiwyg-preset.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import type {FileUploadHandler} from '../utils/upload';
1616

1717
import {wCommandMenuConfigByPreset, wSelectionMenuConfigByPreset} from './config/wysiwyg';
1818
import {emojiDefs} from './emoji';
19-
import type {MarkdownEditorPreset} from './types';
19+
import type {MarkdownEditorPreset, WysiwygPlaceholderOptions} from './types';
2020

2121
const DEFAULT_IGNORED_KEYS = ['Tab', 'Shift-Tab'] as const;
2222

@@ -27,6 +27,7 @@ export type BundlePresetOptions = ExtensionsOptions &
2727
preset: MarkdownEditorPreset;
2828
mdBreaks?: boolean;
2929
fileUploadHandler?: FileUploadHandler;
30+
placeholderOptions?: WysiwygPlaceholderOptions;
3031
/**
3132
* If we need to set dimensions for uploaded images
3233
*
@@ -63,9 +64,22 @@ export const BundlePreset: ExtensionAuto<BundlePresetOptions> = (builder, opts)
6364
baseSchema: {
6465
paragraphKey: f.toPM(A.Text),
6566
paragraphPlaceholder: (node: Node, parent?: Node | null) => {
66-
const isDocEmpty =
67-
!node.text && parent?.type.name === BaseNode.Doc && parent.childCount === 1;
68-
return isDocEmpty ? i18nPlaceholder('doc_empty') : null;
67+
const {value, behavior} = opts.placeholderOptions || {};
68+
69+
const emptyEntries = {
70+
'empty-row': !node.text,
71+
'empty-row-top-level': !node.text && parent?.type.name === BaseNode.Doc,
72+
'empty-doc':
73+
!node.text && parent?.type.name === BaseNode.Doc && parent.childCount === 1,
74+
};
75+
76+
const showPlaceholder = emptyEntries[behavior || 'empty-doc'];
77+
78+
if (!showPlaceholder) return null;
79+
80+
return typeof value === 'function'
81+
? value()
82+
: value ?? i18nPlaceholder('doc_empty');
6983
},
7084
...opts.baseSchema,
7185
},

0 commit comments

Comments
 (0)