From 03c5ba6791dcf7e097f14246af61d107cdadaeff Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Fri, 14 Jan 2022 16:28:14 +0100 Subject: chore: improve load more button accessibility On click, the focus should be moved to the last post in the list instead of keeping it on load more button. It helps to keep a consistent navigation for keyboard users for example. --- src/components/PostsList/PostsList.module.scss | 5 ++- src/components/PostsList/PostsList.tsx | 52 ++++++++++++++++++-------- src/pages/blog/index.tsx | 14 ++++++- src/pages/recherche/index.tsx | 15 ++++++-- 4 files changed, 65 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/components/PostsList/PostsList.module.scss b/src/components/PostsList/PostsList.module.scss index c0f8062..6c3f93e 100644 --- a/src/components/PostsList/PostsList.module.scss +++ b/src/components/PostsList/PostsList.module.scss @@ -33,9 +33,12 @@ } li.item { - margin: 0 0 var(--spacing-md) 0; border-bottom: fun.convert-px(1) solid var(--color-border-light); + &:not(:last-of-type) { + margin: 0 0 var(--spacing-md) 0; + } + &:first-of-type { margin-top: var(--spacing-sm); diff --git a/src/components/PostsList/PostsList.tsx b/src/components/PostsList/PostsList.tsx index f401d83..df9dfe4 100644 --- a/src/components/PostsList/PostsList.tsx +++ b/src/components/PostsList/PostsList.tsx @@ -2,22 +2,31 @@ import { t } from '@lingui/macro'; import { PostsList as PostsListData } from '@ts/types/blog'; import styles from './PostsList.module.scss'; import PostPreview from '@components/PostPreview/PostPreview'; -import { Fragment } from 'react'; +import { ForwardedRef, forwardRef, Fragment } from 'react'; import { sortPostsByYear } from '@utils/helpers/sort'; -const PostsList = ({ - data, - showYears, -}: { - data: PostsListData[]; - showYears: boolean; -}) => { +const PostsList = ( + { + data, + showYears, + }: { + data: PostsListData[]; + showYears: boolean; + }, + ref: ForwardedRef +) => { const titleLevel = showYears ? 3 : 2; const getPostsListByYear = () => { const posts = sortPostsByYear(data); const years = Object.keys(posts).reverse(); + const getLastPostId = () => { + const oldestYear = Object.keys(posts)[0]; + const lastPost = posts[oldestYear][posts[oldestYear].length - 1]; + return lastPost.id; + }; + return years.map((year) => { return (
@@ -29,10 +38,14 @@ const PostsList = ({ )}
    {posts[year].map((post) => { + const isLastPost = post.id === getLastPostId(); return ( -
  1. - -
  2. + +
  3. + +
  4. + {isLastPost && } +
    ); })}
@@ -43,6 +56,11 @@ const PostsList = ({ const getPostsList = () => { return data.map((page) => { + const getLastPostId = () => { + const lastPost = page.posts[page.posts.length - 1]; + return lastPost.id; + }; + if (page.posts.length === 0) { return

{t`No results found.`}

; } else { @@ -50,10 +68,14 @@ const PostsList = ({
    {page.posts.map((post) => { + const isLastPost = post.id === getLastPostId(); return ( -
  1. - -
  2. + +
  3. + +
  4. + {isLastPost && } +
    ); })}
@@ -66,4 +88,4 @@ const PostsList = ({ return
{showYears ? getPostsListByYear() : getPostsList()}
; }; -export default PostsList; +export default forwardRef(PostsList); diff --git a/src/pages/blog/index.tsx b/src/pages/blog/index.tsx index faadd6f..e0d35cd 100644 --- a/src/pages/blog/index.tsx +++ b/src/pages/blog/index.tsx @@ -15,8 +15,11 @@ import PostHeader from '@components/PostHeader/PostHeader'; import { ThematicsList, TopicsList } from '@components/Widget'; import Sidebar from '@components/Sidebar/Sidebar'; import styles from '@styles/pages/Page.module.scss'; +import { useRef } from 'react'; const Blog: NextPageWithLayout = ({ fallback }) => { + const lastPostRef = useRef(null); + const getKey = (pageIndex: number, previousData: PostsListData) => { if (previousData && !previousData.posts) return null; @@ -44,6 +47,13 @@ const Blog: NextPageWithLayout = ({ fallback }) => { const hasNextPage = data && data[data.length - 1].pageInfo.hasNextPage; + const loadMorePosts = () => { + if (lastPostRef.current) { + lastPostRef.current.focus(); + } + setSize(size + 1); + }; + return ( <> @@ -55,11 +65,11 @@ const Blog: NextPageWithLayout = ({ fallback }) => { >
- + {hasNextPage && ( )} diff --git a/src/pages/recherche/index.tsx b/src/pages/recherche/index.tsx index c8a7b9b..57f40e2 100644 --- a/src/pages/recherche/index.tsx +++ b/src/pages/recherche/index.tsx @@ -11,7 +11,7 @@ import { loadTranslation } from '@utils/helpers/i18n'; import { GetStaticProps } from 'next'; import Head from 'next/head'; import { useRouter } from 'next/router'; -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import useSWRInfinite from 'swr/infinite'; import Sidebar from '@components/Sidebar/Sidebar'; import { ThematicsList, TopicsList } from '@components/Widget'; @@ -20,6 +20,7 @@ import styles from '@styles/pages/Page.module.scss'; const Search: NextPageWithLayout = () => { const [query, setQuery] = useState(''); const router = useRouter(); + const lastPostRef = useRef(null); useEffect(() => { if (!router.isReady) return; @@ -69,6 +70,13 @@ const Search: NextPageWithLayout = () => { message: 'Search', }); + const loadMorePosts = () => { + if (lastPostRef.current) { + lastPostRef.current.focus(); + } + setSize(size + 1); + }; + return ( <> @@ -80,11 +88,12 @@ const Search: NextPageWithLayout = () => { >
- + {hasNextPage && ( )}
-- cgit v1.2.3