Browse Source

Merge pull request #14795 from overleaf/rd-report-zoom-pdf-visible-focus

Accessibility - make the PDF controls accessible by tab navigation

GitOrigin-RevId: 46eee6fda68861884e602eb341dfdb0c5a4903b0
Rebeka Dekany 3 years ago
parent
commit
9184c0135f

+ 4 - 0
services/web/frontend/extracted-translations.json

@@ -354,6 +354,8 @@
   "first_name": "",
   "first_x_days_free_after_that_y_per_month": "",
   "first_x_days_free_after_that_y_per_year": "",
+  "fit_to_height": "",
+  "fit_to_width": "",
   "fold_line": "",
   "folder_location": "",
   "following_paths_conflict": "",
@@ -1292,6 +1294,8 @@
   "your_subscription": "",
   "your_subscription_has_expired": "",
   "youre_on_free_trial_which_ends_on": "",
+  "zoom_in": "",
+  "zoom_out": "",
   "zotero_groups_loading_error": "",
   "zotero_groups_relink": "",
   "zotero_integration": "",

+ 1 - 1
services/web/frontend/js/features/pdf-preview/components/pdf-js-viewer.js

@@ -410,7 +410,7 @@ function PdfJsViewer({ url, pdfFile }) {
       >
         <div className="pdfViewer" />
       </div>
-      <div className="pdfjs-controls">
+      <div className="pdfjs-controls" tabIndex="0">
         <PdfViewerControls setZoom={setZoom} />
       </div>
     </div>

+ 10 - 4
services/web/frontend/js/features/pdf-preview/components/pdf-viewer-controls.js

@@ -3,38 +3,44 @@ import PropTypes from 'prop-types'
 import Button from 'react-bootstrap/lib/Button'
 import Icon from '../../../shared/components/icon'
 import { memo } from 'react'
+import { useTranslation } from 'react-i18next'
 
 function PdfViewerControls({ setZoom }) {
+  const { t } = useTranslation()
   return (
     <ButtonGroup>
       <Button
+        aria-label={t('fit_to_width')}
+        bsSize="large"
         bsStyle={null}
         className="btn-secondary-info btn-secondary"
-        bsSize="large"
         onClick={() => setZoom('fit-width')}
       >
         <Icon type="arrows-h" />
       </Button>
       <Button
+        aria-label={t('fit_to_height')}
+        bsSize="large"
         bsStyle={null}
         className="btn-secondary-info btn-secondary"
-        bsSize="large"
         onClick={() => setZoom('fit-height')}
       >
         <Icon type="arrows-v" />
       </Button>
       <Button
+        aria-label={t('zoom_in')}
+        bsSize="large"
         bsStyle={null}
         className="btn-secondary-info btn-secondary"
-        bsSize="large"
         onClick={() => setZoom('zoom-in')}
       >
         <Icon type="search-plus" />
       </Button>
       <Button
+        aria-label={t('zoom_out')}
+        bsSize="large"
         bsStyle={null}
         className="btn-secondary-info btn-secondary"
-        bsSize="large"
         onClick={() => setZoom('zoom-out')}
       >
         <Icon type="search-minus" />

+ 12 - 0
services/web/frontend/stylesheets/app/editor/pdf.less

@@ -210,11 +210,23 @@
     left: 0;
     display: inline-block;
     z-index: 10; // above the PDF viewer
+
     .btn-group {
       transition: opacity 0.5s ease, visibility 0 linear 0.5s;
       visibility: hidden;
       opacity: 0;
     }
+
+    &:focus-within,
+    &:hover {
+      // make .pdfjs-controls and its children visible when it or any of its descendants are focused
+      .btn-group {
+        transition: none;
+        visibility: visible;
+        opacity: 1;
+      }
+    }
+
     &:hover,
     &.flash {
       .btn-group {

+ 4 - 0
services/web/locales/en.json

@@ -572,6 +572,8 @@
   "first_name": "First Name",
   "first_x_days_free_after_that_y_per_month": "First <0>__trialLen__ days free</0>, after that <0>__price__</0> per month",
   "first_x_days_free_after_that_y_per_year": "First <0>__trialLen__ days free</0>, after that <0>__price__</0> per year",
+  "fit_to_height": "Fit to height",
+  "fit_to_width": "Fit to width",
   "fold_line": "Fold line",
   "folder_location": "Folder location",
   "folders": "Folders",
@@ -2003,6 +2005,8 @@
   "youre_on_free_trial_which_ends_on": "You’re on a free trial which ends on <0>__date__</0>.",
   "zh-CN": "Chinese",
   "zip_contents_too_large": "Zip contents too large",
+  "zoom_in": "Zoom in",
+  "zoom_out": "Zoom out",
   "zotero": "Zotero",
   "zotero_and_mendeley_integrations": "<0>Zotero</0> and <0>Mendeley</0> integrations",
   "zotero_groups_loading_error": "There was an error loading groups from Zotero",