New features:
You can now pass a paste
prop with a saveImage
function and an optional command
to execute on paste.
Example:
paste={{
command: "save-image", // optional
saveImage: save
}}
saveImage
should be an async generator function that yields the URL for the uploaded image and returns true, indicating the upload was successful.
const save: SaveImageHandler = async function*(data: ArrayBuffer) {
// Promise that waits for "time" milliseconds
const wait = function(time: number) {
return new Promise((a, r) => {
setTimeout(() => a(), time);
});
};
// Upload "data" to your server
// Use XMLHttpRequest.send to send a FormData object containing
// "data"
// Check this question: https://stackoverflow.com/questions/18055422/how-to-receive-php-image-data-over-copy-n-paste-javascript-with-xmlhttprequest
await wait(2000);
// yields the URL that should be inserted in the markdown
yield "https://picsum.photos/300";
await wait(2000);
// returns true meaning that the save was successful
return true;
};
You can now specify toolbar commands in an easier way
Before, if you wanted to control which commands would display in the toolbar, you would have to import each command, compose them in the desired way and pass them into React-mde.
Now, the commands and the way they are displayed have been separated.
The optional commands
prop expects a CommandMap
, which is an object that has string keys and, for each key, a Command
object. If no commands are passed, the default ones are used. Before, you had to pass all commands in, including the default ones. Now, you only need to pass a map of custom Commands. The default commands are always available.
The most interesting new prop is toolbarCommands
, that receives a string[][]
representing which commands should be displayed on the toolbar.
Example:
toolbarCommands={[["code", "bold"], ["italic"]]}
Breaking changes:
The way commands are selected changes
This change does not impact you if you did not customize which commands were displayed.
Before, the commands
prop was a Command[][]
. Now it is a Record<string, Command>
. This is because the way commands are displayed on the toolbar have been disassociated with the list of commands itself.
As stated on the "New features", to specify the commands on the toolbar, use the the toolbarCommands
prop:
toolbarCommands={[["code", "bold"], ["italic"]]}
The Command execute
API changed
This change does not affect you if you don't implement custom commands.
Before, the execute
signature was:
execute(state0: TextState, api: TextApi) { }
Now it is
execute({ initialState, textApi, context, l18n }: ExecuteOptions) {}
Now execute
takes an ExecuteOptions
object. This is, of course, because new APIs had to be introduced. context
, now, varies with the command. For the paste commands, context
contains event
and saveImage
, the function that really saves the image.
Commands no longer have a name
The commands are now identified by their keys on the CommandMap