Skip to content
This repository has been archived by the owner on May 30, 2023. It is now read-only.

fix(project): image link, update CSS, add code highlighter #1259

Merged
merged 2 commits into from
Jun 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions src/projects/markdown-previewer/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.23.0/themes/prism.min.css"
/>

<div id="app"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.6/marked.js"></script>
<script
crossorigin
src="https://unpkg.com/react@17/umd/react.production.min.js"
></script>
<script
crossorigin
src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"
></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/2.0.3/marked.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.23.0/prism.min.js"></script>
47 changes: 25 additions & 22 deletions src/projects/markdown-previewer/index.jsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
/* globals marked, React, ReactDOM */
/* globals marked, Prism, React, ReactDOM */
/* eslint-disable react/prop-types, no-nested-ternary */

// View a more complex version of this project with custom toolbar here:
// https://codepen.io/no_stack_dub_sack/pen/JbPZvm?editors=0110

// coded by @no-stack-dub-sack (github) / @no_stack_sub_sack (codepen)
// coded by @no-stack-dub-sack (github) / @no_stack_sub_sack (Codepen)

// eslint-disable-next-line no-unused-vars
const projectName = 'markdown-previewer';

// ALLOWS LINE BREAKS WITH RETURN BUTTON
marked.setOptions({
breaks: true
breaks: true,
highlight: function (code) {
return Prism.highlight(code, Prism.languages.javascript, 'javascript');
}
});

// INSERTS target="_blank" INTO HREF TAGS (required for codepen links)
// INSERTS target="_blank" INTO HREF TAGS (required for Codepen links)
const renderer = new marked.Renderer();
renderer.link = function(href, title, text) {
return `<a target="_blank" href="${href}">${text}` + '</a>';
renderer.link = function (href, title, text) {
return `<a target="_blank" href="${href}">${text}</a>`;
};

class App extends React.Component {
Expand Down Expand Up @@ -51,24 +54,24 @@ class App extends React.Component {
const classes = this.state.editorMaximized
? ['editorWrap maximized', 'previewWrap hide', 'fa fa-compress']
: this.state.previewMaximized
? ['editorWrap hide', 'previewWrap maximized', 'fa fa-compress']
: ['editorWrap', 'previewWrap', 'fa fa-arrows-alt'];
? ['editorWrap hide', 'previewWrap maximized', 'fa fa-compress']
: ['editorWrap', 'previewWrap', 'fa fa-arrows-alt'];
return (
<div>
<div className={classes[0]}>
<Toolbar
icon={classes[2]}
onClick={this.handleEditorMaximize}
text='Editor'
text="Editor"
/>
<Editor markdown={this.state.markdown} onChange={this.handleChange} />
</div>
<div className='converter' />
<div className="converter" />
<div className={classes[1]}>
<Toolbar
icon={classes[2]}
onClick={this.handlePreviewMaximize}
text='Previewer'
text="Previewer"
/>
<Preview markdown={this.state.markdown} />
</div>
Expand All @@ -77,34 +80,34 @@ class App extends React.Component {
}
}

const Toolbar = props => {
const Toolbar = (props) => {
return (
<div className='toolbar'>
<i className='fa fa-free-code-camp' title='no-stack-dub-sack' />
<div className="toolbar">
<i className="fa fa-free-code-camp" title="no-stack-dub-sack" />
{props.text}
<i className={props.icon} onClick={props.onClick} />
</div>
);
};

const Editor = props => {
const Editor = (props) => {
return (
<textarea
id='editor'
id="editor"
onChange={props.onChange}
type='text'
type="text"
value={props.markdown}
/>
);
};

const Preview = props => {
const Preview = (props) => {
return (
<div
dangerouslySetInnerHTML={{
__html: marked(props.markdown, { renderer: renderer })
}}
id='preview'
id="preview"
/>
);
};
Expand All @@ -131,7 +134,7 @@ Or _italic_.
Or... wait for it... **_both!_**
And feel free to go crazy ~~crossing stuff out~~.

There's also [links](https://www.freecodecamp.com), and
There's also [links](https://www.freecodecamp.org), and
> Block Quotes!

And if you want to get really crazy, even tables:
Expand All @@ -147,11 +150,11 @@ And here. | Okay. | I think we get it.
- That look like this.


1. And there are numbererd lists too.
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:

![React Logo w/ Text](https://goo.gl/Umyytc)
![freeCodeCamp Logo](https://cdn.freecodecamp.org/testable-projects-fcc/images/fcc_secondary.svg)
`;

ReactDOM.render(<App />, document.getElementById('app'));
88 changes: 49 additions & 39 deletions src/projects/markdown-previewer/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,23 @@ $backgroundBase: #619e9e;
$shadow: 1px 1px 10px 2px darken($backgroundBase, 20%);
$default-border: 1px solid darken($backgroundBase, 35%);

* {
box-sizing: border-box;
}

body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background: lighten($backgroundBase, 12%);
margin: 10px 0;
}

#preview,
.title {
display: inline-block;
}

.colorScheme {
background-color: lighten($backgroundBase, 30%);
border: $default-border;
Expand All @@ -24,22 +31,22 @@ body {
}

.toolbar {
position: relative;
display: flex;
align-items: center;
background-color: lighten($darkAccent, 25%);
padding: 4px 4px 3px 3px;
padding: 0.3rem;
border: $default-border;
box-shadow: $shadow;
font-family: Russo One;
font-size: 15px;
font-size: 1rem;
color: black;
i {
width: 25px;
color: black;
margin-left: 5px;
}
.fa-arrows-alt,
.fa-compress {
position: absolute;
right: -5px;
margin-left: auto;
}
}

Expand All @@ -57,8 +64,8 @@ body {
}

.editorWrap {
width: 600px;
margin: 18px auto;
max-width: 600px;
margin: 1.125rem auto;
.toolbar {
width: 99%;
}
Expand All @@ -71,7 +78,7 @@ body {
outline: none;
padding-left: 5px;
padding-top: 5px;
font-size: 12px;
font-size: 0.875rem;
}
}

Expand All @@ -84,29 +91,18 @@ body {

.previewWrap {
@extend .colorScheme;
width: 800px;
margin: 20px auto;
max-width: 800px;
margin: 1.25rem auto;
min-height: 200px;
overflow-wrap: break-word;
padding-right: 20px;
.toolbar {
left: -1px;
width: 100%;
padding-right: 17px;
}
#preview {
margin-left: 5px;
margin-top: -10px;
width: 100%;
}
}

@media screen and (max-width: 850px) {
.previewWrap {
width: 630px;
max-width: 630px;
}
.editorWrap {
width: 550px;
max-width: 550px;
}
}

Expand Down Expand Up @@ -137,35 +133,37 @@ body {
margin: auto;
}
.previewWrap {
width: 95vw;
#preview {
width: 100%;
img {
height: 200px;
}
}
width: 90vw;
}
}

// MARKDOWN STYLES
#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;
padding: 1px 4px 2px 4px;
font-size: 12px;
font-size: 0.875rem;
font-weight: bold;
}

pre {
display: block;
overflow: auto;
background: white;
padding: 5px 0 5px 5px;
padding: 5px;
line-height: 1.2;
}

h1 {
Expand All @@ -186,4 +184,16 @@ body {
padding-left: 5px;
padding-right: 5px;
}

img {
display: block;
max-width: 90%;
margin: 2rem auto;
}
}

@media screen and (max-width: 420px) {
body {
font-size: 0.875rem;
}
}