diff --git a/.eslintrc.json b/.eslintrc.json index 598b7f3f..f82e6b06 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -26,9 +26,7 @@ "jsx-a11y/aria-activedescendant-has-tabindex": 1, "jsx-a11y/aria-role": 1, "jsx-a11y/click-events-have-key-events": 1, - "jsx-a11y/iframe-has-title": 1, "jsx-a11y/interactive-supports-focus": 1, - "jsx-a11y/no-redundant-roles": 1, "jsx-a11y/no-static-element-interactions": 1, "jsx-a11y/role-has-required-aria-props": 1, "curly": 0, diff --git a/src/assets/css/main.css b/src/assets/css/main.css index d61dafda..6c739549 100644 --- a/src/assets/css/main.css +++ b/src/assets/css/main.css @@ -124,7 +124,8 @@ .emoji-picker-container { position: absolute; - top: 30px; + top: 0; + left: 50%; z-index: 1000; transform: translateX(-50%); } diff --git a/src/shared/components/app/app.tsx b/src/shared/components/app/app.tsx index 96bf1016..3e334376 100644 --- a/src/shared/components/app/app.tsx +++ b/src/shared/components/app/app.tsx @@ -33,12 +33,13 @@ export class App extends Component { <>
- - ${I18NextService.i18n.t("jump_to_content", "Jump to content")} - + {I18NextService.i18n.t("jump_to_content", "Jump to content")} + {siteView && ( )} diff --git a/src/shared/components/app/navbar.tsx b/src/shared/components/app/navbar.tsx index 2ede00e1..11cfb6c6 100644 --- a/src/shared/components/app/navbar.tsx +++ b/src/shared/components/app/navbar.tsx @@ -347,10 +347,10 @@ export class Navbar extends Component { )} {person && ( - + )} ) : ( diff --git a/src/shared/components/common/emoji-picker.tsx b/src/shared/components/common/emoji-picker.tsx index ba36d755..1385ce8f 100644 --- a/src/shared/components/common/emoji-picker.tsx +++ b/src/shared/components/common/emoji-picker.tsx @@ -12,6 +12,10 @@ interface EmojiPickerState { showPicker: boolean; } +function closeEmojiMartOnEsc(i, event): void { + event.key === "Escape" && i.setState({ showPicker: false }); +} + export class EmojiPicker extends Component { private emptyState: EmojiPickerState = { showPicker: false, @@ -23,6 +27,7 @@ export class EmojiPicker extends Component { this.state = this.emptyState; this.handleEmojiClick = this.handleEmojiClick.bind(this); } + render() { return ( @@ -38,8 +43,8 @@ export class EmojiPicker extends Component { {this.state.showPicker && ( <> -
-
+
+
{ ); } + componentWillUnmount() { + document.removeEventListener("keyup", e => closeEmojiMartOnEsc(this, e)); + } + togglePicker(i: EmojiPicker, e: any) { e.preventDefault(); i.setState({ showPicker: !i.state.showPicker }); + + i.state.showPicker + ? document.addEventListener("keyup", e => closeEmojiMartOnEsc(i, e)) + : document.removeEventListener("keyup", e => closeEmojiMartOnEsc(i, e)); } handleEmojiClick(e: any) { diff --git a/src/shared/components/common/icon.tsx b/src/shared/components/common/icon.tsx index 7aedee71..5b6ddf81 100644 --- a/src/shared/components/common/icon.tsx +++ b/src/shared/components/common/icon.tsx @@ -35,6 +35,7 @@ export class Icon extends Component { interface SpinnerProps { large?: boolean; + className?: string; } export class Spinner extends Component { @@ -46,7 +47,9 @@ export class Spinner extends Component { return ( ); } diff --git a/src/shared/components/common/markdown-textarea.tsx b/src/shared/components/common/markdown-textarea.tsx index 2d306dca..25906097 100644 --- a/src/shared/components/common/markdown-textarea.tsx +++ b/src/shared/components/common/markdown-textarea.tsx @@ -23,15 +23,28 @@ import NavigationPrompt from "./navigation-prompt"; import ProgressBar from "./progress-bar"; interface MarkdownTextAreaProps { + /** + * Initial content inside the textarea + */ initialContent?: string; + /** + * Numerical ID of the language to select in dropdown + */ initialLanguageId?: number; placeholder?: string; buttonTitle?: string; maxLength?: number; + /** + * Whether this form is for a reply to a Private Message. + * If true, a "Cancel" button is shown that will close the reply. + */ replyType?: boolean; focus?: boolean; disabled?: boolean; finished?: boolean; + /** + * Whether to show the language selector + */ showLanguage?: boolean; hideNavigationWarnings?: boolean; onContentChange?(val: string): void; @@ -276,19 +289,6 @@ export class MarkdownTextArea extends Component< {/* A flex expander */}
- {this.props.buttonTitle && ( - - )} {this.props.replyType && ( + {this.props.buttonTitle && ( )}
diff --git a/src/shared/components/post/post-listing.tsx b/src/shared/components/post/post-listing.tsx index d5ddc2f2..d11db0df 100644 --- a/src/shared/components/post/post-listing.tsx +++ b/src/shared/components/post/post-listing.tsx @@ -707,13 +707,16 @@ export class PostListing extends Component { data-tippy-content={I18NextService.i18n.t("more")} data-bs-toggle="dropdown" aria-expanded="false" - aria-controls="advancedButtonsDropdown" + aria-controls={`advancedButtonsDropdown${post.id}`} aria-label={I18NextService.i18n.t("more")} > -
    +
      {!this.myPost ? ( <>
    • {this.reportButton}
    • diff --git a/src/shared/components/private_message/create-private-message.tsx b/src/shared/components/private_message/create-private-message.tsx index 8afd3488..840a4425 100644 --- a/src/shared/components/private_message/create-private-message.tsx +++ b/src/shared/components/private_message/create-private-message.tsx @@ -115,7 +115,9 @@ export class CreatePrivateMessage extends Component< return (
      -
      {I18NextService.i18n.t("create_private_message")}
      +

      + {I18NextService.i18n.t("create_private_message")} +

      +
      {!this.props.privateMessageView && ( -
      +
      -
      +
      )} +
      + + + # + + # + + +
      { + this.handlePrivateMessageSubmit(this, event); + }} initialContent={this.state.content} onContentChange={this.handleContentChange} allLanguages={[]} siteLanguages={[]} hideNavigationWarnings + onReplyCancel={() => this.handleCancel(this)} + replyType={this.props.replyType} + buttonTitle={ + this.props.privateMessageView + ? capitalizeFirstLetter(I18NextService.i18n.t("save")) + : capitalizeFirstLetter(I18NextService.i18n.t("send_message")) + } />
      - - {this.state.showDisclaimer && ( -
      -
      -
      - - # - - # - - -
      -
      -
      - )} -
      -
      - - {this.props.privateMessageView && ( - - )} -
        -
      • -
      -
      -
      ); } @@ -200,8 +161,4 @@ export class PrivateMessageForm extends Component< event.preventDefault(); i.setState({ previewMode: !i.state.previewMode }); } - - handleShowDisclaimer(i: PrivateMessageForm) { - i.setState({ showDisclaimer: !i.state.showDisclaimer }); - } } diff --git a/src/shared/components/private_message/private-message.tsx b/src/shared/components/private_message/private-message.tsx index af8d64e5..110a908f 100644 --- a/src/shared/components/private_message/private-message.tsx +++ b/src/shared/components/private_message/private-message.tsx @@ -145,6 +145,7 @@ export class PrivateMessage extends Component< <>