diff options
| author | Armand Philippot <git@armandphilippot.com> | 2023-11-03 23:03:06 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2023-11-11 18:15:27 +0100 |
| commit | ce4a18899f24ba89b63ef743476ec0dbf1999ecf (patch) | |
| tree | 003a59ee62bc5f1f97110926559d941a978090ac /src/components/organisms/layout | |
| parent | ddd45e29745b73e7fe1684e197dcff598b375644 (diff) | |
refactor(components): rewrite SearchForm component
* remove searchPage prop (the consumer should handle the submit)
* change onSubmit type
* use `useForm` hook to handle the form
Diffstat (limited to 'src/components/organisms/layout')
7 files changed, 87 insertions, 105 deletions
diff --git a/src/components/organisms/layout/no-results.stories.tsx b/src/components/organisms/layout/no-results.stories.tsx index b157572..cfcee83 100644 --- a/src/components/organisms/layout/no-results.stories.tsx +++ b/src/components/organisms/layout/no-results.stories.tsx @@ -1,21 +1,10 @@ -import { ComponentMeta, ComponentStory } from '@storybook/react'; +import type { ComponentMeta, ComponentStory } from '@storybook/react'; import { NoResults as NoResultsComponent } from './no-results'; export default { title: 'Organisms/Layout', component: NoResultsComponent, - argTypes: { - searchPage: { - control: { - type: 'text', - }, - description: 'The search results page.', - type: { - name: 'string', - required: true, - }, - }, - }, + argTypes: {}, } as ComponentMeta<typeof NoResultsComponent>; const Template: ComponentStory<typeof NoResultsComponent> = (args) => ( @@ -23,6 +12,4 @@ const Template: ComponentStory<typeof NoResultsComponent> = (args) => ( ); export const NoResults = Template.bind({}); -NoResults.args = { - searchPage: '#', -}; +NoResults.args = {}; diff --git a/src/components/organisms/layout/no-results.test.tsx b/src/components/organisms/layout/no-results.test.tsx index 85f60cf..fdd86f7 100644 --- a/src/components/organisms/layout/no-results.test.tsx +++ b/src/components/organisms/layout/no-results.test.tsx @@ -1,15 +1,12 @@ import { describe, expect, it } from '@jest/globals'; -import { render, screen } from '../../../../tests/utils'; +import { render, screen as rtlScreen } from '../../../../tests/utils'; import { NoResults } from './no-results'; describe('NoResults', () => { - it('renders a no results text', () => { - render(<NoResults searchPage="#" />); - expect(screen.getByText(/No results/i)).toBeInTheDocument(); - }); + it('renders a text with a form', () => { + render(<NoResults />); - it('renders a search form', () => { - render(<NoResults searchPage="#" />); - expect(screen.getByRole('searchbox')).toBeInTheDocument(); + expect(rtlScreen.getByText(/No results/i)).toBeInTheDocument(); + expect(rtlScreen.getByRole('searchbox')).toBeInTheDocument(); }); }); diff --git a/src/components/organisms/layout/no-results.tsx b/src/components/organisms/layout/no-results.tsx index b2acf12..f760616 100644 --- a/src/components/organisms/layout/no-results.tsx +++ b/src/components/organisms/layout/no-results.tsx @@ -1,16 +1,37 @@ -import { FC } from 'react'; +import { useRouter } from 'next/router'; +import { type FC, useCallback } from 'react'; import { useIntl } from 'react-intl'; -import { SearchForm, type SearchFormProps } from '../forms'; - -export type NoResultsProps = Pick<SearchFormProps, 'searchPage'>; +import { ROUTES } from '../../../utils/constants'; +import { SearchForm, type SearchFormSubmit } from '../forms'; /** * NoResults component * * Renders a no results text with a search form. */ -export const NoResults: FC<NoResultsProps> = ({ searchPage }) => { +export const NoResults: FC = () => { const intl = useIntl(); + const router = useRouter(); + const searchSubmitHandler: SearchFormSubmit = useCallback( + ({ query }) => { + if (!query) + return { + messages: { + error: intl.formatMessage({ + defaultMessage: 'Query must be longer than one character.', + description: 'NoResults: invalid query message', + id: 'VkfO7t', + }), + }, + validator: (value) => value.query.length > 1, + }; + + router.push({ pathname: ROUTES.SEARCH, query: { s: query } }); + + return undefined; + }, + [intl, router] + ); return ( <> @@ -28,7 +49,7 @@ export const NoResults: FC<NoResultsProps> = ({ searchPage }) => { id: 'DVBwfu', })} </p> - <SearchForm isLabelHidden searchPage={searchPage} /> + <SearchForm isLabelHidden onSubmit={searchSubmitHandler} /> </> ); }; diff --git a/src/components/organisms/layout/posts-list.fixture.ts b/src/components/organisms/layout/posts-list.fixture.ts index 6109411..dfb0d97 100644 --- a/src/components/organisms/layout/posts-list.fixture.ts +++ b/src/components/organisms/layout/posts-list.fixture.ts @@ -59,5 +59,3 @@ export const posts: Post[] = [ url: '#', }, ]; - -export const searchPage = '#'; diff --git a/src/components/organisms/layout/posts-list.stories.tsx b/src/components/organisms/layout/posts-list.stories.tsx index d56c7e6..b5af1d3 100644 --- a/src/components/organisms/layout/posts-list.stories.tsx +++ b/src/components/organisms/layout/posts-list.stories.tsx @@ -1,6 +1,6 @@ -import { ComponentMeta, ComponentStory } from '@storybook/react'; +import type { ComponentMeta, ComponentStory } from '@storybook/react'; import { PostsList } from './posts-list'; -import { posts, searchPage } from './posts-list.fixture'; +import { posts } from './posts-list.fixture'; /** * PostsList - Storybook Meta @@ -161,7 +161,6 @@ const Template: ComponentStory<typeof PostsList> = (args) => ( export const Default = Template.bind({}); Default.args = { posts, - searchPage, total: posts.length, }; @@ -172,7 +171,6 @@ export const ByYears = Template.bind({}); ByYears.args = { posts, byYear: true, - searchPage, total: posts.length, }; ByYears.decorators = [ @@ -189,6 +187,5 @@ ByYears.decorators = [ export const NoResults = Template.bind({}); NoResults.args = { posts: [], - searchPage, total: posts.length, }; diff --git a/src/components/organisms/layout/posts-list.test.tsx b/src/components/organisms/layout/posts-list.test.tsx index d5273fc..fabf31f 100644 --- a/src/components/organisms/layout/posts-list.test.tsx +++ b/src/components/organisms/layout/posts-list.test.tsx @@ -1,47 +1,31 @@ import { describe, expect, it } from '@jest/globals'; -import { render, screen } from '../../../../tests/utils'; +import { render, screen as rtlScreen } from '../../../../tests/utils'; import { PostsList } from './posts-list'; -import { posts, searchPage } from './posts-list.fixture'; +import { posts } from './posts-list.fixture'; describe('PostsList', () => { it('renders the correct number of posts', () => { - render( - <PostsList posts={posts} total={posts.length} searchPage={searchPage} /> - ); - expect(screen.getAllByRole('article')).toHaveLength(posts.length); + render(<PostsList posts={posts} total={posts.length} />); + expect(rtlScreen.getAllByRole('article')).toHaveLength(posts.length); }); it('renders the number of loaded posts', () => { - render( - <PostsList posts={posts} total={posts.length} searchPage={searchPage} /> - ); + render(<PostsList posts={posts} total={posts.length} />); const info = `${posts.length} loaded articles out of a total of ${posts.length}`; - expect(screen.getByText(info)).toBeInTheDocument(); + expect(rtlScreen.getByText(info)).toBeInTheDocument(); }); it('renders a load more button', () => { render( - <PostsList - posts={posts} - total={posts.length} - showLoadMoreBtn={true} - searchPage={searchPage} - /> + <PostsList posts={posts} total={posts.length} showLoadMoreBtn={true} /> ); expect( - screen.getByRole('button', { name: /Load more/i }) + rtlScreen.getByRole('button', { name: /Load more/i }) ).toBeInTheDocument(); }); it('renders a search form if no results', () => { - render( - <PostsList - posts={[]} - total={0} - showLoadMoreBtn={true} - searchPage={searchPage} - /> - ); - expect(screen.getByRole('searchbox')).toBeInTheDocument(); + render(<PostsList posts={[]} total={0} showLoadMoreBtn={true} />); + expect(rtlScreen.getByRole('searchbox')).toBeInTheDocument(); }); }); diff --git a/src/components/organisms/layout/posts-list.tsx b/src/components/organisms/layout/posts-list.tsx index 30beb50..36d3c87 100644 --- a/src/components/organisms/layout/posts-list.tsx +++ b/src/components/organisms/layout/posts-list.tsx @@ -17,7 +17,7 @@ import { type RenderPaginationItemAriaLabel, type RenderPaginationLink, } from '../nav'; -import { NoResults, type NoResultsProps } from './no-results'; +import { NoResults } from './no-results'; import styles from './posts-list.module.scss'; import { Summary, type SummaryProps } from './summary'; @@ -30,45 +30,44 @@ export type Post = Omit<SummaryProps, 'titleLevel'> & { export type YearCollection = Record<string, Post[]>; -export type PostsListProps = Pick<PaginationProps, 'siblings'> & - Pick<NoResultsProps, 'searchPage'> & { - /** - * The pagination base url. - */ - baseUrl?: string; - /** - * True to display the posts by year. Default: false. - */ - byYear?: boolean; - /** - * Determine if the data is loading. - */ - isLoading?: boolean; - /** - * Load more button handler. - */ - loadMore?: () => void; - /** - * The current page number. Default: 1. - */ - pageNumber?: number; - /** - * The posts data. - */ - posts: Post[]; - /** - * Determine if the load more button should be visible. - */ - showLoadMoreBtn?: boolean; - /** - * The posts heading level (hn). - */ - titleLevel?: HeadingLevel; - /** - * The total posts number. - */ - total: number; - }; +export type PostsListProps = Pick<PaginationProps, 'siblings'> & { + /** + * The pagination base url. + */ + baseUrl?: string; + /** + * True to display the posts by year. Default: false. + */ + byYear?: boolean; + /** + * Determine if the data is loading. + */ + isLoading?: boolean; + /** + * Load more button handler. + */ + loadMore?: () => void; + /** + * The current page number. Default: 1. + */ + pageNumber?: number; + /** + * The posts data. + */ + posts: Post[]; + /** + * Determine if the load more button should be visible. + */ + showLoadMoreBtn?: boolean; + /** + * The posts heading level (hn). + */ + titleLevel?: HeadingLevel; + /** + * The total posts number. + */ + total: number; +}; /** * Create a collection of posts sorted by year. @@ -101,7 +100,6 @@ export const PostsList: FC<PostsListProps> = ({ loadMore, pageNumber = 1, posts, - searchPage, showLoadMoreBtn = false, siblings, titleLevel, @@ -305,7 +303,7 @@ export const PostsList: FC<PostsListProps> = ({ ); }; - if (posts.length === 0) return <NoResults searchPage={searchPage} />; + if (posts.length === 0) return <NoResults />; return ( <> |
