Element not responding to the new classes added
I created the markdown app alright but I wanted to add some functionality like maximising the #editor
element while hiding the #preview
and vice versa.
My idea was to add or remove .full
and .hidden
based on the state of the react component and then mutate these states with some functions.
However, the elements are not responding correctly to the added class.
I tried useRef at first but it keeps breaking my app.
If there is a better way to accomplish this, please let me know.
My code so far
HTML
<div id='app'></div>
CSS
#first {
display: flex;
flex-direction: column;
// justify-content: center;
position: absolute;
background-color: #122123;
top: 10px;
margin-top: 10px;
margin-left: 10px;
width: auto;
height: auto;
border: 2px solid black;
}
i {
font-size: 2rem;
color: brown;
}
button {
margin-right: 10px;
display: inline-block;
background-color: inherit;
}
.title {
display: flex;
justify-content: space-between;
align-items: center;
margin: 0;
height: 50px;
background: black;
color: brown;
// padding: auto 20px;
h2 {
text-align: left;
font-family: "Russo One" !important;
font-style: oblique !important;
font-weight: 700 !important;
font-size: 2em !important;
margin-left: 10px;
}
}
#editor {
border: none;
width: 400px;
height: 400px;
overflow: auto;
resize: none;
background-color: #122123;
}
#second {
position: absolute;
background-color: #122123;
top: 20px;
right: 10px;
min-height: 300px;
max-height: auto;
width: 700px;
border: 2px solid black;
}
textarea:focus {
outline: none;
}
#preview {
padding: 0 1rem;
blockquote {
border-left: 3px solid #224b4b;
color: #224b4b;
padding-left: 5px;
margin-left: 25px;
}
> p > code {
padding: 3px;
}
code {
background: white;
font-size: 0.875rem;
font-weight: bold;
}
pre {
display: block;
overflow: auto;
background: white;
padding: 5px;
line-height: 1.2;
}
h1 {
border-bottom: 2px solid black;
}
h2 {
border-bottom: 1px solid black;
}
table {
border-collapse: collapse;
}
td,
th {
border: 2px solid black;
padding-left: 5px;
padding-right: 5px;
}
img {
display: block;
max-width: 90%;
margin: 2rem auto;
}
}
.hidden {
display: none;
}
.full {
width: 95%;
min-height: 80vh;
max-height: auto;
}
JS(babel)
// marked.setOptions({
// gfm: true,
// breaks: true,
// sanitize: true
// });
// const renderer = new marked.Renderer();
// renderer.link = function (href, title, text) {
// return `<a target="_blank" href="${href}">${text}</a>`;
// };
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
editor: placeholder,
maxEditor: false,
maxPreview: false,
hideEditor: false,
hidePreview: false,
minBtn: true,
maxBtn: false
};
this.handleChange = this.handleChange.bind(this);
this.maxEditor = this.maxEditor.bind(this);
this.minEditor = this.minEditor.bind(this);
this.maxPreview = this.maxPreview.bind(this);
this.minPreview = this.minPreview.bind(this);
}
handleChange(event) {
this.setState({
editor: event.target.value
});
console.log(document.getElementById('first').classList)
console.log(document.getElementById('second').classList)
}
maxEditor(event) {
this.setState({
maxEditor: !this.state.maxEditor,
hidePreview: !this.state.hidePreview,
minBtn: !this.state.minBtn,
maxBtn: !this.state.maxBtn
});
console.log(document.getElementById('first').classList)
console.log(document.getElementById('second').classList)
}
minEditor(event) {
this.setState({
maxEditor: false,
hidePreview: false,
minBtn: true,
maxBtn: false
});
console.log(document.getElementById('first').classList)
console.log(document.getElementById('second').classList)
}
maxPreview(event) {
this.setState({
maxPreview: true,
hideEditor: true,
minBtn: false,
maxBtn: true
});
console.log(document.getElementById('first').classList)
console.log(document.getElementById('second').classList)
}
minPreview(event) {
this.setState({
maxPreview: false,
hideEditor: false,
minBtn: true,
maxBtn: false
});
console.log(document.getElementById('first').classList)
console.log(document.getElementById('second').classList)
}
render() {
return (
<div className="app">
<div
className={`markup ${this.state.hideEditor ? "hidden" : ""} ${
this.state.maxEditor ? "full" : ""
}`}
id="first"
>
<div className="title">
<h2>Editor</h2>
<button
onClick={this.maxEditor}
className={`markup-btn increase ${
this.state.maxBtn ? "hidden" : ""
}`}
>
<i className="fa-solid fa-maximize"></i>
</button>
<button
onClick={this.minEditor}
className={`markup-btn decrease ${
this.state.minBtn ? "hidden" : ""
}`}
>
<i className="fa-solid fa-minimize"></i>
</button>
</div>
<textarea
name="markup-text"
id="editor"
value={this.state.editor}
onChange={this.handleChange}
></textarea>
</div>
<div
className={`markup ${this.state.hidePreview ? "hidden" : ""} ${
this.state.maxPreview ? "full" : ""
}`}
id="second"
>
<div className="title">
<h2>Preview</h2>
<button onClick={this.maxPreview} className={`markup-btn increase ${
this.state.maxBtn ? "hidden" : ""
}`}>
<i
className="fa-solid fa-maximize"
></i>
</button>
<button onClick={this.minPreview} className={`markup-btn decrease ${
this.state.minBtn ? "hidden" : ""
}`}>
<i className="fa-solid fa-minimize"></i>
</button>
</div>
<Preview markdown={this.state.editor} />
</div>
</div>
);
}
}
const renderer = new marked.Renderer();
renderer.link = function (href, title, text) {
return `<a target="_blank" href="${href}">${text}</a>`;
};
const Preview = (props) => {
return (
<div
dangerouslySetInnerHTML={{
__html: marked(props.markdown, { renderer: renderer, breaks: true })
}}
id="preview"
/>
);
};
const placeholder = `# Welcome to my React Markdown Previewer!
## This is a sub-heading...
### And here's some other cool stuff:
Heres some code, \`<div></div>\`, between 2 backticks.
\`\`\`
// this is multi-line code:
function anotherExample(firstLine, lastLine) {
if (firstLine == '\`\`\`' && lastLine == '\`\`\`') {
return multiLineCode;
}
}
\`\`\`
You can also make text **bold**... whoa!
Or _italic_.
Or... wait for it... **_both!_**
And feel free to go crazy ~~crossing stuff out~~.
There's also [links](https://www.freecodecamp.org), and
> Block Quotes!
And if you want to get really crazy, even tables:
Wild Header | Crazy Header | Another Header?
------------ | ------------- | -------------
Your content can | be here, and it | can be here....
And here. | Okay. | I think we get it.
- And of course there are lists.
- Some are bulleted.
- With different indentation levels.
- That look like this.
1. And there are numbered lists too.
1. Use just 1s if you want!
1. And last but not least, let's not forget embedded images:

`;
ReactDOM.render(<App />, document.getElementById("app"));
Link to my codepen
My Markdown Preview App
Your browser information:
User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36
Challenge: Front End Development Libraries Projects - Build a Markdown Previewer
Link to the challenge: