Skip to content

Commit

Permalink
add home page search
Browse files Browse the repository at this point in the history
  • Loading branch information
tpruisimao committed Nov 25, 2021
1 parent b4c9d51 commit adf2351
Show file tree
Hide file tree
Showing 18 changed files with 5,617 additions and 138 deletions.
8 changes: 8 additions & 0 deletions components/ChapterContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { useTheme } from 'next-themes';
import Head from 'next/head';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';

export default function Container(props: any) {
const router = useRouter();
const [mounted, setMounted] = useState(false);
const { resolvedTheme, setTheme } = useTheme();

Expand Down Expand Up @@ -37,6 +39,12 @@ export default function Container(props: any) {
)}
</Head>
<nav className="flex items-center justify-between w-full max-w-4xl p-8 mx-auto my-0 text-gray-900 bg-white sticky-nav md:my-8 dark:bg-black bg-opacity-60 dark:text-gray-100">
<button
onClick={() => router.push('/')}
className="text-4xl w-12 h-12 font-bold"
>
B.
</button>
<button
aria-label="Toggle Dark Mode"
type="button"
Expand Down
76 changes: 76 additions & 0 deletions components/ChapterList/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { ComboboxList, ComboboxOption } from '@reach/combobox';
import styles from './ChapterList.module.css';
import { PropsWithChildren } from 'react';

interface ChapterListProps {
chapterCount?: number;
onSelect: (chapter: number) => void;
isCombobox?: boolean;
}

function ChapterButton({
chapter,
onClick,
isCombobox
}: {
chapter: number;
onClick: (chapter: number) => void;
isCombobox?: boolean;
}) {
if (isCombobox) {
return (
<ComboboxOption
className="flex justify-center items-center text-gray-900 dark:text-gray-100 w-12 h-12 border border-gray-300 dark:border-gray-800 hover:bg-gray dark:hover:bg-gray-800 rounded-xl"
key={chapter.toString()}
value={chapter.toString()}
/>
);
}

return (
<button
tabIndex={0}
type="button"
className="text-gray-900 dark:text-gray-100 w-12 h-12 border border-gray-300 dark:border-gray-800 hover:bg-gray dark:hover:bg-gray-800 rounded-xl"
onClick={() => onClick(chapter)}
>
{chapter}
</button>
);
}

export default function ChapterList({
chapterCount,
onSelect,
isCombobox
}: ChapterListProps) {
const chapters = Array(chapterCount)
.fill(null)
.map((_, i) => i + 1);

if (isCombobox) {
return (
<ComboboxList
className="grid grid grid-cols-7 justify-items-center gap-y-4 grid-flow-row max-h-72 overflow-auto"
aria-labelledby="chapter"
>
{chapters.map((chapter) => (
<ChapterButton
isCombobox
key={chapter}
chapter={chapter}
onClick={onSelect}
/>
))}
</ComboboxList>
);
}

return (
<div className="grid grid grid-cols-6 justify-items-center gap-y-4 grid-flow-row p-6">
{chapters.map((chapter) => (
<ChapterButton key={chapter} chapter={chapter} onClick={onSelect} />
))}
</div>
);
}
9 changes: 8 additions & 1 deletion components/Container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,14 @@ export default function Container(props: any) {
<meta property="article:published_time" content={meta.date} />
)}
</Head>
<nav className="flex items-center justify-between w-full max-w-4xl p-8 mx-auto my-0 text-gray-900 bg-white sticky-nav md:my-8 dark:bg-black bg-opacity-60 dark:text-gray-100">
{/* sticky-nav */}
<nav className="flex items-center justify-between w-full max-w-4xl p-8 mx-auto my-0 text-gray-900 bg-white dark:bg-black bg-opacity-60 dark:text-gray-100">
<button
onClick={() => router.push('/')}
className="text-4xl w-12 h-12 font-bold"
>
B.
</button>
<button
aria-label="Toggle Dark Mode"
type="button"
Expand Down
42 changes: 42 additions & 0 deletions components/SearchForm/BookCombobox/BookCombobox.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.search-popover[data-reach-combobox-popover] {
@apply rounded-xl bg-white absolute mt-5;
overflow: hidden;
left: 0;
right: 55%;
}

:global(.dark) .search-popover[data-reach-combobox-popover] {
@apply border-0 bg-gray-800;
overflow: hidden;
}

.search-list[data-reach-combobox-list] {
@apply border-gray-300 rounded-md hidden md:block;

max-height: 300px;
overflow: auto;
}

:global(.dark) .search-list[data-reach-combobox-list] {
@apply border-0;
}

.search-list-item[data-reach-combobox-option] {
@apply text-base bg-white text-gray-900;
padding: 0.5rem 0.75rem;
}

:global(.dark) .search-list-item[data-reach-combobox-option] {
@apply bg-gray-800 text-gray-100;
}

.search-list-item:hover,
.search-list-item[data-reach-combobox-option][aria-selected='true'] {
@apply bg-gray-100;
}

:global(.dark) .search-list-item:hover,
:global(.dark)
.search-list-item[data-reach-combobox-option][aria-selected='true'] {
@apply bg-gray-900;
}
100 changes: 100 additions & 0 deletions components/SearchForm/BookCombobox/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import {
Combobox,
ComboboxInput,
ComboboxList,
ComboboxOption,
ComboboxPopover
} from '@reach/combobox';
import '@reach/combobox/styles.css';
import { useWindowSize } from '@reach/window-size';
import classnames from 'classnames';
import { Ref, useState } from 'react';
import { autocompleteMatch } from '../../../utils';
import styles from './BookCombobox.module.css';

type BookComboboxProps = {
results: any;
inputRef: Ref<HTMLInputElement>;
onSelect: (item: string) => void;
onFocus: () => void;
onBlur: () => void;
onClick: () => void;
};

export default function BookCombobox({
results,
inputRef,
onSelect,
onFocus,
onBlur,
onClick
}: BookComboboxProps) {
const [search, setSearch] = useState('');
const bookResults = autocompleteMatch(results, search);

function handleSelect(item: string) {
setSearch(item);
onSelect(item);
}

return (
<>
<input
readOnly
onClick={onClick}
onFocus={onFocus}
onBlur={onBlur}
ref={inputRef}
// id="book"
// name="book"
placeholder="O que vai ler?"
onChange={(e) => setSearch(e.target.value)}
className="text-base w-full md:w-auto block md:hidden text-gray-900 dark:text-gray-100 bg-transparent outline-none"
// aria-labelledby="book"
/>
<Combobox
className="hidden md:block"
onSelect={(item) => handleSelect(item)}
openOnFocus
>
<ComboboxInput
onClick={onClick}
onFocus={onFocus}
onBlur={onBlur}
ref={inputRef}
id="book"
name="book"
placeholder="O que vai ler?"
onChange={(e) => setSearch(e.target.value)}
className="text-base w-full md:w-auto block text-gray-900 dark:text-gray-100 bg-transparent outline-none"
aria-labelledby="book"
/>
<ComboboxPopover portal={false} className={styles['search-popover']}>
<ComboboxList
className={styles['search-list']}
aria-labelledby="book"
>
{bookResults.length > 0 ? (
bookResults.map((book) => (
<ComboboxOption
className={classnames(
styles['search-list-item'],
'px-2 py-4'
)}
key={book.code}
value={book.book_pt}
/>
))
) : (
<ComboboxOption
tabIndex={-1}
className={styles['search-list-item']}
value="No Results"
/>
)}
</ComboboxList>
</ComboboxPopover>
</Combobox>
</>
);
}
11 changes: 11 additions & 0 deletions components/SearchForm/ChapterInput/ChapterInput.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.search-popover[data-reach-combobox-popover] {
@apply rounded-xl bg-white absolute mt-5 py-4;
overflow: hidden;
right: 0;
left: 0;
}

:global(.dark) .search-popover[data-reach-combobox-popover] {
@apply border-0 bg-gray-800;
overflow: hidden;
}
72 changes: 72 additions & 0 deletions components/SearchForm/ChapterInput/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Combobox, ComboboxInput, ComboboxPopover } from '@reach/combobox';
import '@reach/dialog/styles.css';
import { useWindowSize } from '@reach/window-size';
import { Ref, useState } from 'react';
import { BibleBook } from '../../../data/bible-books';
import ChapterList from '../../ChapterList';
import styles from './ChapterInput.module.css';

export default function ChapterInput({
book,
onSelect,
onBlur,
onFocus,
onClick,
inputRef
}: {
book?: BibleBook;
onSelect: (chapter: number) => void;
onFocus: () => void;
onBlur: () => void;
onClick: () => void;
inputRef: Ref<HTMLInputElement>;
}) {
const [chapter, setChapter] = useState<number>();

function handleSelect(chapter: number) {
const selected = Number(chapter);
onSelect(selected);
setChapter(selected);
}

return (
<>
<input
ref={inputRef}
onClick={onClick}
onBlur={onBlur}
onFocus={onFocus}
value={chapter?.toString()}
readOnly={!book}
// id="chapter"
// name="chapter"
placeholder="Escolha um capítulo"
className="block md:hidden text-gray-900 dark:text-gray-100 bg-transparent outline-none"
// aria-labelledby="chapter"
/>

<Combobox openOnFocus>
<ComboboxInput
ref={inputRef}
value={chapter?.toString()}
readOnly={!book}
onBlur={onBlur}
onFocus={onFocus}
onClick={onClick}
id="chapter"
name="chapter"
placeholder="Escolha um capítulo"
className="hidden md:block text-gray-900 dark:text-gray-100 bg-transparent outline-none"
aria-labelledby="chapter"
/>
<ComboboxPopover portal={false} className={styles['search-popover']}>
<ChapterList
isCombobox
chapterCount={book?.chapters}
onSelect={handleSelect}
/>
</ComboboxPopover>
</Combobox>
</>
);
}
39 changes: 39 additions & 0 deletions components/SearchForm/Dialog/MobileSearch.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
.search-mobile[data-reach-dialog-content] {
@apply rounded-full;
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
}

.mobile-search-input {
}

.search-list[data-reach-combobox-list] {
@apply border-gray-300;

overflow: auto;
}

:global(.dark) .search-list[data-reach-combobox-list] {
@apply border-0;
}

.search-list-item[data-reach-combobox-option] {
@apply text-base bg-white text-gray-900 px-10 py-3;
}

:global(.dark) .search-list-item[data-reach-combobox-option] {
@apply bg-black text-gray-100;
}

.search-list-item:hover,
.search-list-item[data-reach-combobox-option][aria-selected='true'] {
@apply bg-gray-100;
}

:global(.dark) .search-list-item:hover,
:global(.dark)
.search-list-item[data-reach-combobox-option][aria-selected='true'] {
@apply bg-gray-900;
}
Loading

1 comment on commit adf2351

@vercel
Copy link

@vercel vercel bot commented on adf2351 Nov 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.