Skip to content

Commit

Permalink
docs(examples): add Vue 3 example (#576)
Browse files Browse the repository at this point in the history
  • Loading branch information
francoischalifour authored May 6, 2021
1 parent 2b37a56 commit 1bb20ac
Show file tree
Hide file tree
Showing 12 changed files with 420 additions and 61 deletions.
3 changes: 2 additions & 1 deletion .codesandbox/ci.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"/examples/recently-viewed-items",
"/examples/starter-algolia",
"/examples/starter",
"/examples/voice-search"
"/examples/voice-search",
"/examples/vue"
],
"node": "14"
}
Empty file added examples/vue/README.md
Empty file.
6 changes: 6 additions & 0 deletions examples/vue/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Parcel picks the `source` field of the monorepo packages and thus doesn't
// apply the Babel config. We therefore need to manually override the constants
// in the app, as well as the React pragmas.
// See https://twitter.com/devongovett/status/1134231234605830144
(global as any).__DEV__ = process.env.NODE_ENV !== 'production';
(global as any).__TEST__ = false;
Binary file added examples/vue/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions examples/vue/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<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>Vue | Autocomplete</title>
</head>

<body>
<div id="app"></div>

<script src="env.ts"></script>
<script src="src/main.js"></script>
</body>
</html>
27 changes: 27 additions & 0 deletions examples/vue/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "@algolia/autocomplete-example-vue",
"description": "Autocomplete with Vue",
"version": "1.0.0",
"private": true,
"license": "MIT",
"scripts": {
"build": "parcel build index.html",
"start": "parcel index.html"
},
"dependencies": {
"@algolia/autocomplete-js": "1.0.0",
"@algolia/autocomplete-theme-classic": "1.0.0",
"algoliasearch": "4.9.1",
"vue": "3.0.11"
},
"devDependencies": {
"@algolia/client-search": "4.9.1",
"@parcel/transformer-vue": "2.0.0-beta.2",
"parcel": "2.0.0-beta.2"
},
"keywords": [
"algolia",
"autocomplete",
"javascript"
]
}
72 changes: 72 additions & 0 deletions examples/vue/src/App.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<template>
<div class="container">
<div id="autocomplete" />
</div>
</template>

<script>
import { h, Fragment, render, onMounted } from 'vue';
import { autocomplete, getAlgoliaResults } from '@algolia/autocomplete-js';
import algoliasearch from 'algoliasearch/lite';
import '@algolia/autocomplete-theme-classic';
import { createElement } from './adapter';
import ProductItem from './ProductItem.vue';
const appId = 'latency';
const apiKey = '6be0576ff61c053d5f9a3225e2a90f76';
const searchClient = algoliasearch(appId, apiKey);
export default {
name: 'App',
setup() {
onMounted(() => {
autocomplete({
container: '#autocomplete',
placeholder: 'Search',
getSources({ query }) {
return [
{
sourceId: 'products',
getItems() {
return getAlgoliaResults({
searchClient,
queries: [
{
indexName: 'instant_search',
query,
},
],
});
},
templates: {
item({ item, components }) {
return (
<ProductItem item={item} highlight={components.Highlight} />
);
},
},
},
];
},
renderer: {
createElement,
Fragment,
},
render({ children }, root) {
render(children, root);
},
});
});
},
};
</script>

<style>
.container {
margin: 0 auto;
max-width: 640px;
width: 100%;
}
</style>
64 changes: 64 additions & 0 deletions examples/vue/src/ProductItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<template>
<div class="aa-ItemWrapper">
<div class="aa-ItemContent">
<div class="aa-ItemIcon aa-ItemIcon--picture aa-ItemIcon--alignTop">
<img :src="item.image" :alt="item.name" width="40" height="40" />
</div>
<div className="aa-ItemContentBody">
<div class="aa-ItemContentTitle">
<component :is="highlight" :hit="item" attribute="name" />
</div>
<div class="aa-ItemContentDescription">
By <strong>{{ item.brand }}</strong> in
<strong>{{ item.categories[0] }}</strong>
</div>
</div>
</div>
<div class="aa-ItemActions">
<button
class="aa-ItemActionButton aa-TouchOnly aa-ActiveOnly"
type="button"
title="Select"
>
<svg fill="currentColor" viewBox="0 0 24 24" width="20" height="20">
<path
d="M18.984 6.984h2.016v6h-15.188l3.609 3.609-1.406 1.406-6-6 6-6 1.406 1.406-3.609 3.609h13.172v-4.031z"
/>
</svg>
</button>
<button
class="aa-ItemActionButton"
type="button"
title="Add to cart"
@click="onAddToCart"
>
<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor">
<path
d="M19 5h-14l1.5-2h11zM21.794 5.392l-2.994-3.992c-0.196-0.261-0.494-0.399-0.8-0.4h-12c-0.326 0-0.616 0.156-0.8 0.4l-2.994 3.992c-0.043 0.056-0.081 0.117-0.111 0.182-0.065 0.137-0.096 0.283-0.095 0.426v14c0 0.828 0.337 1.58 0.879 2.121s1.293 0.879 2.121 0.879h14c0.828 0 1.58-0.337 2.121-0.879s0.879-1.293 0.879-2.121v-14c0-0.219-0.071-0.422-0.189-0.585-0.004-0.005-0.007-0.010-0.011-0.015zM4 7h16v13c0 0.276-0.111 0.525-0.293 0.707s-0.431 0.293-0.707 0.293h-14c-0.276 0-0.525-0.111-0.707-0.293s-0.293-0.431-0.293-0.707zM15 10c0 0.829-0.335 1.577-0.879 2.121s-1.292 0.879-2.121 0.879-1.577-0.335-2.121-0.879-0.879-1.292-0.879-2.121c0-0.552-0.448-1-1-1s-1 0.448-1 1c0 1.38 0.561 2.632 1.464 3.536s2.156 1.464 3.536 1.464 2.632-0.561 3.536-1.464 1.464-2.156 1.464-3.536c0-0.552-0.448-1-1-1s-1 0.448-1 1z"
/>
</svg>
</button>
</div>
</div>
</template>

<script lang="ts">
export default {
props: {
item: Object,
highlight: Function,
},
setup() {
function onAddToCart(event) {
event.preventDefault();
event.stopPropagation();
console.log('Add to cart');
}
return {
onAddToCart,
};
},
};
</script>
20 changes: 20 additions & 0 deletions examples/vue/src/adapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { h } from 'vue';

export function createElement(type, props, ...children) {
const adaptedProps = Object.entries(props || {}).reduce(
(acc, [key, value]) => {
// Vue 3 accepts lower-case event names so we need to transform props like
// `onMouseMove` to `onMousemove`.
const property =
key[0] === 'o' && key[1] === 'n'
? key.slice(0, 3) + key.slice(3).toLowerCase()
: key;

acc[property] = value;
return acc;
},
{}
);

return h(type, adaptedProps, ...children);
}
5 changes: 5 additions & 0 deletions examples/vue/src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createApp } from 'vue';

import App from './App.vue';

createApp(App).mount('#app');
14 changes: 14 additions & 0 deletions examples/vue/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
* {
box-sizing: border-box;
}

body {
background-color: rgb(244, 244, 249);
color: rgb(65, 65, 65);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
padding: 1rem;
}
Loading

0 comments on commit 1bb20ac

Please sign in to comment.