diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 000000000..c89c58309 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,12 @@ +{ + "arrowParens": "avoid", + "bracketSpacing": true, + "htmlWhitespaceSensitivity": "css", + "insertPragma": false, + "jsxBracketSameLine": false, + "jsxSingleQuote": false, + "printWidth": 120, + "quoteProps": "preserve", + "singleQuote": true, + "trailingComma": "all" +} diff --git a/src/components/Accessibility/Accessibility.js b/src/components/Accessibility/Accessibility.js index 1e045e9ed..1c46f68b2 100644 --- a/src/components/Accessibility/Accessibility.js +++ b/src/components/Accessibility/Accessibility.js @@ -1,54 +1,62 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { connect } from 'react-redux'; - +import React, { useState } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; import selectors from 'selectors'; - import './Accessibility.scss'; +import classNames from 'classnames'; +import actions from 'actions'; -class Accessibility extends React.PureComponent { - static propTypes = { - isAccessibleMode: PropTypes.bool, - isNotesPanelDisabled: PropTypes.bool, - } +function Accessibility() { + const dispatch = useDispatch(); + const [isVisible, setIsVisible] = useState(false); - state = { - isVisible: false, - } + const isAccessibleMode = useSelector(selectors.isAccessibleMode); - onFocus = () => { - this.setState({ isVisible: true }); - } + const isNotesPanelOpen = useSelector(state => selectors.isElementOpen(state, 'notesPanel')); + const isNotesPanelDisabled = useSelector(state => selectors.isElementDisabled(state, 'notesPanel')); - onBlur = () => { - this.setState({ isVisible: false }); - } + const isSearchPanelOpen = useSelector(state => selectors.isElementOpen(state, 'searchPanel')); + const isSearchPanelDisabled = useSelector(state => selectors.isElementDisabled(state, 'searchPanel')); - render() { - const { isAccessibleMode, isNotesPanelDisabled } = this.props; - const { isVisible } = this.state; + const onFocus = () => setIsVisible(true); + const onBlur = () => setIsVisible(false); - if (!isAccessibleMode) { - return null; + const onSkipToDocument = () => { + document.getElementById('pageText1').focus(); + }; + + const onSkipToSearch = () => { + if (isSearchPanelOpen) { + const searchEl = document.getElementById('SearchPanel__input'); + searchEl && searchEl.focus(); + } else { + dispatch(actions.openElement('searchPanel')); + } + }; + + const onSkipToNotes = () => { + if (isNotesPanelOpen) { + const noteEl = document.getElementById('NotesPanel__input'); + noteEl && noteEl.focus(); + } else { + dispatch(actions.openElement('notesPanel')); } + }; - const skiptoNotes = isNotesPanelDisabled ? null :
Notes
; - const className = `Accessibility ${isVisible ? 'visible' : 'hidden'}`; - - return ( -
-
Skip to:
- -
Document
- {skiptoNotes} -
- ); + if (!isAccessibleMode) { + return null; } -} -const mapStateToProps = state => ({ - isAccessibleMode: selectors.isAccessibleMode(state), - isNotesPanelDisabled: selectors.isElementDisabled(state, 'notesPanel') -}); + const a11yClass = classNames('Accessibility', isVisible ? 'visible' : 'hidden'); + + return ( +
+
Skip to:
+ + + {isSearchPanelDisabled ? null : } + {isNotesPanelDisabled ? null : } +
+ ); +} -export default connect(mapStateToProps)(Accessibility); \ No newline at end of file +export default Accessibility; diff --git a/src/components/Accessibility/Accessibility.scss b/src/components/Accessibility/Accessibility.scss index abd3ec884..498cf3256 100644 --- a/src/components/Accessibility/Accessibility.scss +++ b/src/components/Accessibility/Accessibility.scss @@ -2,37 +2,33 @@ .Accessibility { position: fixed; - left: 50%; - transform: translate(-50%); - z-index: 30; + z-index: 9999; display: flex; + align-items: center; overflow: hidden; background: white; - color: $pdftron-blue; - font-style: italic; + color: black; font-size: 1.2em; - border-bottom: 1px solid var(--border); + border: 1px solid var(--border); + + height: $top-bar-height; + padding: 0 10px; &.visible { - height: $top-bar-height; - padding: 10px; + transform: translateY(0%); } &.hidden { - height: 0; - padding: 0; + transform: translateY(-100%); } - div { - margin: 2px 7px; - padding: 1px; - } - - .skip-to-hack { - width: 0; - height: 0; + button { border: none; + background-color: transparent; + color: black; + margin: 0 7px; + padding: 2px 6px; } } \ No newline at end of file diff --git a/src/components/Note/Note.js b/src/components/Note/Note.js index d6be65abf..1aee91076 100644 --- a/src/components/Note/Note.js +++ b/src/components/Note/Note.js @@ -79,7 +79,7 @@ const Note = ({ annotation }) => { const handleNoteClick = e => { // stop bubbling up otherwise the note will be closed // due to annotation deselection - e.stopPropagation(); + e && e.stopPropagation(); if (!isSelected) { core.deselectAllAnnotations(); @@ -105,10 +105,11 @@ const Note = ({ annotation }) => { const showReplyArea = !Object.values(isEditingMap).some(val => val); const handleNoteKeydown = e => { - // Stop enter/space key on Note from being submitted into field. + // Click if enter or space is pressed and is current target. const isNote = e.target === e.currentTarget; if (isNote && (e.key === 'Enter' || e.key === ' ')) { - e.preventDefault(); + e.preventDefault(); // Stop from being entered in field + handleNoteClick(); } }; @@ -123,7 +124,14 @@ const Note = ({ annotation }) => { ); return ( -
+
{
{replies.map((reply, i) => ( { placeholder={t('message.searchCommentsPlaceholder')} onChange={handleInputChange} ref={inputRef} + id="NotesPanel__input" />
diff --git a/src/components/SearchOverlay/SearchOverlay.js b/src/components/SearchOverlay/SearchOverlay.js index d1c52f3e8..d961e719e 100644 --- a/src/components/SearchOverlay/SearchOverlay.js +++ b/src/components/SearchOverlay/SearchOverlay.js @@ -479,6 +479,7 @@ class SearchOverlay extends React.PureComponent { onKeyDown={this.onKeyDown} value={searchValue} placeholder={t('message.searchDocumentPlaceholder')} + id="SearchPanel__input" />