Skip to content

Commit

Permalink
fix: Stop double scroll issue (#151)
Browse files Browse the repository at this point in the history
* Stop double scroll issue

* Revert move of profile thing
  • Loading branch information
vinnyjth authored Jan 29, 2024
1 parent 29c0b9c commit 6d979b1
Show file tree
Hide file tree
Showing 4 changed files with 341 additions and 329 deletions.
299 changes: 5 additions & 294 deletions packages/web-shared/components/Searchbar/Autocomplete.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,21 @@
import React, { useEffect, useState, useRef, useMemo, createElement, Fragment } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
import { ClockCounterClockwise, MagnifyingGlass, CaretDown, CaretRight, X } from 'phosphor-react';
import React, { useEffect, useRef, useMemo } from 'react';
import { X } from 'phosphor-react';

import algoliasearch from 'algoliasearch/lite';
import { createAutocomplete } from '@algolia/autocomplete-core';
import { getAlgoliaResults, parseAlgoliaHitHighlight } from '@algolia/autocomplete-preset-algolia';
import { getAlgoliaResults } from '@algolia/autocomplete-preset-algolia';
import { createQuerySuggestionsPlugin } from '@algolia/autocomplete-plugin-query-suggestions';
import { createLocalStorageRecentSearchesPlugin } from '@algolia/autocomplete-plugin-recent-searches';
import '@algolia/autocomplete-theme-classic';

import { FeatureFeedProvider } from '../../providers';
import Feed from '../FeatureFeed';
import { ResourceCard, Box } from '../../ui-kit';

import { useSearchState } from '../../providers/SearchProvider';
import { getURLFromType } from '../../utils';
import Styled from './Search.styles';
import { add as addBreadcrumb, useBreadcrumbDispatch } from '../../providers/BreadcrumbProvider';
import { open as openModal, set as setModal, useModal } from '../../providers/ModalProvider';

const MOBILE_BREAKPOINT = 428;
const appId = "Z0GWPR8XBE";
const apiKey = "251ec8d76f6c62ac793c1337b39bda58";
const appId = 'Z0GWPR8XBE';
const apiKey = '251ec8d76f6c62ac793c1337b39bda58';
const searchClient = algoliasearch(appId, apiKey);

function Hit({ hit }) {
return hit?.title;
}

// Highlight text render
function Highlight({ hit, attribute, tagName = 'mark' }) {
return createElement(
Fragment,
{},
parseAlgoliaHitHighlight({ hit, attribute }).map(({ value, isHighlighted }, index) => {
if (isHighlighted) {
return createElement(tagName, { key: index }, value);
}

return value;
})
);
}

// Recent Searches Index Definition
const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({
key: 'navbar',
Expand All @@ -57,124 +29,12 @@ const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({
},
});

// Query Suggestion Item Render
function QuerySuggestionItem({ item, autocomplete, handleActionPress }) {
return (
<Box className="aa-ItemWrapper" px="xs">
<div className="aa-ItemContent">
<div className="aa-ItemIcon aa-ItemIcon--noBorder">
<MagnifyingGlass size={24} weight="bold" />
</div>
<div className="aa-ItemContentBody">
<div className="aa-ItemContentTitle">
<Hit hit={item} />
</div>
</div>
</div>
<div className="aa-ItemActions">
<button
className="aa-ItemActionButton"
title={`Fill query with "${item.title}"`}
onClick={(event) => {
event.preventDefault();
event.stopPropagation();
autocomplete.setQuery(item.title);
autocomplete.refresh();
}}
>
<CaretRight size={24} weight="bold" />
</button>
</div>
</Box>
);
}

// Recent Search Item Render
function PastQueryItem({ item, autocomplete }) {
function onRemove(id) {
recentSearchesPlugin.data.removeItem(id);
autocomplete.refresh();
}

function onTapAhead(item) {
autocomplete.setQuery(item.label);
autocomplete.setIsOpen(true);
autocomplete.refresh();
}
return (
<Box className="aa-ItemWrapper" px="xs">
<div className="aa-ItemContent">
<div className="aa-ItemIcon aa-ItemIcon--noBorder">
<ClockCounterClockwise size={24} weight="bold" />
</div>
<div className="aa-ItemContentBody">
<div className="aa-ItemContentTitle">
<Highlight hit={item} attribute="label" />
</div>
</div>
</div>
<div className="aa-ItemActions">
<button
className="aa-ItemActionButton"
title="Remove this search"
onClick={(event) => {
event.preventDefault();
event.stopPropagation();
onRemove(item.id);
}}
>
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M18 7v13c0 0.276-0.111 0.525-0.293 0.707s-0.431 0.293-0.707 0.293h-10c-0.276 0-0.525-0.111-0.707-0.293s-0.293-0.431-0.293-0.707v-13zM17 5v-1c0-0.828-0.337-1.58-0.879-2.121s-1.293-0.879-2.121-0.879h-4c-0.828 0-1.58 0.337-2.121 0.879s-0.879 1.293-0.879 2.121v1h-4c-0.552 0-1 0.448-1 1s0.448 1 1 1h1v13c0 0.828 0.337 1.58 0.879 2.121s1.293 0.879 2.121 0.879h10c0.828 0 1.58-0.337 2.121-0.879s0.879-1.293 0.879-2.121v-13h1c0.552 0 1-0.448 1-1s-0.448-1-1-1zM9 5v-1c0-0.276 0.111-0.525 0.293-0.707s0.431-0.293 0.707-0.293h4c0.276 0 0.525 0.111 0.707 0.293s0.293 0.431 0.293 0.707v1zM9 11v6c0 0.552 0.448 1 1 1s1-0.448 1-1v-6c0-0.552-0.448-1-1-1s-1 0.448-1 1zM13 11v6c0 0.552 0.448 1 1 1s1-0.448 1-1v-6c0-0.552-0.448-1-1-1s-1 0.448-1 1z" />
</svg>
</button>
<button
className="aa-ItemActionButton"
title={`Fill query with "${item.label}"`}
onClick={(event) => {
event.preventDefault();
event.stopPropagation();
onTapAhead(item);
}}
>
<CaretRight size={24} weight="bold" />
</button>
</div>
</Box>
);
}

export default function Autocomplete({
autocompleteState,
setAutocompleteState,
setShowTextPrompt,
getAutocompleteInstance,
}) {
const [searchParams, setSearchParams] = useSearchParams();
const dispatchBreadcrumb = useBreadcrumbDispatch();
const [state, dispatch] = useModal();

const [isResultsEmpty, setIsResultsEmpty] = useState(false);

const handleActionPress = (item) => {
if (searchParams.get('id') !== getURLFromType(item)) {
dispatchBreadcrumb(
addBreadcrumb({
url: `?id=${getURLFromType(item)}`,
title: item.title,
})
);
setSearchParams(`?id=${getURLFromType(item)}`);
}
if (state.modal) {
const url = getURLFromType(item);
dispatch(setModal(url));
dispatch(openModal());
}
};
const handleStaticActionPress = (item) => {
window.location.href = item.url;
};
const navigate = useNavigate();
const searchState = useSearchState();
const inputRef = useRef(null);

Expand Down Expand Up @@ -227,15 +87,6 @@ export default function Autocomplete({
autocomplete.refresh();
};

const handlePanelDropdown = () => {
const updatedAutocompleteState = { ...autocompleteState };
updatedAutocompleteState.isOpen = !updatedAutocompleteState.isOpen;
setAutocompleteState(updatedAutocompleteState);

autocomplete.setIsOpen(!autocompleteState.isOpen);
inputRef.current?.[autocompleteState.isOpen ? 'blur' : 'focus']();
};

// Query Suggesion Index Definition
const querySuggestionsPlugin = createQuerySuggestionsPlugin({
searchClient,
Expand Down Expand Up @@ -394,17 +245,6 @@ export default function Autocomplete({
};
}, [autocompleteState.isOpen, autocomplete, setShowTextPrompt]);

useEffect(() => {
const pagesItems =
autocompleteState.collections.find((collection) => collection.source.sourceId === 'pages')
?.items || [];
const contentItems =
autocompleteState.collections.find((collection) => collection.source.sourceId === 'content')
?.items || [];

setIsResultsEmpty(pagesItems.length === 0 && contentItems.length === 0);
}, [autocompleteState.collections]);

useEffect(() => {
if (getAutocompleteInstance) {
getAutocompleteInstance(autocomplete);
Expand All @@ -424,135 +264,6 @@ export default function Autocomplete({
</div>
) : null}
</form>
<Box
id="panel"
className="aa-Panel"
dropdown={autocompleteState.isOpen}
{...autocomplete.getPanelProps({})}
>
{autocompleteState.isOpen && <div id="panel-top"></div>}
{isResultsEmpty &&
autocompleteState.collections.some((collection) =>
['pages', 'content'].includes(collection.source.sourceId)
) && (
<Box
padding="xs"
fontWeight="500"
color="base.gray"
textAlign="center"
fontStyle="italic"
>
No results found
</Box>
)}
{autocompleteState.isOpen &&
autocompleteState.collections.map((collection, index) => {
const { source, items } = collection;
// Rendering of Query Suggestions
if (
['querySuggestionsPlugin', 'recentSearchesPlugin'].includes(
collection.source.sourceId
)
) {
return (
<div key={`source-${index}`} className="aa-Source">
{collection.source.sourceId === 'querySuggestionsPlugin' && !inputProps.value && (
<Box padding="xs" fontWeight="600" color="base.gray">
Trending Searches
</Box>
)}
{collection.source.sourceId === 'recentSearchesPlugin' && (
<Box padding="xs" fontWeight="600" color="base.gray">
Search History
</Box>
)}
<ul className="aa-List" {...autocomplete.getListProps()}>
{items.map((item, index) => (
<li
key={`${item.objectID ? item.objectID : index}-${
collection.source.sourceId
}`}
className="aa-Item"
{...autocomplete.getItemProps({
item,
source,
})}
>
{collection.source.sourceId === 'querySuggestionsPlugin' && (
<QuerySuggestionItem
item={item}
autocomplete={autocomplete}
handleActionPress={handleActionPress}
{...autocomplete.getItemProps({
item,
source,
})}
/>
)}
{collection.source.sourceId === 'recentSearchesPlugin' && (
<PastQueryItem
item={item}
autocomplete={autocomplete}
{...autocomplete.getItemProps({
item,
source,
})}
/>
)}
</li>
))}
</ul>
</div>
);
}

// Rendering of regular items

return autocompleteState.query !== '' ? (
<div key={`source-${index}`} className="aa-Source">
<ul className="aa-List" {...autocomplete.getListProps()}>
{items.map((item) => (
<Box
as="li"
borderRadius="0"
padding="0"
key={item.objectID}
className="aa-Item"
{...autocomplete.getItemProps({
item,
source,
})}
>
<ResourceCard
leadingAsset={item?.coverImage}
title={item?.title}
onClick={() => {
if (collection.source.sourceId === 'pages') {
return handleStaticActionPress(item);
}
return handleActionPress(item);
}}
background="none"
/>
</Box>
))}
</ul>
</div>
) : null;
})}
{autocompleteState.isOpen && autocompleteState.query === '' && searchState.searchFeed ? (
<Box className="empty-feed">
<FeatureFeedProvider
Component={Feed}
options={{
variables: {
itemId: searchState.searchFeed,
},
}}
/>
</Box>
) : null}
</Box>
</div>
);
}
8 changes: 4 additions & 4 deletions packages/web-shared/components/Searchbar/Search.styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,9 @@ const showPanel = ({ dropdown }) => {
};

const Wrapper = withTheme(styled.div`
align-items: center;
background: ${themeGet('colors.base.white')};
box-shadow: ${themeGet('shadows.medium')};
display: flex;
height: 60px;
justify-content: space-between;
width: 100%;
z-index: 100;
${showDropdown}
Expand All @@ -72,6 +69,9 @@ const Wrapper = withTheme(styled.div`
overflow-x: hidden;
border-radius: 0px 0px 15px 15px;
${showPanel}
position: relative;
display: inline-block;
margin: 0px;
}
.aa-Form:focus-within {
Expand All @@ -91,12 +91,12 @@ const TextPrompt = withTheme(styled.div`
display: flex;
overflow: hidden;
pointer-events: none;
position: absolute;
text-overflow: ellipsis;
top: 50%;
transform: translate(0, -50%);
white-space: nowrap;
width: 100%;
position: absolute;
@media screen and (max-width: ${themeGet('breakpoints.md')}) {
max-width: 70%;
Expand Down
Loading

0 comments on commit 6d979b1

Please sign in to comment.