Skip to content

Commit 5fed868

Browse files
refactored some code
+fixed cursor bug.
1 parent e4d98fe commit 5fed868

File tree

3 files changed

+81
-60
lines changed

3 files changed

+81
-60
lines changed
Lines changed: 53 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
import { FC as FunctionComponent, useState, useEffect, useMemo } from "react";
2-
32
import { Flex, Field } from "@strapi/design-system";
43
import type { Schema } from "@strapi/types";
5-
import MDEditor, { commands, ICommand } from "@uiw/react-md-editor";
4+
import { commands, ICommand } from "@uiw/react-md-editor";
65
import { useIntl } from "react-intl";
76
import { styled } from "styled-components";
8-
97
import "@uiw/react-markdown-preview/markdown.css";
10-
11-
import {PLUGIN_ID} from '../utils/pluginId';
8+
import { PLUGIN_ID } from '../utils/pluginId';
129
import MediaLib from "./MediaLib";
1310
import { useField } from "@strapi/strapi/admin";
14-
import assetsToMarkdown from '../utils/assetsToMarkdown';
11+
import assetsToMarkdown from "../utils/assetsToMarkdown";
12+
import CustomMDEditor from "./CustomMDEditor";
1513

1614
const Wrapper = styled.div`
1715
flex-basis: 100%;
@@ -62,7 +60,7 @@ const Wrapper = styled.div`
6260
}
6361
`;
6462

65-
interface EditorProps {
63+
interface FieldProps {
6664
name: string;
6765
onChange: (e: { target: { name: string; value: string } }) => void;
6866
value: string;
@@ -81,7 +79,12 @@ interface EditorProps {
8179
labelAction?: React.ReactNode; //TO FIX TO CHECK
8280
}
8381

84-
const Editor: FunctionComponent<EditorProps> = ({
82+
interface CursorPosition {
83+
start: number;
84+
end: number;
85+
}
86+
87+
const CustomField: FunctionComponent<FieldProps> = ({
8588
attribute,
8689
name,
8790
disabled,
@@ -92,26 +95,38 @@ const Editor: FunctionComponent<EditorProps> = ({
9295
intlLabel,
9396
}) => {
9497
// const { formatMessage } = useIntl();
95-
const { onChange, value }: any = useField(name);
98+
const field: any = useField(name);
99+
96100
const formatMessage = (message: { id: string; defaultMessage: string }) =>
97101
message?.defaultMessage ?? "";
98102
const [mediaLibVisible, setMediaLibVisible] = useState(false);
99-
const [mediaLibSelection, setMediaLibSelection] = useState(-1);
103+
const [cursorPosition, setCursorPosition] = useState<CursorPosition | null>(null);
100104

101105
const handleToggleMediaLib = () => setMediaLibVisible((prev) => !prev);
102106

107+
const updateFieldValue = (value:any) => {
108+
field.onChange({ target: { name, value: value } });
109+
}
110+
103111
const handleChangeAssets = (assets: Schema.Attribute.MediaValue<true>) => {
104112

105-
const output = value + assetsToMarkdown(assets);
113+
let output;
114+
const assetsString = assetsToMarkdown(assets);
106115

107-
onChange({ target: { name, value: output} });
116+
if (cursorPosition) {
117+
output = field.value.slice(0, cursorPosition.start) + assetsString + field.value.slice(cursorPosition.end);
118+
}else{
119+
output = field.value + assetsString;
120+
}
121+
122+
updateFieldValue(output);
108123
handleToggleMediaLib();
109124
};
110125

111-
const [configs, setConfigs] = useState<{ toolbarCommands?: string[] }>({});
126+
const [config, setConfig] = useState<{ toolbarCommands?: string[] }>({});
112127

113128
const toolbarCommands = useMemo(() => {
114-
const strapiMediaLibrary: ICommand = {
129+
const mediaLibraryButton: ICommand = {
115130
name: "media",
116131
keyCommand: "media",
117132
buttonProps: { "aria-label": "Insert media" },
@@ -124,37 +139,19 @@ const Editor: FunctionComponent<EditorProps> = ({
124139
</svg>
125140
),
126141
execute: (state, _api) => {
127-
setMediaLibSelection(state.selection.end);
142+
setCursorPosition(state.selection);
128143
handleToggleMediaLib();
129144
},
130145
};
131-
if (!configs?.toolbarCommands) {
132-
return [
133-
commands.title2,
134-
commands.title3,
135-
commands.title4,
136-
commands.title5,
137-
commands.title6,
138-
commands.divider,
139-
commands.bold,
140-
commands.codeBlock,
141-
commands.italic,
142-
commands.strikethrough,
143-
commands.hr,
144-
commands.group,
146+
if (!config?.toolbarCommands) {
147+
return [...commands.getCommands(),
145148
commands.divider,
146-
commands.link,
147-
commands.quote,
148-
commands.code,
149-
strapiMediaLibrary,
150-
commands.unorderedListCommand,
151-
commands.orderedListCommand,
152-
commands.checkedListCommand,
149+
mediaLibraryButton
153150
] as ICommand[];
154151
}
155-
const customCommands = configs?.toolbarCommands
152+
const customCommands = config?.toolbarCommands
156153
?.map((config) => {
157-
if (config === "strapiMediaLibrary") return strapiMediaLibrary;
154+
if (config === "mediaLibraryButton") return mediaLibraryButton;
158155
if (
159156
config in commands &&
160157
commands[config as unknown as keyof typeof commands]
@@ -167,48 +164,46 @@ const Editor: FunctionComponent<EditorProps> = ({
167164
.filter((command): command is ICommand => command !== undefined);
168165

169166
return customCommands;
170-
}, [JSON.stringify(configs)]);
167+
}, [JSON.stringify(config)]);
171168

172169
useEffect(() => {
173170
fetch(`/${PLUGIN_ID}`)
174171
.then((response) => response.json())
175172
.then((data) => {
176-
setConfigs(data);
173+
setConfig(data);
177174
});
178175
}, []);
179176

180177
return (
181178
<Field.Root
182-
name= {name }
183-
id={ name }
184-
error={ error }
185-
hint={ description && formatMessage( description ) }
179+
name={name}
180+
id={name}
181+
error={error}
182+
hint={description && formatMessage(description)}
186183
>
187-
<Flex spacing={ 1 } alignItems="normal" style={ { 'flexDirection': 'column' } }>
188-
<Field.Label action={ labelAction } required={ required }>
189-
{ intlLabel ? formatMessage( intlLabel ) : name }
190-
</Field.Label>
184+
<Flex spacing={1} alignItems="normal" style={{ flexDirection: "column" }}>
185+
<Field.Label action={labelAction} required={required}>
186+
{intlLabel ? formatMessage(intlLabel) : name}
187+
</Field.Label>
191188
<Wrapper>
192-
<MDEditor
189+
<CustomMDEditor
193190
hidden={disabled}
191+
value={field.value}
192+
onChange={updateFieldValue}
194193
commands={toolbarCommands}
195-
value={value || ""}
196-
onChange={(newValue) => {
197-
onChange({ target: { name, value: newValue || "" } });
198-
}}
199194
/>
200195
</Wrapper>
201196
<Field.Hint />
202197
<Field.Error />
203198
</Flex>
204199
<MediaLib
205-
/*allowedTypes={['images']}*/
206-
isOpen={ mediaLibVisible }
207-
onChange={ handleChangeAssets }
208-
onToggle={ handleToggleMediaLib }
200+
/*allowedTypes={['images']}*/
201+
isOpen={mediaLibVisible}
202+
onChange={handleChangeAssets}
203+
onToggle={handleToggleMediaLib}
209204
/>
210205
</Field.Root>
211206
);
212207
};
213208

214-
export { Editor };
209+
export { CustomField };
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React, { useState,useEffect } from "react";
2+
import MDEditor from "@uiw/react-md-editor";
3+
4+
const CustomMDEditor = (props:any) => {
5+
6+
const [value, setValue] = useState<string | undefined>(props.value);
7+
8+
useEffect(() => {
9+
setValue(props.value)
10+
}, [props.value]);
11+
12+
useEffect(() => {
13+
props.onChange(value);
14+
}, [value]);
15+
16+
return (
17+
<MDEditor
18+
value={value}
19+
onChange={setValue}
20+
hidden={props.hidden}
21+
commands={props.commands}
22+
/>
23+
);
24+
};
25+
26+
export default CustomMDEditor;

admin/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import pluginPkg from "../../package.json";
22
import {PLUGIN_ID} from './utils/pluginId';
33
import { Initializer } from "./components/Initializer";
4-
import { Editor as ReactMdEditor } from "./components/ReactMdEditor";
4+
import { CustomField } from "./components/CustomField";
55
import { getTranslation } from "./utils/getTranslation";
66

77
const name = pluginPkg.strapi.name;
88

99
export default {
1010
register(app: any) {
11-
app.addFields({ type: "richtext", Component: ReactMdEditor });
11+
app.addFields({ type: "richtext", Component: CustomField });
1212
const plugin = {
1313
id: PLUGIN_ID,
1414
initializer: Initializer,

0 commit comments

Comments
 (0)