diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-05-15 19:08:58 +0200 | 
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2022-05-15 19:08:58 +0200 | 
| commit | 056ed0d5f050158cebad689099214b164539899a (patch) | |
| tree | 8e28a82386a785568a7a655bf4d1213096b82589 /src/components | |
| parent | c95cce04393080a52a54191cff7be8fec68af4b0 (diff) | |
chore: improve accessibility
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/atoms/layout/sidebar.stories.tsx | 13 | ||||
| -rw-r--r-- | src/components/atoms/layout/sidebar.tsx | 8 | ||||
| -rw-r--r-- | src/components/atoms/links/link.module.scss | 23 | ||||
| -rw-r--r-- | src/components/molecules/layout/meta.tsx | 26 | ||||
| -rw-r--r-- | src/components/organisms/layout/footer.tsx | 15 | ||||
| -rw-r--r-- | src/components/organisms/layout/summary.module.scss | 5 | ||||
| -rw-r--r-- | src/components/organisms/layout/summary.tsx | 3 | ||||
| -rw-r--r-- | src/components/templates/page/page-layout.tsx | 18 | 
8 files changed, 99 insertions, 12 deletions
| diff --git a/src/components/atoms/layout/sidebar.stories.tsx b/src/components/atoms/layout/sidebar.stories.tsx index 337d0c9..175af94 100644 --- a/src/components/atoms/layout/sidebar.stories.tsx +++ b/src/components/atoms/layout/sidebar.stories.tsx @@ -9,6 +9,19 @@ export default {    title: 'Atoms/Layout',    component: SidebarComponent,    argTypes: { +    'aria-label': { +      control: { +        type: 'text', +      }, +      description: 'An accessible name for the sidebar.', +      table: { +        category: 'Accessibility', +      }, +      type: { +        name: 'string', +        required: false, +      }, +    },      children: {        control: {          type: 'text', diff --git a/src/components/atoms/layout/sidebar.tsx b/src/components/atoms/layout/sidebar.tsx index d13cc0d..d86af37 100644 --- a/src/components/atoms/layout/sidebar.tsx +++ b/src/components/atoms/layout/sidebar.tsx @@ -3,6 +3,10 @@ import styles from './sidebar.module.scss';  export type SidebarProps = {    /** +   * An accessible name for the sidebar. +   */ +  'aria-label'?: string; +  /**     * The sidebar body.     */    children: ReactNode; @@ -17,9 +21,9 @@ export type SidebarProps = {   *   * Render an aside element.   */ -const Sidebar: FC<SidebarProps> = ({ children, className = '' }) => { +const Sidebar: FC<SidebarProps> = ({ children, className = '', ...props }) => {    return ( -    <aside className={`${styles.wrapper} ${className}`}> +    <aside className={`${styles.wrapper} ${className}`} {...props}>        <div className={styles.body}>{children}</div>      </aside>    ); diff --git a/src/components/atoms/links/link.module.scss b/src/components/atoms/links/link.module.scss index 1b89727..5c97bd2 100644 --- a/src/components/atoms/links/link.module.scss +++ b/src/components/atoms/links/link.module.scss @@ -2,6 +2,29 @@  @use "@styles/abstracts/variables" as var;  .link { +  background: linear-gradient(to top, var(--color-primary) 50%, transparent 50%) +    0 0 / 100% 201% no-repeat; +  color: var(--color-primary); +  text-decoration-thickness: 0.15em; +  text-underline-offset: 20%; +  transition: all 0.3s linear 0s, text-decoration 0.18s ease-in-out 0s; + +  &:hover { +    color: var(--color-primary-light); +    text-decoration-thickness: 0.25em; +  } + +  &:focus { +    background-position: 0 100%; +    color: var(--color-fg-inverted); +  } + +  &:active { +    background-position: 0 0; +    color: var(--color-primary-dark); +    text-decoration-thickness: 18%; +  } +    &[hreflang] {      &::after {        display: inline-block; diff --git a/src/components/molecules/layout/meta.tsx b/src/components/molecules/layout/meta.tsx index 1d5e04b..1f6219a 100644 --- a/src/components/molecules/layout/meta.tsx +++ b/src/components/molecules/layout/meta.tsx @@ -14,6 +14,10 @@ export type CustomMeta = {  export type MetaComments = {    /** +   * A page title. +   */ +  about: string; +  /**     * The comments count.     */    count: number; @@ -269,19 +273,29 @@ const Meta: FC<MetaProps> = ({     * @param comments - The comments object.     * @returns {string | JSX.Element} - The comments count.     */ -  const getCommentsCount = (comments: MetaComments) => { -    const { count, target } = comments; +  const getCommentsCount = (comments: MetaComments): string | JSX.Element => { +    const { about, count, target } = comments;      const commentsCount = intl.formatMessage(        {          defaultMessage: -          '{commentsCount, plural, =0 {No comments} one {# comment} other {# comments}}', -        id: 'adTrj7', +          '{commentsCount, plural, =0 {No comments} one {# comment} other {# comments}}<a11y> about {title}</a11y>', +        id: '02rgLO',          description: 'Meta: comments count',        }, -      { commentsCount: count } +      { +        a11y: (chunks: ReactNode) => ( +          <span className="screen-reader-text">{chunks}</span> +        ), +        commentsCount: count, +        title: about, +      }      ); -    return target ? <Link href={target}>{commentsCount}</Link> : commentsCount; +    return target ? ( +      <Link href={target}>{commentsCount as JSX.Element}</Link> +    ) : ( +      (commentsCount as JSX.Element) +    );    };    /** diff --git a/src/components/organisms/layout/footer.tsx b/src/components/organisms/layout/footer.tsx index 15bfa24..1426e96 100644 --- a/src/components/organisms/layout/footer.tsx +++ b/src/components/organisms/layout/footer.tsx @@ -4,6 +4,7 @@ import Copyright, {  import BackToTop from '@components/molecules/buttons/back-to-top';  import Nav, { type NavItem } from '@components/molecules/nav/nav';  import { FC } from 'react'; +import { useIntl } from 'react-intl';  import styles from './footer.module.scss';  export type FooterProps = { @@ -31,6 +32,13 @@ export type FooterProps = {   * Renders a footer with copyright and nav;   */  const Footer: FC<FooterProps> = ({ className, copyright, navItems, topId }) => { +  const intl = useIntl(); +  const ariaLabel = intl.formatMessage({ +    defaultMessage: 'Footer', +    description: 'Footer: an accessible name for footer nav', +    id: 'd4N8nD', +  }); +    return (      <footer className={`${styles.wrapper} ${className}`}>        <Copyright @@ -39,7 +47,12 @@ const Footer: FC<FooterProps> = ({ className, copyright, navItems, topId }) => {          icon={copyright.icon}        />        {navItems && ( -        <Nav kind="footer" items={navItems} className={styles.nav} /> +        <Nav +          aria-label={ariaLabel} +          kind="footer" +          items={navItems} +          className={styles.nav} +        />        )}        <BackToTop target={topId} className={styles['back-to-top']} />      </footer> diff --git a/src/components/organisms/layout/summary.module.scss b/src/components/organisms/layout/summary.module.scss index 9d28bc6..7e86dd2 100644 --- a/src/components/organisms/layout/summary.module.scss +++ b/src/components/organisms/layout/summary.module.scss @@ -80,6 +80,11 @@    }  } +.link { +  display: block; +  width: fit-content; +} +  .title {    margin: 0;    background: none; diff --git a/src/components/organisms/layout/summary.tsx b/src/components/organisms/layout/summary.tsx index 078f9ee..3831c0c 100644 --- a/src/components/organisms/layout/summary.tsx +++ b/src/components/organisms/layout/summary.tsx @@ -116,6 +116,7 @@ const Summary: FC<SummaryProps> = ({          </Link>        )),        comments: { +        about: title,          count: commentsCount || 0,          target: `${url}#comments`,        }, @@ -126,7 +127,7 @@ const Summary: FC<SummaryProps> = ({      <article className={styles.wrapper}>        {cover && <ResponsiveImage className={styles.cover} {...cover} />}        <header className={styles.header}> -        <Link href={url}> +        <Link href={url} className={styles.link}>            <Heading level={titleLevel} className={styles.title}>              {title}            </Heading> diff --git a/src/components/templates/page/page-layout.tsx b/src/components/templates/page/page-layout.tsx index 045b8c1..4e4ff00 100644 --- a/src/components/templates/page/page-layout.tsx +++ b/src/components/templates/page/page-layout.tsx @@ -185,7 +185,14 @@ const PageLayout: FC<PageLayoutProps> = ({          className={styles.header}        />        {withToC && ( -        <Sidebar className={`${styles.sidebar} ${styles['sidebar--first']}`}> +        <Sidebar +          className={`${styles.sidebar} ${styles['sidebar--first']}`} +          aria-label={intl.formatMessage({ +            defaultMessage: 'Table of contents sidebar', +            id: 'Q+1GbT', +            description: 'PageLayout: accessible name for ToC sidebar', +          })} +        >            {isMounted && bodyRef.current && (              <TableOfContents wrapper={bodyRef.current} />            )} @@ -203,7 +210,14 @@ const PageLayout: FC<PageLayoutProps> = ({          </div>        )}        <PageFooter meta={footerMeta} className={styles.footer} /> -      <Sidebar className={`${styles.sidebar} ${styles['sidebar--last']}`}> +      <Sidebar +        className={`${styles.sidebar} ${styles['sidebar--last']}`} +        aria-label={intl.formatMessage({ +          defaultMessage: 'Sidebar', +          id: 'c556Qo', +          description: 'PageLayout: accessible name for the sidebar', +        })} +      >          {widgets}        </Sidebar>        {hasCommentsSection && ( | 
