Skip to content

Commit

Permalink
chore(javascript): add browser playground with instantsearch (#3687)
Browse files Browse the repository at this point in the history
  • Loading branch information
shortcuts authored Sep 11, 2024
1 parent a5319e4 commit 2b5b873
Show file tree
Hide file tree
Showing 14 changed files with 4,349 additions and 2,068 deletions.
1 change: 1 addition & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ jobs:
if [[ $diff > 0 ]]; then
echo "Build the custom github actions by running \`yarn workspace scripts build:actions\`"
git status --porcelain ./scripts/ci/actions
fi
exit $diff
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
"workspaces": [
"scripts/",
"playground/javascript/node/",
"playground/javascript/browser/",
"eslint"
],
"scripts": {
"build": "yarn build:eslint && yarn scripts:build",
"build:eslint": "yarn workspace eslint-plugin-automation-custom build && yarn install",
"clean": "rm -rf **/dist **/build **/.build **/node_modules **/.gradle **/vendor **/bin **/obj **/__pycache__ || true",
"cli": "yarn workspace scripts start",
Expand Down
23 changes: 12 additions & 11 deletions playground/javascript/browser/index.html
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>

<title>algoliasearch-client-javascript generated clients</title>
<link rel="shortcut icon" href="favicon.png" />

<title>React InstantSearch — Getting started</title>
</head>

<body>
<div class="container">
<h1>algoliasearch-client-javascript generated clients</h1>

<button id="search">Click to search!</button>
<noscript> You need to enable JavaScript to run this app. </noscript>

<div id="results"></div>
</div>
<div id="root"></div>

<script src="../../../clients/algoliasearch-client-javascript/packages/client-search/dist/client-search.umd.js"></script>
<script type="module" src="app.ts"></script>
<script type="module" src="src/index.tsx"></script>
</body>
</html>
28 changes: 21 additions & 7 deletions playground/javascript/browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,30 @@
"version": "0.0.0",
"private": true,
"scripts": {
"start": "parcel index.html"
"build": "yarn clean && BABEL_ENV=parcel parcel build index.html products.html",
"clean": "rm -rf .parcel-cache node_modules dist || true && yarn",
"start": "yarn clean && BABEL_ENV=parcel parcel index.html products.html --port 3001"
},
"dependencies": {
"@algolia/client-common": "link:../../../clients/algoliasearch-client-javascript/packages/client-common",
"@algolia/client-search": "link:../../../clients/algoliasearch-client-javascript/packages/client-search",
"@algolia/requester-browser-xhr": "link:../../../clients/algoliasearch-client-javascript/packages/requester-node-http",
"algoliasearch": "link:../../../clients/algoliasearch-client-javascript/packages/algoliasearch"
"algoliasearch": "link:../../../clients/algoliasearch-client-javascript/packages/algoliasearch",
"instantsearch.css": "8.5.1",
"instantsearch.js": "4.74.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-instantsearch": "7.13.1"
},
"devDependencies": {
"parcel": "2.12.0",
"typescript": "5.5.4"
"@parcel/core": "2.10.0",
"@parcel/packager-raw-url": "2.10.0",
"@parcel/transformer-webmanifest": "2.10.0",
"@types/react": "^18.0.9",
"https-browserify": "^1.0.0",
"parcel": "2.10.0",
"stream-http": "^3.1.0",
"typescript": "5.5.2",
"url": "^0.11.0"
},
"@parcel/resolver-default": {
"packageExports": true
}
}
22 changes: 22 additions & 0 deletions playground/javascript/browser/products.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>

<link rel="shortcut icon" href="favicon.png" />

<title>React InstantSearch — Getting started</title>
</head>

<body>
<noscript> You need to enable JavaScript to run this app. </noscript>

<div id="root"></div>

<script type="module" src="src/products.tsx"></script>
</body>
</html>
168 changes: 168 additions & 0 deletions playground/javascript/browser/src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
body,
h1 {
margin: 0;
padding: 0;
}

body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica,
Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
}

em {
background: cyan;
font-style: normal;
}

.header {
display: flex;
align-items: center;
min-height: 50px;
padding: 0.5rem 1rem;
background-image: linear-gradient(to right, #8e43e7, #00aeff);
color: #fff;
margin-bottom: 1rem;
}

.header a {
color: #fff;
text-decoration: none;
}

.header-title {
font-size: 1.2rem;
font-weight: normal;
}

.header-title::after {
content: ' ▸ ';
padding: 0 0.5rem;
}

.header-subtitle {
font-size: 1.2rem;
}

.container {
max-width: 1200px;
margin: 0 auto;
padding: 1rem;
}

.search-panel {
display: flex;
}

.search-panel__filters {
flex: 1;
}

.search-panel__results {
flex: 3;
}

.searchbox {
margin-bottom: 2rem;
}

.pagination {
margin: 2rem auto;
text-align: center;
}

#related-products,
.ais-Hits--single {
margin-top: 1rem;
}

.ais-Hits--single article {
display: flex;
gap: 1rem;
}

.ais-Hits--single img {
width: 150px;
height: 150px;
object-fit: contain;
flex-shrink: 0;
}

.ais-TrendingItems-item,
.ais-RelatedProducts-item {
background: none !important;
align-items: stretch !important;
padding: 0 !important;
box-shadow: none !important;
}

.ais-TrendingItems-item > div,
.ais-RelatedProducts-item > div {
align-items: start;
background: #fff;
align-items: center;
padding: 1.5rem;
display: flex;
box-shadow: 0 0 0 1px #23263b0d, 0 1px 3px #23263b26;
}

.ais-TrendingItems-item img,
.ais-RelatedProducts-item img {
width: 100%;
height: 100px;
object-fit: contain;
}

.ais-TrendingItems-item article,
.ais-RelatedProducts-item article {
display: flex;
flex-direction: column;
height: 100%;
justify-content: space-between;
}

.ais-TrendingItems-item h2,
.ais-RelatedProducts-item h2 {
display: -webkit-box;
-webkit-line-clamp: 4;
-webkit-box-orient: vertical;
overflow: hidden;
line-height: 1.2;
}

.ais-Carousel-item {
padding: 0.5rem !important;
}

.ais-Carousel-list {
margin: -0.5rem !important;
grid-auto-columns: calc(22% - 0.5rem) !important;
}

.ais-Carousel::before,
.ais-Carousel::after {
position: absolute;
top: 0;
bottom: 0;
width: 0.5rem;
display: block;
background: rgb(255, 255, 255);
content: '';
}

.ais-Carousel::before {
left: -0.5rem;
background: linear-gradient(
90deg,
rgba(255, 255, 255, 1) 0%,
rgba(255, 255, 255, 0) 100%
);
}

.ais-Carousel::after {
right: -0.5rem;
background: linear-gradient(
90deg,
rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 1) 100%
);
}
111 changes: 111 additions & 0 deletions playground/javascript/browser/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { liteClient as algoliasearch } from 'algoliasearch/lite';
import { Hit } from 'instantsearch.js';
import React from 'react';
import {
Configure,
Highlight,
Hits,
InstantSearch,
Pagination,
RefinementList,
SearchBox,
TrendingItems,
Carousel,
} from 'react-instantsearch';

import { Panel } from './Panel';

import './App.css';
import 'instantsearch.css/themes/satellite.css';

const searchClient = algoliasearch(
'latency',
'6be0576ff61c053d5f9a3225e2a90f76'
);

export function App() {
return (
<div>
<header className="header">
<h1 className="header-title">
<a href="/">Getting started</a>
</h1>
<p className="header-subtitle">
using{' '}
<a href="https://github.com/algolia/instantsearch/tree/master/packages/react-instantsearch">
React InstantSearch
</a>
</p>
</header>

<div className="container">
<InstantSearch
searchClient={searchClient}
indexName="instant_search"
insights={true}
>
<Configure hitsPerPage={8} />
<div className="search-panel">
<div className="search-panel__filters">
<Panel header="brand">
<RefinementList attribute="brand" />
</Panel>
</div>

<div className="search-panel__results">
<SearchBox placeholder="" className="searchbox" />
<Hits hitComponent={HitComponent} />

<div className="pagination">
<Pagination />
</div>
<div>
<TrendingItems
itemComponent={ItemComponent}
limit={6}
layoutComponent={Carousel}
/>
</div>
</div>
</div>
</InstantSearch>
</div>
</div>
);
}

type HitType = Hit<{
image: string;
name: string;
description: string;
}>;

function HitComponent({ hit }: { hit: HitType }) {
return (
<article>
<h1>
<a href={`/products.html?pid=${hit.objectID}`}>
<Highlight attribute="name" hit={hit} />
</a>
</h1>
<p>
<Highlight attribute="description" hit={hit} />
</p>
<a href={`/products.html?pid=${hit.objectID}`}>See product</a>
</article>
);
}

function ItemComponent({ item }: { item: Hit }) {
return (
<div>
<article>
<div>
<img src={item.image} />
<h2>{item.name}</h2>
</div>
<a href={`/products.html?pid=${item.objectID}`}>See product</a>
</article>
</div>
);
}
Loading

0 comments on commit 2b5b873

Please sign in to comment.