Skip to content

Commit

Permalink
Merge branch 'main' into DOP-5016
Browse files Browse the repository at this point in the history
  • Loading branch information
mayaraman19 authored Oct 4, 2024
2 parents 15bebe6 + e859be8 commit 1a4173e
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 140 deletions.
50 changes: 15 additions & 35 deletions src/components/SearchResults/MobileFilters.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,16 @@
import React, { useContext, useCallback } from 'react';
import { Global, css } from '@emotion/react';
import styled from '@emotion/styled';
import Icon from '@leafygreen-ui/icon';
import { palette } from '@leafygreen-ui/palette';
import useStickyTopValues from '../../hooks/useStickyTopValues';
import { theme } from '../../theme/docsTheme';
import SearchContext from './SearchContext';
import SearchFilters from './SearchFilters';
import { Facets } from './Facets';

// Temporarily apply this css rule to prevent body scrolling only while
// this component is mounted.
const disableBodyScroll = css`
body {
overflow: hidden;
}
`;

const Container = styled('div')`
background-color: var(--background-color-primary);
position: fixed;
left: 0;
top: ${({ topValue }) => topValue};
height: calc(100vh - ${({ topValue }) => topValue});
overflow-y: scroll;
right: 0;
bottom: 0;
padding-top: ${theme.size.large};
width: 100%;
padding: ${theme.size.large} ${theme.size.medium};
z-index: 1;
`;

const BackButton = styled('div')`
Expand All @@ -37,6 +19,8 @@ const BackButton = styled('div')`
cursor: pointer;
display: flex;
gap: 0 ${theme.size.small};
font-size: ${theme.fontSize.default};
line-height: ${theme.size.medium};
.dark-theme & {
color: ${palette.gray.light1};
Expand All @@ -50,29 +34,25 @@ const Label = styled('div')`
`;

const MobileFilters = ({ facets }) => {
const { topSmall } = useStickyTopValues(false, true);
const { setShowMobileFilters, showFacets } = useContext(SearchContext);

const closeMobileFilters = useCallback(() => {
setShowMobileFilters(false);
}, [setShowMobileFilters]);

return (
<>
<Global styles={disableBodyScroll} />
<Container topValue={topSmall}>
<BackButton onClick={closeMobileFilters}>
<Icon glyph="ArrowLeft" />
Back to search results
</BackButton>
<Label>Refine your search</Label>
{showFacets ? (
<Facets facets={facets} />
) : (
<SearchFilters manuallyApplyFilters={true} onApplyFilters={closeMobileFilters} />
)}
</Container>
</>
<Container>
<BackButton onClick={closeMobileFilters}>
<Icon glyph="ArrowLeft" />
Back to search results
</BackButton>
<Label>Refine your search</Label>
{showFacets ? (
<Facets facets={facets} />
) : (
<SearchFilters manuallyApplyFilters={true} onApplyFilters={closeMobileFilters} />
)}
</Container>
);
};

Expand Down
204 changes: 105 additions & 99 deletions src/components/SearchResults/SearchResults.js
Original file line number Diff line number Diff line change
Expand Up @@ -457,117 +457,123 @@ const SearchResults = () => {
},
[searchParams, searchTerm, setSearchTerm]
);

return (
<SearchResultsContainer showFacets={showFacets}>
<HeaderContainer className={cx(headerContainerDynamicStyles)}>
<H3>Search Results</H3>
{/* Classname-attached searchTerm needed for Smartling localization */}
<span style={{ display: 'none' }} className="sl-search-keyword">
{searchTerm}
</span>
{searchTerm && (
<ResultTag>
{!showFacets && Number.isInteger(searchCount) && (
<Overline className={cx(overlineStyle)}>
<>{searchCount} RESULTS</>
</Overline>
)}
{!!searchFilter && (
<div>
{selectedCategory && (
<StyledTag variant="green" onClick={resetFilters}>
{selectedCategory}
<Icon className={cx(iconStyle)} glyph="X" />
</StyledTag>
{showMobileFilters && isTabletOrMobile ? (
<MobileFilters facets={searchResultFacets} />
) : (
<>
<HeaderContainer className={cx(headerContainerDynamicStyles)}>
<H3>Search Results</H3>
{/* Classname-attached searchTerm needed for Smartling localization */}
<span style={{ display: 'none' }} className="sl-search-keyword">
{searchTerm}
</span>
{searchTerm && (
<ResultTag>
{!showFacets && Number.isInteger(searchCount) && (
<Overline className={cx(overlineStyle)}>
<>{searchCount} RESULTS</>
</Overline>
)}
{!!searchFilter && (
<div>
{selectedCategory && (
<StyledTag variant="green" onClick={resetFilters}>
{selectedCategory}
<Icon className={cx(iconStyle)} glyph="X" />
</StyledTag>
)}
{selectedVersion && <StyledTag variant="blue">{selectedVersion}</StyledTag>}
</div>
)}
{selectedVersion && <StyledTag variant="blue">{selectedVersion}</StyledTag>}
</div>
{showFacets && <FacetTags resultsCount={searchCount}></FacetTags>}
</ResultTag>
)}
{showFacets && <FacetTags resultsCount={searchCount}></FacetTags>}
</ResultTag>
)}
<MobileSearchButtonWrapper>
<Button leftGlyph={<Icon glyph={mobileFilterButton.glyph} />} onClick={mobileFilterButton.onClick}>
{mobileFilterButton.text}
</Button>
</MobileSearchButtonWrapper>
</HeaderContainer>

{/* loading state for new search input */}
{!!searchTerm && !searchFinished && (
<>
<StyledSearchResults>
{[...Array(10)].map((_, index) => (
<StyledLoadingSkeletonContainer key={index} className={cx(searchResultDynamicStyling)}>
<StyledParagraphSkeleton withHeader />
</StyledLoadingSkeletonContainer>
))}
</StyledSearchResults>
</>
)}

{/* empty search results */}
{searchTerm && searchFinished && !searchResults?.length && (
<>
<>
<EmptyResultsContainer>
<EmptyResults />
</EmptyResultsContainer>
</>
</>
)}
<MobileSearchButtonWrapper>
<Button leftGlyph={<Icon glyph={mobileFilterButton.glyph} />} onClick={mobileFilterButton.onClick}>
{mobileFilterButton.text}
</Button>
</MobileSearchButtonWrapper>
</HeaderContainer>

{/* loading state for new search input */}
{!!searchTerm && !searchFinished && (
<>
<StyledSearchResults>
{[...Array(10)].map((_, index) => (
<StyledLoadingSkeletonContainer key={index} className={cx(searchResultDynamicStyling)}>
<StyledParagraphSkeleton withHeader />
</StyledLoadingSkeletonContainer>
))}
</StyledSearchResults>
</>
)}

{/* search results for new search page */}
{!!searchTerm && !!searchFinished && !!searchResults.length && (
<>
<StyledSearchResults>
{searchResults.map(({ title, preview, url, searchProperty, facets }, index) => (
<StyledSearchResult
key={`${url}${index}`}
onClick={() =>
reportAnalytics('SearchSelection', { areaFrom: 'ResultsPage', rank: index, selectionUrl: url })
}
title={title}
preview={escapeHtml(preview)}
url={url}
useLargeTitle
searchProperty={searchProperty?.[0]}
facets={facets}
/>
))}
{
{/* empty search results */}
{searchTerm && searchFinished && !searchResults?.length && (
<>
<>
<Pagination
className={paginationStyling}
currentPage={parseInt(new URLSearchParams(search).get('page') || 1)}
numTotalItems={searchCount}
onForwardArrowClick={onPageClick.bind(null, true)}
onBackArrowClick={onPageClick.bind(null, false)}
shouldDisableBackArrow={parseInt(new URLSearchParams(search).get('page')) === 1}
shouldDisableForwardArrow={searchResults?.length && searchResults.length < 10}
></Pagination>
<EmptyResultsContainer>
<EmptyResults />
</EmptyResultsContainer>
</>
}
</StyledSearchResults>
</>
)}

{searchParams.get('q') && (
<FiltersContainer>
{showFacets ? (
<>
{/* Avoid showing Facets component to avoid clashing values with mobile filter */}
{!showMobileFilters && <Facets facets={searchResultFacets} />}
</>
) : (
)}

{/* search results for new search page */}
{!!searchTerm && !!searchFinished && !!searchResults.length && (
<>
<FilterHeader className={cx(filterHeaderDynamicStyles)}>{specifySearchText}</FilterHeader>
<StyledSearchFilters />
<StyledSearchResults>
{searchResults.map(({ title, preview, url, searchProperty, facets }, index) => (
<StyledSearchResult
key={`${url}${index}`}
onClick={() =>
reportAnalytics('SearchSelection', { areaFrom: 'ResultsPage', rank: index, selectionUrl: url })
}
title={title}
preview={escapeHtml(preview)}
url={url}
useLargeTitle
searchProperty={searchProperty?.[0]}
facets={facets}
/>
))}
{
<>
<Pagination
className={paginationStyling}
currentPage={parseInt(new URLSearchParams(search).get('page') || 1)}
numTotalItems={searchCount}
onForwardArrowClick={onPageClick.bind(null, true)}
onBackArrowClick={onPageClick.bind(null, false)}
shouldDisableBackArrow={parseInt(new URLSearchParams(search).get('page')) === 1}
shouldDisableForwardArrow={searchResults?.length && searchResults.length < 10}
></Pagination>
</>
}
</StyledSearchResults>
</>
)}
</FiltersContainer>

{searchParams.get('q') && (
<FiltersContainer>
{showFacets ? (
<>
{/* Avoid showing Facets component to avoid clashing values with mobile filter */}
{!showMobileFilters && <Facets facets={searchResultFacets} />}
</>
) : (
<>
<FilterHeader className={cx(filterHeaderDynamicStyles)}>{specifySearchText}</FilterHeader>
<StyledSearchFilters />
</>
)}
</FiltersContainer>
)}
</>
)}
{showMobileFilters && isTabletOrMobile && <MobileFilters facets={searchResultFacets} />}
</SearchResultsContainer>
);
};
Expand Down
7 changes: 1 addition & 6 deletions tests/unit/SearchResults.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,7 @@ const expectUnfilteredResults = (wrapper) => {
};

const filterByRealm = async (wrapper, screenSize) => {
let listboxIndex = 0;
if (screenSize === 'mobile') {
listboxIndex = 2;
}
const listboxIndex = 0;
const selectElements = wrapper.queryAllByTestId('lg-select');
const dropdownButton = selectElements[listboxIndex];
expect(dropdownButton).toHaveAttribute('aria-expanded', 'false');
Expand Down Expand Up @@ -295,8 +292,6 @@ describe('Search Results Page', () => {

// Set filters but don't apply them
await filterByRealm(renderStitchResults, 'mobile');
expectUnfilteredResults(renderStitchResults);
expect(renderStitchResults.queryByText(MOBILE_SEARCH_BACK_BUTTON_TEXT)).toBeTruthy();

// Hit back button
await act(async () => {
Expand Down

0 comments on commit 1a4173e

Please sign in to comment.