Skip to content

Commit

Permalink
🎨 Reduce number of algolia requests #2470 (#2471)
Browse files Browse the repository at this point in the history
* 🎨 change search to not search when you type

* 🎨 add focus for no search webkit

* :art try more

* 🎨 display none

* 🎨 try this
  • Loading branch information
BorghildSelle authored Aug 21, 2024
1 parent 3b82288 commit c6e013f
Show file tree
Hide file tree
Showing 13 changed files with 171 additions and 178 deletions.
1 change: 1 addition & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ module.exports = {
],
// This rule was so noicy so let's turn it off and see how that works
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/ban-ts-comment': ['error', { 'ts-ignore': 'allow-with-description' }],
'import/newline-after-import': ['error'],
'import/no-unresolved': ['error', { ignore: ['^@'] }],
'react/no-array-index-key': ['error'],
Expand Down
9 changes: 7 additions & 2 deletions web/core/Button/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IconType } from '@equinor/eds-core-react/dist/types/components/Icon/Icon.types'
import { ButtonHTMLAttributes, forwardRef } from 'react'
import { twMerge } from 'tailwind-merge'
import envisTwMerge from '../../twMerge'

export const commonButtonStyling = `
w-fit
Expand Down Expand Up @@ -101,7 +101,12 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ variant = 'contained', type = 'button', children, icon: Icon, className = '', ...rest }, ref) => {
const variantClassNames = getVariant(variant)

const buttonClassNames = twMerge(commonButtonStyling, variantClassNames, `${Icon ? 'flex gap-2' : ''}`, className)
const buttonClassNames = envisTwMerge(
commonButtonStyling,
variantClassNames,
`${Icon ? 'flex gap-2' : ''}`,
className,
)

return (
<button ref={ref} type={type} className={buttonClassNames} {...rest}>
Expand Down
6 changes: 3 additions & 3 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"html-entities": "^2.3.2",
"http-proxy": "^1.18.1",
"ics": "^3.1.0",
"instantsearch.js": "^4.53.0",
"instantsearch.js": "^4.73.4",
"next": "13.5.6",
"next-sanity": "^4.1.7",
"next-sanity-image": "^6.0.0",
Expand All @@ -69,8 +69,8 @@
"react-dom": "^18.2.0",
"react-error-boundary": "^3.1.4",
"react-hook-form": "7.51.3",
"react-instantsearch": "^7.3.0",
"react-instantsearch-router-nextjs": "^7.3.0",
"react-instantsearch": "^7.12.4",
"react-instantsearch-router-nextjs": "^7.12.4",
"react-intl": "^6.0.2",
"react-is": "^18.1.0",
"react-twitter-embed": "^4.0.4",
Expand Down
9 changes: 6 additions & 3 deletions web/pageComponents/pageTemplates/newsroom/Filters.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { useState } from 'react'
import { useIntl } from 'react-intl'
import styled from 'styled-components'
import FilterHeader from './FilterHeader'
import { RefinementList } from './RefinementList'
import UncontrolledSearchBox from './UncontrolledSearchBox'
import { Accordion, AccordionItem, AccordionPanel } from '@chakra-ui/react'
import { SearchBox } from '../../../pageComponents/search/SearchBox'

const StyledAccordion = styled(Accordion)`
@media (min-width: 800px) {
Expand Down Expand Up @@ -32,7 +31,11 @@ const Filters = ({ ...rest }) => {
return (
<StyledFilters {...rest}>
<SearchBoxContainer>
<UncontrolledSearchBox />
<SearchBox
className="bg-white-100 border-grey-40 text-slate-80 focus-visible:envis-outline"
submitClassName="bg-norwegian-woods-100 text-white-100 hover:bg-slate-blue-95"
resetClassName="text-grey-50 border-grey-40"
/>
</SearchBoxContainer>
<StyledAccordion id="filters" allowMultiple>
<AccordionItem>
Expand Down
10 changes: 1 addition & 9 deletions web/pageComponents/search/ControlledSearchBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,7 @@ export type ControlledSearchBoxProps = ComponentProps<'div'> & {
value: string
}

const ControlledSearchBox = ({
inputRef,

onChange,
onReset,
onSubmit,
value,
...props
}: ControlledSearchBoxProps) => {
const ControlledSearchBox = ({ inputRef, onChange, onReset, onSubmit, value, ...props }: ControlledSearchBoxProps) => {
const intl = useIntl()

function handleSubmit(event: React.FormEvent) {
Expand Down
16 changes: 8 additions & 8 deletions web/pageComponents/search/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import dynamic from 'next/dynamic'
import { Flags } from '../../common/helpers/datasetHelpers'
import { SearchBox } from './SearchBox'
import { getIsoFromLocale } from '../../lib/localization'
import { SearchContextProvider } from './SearchContext'
//import { SearchContextProvider } from './SearchContext'
import { createInstantSearchRouterNext } from 'react-instantsearch-router-nextjs'
import singletonRouter, { useRouter } from 'next/router'
import type { UiState } from 'instantsearch.js'
Expand Down Expand Up @@ -168,13 +168,13 @@ const Search = () => {
<Index indexName={index.value} key={index.label} indexId={index.value} />
))}

<SearchContextProvider>
<SearchBox />
<SearchResults resultsRef={resultsRef} items={indices} />
<PaginationContextProvider defaultRef={resultsRef}>
<StyledPagination padding={padding} hitsPerPage={5} />
</PaginationContextProvider>
</SearchContextProvider>
{/* <SearchContextProvider> */}
<SearchBox />
<SearchResults resultsRef={resultsRef} items={indices} />
<PaginationContextProvider defaultRef={resultsRef}>
<StyledPagination padding={padding} hitsPerPage={5} />
</PaginationContextProvider>
{/* </SearchContextProvider> */}
</InstantSearch>
)
}
Expand Down
115 changes: 84 additions & 31 deletions web/pageComponents/search/SearchBox.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,105 @@
import { useEffect, useRef, useState, ChangeEvent, ComponentProps, useContext } from 'react'
import { useRef, useState, ChangeEvent, ComponentProps } from 'react'
import { useSearchBox, UseSearchBoxProps } from 'react-instantsearch'
import ControlledSearchBox from './ControlledSearchBox'
import { SearchContext } from './SearchContext'
import { close, search } from '@equinor/eds-icons'
import { useIntl } from 'react-intl'
import { Icon } from '@equinor/eds-core-react'
import envisTwMerge from '../../twMerge'

const DEBOUNCE_TIME = 800

export type SearchBoxProps = ComponentProps<'div'> & UseSearchBoxProps

let timerId: any = undefined
export type SearchBoxProps = {
className?: string
resetClassName?: string
submitClassName?: string
} & ComponentProps<'div'> &
UseSearchBoxProps

const queryHook: UseSearchBoxProps['queryHook'] = (query, search) => {
if (timerId) {
clearTimeout(timerId)
if (query !== '') {
search(query)
}
timerId = setTimeout(() => search(query), DEBOUNCE_TIME)
}

export function SearchBox(props: SearchBoxProps) {
// I don't think we need iSearchStalled when we don't have a manual reset button and/or loading
// spinner if search is slow? Do we need a spinner if this happens?
const { query, refine /* isSearchStalled */, clear } = useSearchBox({ ...props, queryHook })
export function SearchBox({ className = '', resetClassName = '', submitClassName = '', ...rest }: SearchBoxProps) {
const intl = useIntl()
const { query, refine, clear } = useSearchBox({ ...rest, queryHook })
const [value, setValue] = useState(query)
const { setUserTyped } = useContext(SearchContext)
const inputRef = useRef<HTMLInputElement>(null)

function onReset() {
function handleReset() {
setValue('')
clear()
setUserTyped(false)
}

function onSubmit(event: React.FormEvent) {
event.preventDefault()
event.stopPropagation()
refine(value)
}

function onChange(event: ChangeEvent<HTMLInputElement>) {
setUserTyped(true)
setValue(event.currentTarget.value)
refine(event.currentTarget.value)
}

useEffect(() => {
setValue(query)
}, [query])

return (
<ControlledSearchBox
inputRef={inputRef}
/* isSearchStalled={isSearchStalled} */
onChange={onChange}
onReset={onReset}
value={value}
/>
<form action="" role="search" noValidate onSubmit={onSubmit} onReset={handleReset} className="flex ">
<input
aria-label={intl.formatMessage({ id: 'search', defaultMessage: 'Search' })}
ref={inputRef}
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
placeholder={intl.formatMessage({ id: 'search', defaultMessage: 'Search' })}
spellCheck={false}
maxLength={512}
type="search"
value={value}
onChange={onChange}
className={envisTwMerge(
`flex-grow
border-y
border-l
border-white-100
bg-slate-blue-95
rounded-s-xs
focus:outline-none
focus-visible:envis-outline-invert
text-white-100
pl-6 pr-12
py-4
`,
className,
)}
/>
<button
type="reset"
hidden={value.length === 0}
className={envisTwMerge(
`group/reset px-4 border-y
border-r
border-white-100 focus:outline-none focus-visible:envis-outline-invert
text-white-100 group-hover/reset:text-white-100/40`,
resetClassName,
)}
>
<Icon size={24} data={close} />
</button>
<button
type="submit"
className={envisTwMerge(
`h-inherit
rounded-e-xs
px-4
py-3
bg-white-100
text-slate-blue-95
hover:bg-white-100/40
hover:text-white-100
focus:outline-none
focus-visible:envis-outline-invert`,
submitClassName,
)}
>
<Icon size={24} data={search} />
</button>
</form>
)
}
41 changes: 16 additions & 25 deletions web/pages/search/index.global.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import type { GetStaticProps } from 'next/types'
import { defaultLanguage } from '../../languages'
import { getIsoFromLocale } from '../../lib/localization'
import getIntl from '../../common/helpers/getIntl'
import styled from 'styled-components'
import { Button } from '@components'
import { Icon } from '@equinor/eds-core-react'
import { close } from '@equinor/eds-icons'
import { TopbarDropdown } from '../../pageComponents/shared/siteMenu/TopbarDropdown'
Expand All @@ -16,24 +14,6 @@ import Search from '../../pageComponents/search/Search'
import { useRouter } from 'next/router'
import { FloatingOverlay } from '@floating-ui/react'

const InvertedButton = styled(Button)`
color: var(--white-100);
&:hover {
color: var(--slate-blue-95);
background-color: var(--moss-green-60);
}
&:focus-visible,
&[data-focus-visible-added]:focus {
outline-color: var(--mist-blue-100);
}
`

const SearchContainer = styled.div`
padding: var(--space-large);
max-width: 700px;
margin: 0 auto;
`

export default function SearchPage() {
const router = useRouter()
const intl = useIntl()
Expand All @@ -47,20 +27,31 @@ export default function SearchPage() {
<TopbarDropdown background={{ backgroundColor: 'Slate Blue 95' }}>
<NavTopbar>
<LogoLink />
<InvertedButton
variant="ghost_icon"
<button
type="button"
aria-expanded={true}
aria-label="Close search"
onClick={() => {
router.back()
}}
className={`
p-3
rounded-full
text-white-100
hover:bg-moss-green-50
hover:text-slate-blue-95
focus:outline-none
focus-visible:envis-outline-invert
active:scale-99
active:bg-white-100/20
`}
>
<Icon size={24} data={close} />
</InvertedButton>
</button>
</NavTopbar>
<SearchContainer>
<div className="p-8 max-w-[700px] mx-auto">
<Search />
</SearchContainer>
</div>
</TopbarDropdown>
</FloatingOverlay>
</>
Expand Down
Loading

0 comments on commit c6e013f

Please sign in to comment.