Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/js/components/ManageMenu/CommunityCloud/CloudSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ const SearchBox = () => {
onChange={event => setQuery(event.target.value)}
placeholder={__('e.g. Remove unused JavaScript…', 'code-snippets')}
/>
{isSearching && <Spinner />}
<span role="status" aria-live="polite">
{isSearching && <>
<Spinner />
<span className="screen-reader-text">{__('Searching…', 'code-snippets')}</span>
</>}
</span>
</div>

<SubmitButton primary disabled={isSearching} text={__('Search Cloud Library', 'code-snippets')} />
Expand Down Expand Up @@ -90,12 +95,12 @@ const SearchResultsTable = () => {
}

const ErrorBanner = () =>
<div className="banner banner-error">
<div className="banner banner-error" role="alert">
<p>{__('An error occurred while fetching search results. Please try again.')}</p>
</div>

const NoSearchResultsBanner = () =>
<div className="banner banner-neutral no-results">
<div className="banner banner-neutral no-results" role="status" aria-live="polite">
<p>{__('No snippets or codevault could be found with that search term. Please try again.', 'code-snippets')}</p>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const CommunityCloud = () => {
key={tab}
href={buildUrl(window.location.href, { type: tab })}
className={classnames('nav-tab', `${tab}-tab`, { 'nav-tab-active': tab === currentTab })}
aria-current={tab === currentTab ? 'page' : undefined}
onClick={event => {
event.preventDefault()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ const CloudSnippetDetails: React.FC<CloudSnippetDetailsProps> = ({ snippet, setI
<Badge name={getSnippetType(snippet)} />
<span className="cloud-snippet-votes">
<span className="dashicons dashicons-thumbs-up" aria-hidden="true"></span>
<span>{snippet.vote_count}</span>
<span>
{snippet.vote_count}
<span className="screen-reader-text">{` ${__('votes', 'code-snippets')}`}</span>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be interpolated with sprintf? 'votes' by itself doesn't really make sense without the number attached. Also, this code as-is will not include a space between the numeral and the text (e.g. it'll appear as 4votes).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, we should not use sprintf() here because the number is visible and the text is not.

image

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rami-elementor my concern is more on the translators side, they don't necessarily have the context for knowing how 'votes' should be translated. If you think it's fine, then I'll bow to your experience with translations/accessibility.

</span>
</span>
{0 < snippet.tags.length
? <span className="cloud-snippet-category">
Expand Down
26 changes: 23 additions & 3 deletions src/js/components/ManageMenu/SnippetsTable/SnippetsListTable.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { __, _x, sprintf } from '@wordpress/i18n'
import { __, _n, _x, sprintf } from '@wordpress/i18n'
import React, { Fragment, useEffect, useMemo, useState } from 'react'
import classnames from 'classnames'
import { createInterpolateElement } from '@wordpress/element'
Expand All @@ -7,7 +7,7 @@ import { useSnippetsList } from '../../../hooks/useSnippetsList'
import { handleUnknownError } from '../../../utils/errors'
import { downloadBulkSnippetExportFile } from '../../../utils/files'
import { REST_BASES } from '../../../utils/restAPI'
import { getSnippetType } from '../../../utils/snippets/snippets'
import { getSnippetDisplayName, getSnippetType } from '../../../utils/snippets/snippets'
import { buildUrl } from '../../../utils/urls'
import { ListTable } from '../../common/ListTable'
import { SubmitButton } from '../../common/SubmitButton'
Expand Down Expand Up @@ -96,6 +96,7 @@ const SnippetStatusCounts = () => {
<a
href={buildUrl(window.location.href, { status: INDEX_STATUS === status ? undefined : status })}
className={currentStatus === status ? 'current' : undefined}
aria-current={currentStatus === status ? 'page' : undefined}
onClick={event => {
event.preventDefault()
setCurrentStatus(status)
Expand All @@ -107,8 +108,8 @@ const SnippetStatusCounts = () => {
sprintf(_x('(%d)', 'table view count', 'code-snippets'), snippetsByStatus.get(status)?.length ?? 0)
}</span>
</a>
{index < visibleStatuses.length - 1 && ' | '}
</li>
{index < visibleStatuses.length - 1 && ' | '}
</Fragment>)}
</ul>
)
Expand Down Expand Up @@ -192,9 +193,14 @@ const FilterByTagControl: React.FC<ExtraTableNavProps> = ({ visibleSnippets }) =

return 0 < tagsList.size
? <div className="alignleft actions">
<label htmlFor="snippets-tag-filter" className="screen-reader-text">
{__('Filter snippets by tag', 'code-snippets')}
</label>
<select
id="snippets-tag-filter"
name="tag"
value={currentTag}
aria-label={__('Filter snippets by tag', 'code-snippets')}
onChange={event => setCurrentTag(event.target.value)}
>
<option value="">{__('Show all tags', 'code-snippets')}</option>
Expand Down Expand Up @@ -311,9 +317,23 @@ export const SnippetsListTable: React.FC = () => {
<SnippetStatusCounts />
<SearchBox />

<p className="screen-reader-text" role="status" aria-live="polite">
{sprintf(
// translators: %d: number of snippets matching current filters.
_n('%d snippet found.', '%d snippets found.', totalItems),
totalItems
)}
</p>

<ListTable
items={snippetsByStatus.get(currentStatus) ?? []}
getKey={snippet => snippet.id}
ariaLabel={__('Snippets list', 'code-snippets')}
getCheckboxAriaLabel={(snippet: Snippet) => sprintf(
// translators: %s: Snippet name.
__('Select %s', 'code-snippets'),
getSnippetDisplayName(snippet)
)}
className={classnames({ 'truncate-row-values': truncateRowValues })}
columns={columns}
actions={actions}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const SnippetTypeTab: React.FC<SnippetTypeTabProps> = ({ type, setIsUpgradeDialo
'nav-tab-active': type === currentType,
'nav-tab-inactive': type && type !== currentType && !isLicensed() && isProType(type)
})}
aria-current={type === currentType ? 'page' : undefined}
onClick={event => {
event.preventDefault()

Expand Down
14 changes: 11 additions & 3 deletions src/js/components/ManageMenu/SnippetsTable/TableColumns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ const RunOnceButton: React.FC<ColumnProps> = ({ snippet }) =>
<a
className="snippet-execution-button"
title={__('Run Once', 'code-snippets')}
aria-label={__('Run Once', 'code-snippets')}
href={buildUrl(window.location.href, { action: 'run-once', snippet: snippet.id })}
>
&nbsp;
<span className="screen-reader-text">{__('Run Once', 'code-snippets')}</span>
<span aria-hidden="true">&nbsp;</span>
</a>

const ActivationSwitch: React.FC<ColumnProps> = ({ snippet }) => {
Expand All @@ -51,7 +51,9 @@ const ActivationSwitch: React.FC<ColumnProps> = ({ snippet }) => {
<input
id={`snippet-${snippet.id}-switch`}
type="checkbox"
role="switch"
checked={snippet.active}
aria-checked={snippet.active}
className="switch"
title={actionText}
onChange={() => {
Expand Down Expand Up @@ -172,7 +174,12 @@ const RowActions: React.FC<ColumnProps> = ({ snippet }) => {
const NameColumn: React.FC<ColumnProps> = ({ snippet }) =>
<>
{snippet.locked && (
<Tooltip inline end icon={<span className="dashicons dashicons-lock" aria-hidden="true"></span>}>
<Tooltip
inline
end
label={__('About snippet lock', 'code-snippets')}
icon={<span className="dashicons dashicons-lock" aria-hidden="true"></span>}
>
{__('This snippet is locked and cannot be modified.', 'code-snippets')}
</Tooltip>)}

Expand Down Expand Up @@ -260,6 +267,7 @@ const PriorityColumn: React.FC<ColumnProps> = ({ snippet }) => {
const baseTableColumns: ListTableColumn<Snippet>[] = [
{
id: 'activate',
title: <span className="screen-reader-text">{__('Activate', 'code-snippets')}</span>,
render: snippet => <ActivateColumn snippet={snippet} />
},
{
Expand Down
Loading