install quilljs-markdown on react - reactjs

I need such an editor on react https://cloverhearts.github.io/quilljs-markdown/ , as you can see in it you can put markdown characters directly into the text.
when I do this
import React, { Component } from 'react'
import './App.css'
import ReactQuill from 'react-quill'
import Quill from 'quill'
import QuillMarkdown from 'quilljs-markdown'
const App = () => {
const editor = new Quill('#editor', {
theme: 'snow'
})
new QuillMarkdown(editor)
return (
<div className='app'>
{/*<MyComponent/>*/}
<div id="editor"></div>
</div>
)
}
export default App
I get error TypeError: Cannot read property 'on' of undefined
as I understand I need jQuery for work, but I use react, I found https://www.npmjs.com/package/react-quill this quilljs for react, but I don't know how to combine it with markdown https://www.npmjs.com/package/quilljs-markdown
can anyone help?

I found the solution for this after hours of trying this out.
What you have to do is this:
Create a module for ReactQuill
Register the module.
Pass modules to react quill
Shown Below.
Step 01
const modules = {
markdownOptions: {}
};
Step 02
Quill.register('modules/markdownOptions', QuillMarkdown);
Step 03
<ReactQuill
modules={modules}
/>

It seems like you are trying to initialize the Quill instance and the markdown module before the editor is ready.
Use useEffect hook to initialize it after the div has been rendered:
import {useEffect} from 'react';
...
useEffect(() => {
const editor = new Quill('#editor', {
theme: 'snow'
});
new QuillMarkdown(editor);
});

Related

ReactJS highlight blog post that comes from the server

I've been trying to use highlight.js with my react project , but it never worked.
I have a blog, and for each post I fetch the post data from the server.
Unfortunately - highlight.js does not work properly when it comes to dynamic data and async proccess.
Lets say we have this code that i fetch:
bla blba blahbla blba blahbla blba blahbla blba blah...
<code><div class="test"></div></code>
bbla blba blah....
So , I did try to import highlight.js with the css theme, and used hljs.highlightAll() , but it didn't work properly.
Maybe there is some other solution \ library where I can highlight the code?
What's the alternative?
thank you.
import { React, useEffect } from "react";
import { useParams } from "react-router-dom";
import hljs from "../../node_modules/highlight.js/lib/core";
import "../../node_modules/highlight.js/styles/arta.css";
import "./BlogPost.css";
function BlogPost(props) {
hljs.initHighlightingOnLoad();
const updateCodeSyntaxHighlighting = () => {
document.querySelectorAll("code").forEach((block) => {
hljs.highlightBlock(block);
});
};
useEffect(() => {
getPostData();
updateCodeSyntaxHighlighting();
}, []);
// GetPostDataById(id);
return <div dangerouslySetInnerHTML={{ __html: postData }}></div>;
}
export default BlogPost;
result:
as you can see - the background gets darker , but not really highlighted text.
Your not importing the entire highlight.js library so you can just do import hljs from 'highlight.js' instead of going into the node modules folder to get it. Also you are not specifying the language you want to highlight in with the class of the code block. In the example I am just going to hard code the postData with class='language-javascript' for the <code> block to get the correct syntax highlighting. So here is a working example:
Working Codesandbox
import { React, useEffect } from 'react'
import hljs from 'highlight.js'
import '../../node_modules/highlight.js/styles/arta.css'
const postData = `<pre><code class="language-javascript">console.log('hello');</code></pre>`
function BlogPost(props) {
const updateCodeSyntaxHighlighting = () => {
document.querySelectorAll('code').forEach((block) => {
hljs.highlightElement(block)
})
}
useEffect(() => {
updateCodeSyntaxHighlighting()
}, [])
// GetPostDataById(id);
return <div dangerouslySetInnerHTML={{ __html: postData }}></div>
}

Use SVGR and Material UI together

i'm trying to use SVGR to convert my svg into react components and i need to use <SvgIcon /> of Material UI and pass the converted component as a prop to it.
nothing wrong with this yet.
but,
SVGR saves these component in a folder called svgCom for example and inside of this folder there is index.js plus converted svg components.
i need to wrapp all these components inside of <SvgIcon> so i don't have to wrap this icon with <SvgIcon/> again for each use case;
so far i try to add this component in template.js of SVGR but it throw me an error when try to parse .
is this the best way of doing such thing or there is better way ?
if it is what's wrong with my template.js ?
here is my templete.js :
function template(
{ template },
opts,
{ imports, componentName, props, jsx, exports },
) {
return template.ast`
${imports}
import { SvgIcon } from "#material-ui/core";
///////////////////////////////////// error here
const ${componentName} = (${props}) => <SvgIcon component={${jsx}} />
${exports}
`
}
module.exports = template
thank you.
We had the same problem and after some research I came to the following solution:
const {
identifier,
jsxClosingElement,
jsxElement,
jsxIdentifier,
jsxOpeningElement,
jsxSpreadAttribute,
} = require('#babel/types')
const iconTemplate = ({ template }, _, { componentName, jsx, exports }) => {
const wrappedJsx = jsxElement(
jsxOpeningElement(jsxIdentifier('SvgIcon'), [jsxSpreadAttribute(identifier('props'))]),
jsxClosingElement(jsxIdentifier('SvgIcon')),
[jsx],
false
)
return template.ast`
import React from 'react'
import SvgIcon from '#material-ui/core/SvgIcon'
const ${componentName} = (props) => ${wrappedJsx}
${exports}
`
}
module.exports = iconTemplate
If you don't want {...props} on the <svg> tag, you have to disable the expandProps option

complex layout using react storybook

I am new to react storybook and have created relatively simple stories so far as mentioned below:
import React from 'react';
import { action } from '#storybook/addon-actions';
export default {
title: "Test"
}
export const test = () => <textarea onClick={action('textarea clicked')}>Hong test from me</textarea>;
export const input = () => <input type="text"></input>;
With this knowledge, I want to go ahead and create complex stories i.e. as shown in the image below:
Is there any tutorial which will help me achieve this.
Thanks
I am not sure if I understood your question correctly, but I will try to give you an answer.
What we usually do with storybook stories is to create the story and then import a complex component inside it.
import React from 'react';
import { storiesOf } from '#storybook/react';
import { CustomComponent } from '../src';
storiesOf('CustomComponent', module)
.add('Custom Component story 1', () => (
<CustomComponent />
));

Dynamically loading Material-UI Icons in React

I'm trying to make React component that dynamically imports requested Material-UI icon,
when the page loads. My solution presented here works, but it gives warning
at compile time. Additionally it slows down the compilation of the project.
Any idea on how to do this properly?
https://github.com/jurepetrovic/ordermanager_demo
The main logic is found in App.js, lines 5-10:
import React, { Component } from 'react';
import BarChartIcon from '#material-ui/icons/BarChart';
const MaterialIcon = ({ icon }) => {
console.log("icon: " + icon);
let resolved = require(`#material-ui/icons/${icon}`).default;
return React.createElement(resolved);
}
class App extends Component {
render() {
return (
<div>
<MaterialIcon icon={"PowerSettingsNew"} />
</div>
);
}
}
export default App;
The warning it gives is this:
Compile warning
I finally found the simplest solution to this problem:
import all material icons from the package:
import * as Icons from '#material-ui/icons'
I assume you fetch your icon names from your api and finally you have something like this:
var iconNamesArray = ["FitnessCenter","LocalDrink","Straighten"]
Finally load your Icons like below:
<div className="my-icons-wrapper-css">
{
iconNamesArray.map((el,ind)=>{
let DynamicIcon = Icons[el]
return(
<DynamicIcon className="my-icon-css"/>
);
})
}
</div>
And your icons will appear in the screen.

Using marked in react

I want to use marked in reactjs as described in the reactjs docs.
<div>{marked(mystring)}</div>
I use babel so I import marked like this:
import { marked } from 'marked';
Unfortunately the import statement does not work. marked is not defined.
How do I have to import marked here, so that I can use it?
Here's one way to use marked with React:
Ensure that you've installed marked
Include marked in your project's package.json file:
// package.json
{
dependencies: {
react: "^17.0.0",
marked: "^4.0.0",
},
}
Import marked in your .jsx (or related) file:
import { marked } from "marked";
Use the dangerouslySetInnerHTML approach as shown in the example below:
import React from "react";
import { marked } from "marked";
class MarkdownExample extends React.Component {
getMarkdownText() {
var rawMarkup = marked.parse("This is _Markdown_.");
return { __html: rawMarkup };
}
render() {
return <div dangerouslySetInnerHTML={this.getMarkdownText()} />;
}
}
The dangerouslySetInnerHTML attribute gives you the ability to work with raw (HTML) markup. Make sure to take care when using this attribute, though!
Alternative (Safe)
If you don't want to use dangerouslySetInnerHTML and safely render HTML. Try marked-react, which internally uses marked to render the html elements as react components
npm i marked-react
import Markdown from "marked-react";
const MarkdownComponent = () => {
return <Markdown>{rawmarkdown}</Markdown>;
};
Another alternative is react-markdown
Here is another way of using marked with React Hooks:
Create your MarkedConverter component
import { useState } from 'react'
import marked from 'marked'
export const MarkedConverter = () => {
const [markedVal, setMarkedVal] = useState(
'# Welcome to my React Markdown Previewer!'
)
return <div dangerouslySetInnerHTML={createMarkUp(markedVal)}></div>
}
Create Markup function and pass the value from MarkedConverter Component
export const createMarkUp = (val) => {
return { __html: marked(val) }
}
Finally you can import MarkedConverter Component to any of your Component
With the marked-wrapper react-marked-markdown:
import { MarkdownPreview } from 'react-marked-markdown'
export default ({ post }) => (
<div>
<h1>{ post.title }</h1>
<MarkdownPreview value={ post.content }/>
</div>
)
If you just want to import marked:
import marked from 'marked';
Then call the function in your component:
marked('# Markdown');
Here's an example on how to use marked with react:
Install marked with NPM : npm i marked
import it in your react app (this example is created with create-react-app), and using it
example of a react component using "marked"
result in the browser :
preview

Resources