@gravity-ui/markdown-editor 14.7.0 → 14.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +16 -14
  2. package/build/cjs/bundle/MarkdownEditorView.d.ts +27 -0
  3. package/build/cjs/bundle/MarkdownEditorView.js +19 -2
  4. package/build/cjs/bundle/config/action-names.d.ts +1 -1
  5. package/build/cjs/bundle/config/action-names.js +50 -27
  6. package/build/cjs/bundle/config/index.d.ts +3 -0
  7. package/build/cjs/bundle/config/index.js +3 -0
  8. package/build/cjs/bundle/config/markup.js +3 -0
  9. package/build/cjs/bundle/config/wysiwyg.d.ts +3 -0
  10. package/build/cjs/bundle/toolbar/utils.d.ts +17 -0
  11. package/build/cjs/bundle/toolbar/utils.js +64 -0
  12. package/build/cjs/extensions/markdown/Link/paste-plugin.js +21 -5
  13. package/build/cjs/i18n/menubar/en.json +1 -0
  14. package/build/cjs/i18n/menubar/index.d.ts +2 -1
  15. package/build/cjs/i18n/menubar/ru.json +1 -0
  16. package/build/cjs/markup/codemirror/create.js +24 -11
  17. package/build/cjs/markup/codemirror/smart-reindent/index.d.ts +4 -0
  18. package/build/cjs/markup/codemirror/smart-reindent/index.js +42 -0
  19. package/build/cjs/markup/codemirror/smart-reindent/utils.d.ts +15 -0
  20. package/build/cjs/markup/codemirror/smart-reindent/utils.js +59 -0
  21. package/build/cjs/modules/toolbars/constants.d.ts +13 -0
  22. package/build/cjs/modules/toolbars/constants.js +18 -0
  23. package/build/cjs/modules/toolbars/items.d.ts +127 -0
  24. package/build/cjs/modules/toolbars/items.js +736 -0
  25. package/build/cjs/modules/toolbars/presets.d.ts +6 -0
  26. package/build/cjs/modules/toolbars/presets.js +465 -0
  27. package/build/cjs/modules/toolbars/types.d.ts +62 -0
  28. package/build/cjs/modules/toolbars/types.js +2 -0
  29. package/build/cjs/toolbar/types.d.ts +8 -0
  30. package/build/cjs/toolbar/types.js +2 -0
  31. package/build/cjs/version.js +1 -1
  32. package/build/esm/bundle/MarkdownEditorView.d.ts +27 -0
  33. package/build/esm/bundle/MarkdownEditorView.js +19 -2
  34. package/build/esm/bundle/config/action-names.d.ts +1 -1
  35. package/build/esm/bundle/config/action-names.js +50 -27
  36. package/build/esm/bundle/config/index.d.ts +3 -0
  37. package/build/esm/bundle/config/index.js +3 -0
  38. package/build/esm/bundle/config/markup.js +3 -0
  39. package/build/esm/bundle/config/wysiwyg.d.ts +3 -0
  40. package/build/esm/bundle/toolbar/utils.d.ts +17 -0
  41. package/build/esm/bundle/toolbar/utils.js +59 -0
  42. package/build/esm/extensions/markdown/Link/paste-plugin.js +21 -5
  43. package/build/esm/i18n/menubar/en.json +1 -0
  44. package/build/esm/i18n/menubar/index.d.ts +2 -1
  45. package/build/esm/i18n/menubar/ru.json +1 -0
  46. package/build/esm/markup/codemirror/create.js +24 -11
  47. package/build/esm/markup/codemirror/smart-reindent/index.d.ts +4 -0
  48. package/build/esm/markup/codemirror/smart-reindent/index.js +38 -0
  49. package/build/esm/markup/codemirror/smart-reindent/utils.d.ts +15 -0
  50. package/build/esm/markup/codemirror/smart-reindent/utils.js +55 -0
  51. package/build/esm/modules/toolbars/constants.d.ts +13 -0
  52. package/build/esm/modules/toolbars/constants.js +15 -0
  53. package/build/esm/modules/toolbars/items.d.ts +127 -0
  54. package/build/esm/modules/toolbars/items.js +730 -0
  55. package/build/esm/modules/toolbars/presets.d.ts +6 -0
  56. package/build/esm/modules/toolbars/presets.js +462 -0
  57. package/build/esm/modules/toolbars/types.d.ts +62 -0
  58. package/build/esm/modules/toolbars/types.js +1 -0
  59. package/build/esm/toolbar/types.d.ts +8 -0
  60. package/build/esm/toolbar/types.js +2 -0
  61. package/build/esm/version.js +1 -1
  62. package/package.json +10 -2
package/README.md CHANGED
@@ -52,15 +52,21 @@ function Editor({onSubmit}) {
52
52
  }
53
53
  ```
54
54
  Read more:
55
- - [How to connect the editor in the Create React App](https://github.com/gravity-ui/markdown-editor/blob/main/docs/how-to-add-editor-with-create-react-app.md)
56
- - [How to add preview for markup mode](https://github.com/gravity-ui/markdown-editor/blob/main/docs/how-to-add-preview.md)
57
- - [How to add HTML extension](https://github.com/gravity-ui/markdown-editor/blob/main/docs/how-to-connect-html-extension.md)
58
- - [How to add Latex extension](https://github.com/gravity-ui/markdown-editor/blob/main/docs/how-to-connect-latex-extension.md)
59
- - [How to add Mermaid extension](https://github.com/gravity-ui/markdown-editor/blob/main/docs/how-to-connect-mermaid-extension.md)
60
- - [How to write extension](https://github.com/gravity-ui/markdown-editor/blob/main/docs/how-to-create-extension.md)
61
- - [How to add GPT extension](https://github.com/gravity-ui/markdown-editor/blob/main/docs/how-to-connect-gpt-extensions.md)
62
- - [How to add text binding extension in markdown](https://github.com/gravity-ui/markdown-editor/blob/main/docs/how-to-add-text-binding-extension-in-markdown.md)
55
+ - [How to connect the editor in the Create React App](https://preview.gravity-ui.com/md-editor/?path=/docs/docs-install-create-react-app--docs)
56
+ - [How to add preview for markup mode](https://preview.gravity-ui.com/md-editor/?path=/docs/docs-develop-preview--docs)
57
+ - [How to add HTML extension](https://preview.gravity-ui.com/md-editor/?path=/docs/docs-connect-html-block--docs)
58
+ - [How to add Latex extension](https://preview.gravity-ui.com/md-editor/?path=/docs/docs-connect-latex-extension--docs)
59
+ - [How to add Mermaid extension](https://preview.gravity-ui.com/md-editor/?path=/docs/docs-connect-mermaid-extension--docs)
60
+ - [How to write extension](https://preview.gravity-ui.com/md-editor/?path=/docs/docs-develop-extension-creation--docs)
61
+ - [How to add GPT extension](https://preview.gravity-ui.com/md-editor/?path=/docs/docs-connect-gpt--docs)
62
+ - [How to add text binding extension in markdown](https://preview.gravity-ui.com/md-editor/?path=/docs/docs-develop-extension-with-popup--docs)
63
+
64
+ ### Development
65
+ To start the dev storybook
63
66
 
67
+ ```shell
68
+ npm start
69
+ ```
64
70
 
65
71
 
66
72
  ### i18n
@@ -77,10 +83,6 @@ configure({
77
83
 
78
84
  Don't forget to call `configure()` from [UIKit](https://github.com/gravity-ui/uikit?tab=readme-ov-file#i18n) and other UI libraries.
79
85
 
80
- ## Development
86
+ ### Contributing
81
87
 
82
- To start the dev storybook
83
-
84
- ```shell
85
- npm start
86
- ```
88
+ - [Contributor Guidelines](https://preview.gravity-ui.com/md-editor/?path=/docs/docs-contributing--docs)
@@ -1,15 +1,29 @@
1
1
  import React from 'react';
2
2
  import type { ToasterPublicMethods } from '@gravity-ui/uikit';
3
3
  import { ClassNameProps } from '../classname';
4
+ import type { ToolbarsPreset } from '../modules/toolbars/types';
4
5
  import type { Editor } from './Editor';
5
6
  import { MToolbarData, MToolbarItemData, WToolbarData, WToolbarItemData } from './config';
6
7
  export declare const cnEditorComponent: import("@bem-react/classname").ClassNameFormatter;
7
8
  export declare type MarkdownEditorViewProps = ClassNameProps & {
8
9
  editor?: Editor;
9
10
  autofocus?: boolean;
11
+ toolbarsPreset?: ToolbarsPreset;
12
+ /**
13
+ * @deprecated use `toolbarsPreset` instead
14
+ */
10
15
  markupToolbarConfig?: MToolbarData;
16
+ /**
17
+ * @deprecated use `toolbarsPreset` instead
18
+ */
11
19
  wysiwygToolbarConfig?: WToolbarData;
20
+ /**
21
+ * @deprecated use `toolbarsPreset` instead
22
+ */
12
23
  markupHiddenActionsConfig?: MToolbarItemData[];
24
+ /**
25
+ * @deprecated use `toolbarsPreset` instead
26
+ */
13
27
  wysiwygHiddenActionsConfig?: WToolbarItemData[];
14
28
  /** @default true */
15
29
  settingsVisible?: boolean;
@@ -21,9 +35,22 @@ export declare type MarkdownEditorViewProps = ClassNameProps & {
21
35
  export declare const MarkdownEditorView: React.ForwardRefExoticComponent<ClassNameProps & {
22
36
  editor?: Editor | undefined;
23
37
  autofocus?: boolean | undefined;
38
+ toolbarsPreset?: ToolbarsPreset | undefined;
39
+ /**
40
+ * @deprecated use `toolbarsPreset` instead
41
+ */
24
42
  markupToolbarConfig?: MToolbarData | undefined;
43
+ /**
44
+ * @deprecated use `toolbarsPreset` instead
45
+ */
25
46
  wysiwygToolbarConfig?: WToolbarData | undefined;
47
+ /**
48
+ * @deprecated use `toolbarsPreset` instead
49
+ */
26
50
  markupHiddenActionsConfig?: MToolbarItemData[] | undefined;
51
+ /**
52
+ * @deprecated use `toolbarsPreset` instead
53
+ */
27
54
  wysiwygHiddenActionsConfig?: WToolbarItemData[] | undefined;
28
55
  /** @default true */
29
56
  settingsVisible?: boolean | undefined;
@@ -14,10 +14,10 @@ const HorizontalDrag_1 = require("./HorizontalDrag");
14
14
  const MarkupEditorView_1 = require("./MarkupEditorView");
15
15
  const SplitModeView_1 = require("./SplitModeView");
16
16
  const WysiwygEditorView_1 = require("./WysiwygEditorView");
17
- const config_1 = require("./config");
18
17
  const context_1 = require("./context");
19
18
  const settings_1 = require("./settings");
20
19
  const sticky_1 = require("./sticky");
20
+ const utils_2 = require("./toolbar/utils");
21
21
  // eslint-disable-line import/order
22
22
  exports.cnEditorComponent = (0, classname_1.cn)('editor-component');
23
23
  const b = exports.cnEditorComponent;
@@ -33,7 +33,24 @@ exports.MarkdownEditorView = react_1.default.forwardRef((props, ref) => {
33
33
  const editor = ((_a = props.editor) !== null && _a !== void 0 ? _a : context);
34
34
  if (!editor)
35
35
  throw new Error('[MarkdownEditorView]: an instance of the editor must be passed through the props or context');
36
- const { autofocus, className, settingsVisible = true, markupToolbarConfig = config_1.mToolbarConfigByPreset[editor.preset], wysiwygToolbarConfig = config_1.wToolbarConfigByPreset[editor.preset], markupHiddenActionsConfig = config_1.mHiddenDataByPreset[editor.preset], wysiwygHiddenActionsConfig = config_1.wHiddenDataByPreset[editor.preset], toaster, stickyToolbar, enableSubmitInPreview = true, hidePreviewAfterSubmit = false, } = props;
36
+ const { autofocus, className, settingsVisible = true, toolbarsPreset, toaster, stickyToolbar, wysiwygToolbarConfig: initialWysiwygToolbarConfig, markupToolbarConfig: initialMarkupToolbarConfig, wysiwygHiddenActionsConfig: initialWysiwygHiddenActionsConfig, markupHiddenActionsConfig: initialMarkupHiddenActionsConfig, enableSubmitInPreview = true, hidePreviewAfterSubmit = false, } = props;
37
+ const { wysiwygToolbarConfig, markupToolbarConfig, wysiwygHiddenActionsConfig, markupHiddenActionsConfig, } = (0, react_1.useMemo)(() => (0, utils_2.getToolbarsConfigs)({
38
+ toolbarsPreset,
39
+ props: {
40
+ wysiwygToolbarConfig: initialWysiwygToolbarConfig,
41
+ markupToolbarConfig: initialMarkupToolbarConfig,
42
+ wysiwygHiddenActionsConfig: initialWysiwygHiddenActionsConfig,
43
+ markupHiddenActionsConfig: initialMarkupHiddenActionsConfig,
44
+ },
45
+ preset: editor.preset,
46
+ }), [
47
+ toolbarsPreset,
48
+ initialWysiwygToolbarConfig,
49
+ initialMarkupToolbarConfig,
50
+ initialWysiwygHiddenActionsConfig,
51
+ initialMarkupHiddenActionsConfig,
52
+ editor.preset,
53
+ ]);
37
54
  const rerender = (0, react_use_1.useUpdate)();
38
55
  react_1.default.useLayoutEffect(() => {
39
56
  editor.on('rerender', rerender);
@@ -1,3 +1,3 @@
1
- declare const namesObj: Record<"bold" | "mono" | "link" | "italic" | "strike" | "underline" | "mark" | "quote" | "paragraph" | "anchor" | "table" | "image" | "code_inline" | "code_block" | "file" | "checkbox" | "emoji" | "undo" | "redo" | "heading1" | "heading2" | "heading3" | "heading4" | "heading5" | "heading6" | "bulletList" | "orderedList" | "liftListItem" | "sinkListItem" | "yfm_cut" | "yfm_note" | "yfm_block" | "yfm_html_block" | "yfm_layout" | "horizontalrule" | "math_inline" | "math_block" | "tabs" | "mermaid" | "gpt", string>;
1
+ declare const namesObj: Record<"bold" | "colorify" | "mono" | "link" | "italic" | "strike" | "underline" | "mark" | "quote" | "block" | "paragraph" | "cut" | "anchor" | "table" | "image" | "code_inline" | "code_block" | "note" | "file" | "codeBlock" | "checkbox" | "emoji" | "bulletList" | "codeInline" | "filePopup" | "gpt" | "heading1" | "heading2" | "heading3" | "heading4" | "heading5" | "heading6" | "horizontalrule" | "horizontalRule" | "imagePopup" | "liftListItem" | "math_block" | "mathBlock" | "math_inline" | "mathInline" | "mermaid" | "orderedList" | "redo" | "sinkListItem" | "tabs" | "undo" | "yfm_block" | "yfm_cut" | "yfm_html_block" | "htmlBlock" | "yfm_layout" | "layout" | "yfm_note", string>;
2
2
  export declare const ActionName: Readonly<typeof namesObj>;
3
3
  export {};
@@ -2,46 +2,69 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ActionName = void 0;
4
4
  const names = [
5
- 'undo',
6
- 'redo',
5
+ 'anchor',
7
6
  'bold',
8
- 'italic',
9
- 'underline',
10
- 'strike',
11
- 'mono',
12
- 'mark',
13
- 'paragraph',
7
+ 'bulletList',
8
+ 'checkbox',
9
+ /** @deprecated use codeBlock */
10
+ 'code_block',
11
+ 'codeBlock',
12
+ /** @deprecated use codeInline */
13
+ 'code_inline',
14
+ 'codeInline',
15
+ 'colorify',
16
+ 'emoji',
17
+ 'file',
18
+ 'filePopup',
19
+ 'gpt',
14
20
  'heading1',
15
21
  'heading2',
16
22
  'heading3',
17
23
  'heading4',
18
24
  'heading5',
19
25
  'heading6',
20
- 'bulletList',
21
- 'orderedList',
26
+ /** @deprecated use horizontalRule */
27
+ 'horizontalrule',
28
+ 'horizontalRule',
29
+ 'image',
30
+ 'imagePopup',
31
+ 'italic',
22
32
  'liftListItem',
23
- 'sinkListItem',
24
- 'checkbox',
25
33
  'link',
34
+ 'mark',
35
+ /** @deprecated use mathBlock */
36
+ 'math_block',
37
+ 'mathBlock',
38
+ /** @deprecated use mathInline */
39
+ 'math_inline',
40
+ 'mathInline',
41
+ 'mermaid',
42
+ 'mono',
43
+ 'orderedList',
44
+ 'paragraph',
26
45
  'quote',
27
- 'yfm_cut',
28
- 'yfm_note',
46
+ 'redo',
47
+ 'sinkListItem',
48
+ 'strike',
49
+ 'table',
50
+ 'tabs',
51
+ 'underline',
52
+ 'undo',
53
+ /** @deprecated use block */
29
54
  'yfm_block',
55
+ 'block',
56
+ /** @deprecated use cut */
57
+ 'yfm_cut',
58
+ 'cut',
59
+ /** @deprecated use htmlBlock */
30
60
  'yfm_html_block',
61
+ 'htmlBlock',
62
+ /** @deprecated use layout */
31
63
  'yfm_layout',
32
- 'table',
33
- 'code_inline',
34
- 'code_block',
35
- 'image',
36
- 'horizontalrule',
37
- 'emoji',
38
- 'file',
39
- 'anchor',
40
- 'math_inline',
41
- 'math_block',
42
- 'tabs',
43
- 'mermaid',
44
- 'gpt',
64
+ 'layout',
65
+ /** @deprecated use note */
66
+ 'yfm_note',
67
+ 'note',
45
68
  ];
46
69
  const namesObj = names.reduce((obj, val) => {
47
70
  obj[val] = val;
@@ -1,2 +1,5 @@
1
+ /**
2
+ * @deprecated This file is deprecated. Use ToolbarsPreset instead.
3
+ */
1
4
  export * from './wysiwyg';
2
5
  export * from './markup';
@@ -1,5 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
+ /**
5
+ * @deprecated This file is deprecated. Use ToolbarsPreset instead.
6
+ */
4
7
  tslib_1.__exportStar(require("./wysiwyg"), exports);
5
8
  tslib_1.__exportStar(require("./markup"), exports);
@@ -3,6 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.mListMoveListConfig = exports.mListsListConfig = exports.mHeadingListConfig = exports.mLiftListItemData = exports.mSinkListItemData = exports.mOrderedListItemData = exports.mBulletListItemData = exports.mHeading6ItemData = exports.mHeading5ItemData = exports.mHeading4ItemData = exports.mHeading3ItemData = exports.mHeading2ItemData = exports.mHeading1ItemData = exports.mMathListItem = exports.mEmojiItemData = exports.mHruleItemData = exports.mCodeBlockItemData = exports.mCodeblockItemData = exports.mMermaidItemData = exports.mMermaidButton = exports.mYfmHtmlBlockItemData = exports.mYfmHtmlBlockButton = exports.mMathBlockItemData = exports.mMathInlineItemData = exports.mTabsItemData = exports.mFileItemData = exports.mFilePopupData = exports.mImageItemData = exports.mImagePopupData = exports.mCodeItemData = exports.mTableItemData = exports.mTableButton = exports.mNoteItemData = exports.mNoteButton = exports.mCutItemData = exports.mCutButton = exports.mQuoteItemData = exports.mQuoteButton = exports.mLinkItemData = exports.mLinkButton = exports.mCheckboxItemData = exports.mCheckboxButton = exports.mMarkedItemData = exports.mMonospaceItemData = exports.mStrikethroughItemData = exports.mUnderlineItemData = exports.mItalicItemData = exports.mBoldItemData = exports.mRedoItemData = exports.mUndoItemData = void 0;
4
4
  exports.mHiddenDataByPreset = exports.mToolbarConfigByPreset = exports.mToolbarConfig = exports.mBiusGroupConfig = exports.mHistoryGroupConfig = exports.mHiddenData = exports.mMathListConfig = exports.mCodeListConfig = void 0;
5
5
  const tslib_1 = require("tslib");
6
+ /**
7
+ * @deprecated This file is deprecated. Use ToolbarsPreset instead.
8
+ */
6
9
  const react_1 = tslib_1.__importDefault(require("react"));
7
10
  const menubar_1 = require("../../i18n/menubar");
8
11
  const commands_1 = require("../../markup/commands");
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @deprecated This file is deprecated. Use ToolbarsPreset instead.
3
+ */
1
4
  import { ActionStorage } from 'src/core';
2
5
  import type { SelectionContextConfig, SelectionContextItemData } from '../../extensions/behavior/SelectionContext';
3
6
  import { ToolbarGroupItemData, ToolbarItemData, ToolbarListButtonItemData, ToolbarListItemData, ToolbarSingleItemData } from '../../toolbar';
@@ -0,0 +1,17 @@
1
+ import type { ToolbarsPreset } from '../../modules/toolbars/types';
2
+ import type { MToolbarData, MToolbarItemData, WToolbarData, WToolbarItemData } from '../../toolbar';
3
+ import type { MarkdownEditorViewProps } from '../MarkdownEditorView';
4
+ import { MarkdownEditorPreset } from '../types';
5
+ export declare const createConfig: <T extends MToolbarData | WToolbarData>(editorType: 'wysiwyg' | 'markup', toolbarPreset: ToolbarsPreset | MarkdownEditorPreset, toolbarName: string) => T;
6
+ interface GetToolbarsConfigsArgs {
7
+ toolbarsPreset?: ToolbarsPreset;
8
+ props: Pick<MarkdownEditorViewProps, 'markupToolbarConfig' | 'wysiwygToolbarConfig' | 'wysiwygHiddenActionsConfig' | 'markupHiddenActionsConfig'>;
9
+ preset: MarkdownEditorPreset;
10
+ }
11
+ export declare const getToolbarsConfigs: ({ toolbarsPreset, props, preset }: GetToolbarsConfigsArgs) => {
12
+ wysiwygToolbarConfig: WToolbarData;
13
+ markupToolbarConfig: MToolbarData;
14
+ wysiwygHiddenActionsConfig: WToolbarItemData[];
15
+ markupHiddenActionsConfig: MToolbarItemData[];
16
+ };
17
+ export {};
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getToolbarsConfigs = exports.createConfig = void 0;
4
+ const constants_1 = require("../../modules/toolbars/constants");
5
+ const presets_1 = require("../../modules/toolbars/presets");
6
+ const toolbar_1 = require("../../toolbar");
7
+ const defaultPresets = {
8
+ zero: presets_1.zero,
9
+ commonmark: presets_1.commonmark,
10
+ default: presets_1.defaultPreset,
11
+ yfm: presets_1.yfm,
12
+ full: presets_1.full,
13
+ };
14
+ const transformItem = (type, item, id = 'unknown') => {
15
+ var _a;
16
+ if (!item) {
17
+ console.warn(`Toolbar item "${id}" not found, it might not have been added to the items dictionary.`);
18
+ return {};
19
+ }
20
+ const isListButton = item.view.type === toolbar_1.ToolbarDataType.ListButton;
21
+ return Object.assign(Object.assign(Object.assign({ type: (_a = item.view.type) !== null && _a !== void 0 ? _a : toolbar_1.ToolbarDataType.SingleButton, id, title: item.view.title, hint: item.view.hint, icon: item.view.icon, hotkey: item.view.hotkey }, (isListButton && { withArrow: item.view.withArrow })), (type === 'wysiwyg' && item.wysiwyg && Object.assign({}, item.wysiwyg))), (type === 'markup' && item.markup && Object.assign({}, item.markup)));
22
+ };
23
+ const createConfig = (editorType, toolbarPreset, toolbarName) => {
24
+ var _a;
25
+ const preset = typeof toolbarPreset === 'string'
26
+ ? defaultPresets[toolbarPreset] || defaultPresets.default
27
+ : toolbarPreset;
28
+ const orders = (_a = preset.orders[toolbarName]) !== null && _a !== void 0 ? _a : [[]];
29
+ const { items } = preset;
30
+ const toolbarData = orders.map((group) => group.map((action) => {
31
+ return typeof action === 'string'
32
+ ? transformItem(editorType, items[action], action)
33
+ : Object.assign(Object.assign({}, transformItem(editorType, items[action.id], action.id)), { data: action.items.map((id) => transformItem(editorType, items[id], id)) });
34
+ }));
35
+ return toolbarData;
36
+ };
37
+ exports.createConfig = createConfig;
38
+ const flattenPreset = (config) => {
39
+ var _a;
40
+ // TODO: @makhnatkin add logic for flatten
41
+ return ((_a = config[0]) !== null && _a !== void 0 ? _a : []);
42
+ };
43
+ const getToolbarsConfigs = ({ toolbarsPreset, props, preset }) => {
44
+ var _a, _b, _c, _d;
45
+ const wysiwygToolbarConfig = toolbarsPreset
46
+ ? (0, exports.createConfig)('wysiwyg', toolbarsPreset, constants_1.ToolbarName.wysiwygMain)
47
+ : (_a = props.wysiwygToolbarConfig) !== null && _a !== void 0 ? _a : (0, exports.createConfig)('wysiwyg', preset, constants_1.ToolbarName.wysiwygMain);
48
+ const markupToolbarConfig = toolbarsPreset
49
+ ? (0, exports.createConfig)('markup', toolbarsPreset, constants_1.ToolbarName.markupMain)
50
+ : (_b = props.markupToolbarConfig) !== null && _b !== void 0 ? _b : (0, exports.createConfig)('markup', preset, constants_1.ToolbarName.markupMain);
51
+ const wysiwygHiddenActionsConfig = toolbarsPreset
52
+ ? flattenPreset((0, exports.createConfig)('wysiwyg', toolbarsPreset, constants_1.ToolbarName.wysiwygHidden))
53
+ : (_c = props.wysiwygHiddenActionsConfig) !== null && _c !== void 0 ? _c : flattenPreset((0, exports.createConfig)('wysiwyg', preset, constants_1.ToolbarName.wysiwygHidden));
54
+ const markupHiddenActionsConfig = toolbarsPreset
55
+ ? flattenPreset((0, exports.createConfig)('markup', toolbarsPreset, constants_1.ToolbarName.markupHidden))
56
+ : (_d = props.markupHiddenActionsConfig) !== null && _d !== void 0 ? _d : flattenPreset((0, exports.createConfig)('markup', preset, constants_1.ToolbarName.markupHidden));
57
+ return {
58
+ wysiwygToolbarConfig,
59
+ markupToolbarConfig,
60
+ wysiwygHiddenActionsConfig,
61
+ markupHiddenActionsConfig,
62
+ };
63
+ };
64
+ exports.getToolbarsConfigs = getToolbarsConfigs;
@@ -13,21 +13,37 @@ function linkPasteEnhance({ markupParser: parser }) {
13
13
  paste(view, e) {
14
14
  const { state, dispatch } = view;
15
15
  const sel = state.selection;
16
+ let tr = null;
16
17
  if ((0, selection_1.isTextSelection)(sel) ||
17
18
  ((0, selection_1.isNodeSelection)(sel) && sel.node.type === (0, Image_1.imageType)(state.schema))) {
18
19
  const { $from, $to } = sel;
19
- if ($from.pos !== $to.pos && $from.sameParent($to)) {
20
+ if ($from.pos === $to.pos) {
20
21
  const url = getUrl(e.clipboardData, parser);
21
22
  if (url) {
22
- const tr = state.tr.addMark($from.pos, $to.pos, (0, index_1.linkType)(state.schema).create({
23
+ const linkMarkType = (0, index_1.linkType)(state.schema);
24
+ tr = state.tr.replaceSelectionWith(state.schema.text(url, [
25
+ ...$from
26
+ .marks()
27
+ .filter((mark) => mark.type !== linkMarkType),
28
+ linkMarkType.create({ [index_1.LinkAttr.Href]: url }),
29
+ ]), false);
30
+ }
31
+ }
32
+ else if ($from.sameParent($to)) {
33
+ const url = getUrl(e.clipboardData, parser);
34
+ if (url) {
35
+ tr = state.tr.addMark($from.pos, $to.pos, (0, index_1.linkType)(state.schema).create({
23
36
  [index_1.LinkAttr.Href]: url,
24
37
  }));
25
- dispatch(tr.setSelection(prosemirror_state_1.TextSelection.create(tr.doc, $to.pos)));
26
- e.preventDefault();
27
- return true;
38
+ tr.setSelection(prosemirror_state_1.TextSelection.create(tr.doc, $to.pos));
28
39
  }
29
40
  }
30
41
  }
42
+ if (tr) {
43
+ dispatch(tr.scrollIntoView());
44
+ e.preventDefault();
45
+ return true;
46
+ }
31
47
  return false;
32
48
  },
33
49
  },
@@ -44,6 +44,7 @@
44
44
  "mermaid": "Mermaid",
45
45
  "mono": "Monospace",
46
46
  "more_action": "More action",
47
+ "move_list": "Move list item",
47
48
  "note": "Note",
48
49
  "olist": "Ordered list",
49
50
  "quote": "Quote",
@@ -1,4 +1,4 @@
1
- export declare const i18n: <G extends "bold" | "code" | "colorify" | "mono" | "link" | "italic" | "strike" | "underline" | "mark" | "quote" | "text" | "html" | "cut" | "table" | "image" | "code_inline" | "list" | "heading" | "note" | "file" | "checkbox" | "emoji" | "undo" | "redo" | "heading1" | "heading2" | "heading3" | "heading4" | "heading5" | "heading6" | "math_inline" | "math_block" | "tabs" | "mermaid" | "gpt" | "codeblock" | "math" | "colorify__color_blue" | "colorify__color_default" | "colorify__color_gray" | "colorify__color_green" | "colorify__color_orange" | "colorify__color_red" | "colorify__color_violet" | "colorify__color_yellow" | "colorify__group_text" | "emoji__hint" | "folding-heading" | "folding-heading__hint" | "hrule" | "list__action_lift" | "list__action_sink" | "list_action_disabled" | "more_action" | "olist" | "ulist", S extends string>(key: G | (string extends S ? S : never), params?: {
1
+ export declare const i18n: <G extends "bold" | "code" | "colorify" | "mono" | "link" | "italic" | "strike" | "underline" | "mark" | "quote" | "text" | "html" | "cut" | "table" | "image" | "code_inline" | "list" | "heading" | "note" | "file" | "checkbox" | "emoji" | "gpt" | "heading1" | "heading2" | "heading3" | "heading4" | "heading5" | "heading6" | "math_block" | "math_inline" | "mermaid" | "redo" | "tabs" | "undo" | "codeblock" | "math" | "colorify__color_blue" | "colorify__color_default" | "colorify__color_gray" | "colorify__color_green" | "colorify__color_orange" | "colorify__color_red" | "colorify__color_violet" | "colorify__color_yellow" | "colorify__group_text" | "emoji__hint" | "folding-heading" | "folding-heading__hint" | "hrule" | "list__action_lift" | "list__action_sink" | "list_action_disabled" | "more_action" | "move_list" | "olist" | "ulist", S extends string>(key: G | (string extends S ? S : never), params?: {
2
2
  [key: string]: any;
3
3
  } | undefined) => S extends G ? {
4
4
  bold: string;
@@ -46,6 +46,7 @@ export declare const i18n: <G extends "bold" | "code" | "colorify" | "mono" | "l
46
46
  mermaid: string;
47
47
  mono: string;
48
48
  more_action: string;
49
+ move_list: string;
49
50
  note: string;
50
51
  olist: string;
51
52
  quote: string;
@@ -44,6 +44,7 @@
44
44
  "mermaid": "Mermaid",
45
45
  "mono": "Моноширинный",
46
46
  "more_action": "Другие действия",
47
+ "move_list": "Переместить элемент списка",
47
48
  "note": "Примечание",
48
49
  "olist": "Нумерованный список",
49
50
  "quote": "Цитата",
@@ -17,6 +17,7 @@ const converters_1 = require("./html-to-markdown/converters");
17
17
  const pairing_chars_1 = require("./pairing-chars");
18
18
  const react_facet_1 = require("./react-facet");
19
19
  const plugin_1 = require("./search-plugin/plugin");
20
+ const smart_reindent_1 = require("./smart-reindent");
20
21
  const yfm_1 = require("./yfm");
21
22
  function createCodemirror(params) {
22
23
  const { doc, reactRenderer, onCancel, onScroll, onSubmit, onChange, onDocChange, disabledExtensions = {}, keymaps = [], receiver, yfmLangOptions, extensions: extraExtensions, placeholder: placeholderContent, autocompletion: autocompletionConfig, parseHtmlOnPaste, parseInsertedUrlAsImage, directiveSyntax, } = params;
@@ -73,12 +74,16 @@ function createCodemirror(params) {
73
74
  var _a;
74
75
  if (!event.clipboardData)
75
76
  return;
77
+ const { from } = editor.state.selection.main;
78
+ const line = editor.state.doc.lineAt(from);
79
+ const currentLine = line.text;
76
80
  // if clipboard contains YFM content - avoid any meddling with pasted content
77
81
  // since text/yfm will contain valid markdown
78
82
  const yfmContent = event.clipboardData.getData(clipboard_1.DataTransferType.Yfm);
79
83
  if (yfmContent) {
80
84
  event.preventDefault();
81
- editor.dispatch(editor.state.replaceSelection(yfmContent));
85
+ const reindentedYfmContent = (0, smart_reindent_1.smartReindent)(yfmContent, currentLine);
86
+ editor.dispatch(editor.state.replaceSelection(reindentedYfmContent));
82
87
  return;
83
88
  }
84
89
  // checking if a copy buffer content is suitable for convertion
@@ -103,23 +108,31 @@ function createCodemirror(params) {
103
108
  }
104
109
  if (parsedMarkdownMarkup !== undefined) {
105
110
  event.preventDefault();
106
- editor.dispatch(editor.state.replaceSelection(parsedMarkdownMarkup));
111
+ const reindentedHtmlContent = (0, smart_reindent_1.smartReindent)(parsedMarkdownMarkup, currentLine);
112
+ editor.dispatch(editor.state.replaceSelection(reindentedHtmlContent));
107
113
  return;
108
114
  }
109
115
  }
110
116
  if (parseInsertedUrlAsImage) {
111
117
  const { imageUrl, title } = parseInsertedUrlAsImage((_a = event.clipboardData.getData(clipboard_1.DataTransferType.Text)) !== null && _a !== void 0 ? _a : '') || {};
112
- if (!imageUrl) {
113
- return;
118
+ if (imageUrl) {
119
+ event.preventDefault();
120
+ (0, commands_2.insertImages)([
121
+ {
122
+ url: imageUrl,
123
+ alt: title,
124
+ title,
125
+ },
126
+ ])(editor);
114
127
  }
128
+ }
129
+ // Reindenting pasted plain text
130
+ const pastedText = event.clipboardData.getData(clipboard_1.DataTransferType.Text);
131
+ const reindentedText = (0, smart_reindent_1.smartReindent)(pastedText, currentLine);
132
+ // but only if there is a need for reindentation
133
+ if (pastedText !== reindentedText) {
134
+ editor.dispatch(editor.state.replaceSelection(reindentedText));
115
135
  event.preventDefault();
116
- (0, commands_2.insertImages)([
117
- {
118
- url: imageUrl,
119
- alt: title,
120
- title,
121
- },
122
- ])(editor);
123
136
  }
124
137
  },
125
138
  }), (0, plugin_1.SearchPanelPlugin)({
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Reindents pasted text based on the current line's markers
3
+ */
4
+ export declare function smartReindent(pastedText: string, currentLineText: string): string;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.smartReindent = void 0;
4
+ const utils_1 = require("./utils");
5
+ /**
6
+ * Reindents pasted text based on the current line's markers
7
+ */
8
+ function smartReindent(pastedText, currentLineText) {
9
+ // If current line is empty, return pasted text as is
10
+ if (currentLineText.length === 0) {
11
+ return pastedText;
12
+ }
13
+ // Get markers from current line
14
+ const markers = (0, utils_1.parseMarkers)(currentLineText);
15
+ // If no markers found, return pasted text as is
16
+ if (markers.length === 0) {
17
+ return pastedText;
18
+ }
19
+ // Create indentation for subsequent lines by replacing list markers with spaces
20
+ const subsequentIndent = markers
21
+ .map((marker) => {
22
+ if (marker.match(/^\d{1,6}\. |-|\*|\+/)) {
23
+ return ' '.repeat(marker.length);
24
+ }
25
+ return marker;
26
+ })
27
+ .join('');
28
+ // Split and process the pasted text
29
+ const lines = pastedText.split('\n');
30
+ const reindentedText = lines
31
+ .map((line, index) => {
32
+ // First line doesn't need indentation
33
+ if (index === 0) {
34
+ return line;
35
+ }
36
+ // Add indentation to all subsequent lines, including empty ones
37
+ return subsequentIndent + line;
38
+ })
39
+ .join('\n');
40
+ return reindentedText;
41
+ }
42
+ exports.smartReindent = smartReindent;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Parses markdown-style markers from the start of a line
3
+ * Returns an array of markers found:
4
+ * - ' ' for indentation
5
+ * - '> ' for blockquotes
6
+ * - '* ' or '- ' for list items
7
+ * - '1. ' for numbered lists
8
+ *
9
+ * Example inputs:
10
+ * " * list" -> [' ', '* ']
11
+ * "> quoted" -> ['> ']
12
+ * " nested" -> [' ', ' ']
13
+ * "1. list" -> ['1. ']
14
+ */
15
+ export declare function parseMarkers(text: string): string[];
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseMarkers = void 0;
4
+ /**
5
+ * Parses markdown-style markers from the start of a line
6
+ * Returns an array of markers found:
7
+ * - ' ' for indentation
8
+ * - '> ' for blockquotes
9
+ * - '* ' or '- ' for list items
10
+ * - '1. ' for numbered lists
11
+ *
12
+ * Example inputs:
13
+ * " * list" -> [' ', '* ']
14
+ * "> quoted" -> ['> ']
15
+ * " nested" -> [' ', ' ']
16
+ * "1. list" -> ['1. ']
17
+ */
18
+ function parseMarkers(text) {
19
+ const markers = [];
20
+ let pos = 0;
21
+ while (pos < text.length) {
22
+ // Handle code block (4 spaces)
23
+ if (pos + 3 < text.length &&
24
+ text[pos] === ' ' &&
25
+ text[pos + 1] === ' ' &&
26
+ text[pos + 2] === ' ' &&
27
+ text[pos + 3] === ' ') {
28
+ markers.push(' ');
29
+ pos += 4;
30
+ continue;
31
+ }
32
+ // Handle numbered lists (1-6 digits followed by dot and space)
33
+ if (/^\d{1,6}\. /.test(text.slice(pos))) {
34
+ const match = text.slice(pos).match(/^(\d{1,6}\. )/);
35
+ if (match) {
36
+ markers.push(match[1]);
37
+ pos += match[1].length;
38
+ continue;
39
+ }
40
+ }
41
+ // Handle block quotes and list markers
42
+ if (text[pos] === '>' || text[pos] === '-' || text[pos] === '*' || text[pos] === '+') {
43
+ if (pos + 1 < text.length && text[pos + 1] === ' ') {
44
+ markers.push(text[pos] + ' ');
45
+ pos += 2;
46
+ continue;
47
+ }
48
+ }
49
+ // Handle single space (last priority)
50
+ if (text[pos] === ' ') {
51
+ markers.push(' ');
52
+ pos += 1;
53
+ continue;
54
+ }
55
+ break;
56
+ }
57
+ return markers;
58
+ }
59
+ exports.parseMarkers = parseMarkers;