@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.
- package/README.md +1 -1
- package/esm/Context.d.ts +0 -2
- package/esm/Context.js.map +2 -2
- package/esm/Editor.d.ts +1 -1
- package/esm/Editor.js +11 -4
- package/esm/Editor.js.map +4 -2
- package/esm/commands/title1.js +5 -6
- package/esm/commands/title1.js.map +9 -5
- package/esm/commands/title2.js +5 -6
- package/esm/commands/title2.js.map +9 -5
- package/esm/commands/title3.js +5 -6
- package/esm/commands/title3.js.map +9 -5
- package/esm/commands/title4.js +5 -6
- package/esm/commands/title4.js.map +9 -5
- package/esm/commands/title5.js +5 -6
- package/esm/commands/title5.js.map +9 -5
- package/esm/commands/title6.js +5 -6
- package/esm/commands/title6.js.map +9 -5
- package/esm/components/TextArea/Textarea.js +2 -4
- package/esm/components/TextArea/Textarea.js.map +2 -3
- package/esm/components/TextArea/index.d.ts +3 -2
- package/esm/components/TextArea/index.js +1 -2
- package/esm/components/TextArea/index.js.map +3 -3
- package/esm/utils/InsertTextAtPosition.d.ts +7 -0
- package/esm/utils/InsertTextAtPosition.js +27 -1
- package/esm/utils/InsertTextAtPosition.js.map +14 -6
- package/lib/Context.d.ts +0 -2
- package/lib/Context.js.map +2 -2
- package/lib/Editor.d.ts +1 -1
- package/lib/Editor.js +13 -4
- package/lib/Editor.js.map +4 -2
- package/lib/commands/title1.js +6 -6
- package/lib/commands/title1.js.map +8 -5
- package/lib/commands/title2.js +6 -6
- package/lib/commands/title2.js.map +8 -5
- package/lib/commands/title3.js +6 -6
- package/lib/commands/title3.js.map +8 -5
- package/lib/commands/title4.js +6 -6
- package/lib/commands/title4.js.map +8 -5
- package/lib/commands/title5.js +6 -6
- package/lib/commands/title5.js.map +8 -5
- package/lib/commands/title6.js +6 -6
- package/lib/commands/title6.js.map +8 -5
- package/lib/components/TextArea/Textarea.js +2 -4
- package/lib/components/TextArea/Textarea.js.map +2 -3
- package/lib/components/TextArea/index.d.ts +3 -2
- package/lib/components/TextArea/index.js +1 -2
- package/lib/components/TextArea/index.js.map +3 -3
- package/lib/utils/InsertTextAtPosition.d.ts +7 -0
- package/lib/utils/InsertTextAtPosition.js +30 -0
- package/lib/utils/InsertTextAtPosition.js.map +14 -6
- package/package.json +6 -6
- package/src/Context.tsx +0 -1
- package/src/Editor.tsx +14 -4
- package/src/commands/title1.tsx +5 -4
- package/src/commands/title2.tsx +5 -4
- package/src/commands/title3.tsx +5 -4
- package/src/commands/title4.tsx +5 -4
- package/src/commands/title5.tsx +5 -4
- package/src/commands/title6.tsx +5 -4
- package/src/components/TextArea/Textarea.tsx +3 -4
- package/src/components/TextArea/index.tsx +5 -5
- package/src/utils/InsertTextAtPosition.ts +29 -2
package/src/commands/title3.tsx
CHANGED
|
@@ -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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
};
|
package/src/commands/title4.tsx
CHANGED
|
@@ -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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
};
|
package/src/commands/title5.tsx
CHANGED
|
@@ -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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
};
|
package/src/commands/title6.tsx
CHANGED
|
@@ -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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
|
13
|
-
const { markdown, commands, fullscreen, preview, highlightEnable, extraCommands, tabSize,
|
|
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
|
|
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 {
|
|
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?:
|
|
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,
|
|
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
|
|