Improve landmarks on the Project dashboard and Editor pages (#27401)
* Improve landmarks for the Project Dasbhboard * Improve landmarks for the IDE page * Improve landmarks for the new redesigned IDE page * Sort locales * Fix typo OlButtonToolbar -> OLButtonToolbar * Update project navbar translation * Update labels * Redundant main landmark * Fix failing test * Descriptive name for the rails tab * Header should not be in a button * Update translation to Account and help * Update translation to Project categories and tags * Add explanations * Show landmark for the survey widget when it's rendered * Suggestions for nav stretch/scroll/borders * Source format --------- Co-authored-by: Antoine Clausse <antoine.clausse@overleaf.com> GitOrigin-RevId: d05a738e782d2edb229529aadf92b9004dfd973a
This commit is contained in:
committed by
Copybot
co-authored by
Antoine Clausse
parent
1abb98fac2
commit
7c97cbbfe4
@@ -72,7 +72,7 @@ const ChatPane = React.memo(function ChatPane() {
|
||||
}
|
||||
|
||||
return (
|
||||
<aside className="chat">
|
||||
<aside className="chat" aria-label={t('chat')}>
|
||||
<InfiniteScroll
|
||||
atEnd={atEnd}
|
||||
className="messages"
|
||||
|
||||
+2
-6
@@ -88,11 +88,7 @@ const ToolbarHeader = React.memo(function ToolbarHeader({
|
||||
const shouldDisplayPublishButton = hasPublishPermissions && PublishButton
|
||||
|
||||
return (
|
||||
<header
|
||||
className="toolbar toolbar-header"
|
||||
role="navigation"
|
||||
aria-label={t('project_layout_sharing_submission')}
|
||||
>
|
||||
<nav className="toolbar toolbar-header" aria-label={t('project_actions')}>
|
||||
<div className="toolbar-left">
|
||||
<MenuButton onClick={onShowLeftMenuClick} />
|
||||
{cobranding && cobranding.logoImgUrl && (
|
||||
@@ -158,7 +154,7 @@ const ToolbarHeader = React.memo(function ToolbarHeader({
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
</nav>
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ function ChangeList() {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<aside className="change-list" aria-label={t('project_history_list')}>
|
||||
<aside className="change-list" aria-label={t('project_history_labels')}>
|
||||
<div className="history-header history-toggle-switch-container">
|
||||
<ToggleSwitch labelsOnly={labelsOnly} setLabelsOnly={setLabelsOnly} />
|
||||
</div>
|
||||
|
||||
@@ -55,6 +55,8 @@ export const EditorAndPdf: FC = () => {
|
||||
'ide-panel-group-resizing': resizing,
|
||||
hidden: !editorIsOpen,
|
||||
})}
|
||||
tagName="section"
|
||||
aria-label={t('editor')}
|
||||
>
|
||||
{selectedEntityCount === 0 && <NoSelectionPane />}
|
||||
{selectedEntityCount === 1 && openEntity?.type === 'fileRef' && (
|
||||
@@ -105,6 +107,8 @@ export const EditorAndPdf: FC = () => {
|
||||
onCollapse={handlePdfPaneCollapse}
|
||||
onExpand={handlePdfPaneExpand}
|
||||
className="ide-react-panel"
|
||||
tagName="section"
|
||||
aria-label={t('pdf_preview_logs')}
|
||||
>
|
||||
<PdfPreview />
|
||||
{/* ensure that "sync to code" is available in PDF only layout */}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { OutlineContainer } from '@/features/outline/components/outline-containe
|
||||
import { useOutlinePane } from '@/features/ide-react/hooks/use-outline-pane'
|
||||
import React, { ElementType } from 'react'
|
||||
import importOverleafModules from '../../../../macros/import-overleaf-module.macro'
|
||||
import { t } from 'i18next'
|
||||
|
||||
const editorSidebarComponents = importOverleafModules(
|
||||
'editorSidebarComponents'
|
||||
@@ -18,10 +19,11 @@ export default function EditorSidebar() {
|
||||
const { outlineEnabled, outlinePanelRef } = useOutlinePane()
|
||||
|
||||
return (
|
||||
<aside
|
||||
<nav
|
||||
className={classNames('ide-react-editor-sidebar', {
|
||||
hidden: view === 'history',
|
||||
})}
|
||||
aria-label={t('project_files_outline')}
|
||||
>
|
||||
{editorSidebarComponents.map(
|
||||
({ import: { default: Component }, path }) => (
|
||||
@@ -53,6 +55,6 @@ export default function EditorSidebar() {
|
||||
<OutlineContainer />
|
||||
</Panel>
|
||||
</PanelGroup>
|
||||
</aside>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
export function HistorySidebar() {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<aside
|
||||
<nav
|
||||
id="history-file-tree"
|
||||
className="ide-react-editor-sidebar history-file-tree"
|
||||
aria-label={t('project_files_history')}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ export const ChatPane = () => {
|
||||
<div className="chat-panel">
|
||||
<RailPanelHeader title={t('collaborator_chat')} />
|
||||
<div className="chat-wrapper">
|
||||
<aside className="chat">
|
||||
<aside className="chat" aria-label={t('chat')}>
|
||||
<InfiniteScroll
|
||||
atEnd={atEnd}
|
||||
className="messages"
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@ export default function IntegrationCard({
|
||||
<div className="integrations-panel-card-contents">
|
||||
{icon}
|
||||
<div className="integrations-panel-card-inner">
|
||||
<header className="integrations-panel-card-header">
|
||||
<div className="integrations-panel-card-header">
|
||||
<div className="integrations-panel-card-title">{title}</div>
|
||||
{showPaywallBadge && (
|
||||
<OLBadge
|
||||
@@ -33,7 +33,7 @@ export default function IntegrationCard({
|
||||
{t('premium')}
|
||||
</OLBadge>
|
||||
)}
|
||||
</header>
|
||||
</div>
|
||||
<p className="integrations-panel-card-description">{description}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -68,6 +68,8 @@ export default function MainLayout() {
|
||||
})}
|
||||
minSize={5}
|
||||
defaultSize={50}
|
||||
tagName="section"
|
||||
aria-label={t('editor')}
|
||||
>
|
||||
<div className="ide-redesign-editor-container">
|
||||
<EditorPanel />
|
||||
@@ -108,6 +110,8 @@ export default function MainLayout() {
|
||||
ref={pdfPanelRef}
|
||||
onExpand={handlePdfPaneExpand}
|
||||
onCollapse={handlePdfPaneCollapse}
|
||||
tagName="section"
|
||||
aria-label={t('pdf_preview')}
|
||||
>
|
||||
<PdfPreview />
|
||||
{pdfLayout === 'flat' && view === 'pdf' && (
|
||||
|
||||
+8
-3
@@ -1,14 +1,19 @@
|
||||
import { memo } from 'react'
|
||||
import OlButtonToolbar from '@/features/ui/components/ol/ol-button-toolbar'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import OLButtonToolbar from '@/features/ui/components/ol/ol-button-toolbar'
|
||||
import PdfCompileButton from '@/features/pdf-preview/components/pdf-compile-button'
|
||||
import PdfHybridDownloadButton from '@/features/pdf-preview/components/pdf-hybrid-download-button'
|
||||
import { DetachedSynctexControl } from '@/features/pdf-preview/components/detach-synctex-control'
|
||||
import SwitchToEditorButton from '@/features/pdf-preview/components/switch-to-editor-button'
|
||||
|
||||
function PdfPreviewHybridToolbar() {
|
||||
const { t } = useTranslation()
|
||||
// TODO: add detached pdf logic
|
||||
return (
|
||||
<OlButtonToolbar className="toolbar toolbar-pdf toolbar-pdf-hybrid">
|
||||
<OLButtonToolbar
|
||||
className="toolbar toolbar-pdf toolbar-pdf-hybrid"
|
||||
aria-label={t('pdf')}
|
||||
>
|
||||
<div className="toolbar-pdf-left">
|
||||
<PdfCompileButton />
|
||||
<PdfHybridDownloadButton />
|
||||
@@ -19,7 +24,7 @@ function PdfPreviewHybridToolbar() {
|
||||
<DetachedSynctexControl />
|
||||
{/* TODO: should we have code check? */}
|
||||
</div>
|
||||
</OlButtonToolbar>
|
||||
</OLButtonToolbar>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ export default function RailPanelHeader({
|
||||
const { t } = useTranslation()
|
||||
const { handlePaneCollapse } = useRailContext()
|
||||
return (
|
||||
<header className="rail-panel-header">
|
||||
<div className="rail-panel-header">
|
||||
<h4 className="rail-panel-title">{title}</h4>
|
||||
|
||||
<div className="rail-panel-header-actions">
|
||||
@@ -33,6 +33,6 @@ export default function RailPanelHeader({
|
||||
/>
|
||||
</OLTooltip>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -258,7 +258,13 @@ export const RailLayout = () => {
|
||||
onSelect={onTabSelect}
|
||||
id="ide-rail-tabs"
|
||||
>
|
||||
<div className={classNames('ide-rail', { hidden: isHistoryView })}>
|
||||
{/* The <Nav> element is a "div" and has a "role="tablist"".
|
||||
But it should be identified as a navigation landmark.
|
||||
Therefore, we nest them: the parent <nav> is the landmark, and its child gets the "role="tablist"". */}
|
||||
<nav
|
||||
className={classNames('ide-rail', { hidden: isHistoryView })}
|
||||
aria-label={t('files_collaboration_integrations_logs')}
|
||||
>
|
||||
<Nav activeKey={selectedTab} className="ide-rail-tabs-nav">
|
||||
{railTabs
|
||||
.filter(({ hide }) => !hide)
|
||||
@@ -274,11 +280,13 @@ export const RailLayout = () => {
|
||||
/>
|
||||
))}
|
||||
<div className="flex-grow-1" />
|
||||
{railActions?.map(action => (
|
||||
<RailActionElement key={action.key} action={action} />
|
||||
))}
|
||||
<nav aria-label={t('help_editor_settings')}>
|
||||
{railActions?.map(action => (
|
||||
<RailActionElement key={action.key} action={action} />
|
||||
))}
|
||||
</nav>
|
||||
</Nav>
|
||||
</div>
|
||||
</nav>
|
||||
<Panel
|
||||
id={
|
||||
newErrorlogs
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { ToolbarMenuBar } from './menu-bar'
|
||||
import { ToolbarProjectTitle } from './project-title'
|
||||
import { OnlineUsers } from './online-users'
|
||||
@@ -23,6 +24,7 @@ export const Toolbar = () => {
|
||||
const { view, restoreView } = useLayoutContext()
|
||||
const { cobranding } = useEditorContext()
|
||||
const { permissionsLevel } = useIdeReactContext()
|
||||
const { t } = useTranslation()
|
||||
const shouldDisplaySubmitButton =
|
||||
(permissionsLevel === 'owner' || permissionsLevel === 'readAndWrite') &&
|
||||
SubmitProjectButton
|
||||
@@ -34,18 +36,18 @@ export const Toolbar = () => {
|
||||
|
||||
if (view === 'history') {
|
||||
return (
|
||||
<div className="ide-redesign-toolbar">
|
||||
<nav className="ide-redesign-toolbar" aria-label={t('project_actions')}>
|
||||
<div className="d-flex align-items-center">
|
||||
<BackToEditorButton onClick={handleBackToEditorClick} />
|
||||
</div>
|
||||
<ToolbarProjectTitle />
|
||||
<div /> {/* Empty div used for spacing */}
|
||||
</div>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="ide-redesign-toolbar">
|
||||
<nav className="ide-redesign-toolbar" aria-label={t('project_actions')}>
|
||||
<div className="ide-redesign-toolbar-menu">
|
||||
<ToolbarLogos cobranding={cobranding} />
|
||||
<ToolbarMenuBar />
|
||||
@@ -62,6 +64,6 @@ export const Toolbar = () => {
|
||||
<ShareProjectButton />
|
||||
{getMeta('ol-showUpgradePrompt') && <UpgradeButton />}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ const OutlinePane = React.memo<{
|
||||
|
||||
return (
|
||||
<div className={headerClasses}>
|
||||
<header className="outline-header">
|
||||
<div className="outline-header">
|
||||
<OutlineToggleButton
|
||||
toggleExpanded={toggleExpanded}
|
||||
expanded={expanded}
|
||||
@@ -47,7 +47,7 @@ const OutlinePane = React.memo<{
|
||||
isPartial={isPartial}
|
||||
isTexFile={isTexFile}
|
||||
/>
|
||||
</header>
|
||||
</div>
|
||||
{isOpen && (
|
||||
<div className="outline-body">
|
||||
<OutlineRoot
|
||||
|
||||
@@ -487,6 +487,21 @@ function PdfJsViewer({ url, pdfFile }: PdfJsViewerProps) {
|
||||
const toolbarInfoLoaded =
|
||||
rawScale !== null && page !== null && totalPages !== null
|
||||
|
||||
// Remove the 'region' role from each PDF page container.
|
||||
// This prevents polluting the landmark navigation menu for every page,
|
||||
// which creates a poor screen reader experience. Page navigation should be handled
|
||||
// by the toolbar controls.
|
||||
useEffect(() => {
|
||||
if (!initialised || !pdfJsWrapper) return
|
||||
|
||||
const pageElements = pdfJsWrapper.container.querySelectorAll(
|
||||
'div[data-page-number][role="region"]'
|
||||
)
|
||||
pageElements.forEach(element => {
|
||||
element.removeAttribute('role')
|
||||
})
|
||||
}, [initialised, pdfJsWrapper])
|
||||
|
||||
/* eslint-disable jsx-a11y/no-noninteractive-tabindex */
|
||||
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
|
||||
return (
|
||||
|
||||
+7
-4
@@ -1,6 +1,6 @@
|
||||
import { memo, useState, useEffect, useRef } from 'react'
|
||||
import OlButtonToolbar from '@/features/ui/components/ol/ol-button-toolbar'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import OLButtonToolbar from '@/features/ui/components/ol/ol-button-toolbar'
|
||||
import { useLayoutContext } from '@/shared/context/layout-context'
|
||||
import PdfCompileButton from './pdf-compile-button'
|
||||
import SwitchToEditorButton from './switch-to-editor-button'
|
||||
@@ -15,7 +15,7 @@ const ORPHAN_UI_TIMEOUT_MS = 5000
|
||||
|
||||
function PdfPreviewHybridToolbar() {
|
||||
const { detachRole, detachIsLinked } = useLayoutContext()
|
||||
|
||||
const { t } = useTranslation()
|
||||
const uiTimeoutRef = useRef<number>()
|
||||
const [orphanPdfTabAfterDelay, setOrphanPdfTabAfterDelay] = useState(false)
|
||||
|
||||
@@ -47,9 +47,12 @@ function PdfPreviewHybridToolbar() {
|
||||
}
|
||||
|
||||
return (
|
||||
<OlButtonToolbar className="toolbar toolbar-pdf toolbar-pdf-hybrid">
|
||||
<OLButtonToolbar
|
||||
className="toolbar toolbar-pdf toolbar-pdf-hybrid"
|
||||
aria-label={t('pdf')}
|
||||
>
|
||||
{ToolbarInner}
|
||||
</OlButtonToolbar>
|
||||
</OLButtonToolbar>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ function PreviewLogEntryHeader({
|
||||
const headerTitleText = logType ? `${logType} ${headerTitle}` : headerTitle
|
||||
|
||||
return (
|
||||
<header className={logEntryHeaderClasses}>
|
||||
<div className={logEntryHeaderClasses}>
|
||||
{headerIcon ? (
|
||||
<div className="log-entry-header-icon-container">{headerIcon}</div>
|
||||
) : null}
|
||||
@@ -116,7 +116,7 @@ function PreviewLogEntryHeader({
|
||||
) : (
|
||||
locationLink
|
||||
)}
|
||||
</header>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+7
-2
@@ -1,4 +1,5 @@
|
||||
import { JSXElementConstructor } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Common from './groups/common'
|
||||
import Institution from './groups/institution'
|
||||
import ConfirmEmail from './groups/confirm-email'
|
||||
@@ -32,9 +33,13 @@ const USGovBanner: JSXElementConstructor<Record<string, never>> =
|
||||
function UserNotifications() {
|
||||
const groupSubscriptionsPendingEnrollment =
|
||||
getMeta('ol-groupSubscriptionsPendingEnrollment') || []
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div className="user-notifications notification-list">
|
||||
<section
|
||||
className="user-notifications notification-list"
|
||||
aria-label={t('notification')}
|
||||
>
|
||||
<ul className="list-unstyled">
|
||||
{EnrollmentNotification &&
|
||||
groupSubscriptionsPendingEnrollment.map(subscription => (
|
||||
@@ -58,7 +63,7 @@ function UserNotifications() {
|
||||
|
||||
{isDeprecatedBrowser() && <DeprecatedBrowser />}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -62,73 +62,75 @@ export function ProjectListDsNav() {
|
||||
overleafLogo={overleafLogo}
|
||||
showCloseIcon
|
||||
/>
|
||||
<main className="project-list-wrapper">
|
||||
<div className="project-list-wrapper">
|
||||
<SidebarDsNav />
|
||||
<div className="project-ds-nav-content-and-messages">
|
||||
<div className="project-ds-nav-content">
|
||||
<div className="project-ds-nav-main">
|
||||
{error ? <DashApiError /> : ''}
|
||||
<UserNotifications />
|
||||
<div className="project-list-header-row">
|
||||
<ProjectListTitle
|
||||
filter={filter}
|
||||
selectedTag={selectedTag}
|
||||
selectedTagId={selectedTagId}
|
||||
className="text-truncate d-none d-md-block"
|
||||
/>
|
||||
<div className="project-tools">
|
||||
<div className="d-none d-md-block">
|
||||
{selectedProjects.length === 0 ? (
|
||||
<main aria-labelledby="main-content">
|
||||
<div className="project-list-header-row">
|
||||
<ProjectListTitle
|
||||
filter={filter}
|
||||
selectedTag={selectedTag}
|
||||
selectedTagId={selectedTagId}
|
||||
className="text-truncate d-none d-md-block"
|
||||
/>
|
||||
<div className="project-tools">
|
||||
<div className="d-none d-md-block">
|
||||
{selectedProjects.length === 0 ? (
|
||||
<CurrentPlanWidget />
|
||||
) : (
|
||||
<ProjectTools />
|
||||
)}
|
||||
</div>
|
||||
<div className="d-md-none">
|
||||
<CurrentPlanWidget />
|
||||
) : (
|
||||
<ProjectTools />
|
||||
)}
|
||||
</div>
|
||||
<div className="d-md-none">
|
||||
<CurrentPlanWidget />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="project-ds-nav-project-list">
|
||||
<OLRow className="d-none d-md-block">
|
||||
<OLCol lg={7}>
|
||||
<SearchForm
|
||||
inputValue={searchText}
|
||||
setInputValue={setSearchText}
|
||||
filter={filter}
|
||||
selectedTag={selectedTag}
|
||||
/>
|
||||
</OLCol>
|
||||
</OLRow>
|
||||
<div className="project-list-sidebar-survey-wrapper d-md-none">
|
||||
{/* Omit the survey card in mobile view for now */}
|
||||
</div>
|
||||
<div className="mt-1 d-md-none">
|
||||
<div
|
||||
role="toolbar"
|
||||
className="projects-toolbar"
|
||||
aria-label={t('projects')}
|
||||
>
|
||||
<ProjectsDropdown />
|
||||
<SortByDropdown />
|
||||
<div className="project-ds-nav-project-list">
|
||||
<OLRow className="d-none d-md-block">
|
||||
<OLCol lg={7}>
|
||||
<SearchForm
|
||||
inputValue={searchText}
|
||||
setInputValue={setSearchText}
|
||||
filter={filter}
|
||||
selectedTag={selectedTag}
|
||||
/>
|
||||
</OLCol>
|
||||
</OLRow>
|
||||
<div className="project-list-sidebar-survey-wrapper d-md-none">
|
||||
{/* Omit the survey card in mobile view for now */}
|
||||
</div>
|
||||
<div className="mt-1 d-md-none">
|
||||
<div
|
||||
role="toolbar"
|
||||
className="projects-toolbar"
|
||||
aria-label={t('projects')}
|
||||
>
|
||||
<ProjectsDropdown />
|
||||
<SortByDropdown />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
<TableContainer bordered>
|
||||
{tableTopArea}
|
||||
<ProjectListTable />
|
||||
</TableContainer>
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
<LoadMore />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
<TableContainer bordered>
|
||||
{tableTopArea}
|
||||
<ProjectListTable />
|
||||
</TableContainer>
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
<LoadMore />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
<Footer {...footerProps} />
|
||||
</div>
|
||||
<CookieBanner />
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -50,8 +50,8 @@ function DefaultNavbarAndFooter({ children }: { children: ReactNode }) {
|
||||
<>
|
||||
<DefaultNavbar {...navbarProps} />
|
||||
<main
|
||||
id="main-content"
|
||||
className="content content-alt project-list-react"
|
||||
aria-labelledby="main-content"
|
||||
>
|
||||
{children}
|
||||
</main>
|
||||
|
||||
+23
-15
@@ -1,4 +1,5 @@
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import classnames from 'classnames'
|
||||
import { Question, User } from '@phosphor-icons/react'
|
||||
import NewProjectButton from '../new-project-button'
|
||||
@@ -8,7 +9,6 @@ import { usePersistedResize } from '@/shared/hooks/use-resize'
|
||||
import { Dropdown } from 'react-bootstrap'
|
||||
import getMeta from '@/utils/meta'
|
||||
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { NavDropdownMenuItems } from '@/features/ui/components/bootstrap-5/navbar/nav-dropdown-from-data'
|
||||
import { NavbarDropdownItemData } from '@/features/ui/components/types/navbar'
|
||||
import { useContactUsModal } from '@/shared/hooks/use-contact-us-modal'
|
||||
@@ -45,19 +45,24 @@ function SidebarDsNav() {
|
||||
},
|
||||
})}
|
||||
>
|
||||
<NewProjectButton
|
||||
id="new-project-button-sidebar"
|
||||
className={scrolledDown ? 'show-shadow' : undefined}
|
||||
/>
|
||||
<div
|
||||
className="project-list-sidebar-scroll"
|
||||
ref={containerRef}
|
||||
data-testid="project-list-sidebar-scroll"
|
||||
<nav
|
||||
className="flex-grow flex-shrink"
|
||||
aria-label={t('project_categories_tags')}
|
||||
>
|
||||
<SidebarFilters />
|
||||
{showAddAffiliationWidget && <hr />}
|
||||
<AddAffiliation />
|
||||
</div>
|
||||
<NewProjectButton
|
||||
id="new-project-button-sidebar"
|
||||
className={scrolledDown ? 'show-shadow' : undefined}
|
||||
/>
|
||||
<div
|
||||
className="project-list-sidebar-scroll"
|
||||
ref={containerRef}
|
||||
data-testid="project-list-sidebar-scroll"
|
||||
>
|
||||
<SidebarFilters />
|
||||
{showAddAffiliationWidget && <hr />}
|
||||
<AddAffiliation />
|
||||
</div>
|
||||
</nav>
|
||||
<div
|
||||
className={classnames(
|
||||
'ds-nav-sidebar-lower',
|
||||
@@ -67,7 +72,10 @@ function SidebarDsNav() {
|
||||
<div className="project-list-sidebar-survey-wrapper">
|
||||
<SurveyWidgetDsNav />
|
||||
</div>
|
||||
<div className="d-flex gap-3 mb-2">
|
||||
<nav
|
||||
className="d-flex flex-row gap-3 mb-2"
|
||||
aria-label={t('account_help')}
|
||||
>
|
||||
{helpItem && (
|
||||
<Dropdown
|
||||
className="ds-nav-icon-dropdown"
|
||||
@@ -157,7 +165,7 @@ function SidebarDsNav() {
|
||||
<UserProvider>{contactUsModal}</UserProvider>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</nav>
|
||||
<div className="ds-nav-ds-name" translate="no">
|
||||
<span>Digital Science</span>
|
||||
</div>
|
||||
|
||||
@@ -22,7 +22,7 @@ export function SurveyWidgetDsNav() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="user-notifications">
|
||||
<aside className="user-notifications" aria-label={t('feedback')}>
|
||||
<div className="notification-entry">
|
||||
<div role="alert" className="survey-notification">
|
||||
<div className="notification-body">
|
||||
@@ -48,6 +48,6 @@ export function SurveyWidgetDsNav() {
|
||||
</OLButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
)
|
||||
}
|
||||
|
||||
+4
-2
@@ -44,12 +44,14 @@ function ProjectListTitle({
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
<h1
|
||||
id="main-content"
|
||||
tabIndex={-1}
|
||||
className={classnames('project-list-title', className)}
|
||||
{...extraProps}
|
||||
>
|
||||
{message}
|
||||
</div>
|
||||
</h1>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ function FatFooterBase() {
|
||||
const currentYear = new Date().getFullYear()
|
||||
|
||||
return (
|
||||
<footer className="fat-footer-base">
|
||||
<div className="fat-footer-base">
|
||||
<div className="fat-footer-base-section fat-footer-base-meta">
|
||||
<div className="fat-footer-base-item">
|
||||
<div className="fat-footer-base-copyright" translate="no">
|
||||
@@ -62,7 +62,7 @@ function FatFooterBase() {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -91,11 +91,7 @@ function FatFooter() {
|
||||
|
||||
return (
|
||||
<footer className="fat-footer hidden-print">
|
||||
<div
|
||||
role="navigation"
|
||||
aria-label={t('footer_navigation')}
|
||||
className="fat-footer-container"
|
||||
>
|
||||
<div className="fat-footer-container">
|
||||
<div className={`fat-footer-sections ${hideFatFooter ? 'hidden' : ''}`}>
|
||||
<div className="footer-section" id="footer-brand">
|
||||
<a href="/" aria-label={t('overleaf')} className="footer-brand">
|
||||
|
||||
+2
-1
@@ -61,6 +61,7 @@ function DefaultNavbar(
|
||||
'--navbar-brand-image-redesign-url': `url("${overleafBlackLogo}")`,
|
||||
} as CSSPropertiesWithVariables
|
||||
}
|
||||
aria-label={t('primary')}
|
||||
>
|
||||
<Container className="navbar-container" fluid>
|
||||
<div className="navbar-header">
|
||||
@@ -92,7 +93,7 @@ function DefaultNavbar(
|
||||
<Navbar.Toggle
|
||||
aria-controls="navbar-main-collapse"
|
||||
aria-expanded="false"
|
||||
aria-label={t('main_navigation')}
|
||||
aria-label={t('primary')}
|
||||
>
|
||||
{showCloseIcon && expanded ? (
|
||||
<X />
|
||||
|
||||
Reference in New Issue
Block a user