Comments (13)
Hi, I have tried to implement a way to upload an image by Drag&Drop directly into the editor or by Copy&Paste and display it in the preview.
It may not be a very pretty method, but I hope it will be useful to you.
Here's my EXAMPLE!
import MDEditor from '@uiw/react-md-editor';
import { useState } from 'react';
import onImagePasted from './utils/onImagePasted';
import '@uiw/react-md-editor/markdown-editor.css';
import '@uiw/react-markdown-preview/markdown.css';
const MdEditor = () => {
const [markdown, setMarkdown] = useState<string | undefined>();
return (
<div data-color-mode="light">
<MDEditor
value={markdown}
onChange={(value) => {
setMarkdown(value);
}}
onPaste={async (event) => {
await onImagePasted(event.clipboardData, setMarkdown);
}}
onDrop={async (event) => {
await onImagePasted(event.dataTransfer, setMarkdown);
}}
height={440}
textareaProps={{
placeholder: 'Fill in your markdown for the coolest of the cool.',
}}
hideToolbar
/>
</div>
);
};
export default MdEditor;
import type { SetStateAction } from 'react';
import { fileUpload } from '../../../../../libs/firebase/storage';
import insertToTextArea from './insertToTextArea';
const onImagePasted = async (dataTransfer: DataTransfer, setMarkdown: (value: SetStateAction<string | undefined>) => void) => {
const files: File[] = [];
for (let index = 0; index < dataTransfer.items.length; index += 1) {
const file = dataTransfer.files.item(index);
if (file) {
files.push(file);
}
}
await Promise.all(
files.map(async (file) => {
const url = await fileUpload(file);
const insertedMarkdown = insertToTextArea(`![](${url})`);
if (!insertedMarkdown) {
return;
}
setMarkdown(insertedMarkdown);
}),
);
};
export default onImagePasted;
const insertToTextArea = (intsertString: string) => {
const textarea = document.querySelector('textarea');
if (!textarea) {
return null;
}
let sentence = textarea.value;
const len = sentence.length;
const pos = textarea.selectionStart;
const end = textarea.selectionEnd;
const front = sentence.slice(0, pos);
const back = sentence.slice(pos, len);
sentence = front + intsertString + back;
textarea.value = sentence;
textarea.selectionEnd = end + intsertString.length;
return sentence;
};
export default insertToTextArea;
from react-md-editor.
@TheStarkor I need to expand this
Do you need such an effect?
from react-md-editor.
@TheStarkor Definition tool reference: #85
import React from "react";
import ReactDOM from "react-dom";
import MDEditor, { commands, ICommand, TextState, TextApi } from '@uiw/react-md-editor';
const title3: ICommand = {
name: 'title3',
keyCommand: 'title3',
buttonProps: { 'aria-label': 'Insert title3' },
icon: (
<svg width="12" height="12" viewBox="0 0 520 520">
<path fill="currentColor" d="M15.7083333,468 C7.03242448,468 0,462.030833 0,454.666667 L0,421.333333 C0,413.969167 7.03242448,408 15.7083333,408 L361.291667,408 C369.967576,408 377,413.969167 377,421.333333 L377,454.666667 C377,462.030833 369.967576,468 361.291667,468 L15.7083333,468 Z M21.6666667,366 C9.69989583,366 0,359.831861 0,352.222222 L0,317.777778 C0,310.168139 9.69989583,304 21.6666667,304 L498.333333,304 C510.300104,304 520,310.168139 520,317.777778 L520,352.222222 C520,359.831861 510.300104,366 498.333333,366 L21.6666667,366 Z M136.835938,64 L136.835937,126 L107.25,126 L107.25,251 L40.75,251 L40.75,126 L-5.68434189e-14,126 L-5.68434189e-14,64 L136.835938,64 Z M212,64 L212,251 L161.648438,251 L161.648438,64 L212,64 Z M378,64 L378,126 L343.25,126 L343.25,251 L281.75,251 L281.75,126 L238,126 L238,64 L378,64 Z M449.047619,189.550781 L520,189.550781 L520,251 L405,251 L405,64 L449.047619,64 L449.047619,189.550781 Z" />
</svg>
),
execute: (state: TextState, api: TextApi) => {
let modifyText = `### ${state.selectedText}\n`;
if (!state.selectedText) {
modifyText = `### `;
}
api.replaceSelection(modifyText);
},
};
export default function App() {
const [value, setValue] = React.useState("**Hello world!!!**");
return (
<div className="container">
<MDEditor
value="Hello Markdown!"
commands={[
commands.bold, commands.hr, commands.italic, commands.divider, commands.codeEdit, commands.codeLive, commands.codePreview, commands.divider,
commands.fullscreen,
// Custom Toolbars
title3,
]}
/>
</div>
);
}
from react-md-editor.
Thank you for answering @jaywcjlove.
What I need is
const image = {
name: 'image',
keyCommand: 'image',
buttonProps: { 'aria-label': 'Insert image' },
icon: (
<svg width="12" height="12" viewBox="0 0 520 520">
<path fill="currentColor" d="M15.7083333,468 C7.03242448,468 0,462.030833 0,454.666667 L0,421.333333 C0,413.969167 7.03242448,408 15.7083333,408 L361.291667,408 C369.967576,408 377,413.969167 377,421.333333 L377,454.666667 C377,462.030833 369.967576,468 361.291667,468 L15.7083333,468 Z M21.6666667,366 C9.69989583,366 0,359.831861 0,352.222222 L0,317.777778 C0,310.168139 9.69989583,304 21.6666667,304 L498.333333,304 C510.300104,304 520,310.168139 520,317.777778 L520,352.222222 C520,359.831861 510.300104,366 498.333333,366 L21.6666667,366 Z M136.835938,64 L136.835937,126 L107.25,126 L107.25,251 L40.75,251 L40.75,126 L-5.68434189e-14,126 L-5.68434189e-14,64 L136.835938,64 Z M212,64 L212,251 L161.648438,251 L161.648438,64 L212,64 Z M378,64 L378,126 L343.25,126 L343.25,251 L281.75,251 L281.75,126 L238,126 L238,64 L378,64 Z M449.047619,189.550781 L520,189.550781 L520,251 L405,251 L405,64 L449.047619,64 L449.047619,189.550781 Z" />
</svg>
),
execute: async (state, api) => {
// OPEN my component.
// example
// const [image, setImaeg] = React.useState('');
// <ImageUploader value={image} onChange={setImage} />
let image_url = await upload_image(image);
let modifyText = `![](${image_url})\n`;
api.replaceSelection(modifyText);
},
};
- I click my custom button. (like title3)
- Show my component that can upload an image like the figure.
- Get image buffer and upload.
- Modify text.
Can I open a component below the button(commands)?
from react-md-editor.
@TheStarkor Example: https://codesandbox.io/s/dazzling-resonance-m08m7
from react-md-editor.
Hello @jaywcjlove the example is not working and we wanted to implement a small drag & drop it
into our markdown
from react-md-editor.
How to implement with a custom component eg: Modal?
from react-md-editor.
Yes! That's what I want.
from react-md-editor.
react-md-editor/website/ExampleCustomToolbar.tsx
Lines 1 to 55 in 70760fd
Upgrade + @uiw/[email protected]
from react-md-editor.
hi @jaywcjlove can you give more example on how to achieve this functionality ? Thanks
from react-md-editor.
@TheStarkor Example: https://codesandbox.io/s/dazzling-resonance-m08m7
getting TypeError: handle.getState is not a function
error
from react-md-editor.
Thank you for answering @jaywcjlove.
What I need is
const image = { name: 'image', keyCommand: 'image', buttonProps: { 'aria-label': 'Insert image' }, icon: ( <svg width="12" height="12" viewBox="0 0 520 520"> <path fill="currentColor" d="M15.7083333,468 C7.03242448,468 0,462.030833 0,454.666667 L0,421.333333 C0,413.969167 7.03242448,408 15.7083333,408 L361.291667,408 C369.967576,408 377,413.969167 377,421.333333 L377,454.666667 C377,462.030833 369.967576,468 361.291667,468 L15.7083333,468 Z M21.6666667,366 C9.69989583,366 0,359.831861 0,352.222222 L0,317.777778 C0,310.168139 9.69989583,304 21.6666667,304 L498.333333,304 C510.300104,304 520,310.168139 520,317.777778 L520,352.222222 C520,359.831861 510.300104,366 498.333333,366 L21.6666667,366 Z M136.835938,64 L136.835937,126 L107.25,126 L107.25,251 L40.75,251 L40.75,126 L-5.68434189e-14,126 L-5.68434189e-14,64 L136.835938,64 Z M212,64 L212,251 L161.648438,251 L161.648438,64 L212,64 Z M378,64 L378,126 L343.25,126 L343.25,251 L281.75,251 L281.75,126 L238,126 L238,64 L378,64 Z M449.047619,189.550781 L520,189.550781 L520,251 L405,251 L405,64 L449.047619,64 L449.047619,189.550781 Z" /> </svg> ), execute: async (state, api) => { // OPEN my component. // example // const [image, setImaeg] = React.useState(''); // <ImageUploader value={image} onChange={setImage} /> let image_url = await upload_image(image); let modifyText = `![](${image_url})\n`; api.replaceSelection(modifyText); }, };
- I click my custom button. (like title3)
- Show my component that can upload an image like the figure.
- Get image buffer and upload.
- Modify text.
Can I open a component below the button(commands)?
can you share the code that open your component (e.g a modal) ?
from react-md-editor.
Hi, I have tried to implement a way to upload an image by Drag&Drop directly into the editor or by Copy&Paste and display it in the preview. It may not be a very pretty method, but I hope it will be useful to you. Here's my EXAMPLE!
import MDEditor from '@uiw/react-md-editor'; import { useState } from 'react'; import onImagePasted from './utils/onImagePasted'; import '@uiw/react-md-editor/markdown-editor.css'; import '@uiw/react-markdown-preview/markdown.css'; const MdEditor = () => { const [markdown, setMarkdown] = useState<string | undefined>(); return ( <div data-color-mode="light"> <MDEditor value={markdown} onChange={(value) => { setMarkdown(value); }} onPaste={async (event) => { await onImagePasted(event.clipboardData, setMarkdown); }} onDrop={async (event) => { await onImagePasted(event.dataTransfer, setMarkdown); }} height={440} textareaProps={{ placeholder: 'Fill in your markdown for the coolest of the cool.', }} hideToolbar /> </div> ); }; export default MdEditor;import type { SetStateAction } from 'react'; import { fileUpload } from '../../../../../libs/firebase/storage'; import insertToTextArea from './insertToTextArea'; const onImagePasted = async (dataTransfer: DataTransfer, setMarkdown: (value: SetStateAction<string | undefined>) => void) => { const files: File[] = []; for (let index = 0; index < dataTransfer.items.length; index += 1) { const file = dataTransfer.files.item(index); if (file) { files.push(file); } } await Promise.all( files.map(async (file) => { const url = await fileUpload(file); const insertedMarkdown = insertToTextArea(`![](${url})`); if (!insertedMarkdown) { return; } setMarkdown(insertedMarkdown); }), ); }; export default onImagePasted;const insertToTextArea = (intsertString: string) => { const textarea = document.querySelector('textarea'); if (!textarea) { return null; } let sentence = textarea.value; const len = sentence.length; const pos = textarea.selectionStart; const end = textarea.selectionEnd; const front = sentence.slice(0, pos); const back = sentence.slice(pos, len); sentence = front + intsertString + back; textarea.value = sentence; textarea.selectionEnd = end + intsertString.length; return sentence; }; export default insertToTextArea;
great job, my friend
from react-md-editor.
Related Issues (20)
- skipHtml not working
- Controlled toolbar? HOT 1
- Bug: When I push (option+ ₩) + (option + Enter) in MacOS, the cursor is broken HOT 1
- blinking cursor not showing inside md editor when placed in overflows modal HOT 1
- THIS IS NOT AN ISSUE: HACK to Paste Image directly from clipboard HOT 2
- The editor is stuck When value is large HOT 1
- 工具栏提示如何设置中文 HOT 2
- Spell Checker/ Auto Correct? HOT 1
- 预览标题的时候可以屏蔽链接标识吗 HOT 1
- Missing Source Map Files for parse5 in hast-util-raw Dependencies HOT 4
- How can i set textarea(.w-md-editor-text-input)'s parent <div> height style? HOT 4
- IMPORTANT MISSING FEATURE: Prop to limit the character length - maxLength and minLength attributes HOT 2
- [BUG] numbered list can't render number in preview panel HOT 3
- How to have hashtags render as links? HOT 3
- 预览模式下换行符显示问题 HOT 2
- 自适应高度时,切到preview模式,高度没了 HOT 6
- Change font size of editor HOT 1
- css variables 藏在哪里了找不到 HOT 1
- code highlight and rendering style seems not to work well in mac m1 HOT 1
- I need to check why my text is not being properly converted to markdown
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-md-editor.