docbrown/app/javascript/article-form/components/Help.jsx
Suzanne Aitchison 5bed8f56d4
improve keyboard accessibility of modals 12427 10610 (#12511)
* 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>
2021-02-24 16:01:10 +00:00

311 lines
9.7 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,
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">&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.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';