Skip to content

Commit 7a0bdcb

Browse files
authored
feat: beforeEditorModeChange (experimental) (#341)
1 parent 14d4d3e commit 7a0bdcb

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

src/bundle/Editor.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ export interface EditorInt
104104

105105
type SetEditorModeOptions = Pick<ChangeEditorModeOptions, 'emit'>;
106106

107-
/** @internal */
108107
type ChangeEditorModeOptions = {
109108
mode: EditorMode;
110109
reason: 'error-boundary' | 'settings' | 'manually';
@@ -157,6 +156,9 @@ export type EditorOptions = Pick<
157156
* You can use it to pre-process the value from the markup editor before it gets into the wysiwyg editor.
158157
*/
159158
prepareRawMarkup?: (value: MarkupString) => MarkupString;
159+
experimental_beforeEditorModeChange?: (
160+
options: Pick<ChangeEditorModeOptions, 'mode' | 'reason'>,
161+
) => boolean | undefined;
160162
splitMode?: SplitMode;
161163
renderPreview?: RenderPreview;
162164
preset: EditorPreset;
@@ -188,6 +190,9 @@ export class EditorImpl extends SafeEventEmitter<EventMapInt> implements EditorI
188190
#fileUploadHandler?: FileUploadHandler;
189191
#needToSetDimensionsForUploadedImages: boolean;
190192
#prepareRawMarkup?: (value: MarkupString) => MarkupString;
193+
#beforeEditorModeChange?: (
194+
options: Pick<ChangeEditorModeOptions, 'mode' | 'reason'>,
195+
) => boolean | undefined;
191196

192197
get _wysiwygView(): PMEditorView {
193198
// @ts-expect-error internal typing
@@ -349,6 +354,7 @@ export class EditorImpl extends SafeEventEmitter<EventMapInt> implements EditorI
349354
);
350355
this.#prepareRawMarkup = opts.prepareRawMarkup;
351356
this.#escapeConfig = opts.escapeConfig;
357+
this.#beforeEditorModeChange = opts.experimental_beforeEditorModeChange;
352358
}
353359

354360
// ---> implements CodeEditor
@@ -385,8 +391,14 @@ export class EditorImpl extends SafeEventEmitter<EventMapInt> implements EditorI
385391

386392
changeEditorMode({emit = true, ...opts}: ChangeEditorModeOptions): void {
387393
if (this.#editorMode === opts.mode) return;
394+
395+
if (this.#beforeEditorModeChange?.({mode: opts.mode, reason: opts.reason}) === false) {
396+
return;
397+
}
398+
388399
this.currentMode = opts.mode;
389400
this.emit('rerender', null);
401+
390402
if (emit) {
391403
this.emit('change-editor-mode', opts);
392404
}

src/bundle/settings/index.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ const placement: PopupPlacement = ['bottom-end', 'top-end'];
3232
const bSettings = cn('editor-settings');
3333
const bContent = cn('settings-content');
3434

35-
export type EditorSettingsProps = SettingsContentProps & {renderPreviewButton?: boolean};
35+
export type EditorSettingsProps = Omit<SettingsContentProps, 'onClose'> & {
36+
renderPreviewButton?: boolean;
37+
};
3638

3739
export const EditorSettings = React.memo<EditorSettingsProps>(function EditorSettings(props) {
3840
const {className, onShowPreviewChange, showPreview, renderPreviewButton} = props;
@@ -79,14 +81,15 @@ export const EditorSettings = React.memo<EditorSettingsProps>(function EditorSet
7981
placement={placement}
8082
onClose={hidePopup}
8183
>
82-
<SettingsContent {...props} className={bSettings('content')} />
84+
<SettingsContent {...props} onClose={hidePopup} className={bSettings('content')} />
8385
</Popup>
8486
</div>
8587
);
8688
});
8789

8890
type SettingsContentProps = ClassNameProps & {
8991
mode: EditorMode;
92+
onClose: () => void;
9093
onModeChange: (mode: EditorMode) => void;
9194
onShowPreviewChange: (showPreview: boolean) => void;
9295
showPreview: boolean;
@@ -101,6 +104,7 @@ const mdHelpPlacement: PopupPlacement = ['bottom', 'bottom-end', 'right-start',
101104

102105
const SettingsContent: React.FC<SettingsContentProps> = function SettingsContent({
103106
mode,
107+
onClose,
104108
onModeChange,
105109
toolbarVisibility,
106110
onToolbarVisibilityChange,
@@ -115,14 +119,20 @@ const SettingsContent: React.FC<SettingsContentProps> = function SettingsContent
115119
<Menu size="l" className={bContent('mode')}>
116120
<Menu.Item
117121
active={mode === 'wysiwyg'}
118-
onClick={() => onModeChange('wysiwyg')}
122+
onClick={() => {
123+
onModeChange('wysiwyg');
124+
onClose();
125+
}}
119126
icon={<Icon data={WysiwygModeIcon} />}
120127
>
121128
{i18n('settings_wysiwyg')}
122129
</Menu.Item>
123130
<Menu.Item
124131
active={mode === 'markup'}
125-
onClick={() => onModeChange('markup')}
132+
onClick={() => {
133+
onModeChange('markup');
134+
onClose();
135+
}}
126136
icon={<Icon data={LogoMarkdown} />}
127137
>
128138
{i18n('settings_markup')}

0 commit comments

Comments
 (0)