diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/FooterNav/FooterNav.tsx | 8 | ||||
| -rw-r--r-- | src/components/MainNav/MainNav.tsx | 8 | ||||
| -rw-r--r-- | src/components/PostsList/PostsList.tsx | 6 | ||||
| -rw-r--r-- | src/components/SearchForm/SearchForm.tsx | 6 | ||||
| -rw-r--r-- | src/components/Sidebar/Sidebar.tsx | 10 | ||||
| -rw-r--r-- | src/components/Widgets/ToC/ToC.tsx | 15 | ||||
| m--------- | src/content | 0 | ||||
| -rw-r--r-- | src/i18n/en.json | 56 | ||||
| -rw-r--r-- | src/i18n/fr.json | 56 | ||||
| -rw-r--r-- | src/pages/article/[slug].tsx | 16 | ||||
| -rw-r--r-- | src/pages/cv.tsx | 16 | ||||
| -rw-r--r-- | src/pages/projet/[slug].tsx | 18 | ||||
| -rw-r--r-- | src/pages/sujet/[slug].tsx | 16 | ||||
| -rw-r--r-- | src/pages/thematique/[slug].tsx | 16 |
14 files changed, 230 insertions, 17 deletions
diff --git a/src/components/FooterNav/FooterNav.tsx b/src/components/FooterNav/FooterNav.tsx index 918fed7..f1fd0b7 100644 --- a/src/components/FooterNav/FooterNav.tsx +++ b/src/components/FooterNav/FooterNav.tsx @@ -29,7 +29,13 @@ const FooterNav = () => { return ( <div className={styles.wrapper}> - <nav className={styles.nav}> + <nav + className={styles.nav} + aria-label={intl.formatMessage({ + defaultMessage: 'Footer', + description: 'FooterNav: aria-label', + })} + > <ul className={styles.list}>{navItems}</ul> </nav> </div> diff --git a/src/components/MainNav/MainNav.tsx b/src/components/MainNav/MainNav.tsx index e996e89..c7789ba 100644 --- a/src/components/MainNav/MainNav.tsx +++ b/src/components/MainNav/MainNav.tsx @@ -151,7 +151,13 @@ const MainNav = ({ })} </span> </label> - <nav className={styles.nav}> + <nav + className={styles.nav} + aria-label={intl.formatMessage({ + defaultMessage: 'Primary', + description: 'MainNav: aria-label', + })} + > <ul className={styles.list}>{navItems}</ul> </nav> </div> diff --git a/src/components/PostsList/PostsList.tsx b/src/components/PostsList/PostsList.tsx index 16deee3..b57630e 100644 --- a/src/components/PostsList/PostsList.tsx +++ b/src/components/PostsList/PostsList.tsx @@ -50,7 +50,11 @@ const PostsList = ( <li className={styles.item}> <PostPreview post={post} titleLevel={titleLevel} /> </li> - {isLastPost && <span ref={ref} tabIndex={-1} />} + {isLastPost && ( + <li className={styles.item}> + <span ref={ref} tabIndex={-1} /> + </li> + )} </Fragment> ); })} diff --git a/src/components/SearchForm/SearchForm.tsx b/src/components/SearchForm/SearchForm.tsx index 38ae60d..da6f25c 100644 --- a/src/components/SearchForm/SearchForm.tsx +++ b/src/components/SearchForm/SearchForm.tsx @@ -35,6 +35,12 @@ const SearchForm = ({ isOpened }: { isOpened: boolean }) => { })} </div> <Form submitHandler={launchSearch} modifier="search"> + <label htmlFor="search-query" className="screen-reader-text"> + {intl.formatMessage({ + defaultMessage: 'Keywords:', + description: 'SearchForm: search field label', + })} + </label> <Input ref={inputRef} id="search-query" diff --git a/src/components/Sidebar/Sidebar.tsx b/src/components/Sidebar/Sidebar.tsx index f319f9e..9e2079d 100644 --- a/src/components/Sidebar/Sidebar.tsx +++ b/src/components/Sidebar/Sidebar.tsx @@ -6,10 +6,12 @@ type SidebarPosition = 'left' | 'right'; const Sidebar = ({ children, position, + ariaLabel, title, }: { children: ReactNode; position: SidebarPosition; + ariaLabel?: string; title?: string; }) => { const childrenWithProps = Children.map(children, (child) => { @@ -22,9 +24,13 @@ const Sidebar = ({ const positionClass = `wrapper--${position}`; return ( - <aside className={`${styles.wrapper} ${styles[positionClass]}`}> + <aside + className={`${styles.wrapper} ${styles[positionClass]}`} + aria-label={ariaLabel} + aria-labelledby={title ? `${position}-sidebar-title` : undefined} + > <div className={styles.body}> - {title && <h2>{title}</h2>} + {title && <h2 id={`${position}-sidebar-title`}>{title}</h2>} {childrenWithProps} </div> </aside> diff --git a/src/components/Widgets/ToC/ToC.tsx b/src/components/Widgets/ToC/ToC.tsx index 8a2d493..f3f783c 100644 --- a/src/components/Widgets/ToC/ToC.tsx +++ b/src/components/Widgets/ToC/ToC.tsx @@ -1,7 +1,7 @@ import { ExpandableWidget, OrderedList } from '@components/WidgetParts'; import { Heading } from '@ts/types/app'; import useHeadingsTree from '@utils/hooks/useHeadingsTree'; -import { useIntl } from 'react-intl'; +import { FormattedMessage, useIntl } from 'react-intl'; const ToC = () => { const intl = useIntl(); @@ -15,7 +15,18 @@ const ToC = () => { return headings.map((heading) => { return ( <li key={heading.id}> - <a href={`#${heading.id}`}>{heading.title}</a> + <a href={`#${heading.id}`}> + <FormattedMessage + defaultMessage="<a11y>Jump to </a11y>{title}" + description="ToC: link" + values={{ + title: heading.title, + a11y: (chunks: string) => ( + <span className="screen-reader-text">{chunks}</span> + ), + }} + /> + </a> {heading.children.length > 0 && ( <OrderedList items={getItems(heading.children)} /> )} diff --git a/src/content b/src/content -Subproject 94917e7d3d431dadf3d3920bf5aa31fd5dcdddf +Subproject 4ef65066368e293376a9b39476010a843e8e38e diff --git a/src/i18n/en.json b/src/i18n/en.json index 015e87c..4f01ec1 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -67,6 +67,10 @@ "defaultMessage": "Legal notice - {websiteName}", "description": "LegalNoticePage: SEO - Page title" }, + "6dXfvr": { + "defaultMessage": "Table of Contents", + "description": "ProjectPage: ToC sidebar aria-label" + }, "6ibqFS": { "defaultMessage": "Name", "description": "ContactForm: name field label" @@ -83,6 +87,10 @@ "defaultMessage": "Please fill the form to contact me.", "description": "ContactPage: page introduction" }, + "9nhYRA": { + "defaultMessage": "Table of Contents", + "description": "ArticlePage: ToC sidebar aria-label" + }, "A4LTGq": { "defaultMessage": "Discover search results for {query}", "description": "SearchPage: meta description with query" @@ -155,6 +163,18 @@ "defaultMessage": "Reading time:", "description": "Article meta" }, + "GgIWnN": { + "defaultMessage": "<a11y>Jump to </a11y>{title}", + "description": "ToC: link" + }, + "H7C5Bk": { + "defaultMessage": "Primary", + "description": "MainNav: aria-label" + }, + "HTdaZj": { + "defaultMessage": "Footer", + "description": "FooterNav: aria-label" + }, "HriY57": { "defaultMessage": "Thematics", "description": "BlogPage: thematics list widget title" @@ -175,6 +195,10 @@ "defaultMessage": "Comment", "description": "CommentForm: Comment field label" }, + "JeYOeA": { + "defaultMessage": "Sidebar", + "description": "ArticlePage: right sidebar aria-label" + }, "KERk7L": { "defaultMessage": "Filter by:", "description": "BlogPage: sidebar title" @@ -255,6 +279,10 @@ "defaultMessage": "Failed to load.", "description": "ThematicsList: failed to load text" }, + "QHOm5t": { + "defaultMessage": "Sidebar", + "description": "CVPage: right sidebar aria-label" + }, "Qh2CwH": { "defaultMessage": "Find me elsewhere", "description": "ContactPage: social media widget title" @@ -351,6 +379,14 @@ "defaultMessage": "Read more articles about:", "description": "PostFooter: read more posts about given subjects" }, + "YvMPuD": { + "defaultMessage": "Keywords:", + "description": "SearchForm: search field label" + }, + "YwvYfw": { + "defaultMessage": "Table of Contents", + "description": "ThematicPage: ToC sidebar aria-label" + }, "Z1eSIz": { "defaultMessage": "Open {type}", "description": "ButtonToolbar: Open button" @@ -435,6 +471,10 @@ "defaultMessage": "{count, plural, =0 {Technologies:} one {Technology:} other {Technologies:}}", "description": "ProjectSummary: technologies list label" }, + "eu3beS": { + "defaultMessage": "Sidebar", + "description": "TopicPage: right sidebar aria-label" + }, "fGnfqp": { "defaultMessage": "Published on:", "description": "PostMeta: publication date label" @@ -443,10 +483,18 @@ "defaultMessage": "Failed to load.", "description": "SearchPage: failed to load text" }, + "g4DckL": { + "defaultMessage": "Table of Contents", + "description": "CVPage: ToC sidebar aria-label" + }, "gQKeF+": { "defaultMessage": "Thanks. Your message was successfully sent. I will answer it as soon as possible.", "description": "ContactForm: success message" }, + "hHrNd0": { + "defaultMessage": "Sidebar", + "description": "ProjectPage: right sidebar aria-label" + }, "hKagVG": { "defaultMessage": "License:", "description": "ProjectSummary: license label" @@ -491,6 +539,10 @@ "defaultMessage": "Email", "description": "Sharing: Email" }, + "lsDB5G": { + "defaultMessage": "Table of Contents", + "description": "TopicPage: ToC sidebar aria-label" + }, "mC21ht": { "defaultMessage": "Number of articles loaded out of the total available.", "description": "PaginationCursor: loaded articles count aria-label" @@ -555,6 +607,10 @@ "defaultMessage": "Published on:", "description": "Comment: publication date label" }, + "syLgY9": { + "defaultMessage": "Sidebar", + "description": "ThematicPage: right sidebar aria-label" + }, "tMuNTy": { "defaultMessage": "{websiteName} is a front-end developer located in France. He codes and he writes mostly about web development and open-source.", "description": "HomePage: SEO - Meta description" diff --git a/src/i18n/fr.json b/src/i18n/fr.json index b20a241..812475b 100644 --- a/src/i18n/fr.json +++ b/src/i18n/fr.json @@ -67,6 +67,10 @@ "defaultMessage": "Mentions légales - {websiteName}", "description": "LegalNoticePage: SEO - Page title" }, + "6dXfvr": { + "defaultMessage": "Table des matières", + "description": "ProjectPage: ToC sidebar aria-label" + }, "6ibqFS": { "defaultMessage": "Nom", "description": "ContactForm: name field label" @@ -83,6 +87,10 @@ "defaultMessage": "Veuillez remplir le formulaire pour me contacter.", "description": "ContactPage: page introduction" }, + "9nhYRA": { + "defaultMessage": "Table des matières", + "description": "ArticlePage: ToC sidebar aria-label" + }, "A4LTGq": { "defaultMessage": "Découvrez les résultats de recherche pour {query}", "description": "SearchPage: meta description with query" @@ -155,6 +163,18 @@ "defaultMessage": "Temps de lecture :", "description": "Article meta" }, + "GgIWnN": { + "defaultMessage": "<a11y>Atteindre </a11y>{title}", + "description": "ToC: link" + }, + "H7C5Bk": { + "defaultMessage": "Principal", + "description": "MainNav: aria-label" + }, + "HTdaZj": { + "defaultMessage": "Pied de page", + "description": "FooterNav: aria-label" + }, "HriY57": { "defaultMessage": "Thématiques", "description": "BlogPage: thematics list widget title" @@ -175,6 +195,10 @@ "defaultMessage": "Commentaire", "description": "CommentForm: Comment field label" }, + "JeYOeA": { + "defaultMessage": "Barre latérale", + "description": "ArticlePage: right sidebar aria-label" + }, "KERk7L": { "defaultMessage": "Filtrer par :", "description": "BlogPage: sidebar title" @@ -255,6 +279,10 @@ "defaultMessage": "Échec du chargement.", "description": "ThematicsList: failed to load text" }, + "QHOm5t": { + "defaultMessage": "Barre latérale", + "description": "CVPage: right sidebar aria-label" + }, "Qh2CwH": { "defaultMessage": "Retrouvez-moi ailleurs", "description": "ContactPage: social media widget title" @@ -351,6 +379,14 @@ "defaultMessage": "Lire plus d'articles à propos de :", "description": "PostFooter: read more posts about given subjects" }, + "YvMPuD": { + "defaultMessage": "Mots-clés :", + "description": "SearchForm: search field label" + }, + "YwvYfw": { + "defaultMessage": "Table des matières", + "description": "ThematicPage: ToC sidebar aria-label" + }, "Z1eSIz": { "defaultMessage": "Ouvrez {type}", "description": "ButtonToolbar: Open button" @@ -435,6 +471,10 @@ "defaultMessage": "{count, plural, =0 {Technologies :} one {Technologie :} other {Technologies :}}", "description": "ProjectSummary: technologies list label" }, + "eu3beS": { + "defaultMessage": "Barre latérale", + "description": "TopicPage: right sidebar aria-label" + }, "fGnfqp": { "defaultMessage": "Publié le :", "description": "PostMeta: publication date label" @@ -443,10 +483,18 @@ "defaultMessage": "Échec du chargement.", "description": "SearchPage: failed to load text" }, + "g4DckL": { + "defaultMessage": "Table des matières", + "description": "CVPage: ToC sidebar aria-label" + }, "gQKeF+": { "defaultMessage": "Merci. Votre message a bien été envoyé. J'y répondrai dès que possible.", "description": "ContactForm: success message" }, + "hHrNd0": { + "defaultMessage": "Barre latérale", + "description": "ProjectPage: right sidebar aria-label" + }, "hKagVG": { "defaultMessage": "Licence :", "description": "ProjectSummary: license label" @@ -491,6 +539,10 @@ "defaultMessage": "Email", "description": "Sharing: Email" }, + "lsDB5G": { + "defaultMessage": "Table des matières", + "description": "TopicPage: ToC sidebar aria-label" + }, "mC21ht": { "defaultMessage": "Nombre d'articles chargés sur le total disponible.", "description": "PaginationCursor: loaded articles count aria-label" @@ -555,6 +607,10 @@ "defaultMessage": "Publié le :", "description": "Comment: publication date label" }, + "syLgY9": { + "defaultMessage": "Barre latérale", + "description": "ThematicPage: right sidebar aria-label" + }, "tMuNTy": { "defaultMessage": "{websiteName} est intégrateur web / développeur front-end en France. Il code et il écrit essentiellement à propos de développement web et du libre.", "description": "HomePage: SEO - Meta description" diff --git a/src/pages/article/[slug].tsx b/src/pages/article/[slug].tsx index faf2271..689f123 100644 --- a/src/pages/article/[slug].tsx +++ b/src/pages/article/[slug].tsx @@ -175,7 +175,13 @@ const SingleArticle: NextPageWithLayout<ArticleProps> = ({ post }) => { data-prismjs-color-scheme-light={lightTheme} > <PostHeader intro={intro} meta={meta} title={title} /> - <Sidebar position="left"> + <Sidebar + position="left" + ariaLabel={intl.formatMessage({ + defaultMessage: 'Table of Contents', + description: 'ArticlePage: ToC sidebar aria-label', + })} + > <ToC /> </Sidebar> <div @@ -183,7 +189,13 @@ const SingleArticle: NextPageWithLayout<ArticleProps> = ({ post }) => { dangerouslySetInnerHTML={{ __html: content }} ></div> <PostFooter topics={topics} /> - <Sidebar position="right"> + <Sidebar + position="right" + ariaLabel={intl.formatMessage({ + defaultMessage: 'Sidebar', + description: 'ArticlePage: right sidebar aria-label', + })} + > <Sharing title={title} excerpt={intro} /> </Sidebar> <section id="comments" className={styles.comments}> diff --git a/src/pages/cv.tsx b/src/pages/cv.tsx index 311d0ce..e77c586 100644 --- a/src/pages/cv.tsx +++ b/src/pages/cv.tsx @@ -110,13 +110,25 @@ const CV: NextPageWithLayout = () => { className={`${styles.article} ${styles['article--no-comments']}`} > <PostHeader intro={intro} meta={pageMeta} title={meta.title} /> - <Sidebar position="left"> + <Sidebar + position="left" + ariaLabel={intl.formatMessage({ + defaultMessage: 'Table of Contents', + description: 'CVPage: ToC sidebar aria-label', + })} + > <ToC /> </Sidebar> <div className={styles.body}> <CVContent /> </div> - <Sidebar position="right"> + <Sidebar + position="right" + ariaLabel={intl.formatMessage({ + defaultMessage: 'Sidebar', + description: 'CVPage: right sidebar aria-label', + })} + > <CVPreview title={intl.formatMessage({ defaultMessage: 'Others formats', diff --git a/src/pages/projet/[slug].tsx b/src/pages/projet/[slug].tsx index f96da0e..f72063a 100644 --- a/src/pages/projet/[slug].tsx +++ b/src/pages/projet/[slug].tsx @@ -22,6 +22,7 @@ import Head from 'next/head'; import { useRouter } from 'next/router'; import { ParsedUrlQuery } from 'querystring'; import { ComponentType } from 'react'; +import { useIntl } from 'react-intl'; import { Article, Graph, WebPage } from 'schema-dts'; const Project: NextPageWithLayout<ProjectProps> = ({ @@ -29,6 +30,7 @@ const Project: NextPageWithLayout<ProjectProps> = ({ }: { project: ProjectData; }) => { + const intl = useIntl(); const router = useRouter(); const projectUrl = `${settings.url}${router.asPath}`; const { id, intro, meta, title, seo } = project; @@ -107,14 +109,26 @@ const Project: NextPageWithLayout<ProjectProps> = ({ className={`${styles.article} ${styles['article--no-comments']}`} > <PostHeader title={title} intro={intro} meta={{ dates }} /> - <Sidebar position="left"> + <Sidebar + position="left" + ariaLabel={intl.formatMessage({ + defaultMessage: 'Table of Contents', + description: 'ProjectPage: ToC sidebar aria-label', + })} + > <ToC /> </Sidebar> <div className={styles.body}> <ProjectSummary id={id} title={title} meta={meta} /> <ProjectContent components={components} /> </div> - <Sidebar position="right"> + <Sidebar + position="right" + ariaLabel={intl.formatMessage({ + defaultMessage: 'Sidebar', + description: 'ProjectPage: right sidebar aria-label', + })} + > <Sharing title={title} excerpt={intro} /> </Sidebar> </article> diff --git a/src/pages/sujet/[slug].tsx b/src/pages/sujet/[slug].tsx index ca7d7cd..910c02c 100644 --- a/src/pages/sujet/[slug].tsx +++ b/src/pages/sujet/[slug].tsx @@ -126,7 +126,13 @@ const Topic: NextPageWithLayout<TopicProps> = ({ topic }) => { meta={meta} title={topic.title} /> - <Sidebar position="left"> + <Sidebar + position="left" + ariaLabel={intl.formatMessage({ + defaultMessage: 'Table of Contents', + description: 'TopicPage: ToC sidebar aria-label', + })} + > <ToC /> </Sidebar> <div className={styles.body}> @@ -146,7 +152,13 @@ const Topic: NextPageWithLayout<TopicProps> = ({ topic }) => { </section> )} </div> - <Sidebar position="right"> + <Sidebar + position="right" + ariaLabel={intl.formatMessage({ + defaultMessage: 'Sidebar', + description: 'TopicPage: right sidebar aria-label', + })} + > <RelatedThematics thematics={relatedThematics.current} /> <TopicsList title={intl.formatMessage({ diff --git a/src/pages/thematique/[slug].tsx b/src/pages/thematique/[slug].tsx index df7ff1a..166e0bb 100644 --- a/src/pages/thematique/[slug].tsx +++ b/src/pages/thematique/[slug].tsx @@ -116,7 +116,13 @@ const Thematic: NextPageWithLayout<ThematicProps> = ({ thematic }) => { className={`${styles.article} ${styles['article--no-comments']}`} > <PostHeader intro={thematic.intro} meta={meta} title={thematic.title} /> - <Sidebar position="left"> + <Sidebar + position="left" + ariaLabel={intl.formatMessage({ + defaultMessage: 'Table of Contents', + description: 'ThematicPage: ToC sidebar aria-label', + })} + > <ToC /> </Sidebar> <div className={styles.body}> @@ -136,7 +142,13 @@ const Thematic: NextPageWithLayout<ThematicProps> = ({ thematic }) => { </section> )} </div> - <Sidebar position="right"> + <Sidebar + position="right" + ariaLabel={intl.formatMessage({ + defaultMessage: 'Sidebar', + description: 'ThematicPage: right sidebar aria-label', + })} + > <RelatedTopics topics={relatedTopics.current} /> <ThematicsList title={intl.formatMessage({ |
