@uiw/react-md-editor 3.8.0 → 3.8.4

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 (63) hide show
  1. package/README.md +1 -1
  2. package/esm/Context.d.ts +0 -2
  3. package/esm/Context.js.map +2 -2
  4. package/esm/Editor.d.ts +1 -1
  5. package/esm/Editor.js +11 -4
  6. package/esm/Editor.js.map +4 -2
  7. package/esm/commands/title1.js +5 -6
  8. package/esm/commands/title1.js.map +9 -5
  9. package/esm/commands/title2.js +5 -6
  10. package/esm/commands/title2.js.map +9 -5
  11. package/esm/commands/title3.js +5 -6
  12. package/esm/commands/title3.js.map +9 -5
  13. package/esm/commands/title4.js +5 -6
  14. package/esm/commands/title4.js.map +9 -5
  15. package/esm/commands/title5.js +5 -6
  16. package/esm/commands/title5.js.map +9 -5
  17. package/esm/commands/title6.js +5 -6
  18. package/esm/commands/title6.js.map +9 -5
  19. package/esm/components/TextArea/Textarea.js +2 -4
  20. package/esm/components/TextArea/Textarea.js.map +2 -3
  21. package/esm/components/TextArea/index.d.ts +3 -2
  22. package/esm/components/TextArea/index.js +1 -2
  23. package/esm/components/TextArea/index.js.map +3 -3
  24. package/esm/utils/InsertTextAtPosition.d.ts +7 -0
  25. package/esm/utils/InsertTextAtPosition.js +27 -1
  26. package/esm/utils/InsertTextAtPosition.js.map +14 -6
  27. package/lib/Context.d.ts +0 -2
  28. package/lib/Context.js.map +2 -2
  29. package/lib/Editor.d.ts +1 -1
  30. package/lib/Editor.js +13 -4
  31. package/lib/Editor.js.map +4 -2
  32. package/lib/commands/title1.js +6 -6
  33. package/lib/commands/title1.js.map +8 -5
  34. package/lib/commands/title2.js +6 -6
  35. package/lib/commands/title2.js.map +8 -5
  36. package/lib/commands/title3.js +6 -6
  37. package/lib/commands/title3.js.map +8 -5
  38. package/lib/commands/title4.js +6 -6
  39. package/lib/commands/title4.js.map +8 -5
  40. package/lib/commands/title5.js +6 -6
  41. package/lib/commands/title5.js.map +8 -5
  42. package/lib/commands/title6.js +6 -6
  43. package/lib/commands/title6.js.map +8 -5
  44. package/lib/components/TextArea/Textarea.js +2 -4
  45. package/lib/components/TextArea/Textarea.js.map +2 -3
  46. package/lib/components/TextArea/index.d.ts +3 -2
  47. package/lib/components/TextArea/index.js +1 -2
  48. package/lib/components/TextArea/index.js.map +3 -3
  49. package/lib/utils/InsertTextAtPosition.d.ts +7 -0
  50. package/lib/utils/InsertTextAtPosition.js +30 -0
  51. package/lib/utils/InsertTextAtPosition.js.map +14 -6
  52. package/package.json +6 -6
  53. package/src/Context.tsx +0 -1
  54. package/src/Editor.tsx +14 -4
  55. package/src/commands/title1.tsx +5 -4
  56. package/src/commands/title2.tsx +5 -4
  57. package/src/commands/title3.tsx +5 -4
  58. package/src/commands/title4.tsx +5 -4
  59. package/src/commands/title5.tsx +5 -4
  60. package/src/commands/title6.tsx +5 -4
  61. package/src/components/TextArea/Textarea.tsx +3 -4
  62. package/src/components/TextArea/index.tsx +5 -5
  63. package/src/utils/InsertTextAtPosition.ts +29 -2
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { insertAtLineStart } from '../utils/InsertTextAtPosition';
2
3
  import { ICommand, TextState, TextAreaTextApi } from './';
3
4
 
4
5
  export const title3: ICommand = {
@@ -8,10 +9,10 @@ export const title3: ICommand = {
8
9
  buttonProps: { 'aria-label': 'Insert title3', title: 'Insert title 3' },
9
10
  icon: <div style={{ fontSize: 15, textAlign: 'left' }}>Title 3</div>,
10
11
  execute: (state: TextState, api: TextAreaTextApi) => {
11
- let modifyText = `### ${state.selectedText}\n`;
12
- if (!state.selectedText) {
13
- modifyText = `### `;
12
+ if (state.selection.start === 0 || /\n$/.test(state.text)) {
13
+ api.replaceSelection('### ');
14
+ } else {
15
+ insertAtLineStart('### ', state.selection.start, api.textArea);
14
16
  }
15
- api.replaceSelection(modifyText);
16
17
  },
17
18
  };
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { insertAtLineStart } from '../utils/InsertTextAtPosition';
2
3
  import { ICommand, TextState, TextAreaTextApi } from './';
3
4
 
4
5
  export const title4: ICommand = {
@@ -8,10 +9,10 @@ export const title4: ICommand = {
8
9
  buttonProps: { 'aria-label': 'Insert title4', title: 'Insert title 4' },
9
10
  icon: <div style={{ fontSize: 14, textAlign: 'left' }}>Title 4</div>,
10
11
  execute: (state: TextState, api: TextAreaTextApi) => {
11
- let modifyText = `#### ${state.selectedText}\n`;
12
- if (!state.selectedText) {
13
- modifyText = `#### `;
12
+ if (state.selection.start === 0 || /\n$/.test(state.text)) {
13
+ api.replaceSelection('#### ');
14
+ } else {
15
+ insertAtLineStart('#### ', state.selection.start, api.textArea);
14
16
  }
15
- api.replaceSelection(modifyText);
16
17
  },
17
18
  };
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { insertAtLineStart } from '../utils/InsertTextAtPosition';
2
3
  import { ICommand, TextState, TextAreaTextApi } from './';
3
4
 
4
5
  export const title5: ICommand = {
@@ -8,10 +9,10 @@ export const title5: ICommand = {
8
9
  buttonProps: { 'aria-label': 'Insert title5', title: 'Insert title 5' },
9
10
  icon: <div style={{ fontSize: 12, textAlign: 'left' }}>Title 5</div>,
10
11
  execute: (state: TextState, api: TextAreaTextApi) => {
11
- let modifyText = `##### ${state.selectedText}\n`;
12
- if (!state.selectedText) {
13
- modifyText = `##### `;
12
+ if (state.selection.start === 0 || /\n$/.test(state.text)) {
13
+ api.replaceSelection('##### ');
14
+ } else {
15
+ insertAtLineStart('##### ', state.selection.start, api.textArea);
14
16
  }
15
- api.replaceSelection(modifyText);
16
17
  },
17
18
  };
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { insertAtLineStart } from '../utils/InsertTextAtPosition';
2
3
  import { ICommand, TextState, TextAreaTextApi } from './';
3
4
 
4
5
  export const title6: ICommand = {
@@ -8,10 +9,10 @@ export const title6: ICommand = {
8
9
  buttonProps: { 'aria-label': 'Insert title6', title: 'Insert title 6' },
9
10
  icon: <div style={{ fontSize: 12, textAlign: 'left' }}>Title 6</div>,
10
11
  execute: (state: TextState, api: TextAreaTextApi) => {
11
- let modifyText = `###### ${state.selectedText}\n`;
12
- if (!state.selectedText) {
13
- modifyText = `###### `;
12
+ if (state.selection.start === 0 || /\n$/.test(state.text)) {
13
+ api.replaceSelection('###### ');
14
+ } else {
15
+ insertAtLineStart('###### ', state.selection.start, api.textArea);
14
16
  }
15
- api.replaceSelection(modifyText);
16
17
  },
17
18
  };
@@ -9,8 +9,8 @@ import './index.less';
9
9
  export interface TextAreaProps extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'value'>, IProps {}
10
10
 
11
11
  export default function Textarea(props: TextAreaProps) {
12
- const { prefixCls, onChange: onChangeFromProps, ...other } = props;
13
- const { markdown, commands, fullscreen, preview, highlightEnable, extraCommands, tabSize, onChange, dispatch } =
12
+ const { prefixCls, onChange, ...other } = props;
13
+ const { markdown, commands, fullscreen, preview, highlightEnable, extraCommands, tabSize, dispatch } =
14
14
  useContext(EditorContext);
15
15
  const textRef = React.useRef<HTMLTextAreaElement>(null);
16
16
  const executeRef = React.useRef<TextAreaCommandOrchestrator>();
@@ -58,8 +58,7 @@ export default function Textarea(props: TextAreaProps) {
58
58
  value={markdown}
59
59
  onChange={(e) => {
60
60
  dispatch && dispatch({ markdown: e.target.value });
61
- onChange && onChange(e.target.value);
62
- onChangeFromProps && onChangeFromProps(e);
61
+ onChange && onChange(e);
63
62
  }}
64
63
  />
65
64
  );
@@ -2,14 +2,14 @@ import React, { useEffect, Fragment, useContext } from 'react';
2
2
  import { EditorContext, ContextStore, ExecuteCommandState } from '../../Context';
3
3
  import shortcuts from './shortcuts';
4
4
  import Markdown from './Markdown';
5
- import Textarea from './Textarea';
6
- import { MDEditorProps, IProps } from '../../Editor';
5
+ import Textarea, { TextAreaProps } from './Textarea';
6
+ import { IProps } from '../../Editor';
7
7
  import { TextAreaCommandOrchestrator, ICommand } from '../../commands';
8
8
  import './index.less';
9
9
 
10
10
  type RenderTextareaHandle = {
11
11
  dispatch: ContextStore['dispatch'];
12
- onChange?: MDEditorProps['onChange'];
12
+ onChange?: TextAreaProps['onChange'];
13
13
  useContext?: {
14
14
  commands: ContextStore['commands'];
15
15
  extraCommands: ContextStore['extraCommands'];
@@ -42,7 +42,7 @@ export type TextAreaRef = {
42
42
 
43
43
  export default function TextArea(props: ITextAreaProps) {
44
44
  const { prefixCls, className, onScroll, renderTextarea, ...otherProps } = props || {};
45
- const { markdown, scrollTop, commands, extraCommands, onChange, dispatch } = useContext(EditorContext);
45
+ const { markdown, scrollTop, commands, extraCommands, dispatch } = useContext(EditorContext);
46
46
  const textRef = React.useRef<HTMLTextAreaElement>(null);
47
47
  const executeRef = React.useRef<TextAreaCommandOrchestrator>();
48
48
  const warp = React.createRef<HTMLDivElement>();
@@ -88,7 +88,7 @@ export default function TextArea(props: ITextAreaProps) {
88
88
  },
89
89
  {
90
90
  dispatch,
91
- onChange,
91
+ onChange: otherProps.onChange,
92
92
  shortcuts,
93
93
  useContext: { commands, extraCommands, commandOrchestrator: executeRef.current },
94
94
  },
@@ -10,7 +10,7 @@ let browserSupportsTextareaTextNodes: any;
10
10
  * @param {HTMLElement} input
11
11
  * @return {boolean}
12
12
  */
13
- function canManipulateViaTextNodes(input: HTMLTextAreaElement | HTMLInputElement) {
13
+ function canManipulateViaTextNodes(input: HTMLTextAreaElement | HTMLInputElement): boolean {
14
14
  if (input.nodeName !== 'TEXTAREA') {
15
15
  return false;
16
16
  }
@@ -22,12 +22,39 @@ function canManipulateViaTextNodes(input: HTMLTextAreaElement | HTMLInputElement
22
22
  return browserSupportsTextareaTextNodes;
23
23
  }
24
24
 
25
+ /**
26
+ * @param {string} val
27
+ * @param {number} cursorIdx
28
+ * @param {HTMLTextAreaElement|HTMLInputElement} input
29
+ * @return {void}
30
+ */
31
+ export const insertAtLineStart = (
32
+ val: string,
33
+ cursorIdx: number,
34
+ input: HTMLTextAreaElement | HTMLInputElement,
35
+ ): void => {
36
+ const content = input.value;
37
+ let startIdx = 0;
38
+
39
+ while (cursorIdx--) {
40
+ let char = content[cursorIdx];
41
+ if (char === '\n') {
42
+ startIdx = cursorIdx + 1;
43
+ break;
44
+ }
45
+ }
46
+
47
+ input.focus();
48
+ input.setRangeText(val, startIdx, startIdx);
49
+ input.dispatchEvent(new Event('input', { bubbles: true }));
50
+ };
51
+
25
52
  /**
26
53
  * @param {HTMLTextAreaElement|HTMLInputElement} input
27
54
  * @param {string} text
28
55
  * @returns {void}
29
56
  */
30
- export function insertTextAtPosition(input: HTMLTextAreaElement | HTMLInputElement, text: string) {
57
+ export function insertTextAtPosition(input: HTMLTextAreaElement | HTMLInputElement, text: string): void {
31
58
  // Most of the used APIs only work with the field selected
32
59
  input.focus();
33
60