docbrown/app/javascript/article-form/components/Help.jsx
Nick Taylor f0963c1bfa
Drag and drop an image in the editor (#10145)
* Refactored drag n drop functionality to a hook and component.

* Add the snackbar to the article editor.

* Now you can drag and drop images in the post body content.

* Cleaning up a few things.

* Now post cover images can be dragged and dropped.

* Removed unused empty function.

* Added @testing-library/preact-hooks so that we can test hooks.

* Some renaming, small refactor.

* Added tests

* Added more tests.

* Added more tests.

* Added message about dropping only one image in post body.

* Added message about dropping only one image for cover image.

* put onDrop into it's own meethod.

* More tests.

* Added some API documentation.

* Updated editor help with drag and drop image help.

* Changed wording.

* Now the alt text for markdown removes the file extension.

* Updated help wording. Thanks @rhymes

* Now the image markdown adds a new line at the end as we currently do not support inline images.
2020-09-04 14:12:59 -04:00

319 lines
9.8 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { h, Component } from 'preact';
import PropTypes from 'prop-types';
import { Modal } from '@crayons';
export class Help extends Component {
constructor(props) {
super(props);
this.state = {
liquidHelpHTML:
document.getElementById('editor-liquid-help') &&
document.getElementById('editor-liquid-help').innerHTML,
markdownHelpHTML:
document.getElementById('editor-markdown-help') &&
document.getElementById('editor-markdown-help').innerHTML,
frontmatterHelpHTML:
document.getElementById('editor-frontmatter-help') &&
document.getElementById('editor-frontmatter-help').innerHTML,
};
}
setCommonProps = ({
liquidShowing = false,
markdownShowing = false,
frontmatterShowing = false,
}) => {
return {
liquidShowing,
markdownShowing,
frontmatterShowing,
};
};
toggleModal = (varShowing) => (e) => {
e.preventDefault();
this.setState((prevState) => ({
...this.setCommonProps({
[varShowing]: !prevState[varShowing],
}),
}));
};
renderArticleFormTitleHelp = () => {
return (
<div
data-testid="title-help"
className="crayons-article-form__help crayons-article-form__help--title"
>
<h4 className="mb-2 fs-l">Writing a Great Post Title</h4>
<ul className="list-disc pl-6 color-base-70">
<li>
Think of your post title as a super short (but compelling!)
description like an overview of the actual post in one short
sentence.
</li>
<li>
Use keywords where appropriate to help ensure people can find your
post by search.
</li>
</ul>
</div>
);
};
renderTagInputHelp = () => {
return (
<div
data-testid="basic-tag-input-help"
className="crayons-article-form__help crayons-article-form__help--tags"
>
<h4 className="mb-2 fs-l">Tagging Guidelines</h4>
<ul className="list-disc pl-6 color-base-70">
<li>Tags help people find your post.</li>
<li>
Think of tags as the topics or categories that best describe your
post.
</li>
<li>
Add up to four tags per post. Combine tags to reach the appropriate
subcommunities.
</li>
<li>Use existing tags whenever possible.</li>
<li>
Some tags, such as help or healthydebate, have special posting
guidelines.
</li>
</ul>
</div>
);
};
renderBasicEditorHelp = () => {
return (
<div
data-testid="basic-editor-help"
className="crayons-card crayons-card--secondary p-4 mb-6"
>
You are currently using the basic markdown editor that uses{' '}
<a href="#frontmatter" onClick={this.toggleModal('frontmatterShowing')}>
Jekyll front matter
</a>
. You can also use the <em>rich+markdown</em> editor you can find in{' '}
<a href="/settings/ux">
UX settings
<svg
width="24"
height="24"
viewBox="0 0 24 24"
className="crayons-icon"
xmlns="http://www.w3.org/2000/svg"
role="img"
aria-labelledby="c038a36b2512ed25db907e179ab45cfc"
>
<title id="c038a36b2512ed25db907e179ab45cfc">
Open UX settings
</title>
<path d="M10.667 8v1.333H7.333v7.334h7.334v-3.334H16v4a.666.666 0 01-.667.667H6.667A.666.666 0 016 17.333V8.667A.667.667 0 016.667 8h4zM18 6v5.333h-1.333V8.275l-5.196 5.196-.942-.942 5.194-5.196h-3.056V6H18z" />
</svg>
</a>
.
</div>
);
};
renderFormatHelp = () => {
return (
<div
data-testid="format-help"
className="crayons-article-form__help crayons-article-form__help--body"
>
<h4 className="mb-2 fs-l">Editor Basics</h4>
<ul className="list-disc pl-6 color-base-70">
<li>
Use{' '}
<a href="#markdown" onClick={this.toggleModal('markdownShowing')}>
Markdown
</a>{' '}
to write and format posts.
<details className="fs-s my-1">
<summary class="cursor-pointer">Commonly used syntax</summary>
<table className="crayons-card crayons-card--secondary crayons-table crayons-table--compact w-100 mt-2 mb-4 lh-tight">
<tbody>
<tr>
<td className="ff-monospace">
# Header
<br />
...
<br />
###### Header
</td>
<td>
H1 Header
<br />
...
<br />
H6 Header
</td>
</tr>
<tr>
<td className="ff-monospace">*italics* or _italics_</td>
<td>
<em>italics</em>
</td>
</tr>
<tr>
<td className="ff-monospace">**bold**</td>
<td>
<strong>bold</strong>
</td>
</tr>
<tr>
<td className="ff-monospace">[Link](https://...)</td>
<td>
<a href="https://forem.com">Link</a>
</td>
</tr>
<tr>
<td className="ff-monospace">
* item 1<br />* item 2
</td>
<td>
<ul class="list-disc ml-5">
<li>item 1</li>
<li>item 2</li>
</ul>
</td>
</tr>
<tr>
<td className="ff-monospace">
1. item 1<br />
2. item 2
</td>
<td>
<ul class="list-decimal ml-5">
<li>item 1</li>
<li>item 2</li>
</ul>
</td>
</tr>
<tr>
<td className="ff-monospace">&gt; quoted text</td>
<td>
<span className="pl-2 border-0 border-solid border-l-4 border-base-50">
quoted text
</span>
</td>
</tr>
<tr>
<td className="ff-monospace">`inline code`</td>
<td>
<code>inline code</code>
</td>
</tr>
<tr>
<td className="ff-monospace">
<span class="fs-xs">```</span>
<br />
code block
<br />
<span class="fs-xs">```</span>
</td>
<td>
<div class="highlight p-2 overflow-hidden">
<code>code block</code>
</div>
</td>
</tr>
</tbody>
</table>
</details>
</li>
<li>
You can use{' '}
<a href="#liquid" onClick={this.toggleModal('liquidShowing')}>
Liquid tags
</a>{' '}
to add rich content such as Tweets, YouTube videos, etc.
</li>
<li>
In addition to images for the post's content, you can also drag and
drop a cover image
</li>
</ul>
</div>
);
};
renderModal = (onClose, title, helpHtml) => {
return (
<Modal onClose={onClose} title={title}>
<div
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: helpHtml }}
/>
</Modal>
);
};
render() {
const { previewShowing, helpFor, helpPosition, version } = this.props;
const {
liquidHelpHTML,
markdownHelpHTML,
frontmatterHelpHTML,
liquidShowing,
markdownShowing,
frontmatterShowing,
} = this.state;
return (
<div className="crayons-article-form__aside">
{!previewShowing && (
<div
data-testid="article-form__help-section"
className="sticky"
style={{ top: version === 'v1' ? '56px' : helpPosition }}
>
{helpFor === 'article-form-title' &&
this.renderArticleFormTitleHelp()}
{helpFor === 'tag-input' && this.renderTagInputHelp()}
{version === 'v1' && this.renderBasicEditorHelp()}
{(helpFor === 'article_body_markdown' || version === 'v1') &&
this.renderFormatHelp()}
</div>
)}
{liquidShowing &&
this.renderModal(
this.toggleModal('liquidShowing'),
'🌊 Liquid Tags',
liquidHelpHTML,
)}
{markdownShowing &&
this.renderModal(
this.toggleModal('markdownShowing'),
' Markdown',
markdownHelpHTML,
)}
{frontmatterShowing &&
this.renderModal(
this.toggleModal('frontmatterShowing'),
'Jekyll Front Matter',
frontmatterHelpHTML,
)}
</div>
);
}
}
Help.propTypes = {
previewShowing: PropTypes.bool.isRequired,
helpFor: PropTypes.string.isRequired,
helpPosition: PropTypes.string.isRequired,
version: PropTypes.string.isRequired,
};
Help.displayName = 'Help';