* adds focusTrap wrapper to preact Modal component * add view specific code for focus trap in admin add nav link * add script to return a focustrap toggle, use in add nav link modal partial * add trap to edit nav link modal * add handlers for sign up modal * update modal controller for admin section, update nav link modals to use * update other admin modals with new data values for trap * remove unneeded erb script file * remove unneeded target * refactor to remove extra unneeded param * remove duplicate code, store getFocusTrapToggle in window * trap focus in comment and bookmark showModal instances for not logged in user * remove need for activator id * clean up id refs no longer needed * remove custom code and re-use focsu-trap lib * update storybook docs * update default export in focusTrap * prevent close button click triggering a modal toggle twice * ensure if user navigates from a modal the trap is deactivated * add jsdoc comments and add dynamic import * ensure admin controller modal traps are cleaned up on disconnect * update sign up modal to use crayons * update modal controller and admin nav links modals to use preact modal * update profile fields modals for new controller * tweak styling of sign up and admin modals to match previous * update listings modal to use crayons modal, adapt focus trap to work with click outside * memoize deactivate callback to ensure modal can be presented on first page load * add missed focustrap changes * fix focus trap issues in onboarding flow * refactor onboarding focus trap, remove getFocusTrapToggle * tweaks for styling and article modal toggle * add click outside tests to modal * add cypress tests for the login modal * update liquid tag tests affected by change * refactors to address review comments * fix issue with login modal presented twice on comment add * change ids to selectors in admin modals * small pr comment refactors * add listings e2e tests * add nav link modal tests * fix issue with help modal * tweak to fix ui bug from merge * remove context from showLoginModal * rename toggleModal * rename state property for clarity Co-authored-by: Nick Taylor <nick@dev.to>
311 lines
9.7 KiB
JavaScript
311 lines
9.7 KiB
JavaScript
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,
|
||
liquidShowing: false,
|
||
markdownShowing: false,
|
||
frontmatterShowing: false,
|
||
};
|
||
}
|
||
|
||
showModal = (sectionShowing, isOpen) => () => {
|
||
this.setState({ [sectionShowing]: isOpen });
|
||
};
|
||
|
||
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 comma-separated 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.showModal('frontmatterShowing', true)}
|
||
>
|
||
Jekyll front matter
|
||
</a>
|
||
. You can also use the <em>rich+markdown</em> editor you can find in{' '}
|
||
<a href="/settings/customization">
|
||
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.showModal('markdownShowing', true)}
|
||
>
|
||
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">> 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.showModal('liquidShowing', true)}>
|
||
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.showModal('liquidShowing', false),
|
||
'🌊 Liquid Tags',
|
||
liquidHelpHTML,
|
||
)}
|
||
|
||
{markdownShowing &&
|
||
this.renderModal(
|
||
this.showModal('markdownShowing', false),
|
||
'✍️ Markdown',
|
||
markdownHelpHTML,
|
||
)}
|
||
|
||
{frontmatterShowing &&
|
||
this.renderModal(
|
||
this.showModal('frontmatterShowing', false),
|
||
'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';
|