Представленное ниже приложение делает следующее:
- Показывает модальное окно с текстовым полем
- Модальное окно служит для ввода текста в формате Markdown
- Выводит текст введенный текст в отформатированом виде
Вывод производится с помощью функционального компонента
Используемые библиотеки, помимо React
bootstrap— для оформленияreact-bootstrap— Для использования модальностиmarkdown-it— для конвертации Markdown в htmlhtml-to-react— для отображения html уже отформатированым, а не чистым текстом на страницеrefractor— для раскрашивания блоков кодаrehype— для преобразования блоков кода в html
Элемент ввода текста MyInput
[su_spoiler title=»MyInput» style=»fancy»]
[js]
import React from ‘react’
import ‘./my-input.css’
const MyInput = (props) => {
const {caption, setCaption} = props;
const handleChange = (e) => {
setCaption(e.target.value);
};
return (
<>
<textarea value={caption} onChange={handleChange} className="form-control" placeholder="Input text" />
</>
)
};
export default MyInput
[/js]
[/su_spoiler]
Модальное окно MyModal
[su_spoiler title=»MyModal» style=»fancy»]
[js]
import React from "react";
import {Modal, Button} from "react-bootstrap";
import MyInput from "../my-input";
const MyModal = (props) => {
const {show, handleShow, caption, setCaption} = props;
return (
<>
<Button onClick={handleShow} variant={"primary"}>
Launch
</Button>
<Modal show={show} onHide={handleShow}>
<Modal.Header closeButton>
<Modal.Title>Just a head</Modal.Title>
</Modal.Header>
<Modal.Body>
<p>
<MyInput {…{caption, setCaption}} />
</p>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleShow}>
Close
</Button>
<Button variant="primary" onClick={handleShow}>
Save
</Button>
</Modal.Footer>
</Modal>
<div>
{show ? ‘show’ : ‘hide’}
</div>
</>
)
};
export default MyModal[/js]
[/su_spoiler]
Главный компонент App.js
[su_spoiler title=»App.js» style=»fancy»]
[js]
import React, {useState} from ‘react’;
import ‘./App.css’;
import MyModal from "./components/my-modal";
import ‘bootstrap/dist/css/bootstrap.min.css’
import MarkdownIt from ‘markdown-it’;
import {Parser} from ‘html-to-react’
import refractor from ‘refractor’;
import Rehype from ‘rehype’
const rehype = Rehype();
const parser = new Parser();
const md = MarkdownIt({
html: true,
xhtmlOut: true,
highlight: (code, lang) => {
console.log("CODE===>", code);
try {
const result = refractor.highlight(code, lang);
const html = rehype.stringify({type: ‘root’, children: result}).toString();
console.log(html);
return html;
}catch(__){}
}
});
function App() {
const [show, setShow] = useState(false);
const [caption, setCaption] = useState(»);
const handleShow = () => {
setShow(!show);
};
return (
<div className="container App">
<MyModal {…{show, handleShow, caption, setCaption}}/>
{parser.parse(md.render(caption))}
</div>
);
}
export default App;[/js]
[/su_spoiler]
Стили для раскраски текста app.css
[su_spoiler title=»app.css» style=»fancy»]
[css]
.App {
text-align: left;
margin-top: 40px;
}
.language-jsx {
padding: 20px;
display: block;
background: black;
color: white;
}
.language-jsx .keyword {
color: tomato;
}
.language-jsx .function {
color: green;
font-weight: bold;
}
.language-jsx .operator {
color: red;
}
.language-jsx .punctuation{
color: blue;
font-size: 0.9rem;
}
.language-jsx .tag {
color: darkcyan;
}
.language-jsx .comment {
color: gray;
}
.language-jsx .parameter {
color: bisque;
}
[/css]
[/su_spoiler]
Результат
