aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/components/PostsList/PostsList.module.scss5
-rw-r--r--src/components/PostsList/PostsList.tsx52
-rw-r--r--src/pages/blog/index.tsx14
-rw-r--r--src/pages/recherche/index.tsx15
4 files changed, 65 insertions, 21 deletions
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<HTMLSpanElement>
+) => {
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 (
<section key={year} className={styles.section}>
@@ -29,10 +38,14 @@ const PostsList = ({
)}
<ol className={styles.list}>
{posts[year].map((post) => {
+ const isLastPost = post.id === getLastPostId();
return (
- <li key={post.id} className={styles.item}>
- <PostPreview post={post} titleLevel={titleLevel} />
- </li>
+ <Fragment key={post.id}>
+ <li className={styles.item}>
+ <PostPreview post={post} titleLevel={titleLevel} />
+ </li>
+ {isLastPost && <span ref={ref} tabIndex={-1} />}
+ </Fragment>
);
})}
</ol>
@@ -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 <p key="no-result">{t`No results found.`}</p>;
} else {
@@ -50,10 +68,14 @@ const PostsList = ({
<Fragment key={page.pageInfo.endCursor}>
<ol className={styles.list}>
{page.posts.map((post) => {
+ const isLastPost = post.id === getLastPostId();
return (
- <li key={post.id} className={styles.item}>
- <PostPreview post={post} titleLevel={titleLevel} />
- </li>
+ <Fragment key={post.id}>
+ <li key={post.id} className={styles.item}>
+ <PostPreview post={post} titleLevel={titleLevel} />
+ </li>
+ {isLastPost && <span ref={ref} tabIndex={-1} />}
+ </Fragment>
);
})}
</ol>
@@ -66,4 +88,4 @@ const PostsList = ({
return <div>{showYears ? getPostsListByYear() : getPostsList()}</div>;
};
-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<BlogPageProps> = ({ fallback }) => {
+ const lastPostRef = useRef<HTMLSpanElement>(null);
+
const getKey = (pageIndex: number, previousData: PostsListData) => {
if (previousData && !previousData.posts) return null;
@@ -44,6 +47,13 @@ const Blog: NextPageWithLayout<BlogPageProps> = ({ fallback }) => {
const hasNextPage = data && data[data.length - 1].pageInfo.hasNextPage;
+ const loadMorePosts = () => {
+ if (lastPostRef.current) {
+ lastPostRef.current.focus();
+ }
+ setSize(size + 1);
+ };
+
return (
<>
<Head>
@@ -55,11 +65,11 @@ const Blog: NextPageWithLayout<BlogPageProps> = ({ fallback }) => {
>
<PostHeader title={t`Blog`} />
<div className={styles.body}>
- <PostsList data={data} showYears={true} />
+ <PostsList ref={lastPostRef} data={data} showYears={true} />
{hasNextPage && (
<Button
isDisabled={isLoadingMore}
- clickHandler={() => setSize(size + 1)}
+ clickHandler={loadMorePosts}
position="center"
>{t`Load more?`}</Button>
)}
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<HTMLSpanElement>(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 (
<>
<Head>
@@ -80,11 +88,12 @@ const Search: NextPageWithLayout = () => {
>
<PostHeader title={title} />
<div className={styles.body}>
- <PostsList data={data} showYears={false} />
+ <PostsList ref={lastPostRef} data={data} showYears={false} />
{hasNextPage && (
<Button
isDisabled={isLoadingMore}
- clickHandler={() => setSize(size + 1)}
+ clickHandler={loadMorePosts}
+ position="center"
>{t`Load more?`}</Button>
)}
</div>