Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(specs): add playground #5973

Draft
wants to merge 1 commit into
base: chore/remove-vue-cli
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions specs/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import react from '@astrojs/react';
import { defineConfig } from 'astro/config';

export default defineConfig({
site: 'https://instantsearchjs.netlify.app/',
base: '/specs',
outDir: '../website/specs',
integrations: [react()],
vite: {
ssr: {
noExternal: [
'@codesandbox/sandpack-react',
'@codesandbox/sandpack-themes',
'@codesandbox/sandpack-client',
],
},
},
});
6 changes: 5 additions & 1 deletion specs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
"devDependencies": {
"@types/node": "18.11.13",
"astro": "4.0.4",
"@astrojs/react": "3.0.8",
"instantsearch.css": "8.1.0",
"sass": "1.56.2"
"sass": "1.56.2",
"@codesandbox/sandpack-react": "2.10.0",
"@codesandbox/sandpack-themes": "2.0.21",
"dedent": "1.5.1"
}
}
199 changes: 199 additions & 0 deletions specs/src/components/Sandbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
/* eslint-disable react/react-in-jsx-scope */
import { Sandpack } from '@codesandbox/sandpack-react';
import { githubLight } from '@codesandbox/sandpack-themes';
import dedent from 'dedent';

const settings = {
js: {
html: /* HTML */ `
<style>
body {
font-family: sans-serif;
}
</style>
<div id="custom"></div>
<div id="searchbox"></div>
<div id="hits"></div>
`,
preamble: /* JS */ `
import 'instantsearch.css/themes/satellite-min.css';
import algoliasearch from 'algoliasearch/lite';
import instantsearch from 'instantsearch.js';
import { history } from 'instantsearch.js/es/lib/routers';
import { searchBox, hits } from 'instantsearch.js/es/widgets';
import { createWidgets } from './widget.ts';

const search = instantsearch({
indexName: 'instant_search',
searchClient: algoliasearch('latency', '6be0576ff61c053d5f9a3225e2a90f76'),
future: {
preserveSharedStateOnUnmount: true,
},
routing: {
router: history({
cleanUrlOnDispose: false,
})
}
});

search.addWidgets([
...createWidgets(document.querySelector('#custom')),
searchBox({
container: '#searchbox',
}),
hits({
container: '#hits',
templates: {
item: (hit, { components }) => components.Highlight({ attribute: 'name', hit }),
},
}),
]);

search.start();
`,
dependencies: {
// TODO: use current version somehow, both locally and in the built website
'instantsearch.js': 'latest',
'instantsearch.css': 'latest',
algoliasearch: 'latest',
},
filename: '/widget.ts',
},
react: {
html: /* HTML */ `
<style>
body {
font-family: sans-serif;
}
</style>
<main id="root"></main>
`,
preamble: /* TSX */ `
import 'instantsearch.css/themes/satellite-min.css';
import React from "react";
import { createRoot } from "react-dom/client";
import algoliasearch from "algoliasearch/lite";
import { history } from "instantsearch.js/es/lib/routers";
import { InstantSearch, SearchBox, Hits, Highlight } from "react-instantsearch";
import { widgets } from "./widget.tsx";

createRoot(document.getElementById('root')).render(
<InstantSearch
indexName="instant_search"
searchClient={algoliasearch('latency', '6be0576ff61c053d5f9a3225e2a90f76')}
future={{
preserveSharedStateOnUnmount: true,
}}
routing={{
router: history({
cleanUrlOnDispose: false,
})
}}
>
{widgets}
<SearchBox />
<Hits hitComponent={Hit}/>
</InstantSearch>
);

function Hit({ hit }) {
return <Highlight hit={hit} attribute="name" />;
}
`,
dependencies: {
react: 'latest',
'react-dom': 'latest',
algoliasearch: 'latest',
'instantsearch.css': 'latest',
'react-instantsearch': 'latest',
},
filename: '/widget.tsx',
},
vue: {
html: /* HTML */ `
<style>
body {
font-family: sans-serif;
}
</style>
<main id="app"></main>
`,
preamble: `
import "instantsearch.css/themes/satellite-min.css";
import Vue from "vue";
import algoliasearch from "algoliasearch/lite";
import { history } from "instantsearch.js/es/lib/routers";
import { AisInstantSearch, AisHits, AisSearchBox } from "vue-instantsearch/vue2/es";
import Widget from "./Widget.vue";

Vue.config.productionTip = false;

new Vue({
render: (h) =>
h(
AisInstantSearch,
{
props: {
searchClient: algoliasearch(
"latency",
"6be0576ff61c053d5f9a3225e2a90f76"
),
indexName: "instant_search",
future: {
preserveSharedStateOnUnmount: true,
},
routing: {
router: history({
cleanUrlOnDispose: false,
})
}
},
},
[h(Widget), h(AisSearchBox), h(AisHits)]
),
}).$mount("#app");
`,
dependencies: {
vue: '2',
algoliasearch: 'latest',
'instantsearch.css': 'latest',
'vue-instantsearch': 'latest',
},
filename: '/Widget.vue',
},
};

export default function Sandbox({
code,
flavor,
}: {
code: string;
flavor: 'react' | 'js' | 'vue';
}) {
const { preamble, html, filename, dependencies } = settings[flavor];
return (
<Sandpack
files={{
'/index.html': {
hidden: true,
code: dedent(html),
},
'/index.js': {
code: dedent(preamble),
},
[filename]: {
code,
},
}}
customSetup={{
dependencies,
entry: '/index.js',
}}
options={{
activeFile: filename,
showNavigator: true,
}}
theme={githubLight}
/>
);
}
22 changes: 21 additions & 1 deletion specs/src/components/WidgetContent.astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
import { Code } from 'astro/components';
import type { WidgetFrontmatter } from '../types';
import ThemeSelector from './ThemeSelector.astro';
import Sandbox from './Sandbox.jsx';
import { getSandpackCssText } from "@codesandbox/sandpack-react";


type Props = {
frontmatter: WidgetFrontmatter;
Expand All @@ -23,7 +26,8 @@ const title = frontmatter.title;
{
frontmatter.info && (
<div class="info">
<p>{frontmatter.info}</p>
{' '}
<p>{frontmatter.info}</p>{' '}
</div>
)
}
Expand Down Expand Up @@ -110,6 +114,22 @@ const title = frontmatter.title;
)
}

{frontmatter.examples ? (
<>
<h3 id="example">Usage</h3>
<!-- TODO: theme is implied dark? -->
<style is:inline set:html={getSandpackCssText()}></style>
{frontmatter.examples.map(({ code, flavor, library }) => (
<div class="example">
<h4>{library}</h4>
<div class="code-output">
<Sandbox code={code} flavor={flavor} client:load />
</div>
</div>
))}
</>
) : null}

<h3 id="css-classes">CSS classes</h3>
{
frontmatter.classes ? (
Expand Down
1 change: 1 addition & 0 deletions specs/src/env.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/// <reference path="../.astro/types.d.ts" />
// / <reference types="astro/client" />
53 changes: 53 additions & 0 deletions specs/src/pages/widgets/breadcrumb.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,57 @@ translations:
- name: separatorText
default: '" > "'
description: The text for the breadcrumb’s separator.
examples:
- flavor: js
library: instantsearch.js
code: |
import { breadcrumb } from 'instantsearch.js/es/widgets';

export const createWidgets = (container) => [
breadcrumb({
container,
attributes: [
'hierarchicalCategories.lvl0',
'hierarchicalCategories.lvl1',
'hierarchicalCategories.lvl2',
],
}),
];
- flavor: react
library: react-instantsearch
code: |
import React from 'react';
import { Breadcrumb } from 'react-instantsearch';

export const widgets = (
<Breadcrumb
attributes={[
'hierarchicalCategories.lvl0',
'hierarchicalCategories.lvl1',
'hierarchicalCategories.lvl2',
]}
/>
);
- flavor: vue
library: vue-instantsearch
code: |
<template>
<ais-breadcrumb
:attributes="[
'hierarchicalCategories.lvl0',
'hierarchicalCategories.lvl1',
'hierarchicalCategories.lvl2',
]"
/>
</template>

<script>
import { AisBreadcrumb } from 'vue-instantsearch';

export default {
components: {
AisBreadcrumb,
},
};
</script>
---