-
Notifications
You must be signed in to change notification settings - Fork 332
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: add two-columns layout example (#908)
* docs(examples): scaffold two columns layout example * fix consistent naming * chore: fix linting * chore: fix styles * chore: fix deps * chore: add missing dep for Codesandbox * apply suggestions from code review * remove useless media queries * apply suggestions from code review * docs(two-column-layout-example): add products plugin (#909) * docs(two-columns-layout-example): add products plugin * apply suggestions from review * remove useless type * use classic header for recent searches and fix padding * apply suggestions from code review * docs(two-column-layout-example): add categories, brands and faq plugins (#910) * chore(two-columns-layout-example): add categories plugin * chore(two-columns-layout-example): add brands plugin * chore(two-columns-layout-example): add faq plugin * apply suggestions from code review * remove debug option * docs(two-column-layout-example): add articles and popular plugins (#911) * chore(two-columns-layout-example): add articles plugin * chore(two-columns-layout-example): add popular plugin * apply suggestions from code review * docs(two-column-layout-example): add reshape functions and quick access plugin (#912) * chore(two-columns-layout-example): add reshape functions * docs(two-columns-layout-example): add quick access plugin * chore: move reshape functions at file top-level * apply suggestions from code review * docs(two-column-layout-example): add smart preview feature (#913) * docs(two-columns-layout-example): add smart preview feature * docs(two-columns-layout-example): add faq article preview * apply suggestions from code review * docs(two-column-layout-example): add no results state and popular categories plugin (#914) * docs(two-columns-layout-example): add no results state and popular categories plugin * chore: fix empty div with Fragment * chore: fix empty div when no recent searches exist * chore: fix casing * apply suggestions from code review * apply suggestions from pair session * fix empty recent searches * fix linting * apply suggestion from code review * smart preview no longer depends on the DOM * apply suggestions from feedback * apply suggestions from feedback * apply suggestion from code review * apply suggestion from feedback * remove smart preview for now * add quick access selected transition * fix see all link margin * add getItemInputValue for faq * apply feedback * apply feedback * apply feedback * apply last fixes
- Loading branch information
1 parent
6f59dd5
commit 927b1bc
Showing
46 changed files
with
2,460 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# See https://help.github.com/ignore-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
|
||
# testing | ||
/coverage | ||
|
||
# production | ||
/dist | ||
/.cache | ||
/.parcel-cache | ||
|
||
# misc | ||
.DS_Store | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Autocomplete with a two-column layout example | ||
|
||
This example shows how to integrate Autocomplete with a two-column layout. | ||
|
||
<p align="center"><img src="capture.png?raw=true" alt="A capture of the Autocomplete with a two-column layout example" /></p> | ||
|
||
## Demo | ||
|
||
[Access the demo](https://codesandbox.io/s/github/algolia/autocomplete/tree/next/examples/two-column-layout) | ||
|
||
## How to run this example locally | ||
|
||
### 1. Clone this repository | ||
|
||
```sh | ||
git clone [email protected]:algolia/autocomplete.git | ||
``` | ||
|
||
### 2. Install the dependencies and run the server | ||
|
||
```sh | ||
yarn | ||
yarn workspace @algolia/autocomplete-example-two-column-layout start | ||
``` | ||
|
||
Alternatively, you may use npm: | ||
|
||
```sh | ||
cd examples/two-column-layout | ||
npm install | ||
npm run start | ||
``` | ||
|
||
Open <http://localhost:1234> to see your app. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
|
||
<link rel="shortcut icon" href="favicon.png" type="image/x-icon" /> | ||
<link rel="stylesheet" href="style.css" /> | ||
|
||
<title>Autocomplete with a two-column layout</title> | ||
</head> | ||
|
||
<body> | ||
<noscript> You need to enable JavaScript to run this app. </noscript> | ||
|
||
<div class="container"> | ||
<div id="autocomplete"></div> | ||
</div> | ||
|
||
<script src="src/app.tsx"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
{ | ||
"name": "@algolia/autocomplete-example-two-column-layout", | ||
"description": "Autocomplete example with two-column layout", | ||
"version": "1.5.3", | ||
"private": true, | ||
"license": "MIT", | ||
"scripts": { | ||
"build": "parcel build index.html", | ||
"start": "parcel index.html" | ||
}, | ||
"dependencies": { | ||
"@algolia/autocomplete-core": "1.5.3", | ||
"@algolia/autocomplete-js": "1.5.3", | ||
"@algolia/autocomplete-plugin-query-suggestions": "1.5.3", | ||
"@algolia/autocomplete-plugin-recent-searches": "1.5.3", | ||
"@algolia/autocomplete-theme-classic": "1.5.3", | ||
"@algolia/autocomplete-shared": "1.5.3", | ||
"@algolia/client-search": "4.12.1", | ||
"algoliasearch": "4.12.1", | ||
"blurhash": "^1.1.5", | ||
"dequal": "^2.0.2", | ||
"preact": "10.5.14", | ||
"ramda": "^0.28.0", | ||
"typescript": "^4.6.2" | ||
}, | ||
"devDependencies": { | ||
"parcel": "2.0.0-beta.2" | ||
}, | ||
"keywords": [ | ||
"algolia", | ||
"autocomplete", | ||
"typescript" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
/** @jsx h */ | ||
import { autocomplete } from '@algolia/autocomplete-js'; | ||
import { h, render } from 'preact'; | ||
import { pipe } from 'ramda'; | ||
|
||
import { createFillWith, uniqBy } from './functions'; | ||
import { articlesPlugin } from './plugins/articlesPlugin'; | ||
import { brandsPlugin } from './plugins/brandsPlugin'; | ||
import { categoriesPlugin } from './plugins/categoriesPlugin'; | ||
import { faqPlugin } from './plugins/faqPlugin'; | ||
import { popularCategoriesPlugin } from './plugins/popularCategoriesPlugin'; | ||
import { popularPlugin } from './plugins/popularPlugin'; | ||
import { productsPlugin } from './plugins/productsPlugin'; | ||
import { querySuggestionsPlugin } from './plugins/querySuggestionsPlugin'; | ||
import { quickAccessPlugin } from './plugins/quickAccessPlugin'; | ||
import { recentSearchesPlugin } from './plugins/recentSearchesPlugin'; | ||
import { cx, hasSourceActiveItem, isDetached } from './utils'; | ||
|
||
import '@algolia/autocomplete-theme-classic'; | ||
|
||
const removeDuplicates = uniqBy(({ source, item }) => { | ||
const sourceIds = ['recentSearchesPlugin', 'querySuggestionsPlugin']; | ||
if (sourceIds.indexOf(source.sourceId) === -1) { | ||
return item; | ||
} | ||
|
||
return source.sourceId === 'querySuggestionsPlugin' ? item.query : item.label; | ||
}); | ||
|
||
const fillWith = createFillWith({ | ||
mainSourceId: 'querySuggestionsPlugin', | ||
limit: isDetached() ? 6 : 10, | ||
}); | ||
|
||
const combine = pipe(removeDuplicates, fillWith); | ||
|
||
autocomplete({ | ||
container: '#autocomplete', | ||
placeholder: 'Search products, articles, and FAQs', | ||
autoFocus: true, | ||
openOnFocus: true, | ||
plugins: [ | ||
recentSearchesPlugin, | ||
querySuggestionsPlugin, | ||
categoriesPlugin, | ||
brandsPlugin, | ||
faqPlugin, | ||
productsPlugin, | ||
articlesPlugin, | ||
popularPlugin, | ||
quickAccessPlugin, | ||
popularCategoriesPlugin, | ||
], | ||
reshape({ sourcesBySourceId, sources, state }) { | ||
const { | ||
recentSearchesPlugin: recentSearches, | ||
querySuggestionsPlugin: querySuggestions, | ||
categoriesPlugin: categories, | ||
brandsPlugin: brands, | ||
faqPlugin: faq, | ||
popularPlugin: popular, | ||
popularCategoriesPlugin: popularCategories, | ||
...rest | ||
} = sourcesBySourceId; | ||
|
||
const sourceIdsToExclude = ['popularPlugin', 'popularCategoriesPlugin']; | ||
const shouldDisplayPopularCategories = sources.every((source) => { | ||
if (sourceIdsToExclude.indexOf(source.sourceId) !== -1) { | ||
return true; | ||
} | ||
return source.getItems().length === 0; | ||
}); | ||
|
||
return [ | ||
combine(recentSearches, querySuggestions, categories, brands, faq), | ||
[ | ||
!state.query && popular, | ||
...Object.values(rest), | ||
shouldDisplayPopularCategories && popularCategories, | ||
].filter(Boolean), | ||
]; | ||
}, | ||
render({ elements, state, Fragment }, root) { | ||
const { | ||
recentSearchesPlugin: recentSearches, | ||
querySuggestionsPlugin: querySuggestions, | ||
categoriesPlugin: categories, | ||
brandsPlugin: brands, | ||
faqPlugin: faq, | ||
productsPlugin: products, | ||
articlesPlugin: articles, | ||
popularPlugin: popular, | ||
quickAccessPlugin: quickAccess, | ||
popularCategoriesPlugin: popularCategories, | ||
} = elements; | ||
|
||
const sourceIdsToExclude = ['popularPlugin', 'popularCategoriesPlugin']; | ||
const hasResults = | ||
state.collections | ||
.filter( | ||
({ source }) => sourceIdsToExclude.indexOf(source.sourceId) === -1 | ||
) | ||
.reduce((prev, curr) => prev + curr.items.length, 0) > 0; | ||
|
||
render( | ||
<div className="aa-PanelLayout aa-Panel--scrollable"> | ||
{!hasResults && ( | ||
<div className="aa-NoResultsQuery"> | ||
No results for "{state.query}". | ||
</div> | ||
)} | ||
|
||
<div className="aa-PanelSections"> | ||
<div className="aa-PanelSection--left"> | ||
{hasResults ? ( | ||
(!state.query && recentSearches && ( | ||
<Fragment> | ||
<div className="aa-SourceHeader"> | ||
<span className="aa-SourceHeaderTitle"> | ||
Recent searches | ||
</span> | ||
<div className="aa-SourceHeaderLine" /> | ||
</div> | ||
{recentSearches} | ||
</Fragment> | ||
)) || | ||
(state.query && ( | ||
<Fragment> | ||
<div className="aa-SourceHeader"> | ||
<span className="aa-SourceHeaderTitle">Suggestions</span> | ||
<div className="aa-SourceHeaderLine" /> | ||
</div> | ||
|
||
<div className="aa-PanelSectionSources"> | ||
{recentSearches} | ||
{querySuggestions} | ||
{categories} | ||
{brands} | ||
{faq} | ||
</div> | ||
</Fragment> | ||
)) | ||
) : ( | ||
<div className="aa-NoResultsAdvices"> | ||
<ul className="aa-NoResultsAdvicesList"> | ||
<li>Double-check your spelling</li> | ||
<li>Use fewer keywords</li> | ||
<li>Search for a less specific item</li> | ||
<li>Try navigate using on the of the popular categories</li> | ||
</ul> | ||
</div> | ||
)} | ||
|
||
{!state.query && ( | ||
<div className="aa-PanelSection--popular">{popular}</div> | ||
)} | ||
</div> | ||
<div className="aa-PanelSection--right"> | ||
{products && ( | ||
<div className="aa-PanelSection--products"> | ||
<div className="aa-PanelSectionSource">{products}</div> | ||
</div> | ||
)} | ||
{articles && ( | ||
<div className="aa-PanelSection--articles"> | ||
<div className="aa-PanelSectionSource">{articles}</div> | ||
</div> | ||
)} | ||
|
||
{quickAccess && ( | ||
<div | ||
className={cx( | ||
'aa-PanelSection--quickAccess aa-PanelSection--zoomable', | ||
hasSourceActiveItem('quickAccessPlugin', state) && | ||
'aa-PanelSection--active' | ||
)} | ||
> | ||
{quickAccess} | ||
</div> | ||
)} | ||
|
||
{!hasResults && ( | ||
<div | ||
className={cx( | ||
'aa-PanelSection--popularCategories aa-PanelSection--zoomable', | ||
hasSourceActiveItem('popularCategoriesPlugin', state) && | ||
'aa-PanelSection--active' | ||
)} | ||
> | ||
{popularCategories} | ||
</div> | ||
)} | ||
</div> | ||
</div> | ||
</div>, | ||
root | ||
); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/** @jsx h */ | ||
import { decode } from 'blurhash'; | ||
import { h } from 'preact'; | ||
import { useEffect, useRef } from 'preact/hooks'; | ||
|
||
export interface BlurhashProps { | ||
hash: string; | ||
width: number; | ||
height: number; | ||
punch?: number; | ||
} | ||
|
||
export function Blurhash({ hash, width, height, punch = 1 }: BlurhashProps) { | ||
const canvasRef = useRef<HTMLCanvasElement>(null); | ||
|
||
useEffect(() => { | ||
const pixels = decode(hash, width, height, punch); | ||
|
||
const ctx = canvasRef.current.getContext('2d'); | ||
const imageData = ctx.createImageData(width, height); | ||
imageData.data.set(pixels); | ||
ctx.putImageData(imageData, 0, 0); | ||
}, [hash, width, height, punch]); | ||
|
||
return ( | ||
<canvas | ||
ref={canvasRef} | ||
height={height} | ||
width={width} | ||
className="aa-BlurhashCanvas" | ||
/> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** @jsx h */ | ||
import { h } from 'preact'; | ||
|
||
import { intersperse } from '../utils'; | ||
|
||
import { ChevronRightIcon } from './Icons'; | ||
|
||
type BreadcrumbProps = { | ||
items: JSX.Element[]; | ||
}; | ||
|
||
export function Breadcrumb({ items }: BreadcrumbProps) { | ||
return ( | ||
<div className="aa-Breadcrumb"> | ||
{intersperse( | ||
items, | ||
<div className="aa-ItemIcon aa-ItemIcon--noBorder aa-FavoriteIcon"> | ||
<ChevronRightIcon /> | ||
</div> | ||
)} | ||
</div> | ||
); | ||
} |
Oops, something went wrong.