<html lang="en">
<head></head>
<body>

<form id="mainForm" method="post" action="https://stackblitz.com/run" target="_self">
<input type="hidden" name="project[files][README.md]" value="# Autocomplete playground

This example shows a full-featured Autocomplete example with various plugins.

&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;capture.png?raw=true&quot; alt=&quot;A capture of the Autocomplete playground&quot; /&gt;&lt;/p&gt;

## Demo

[Access the demo](https://codesandbox.io/s/github/algolia/autocomplete/tree/next/examples/playground)

## How to run this example locally

### 1. Clone this repository

```sh
git clone git@github.com:algolia/autocomplete.git
```

### 2. Install the dependencies and run the server

```sh
yarn
yarn workspace @algolia/autocomplete-example-playground start
```

Alternatively, you may use npm:

```sh
cd examples/playground
npm install
npm start
```

Open &lt;http://localhost:1234&gt; to see your app.">
<input type="hidden" name="project[files][app.tsx]" value="/** @jsxRuntime classic */
/** @jsx h */
import {
  autocomplete,
  AutocompleteComponents,
  getAlgoliaResults,
  AutocompleteInsightsApi,
} from &#39;@algolia/autocomplete-js&#39;;
import { createQuerySuggestionsPlugin } from &#39;@algolia/autocomplete-plugin-query-suggestions&#39;;
import { createLocalStorageRecentSearchesPlugin } from &#39;@algolia/autocomplete-plugin-recent-searches&#39;;
import algoliasearch from &#39;algoliasearch/lite&#39;;
import { h, Fragment } from &#39;preact&#39;;

import &#39;@algolia/autocomplete-theme-classic&#39;;

import { createCategoriesPlugin } from &#39;./categoriesPlugin&#39;;
import { shortcutsPlugin } from &#39;./shortcutsPlugin&#39;;
import { ProductRecord, ProductHit } from &#39;./types&#39;;

const appId = &#39;latency&#39;;
const apiKey = &#39;6be0576ff61c053d5f9a3225e2a90f76&#39;;
const searchClient = algoliasearch(appId, apiKey);

const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({
  key: &#39;search&#39;,
  limit: 3,
});
const querySuggestionsPlugin = createQuerySuggestionsPlugin({
  searchClient,
  indexName: &#39;instant_search_demo_query_suggestions&#39;,
  getSearchParams({ state }) {
    return recentSearchesPlugin.data.getAlgoliaSearchParams({
      hitsPerPage: state.query ? 5 : 10,
    });
  },
  categoryAttribute: [
    &#39;instant_search&#39;,
    &#39;facets&#39;,
    &#39;exact_matches&#39;,
    &#39;categories&#39;,
  ],
  categoriesPerItem: 2,
});
const categoriesPlugin = createCategoriesPlugin({ searchClient });

autocomplete&lt;ProductHit&gt;({
  container: &#39;#autocomplete&#39;,
  placeholder: &#39;Search&#39;,
  debug: true,
  openOnFocus: true,
  insights: true,
  plugins: [
    shortcutsPlugin,
    recentSearchesPlugin,
    querySuggestionsPlugin,
    categoriesPlugin,
  ],
  getSources({ query, state }) {
    if (!query) {
      return [];
    }

    return [
      {
        sourceId: &#39;products&#39;,
        getItems() {
          return getAlgoliaResults&lt;ProductRecord&gt;({
            searchClient,
            queries: [
              {
                indexName: &#39;instant_search&#39;,
                query,
                params: {
                  attributesToSnippet: [&#39;name:10&#39;, &#39;description:35&#39;],
                  snippetEllipsisText: &#39;…&#39;,
                },
              },
            ],
            transformResponse({ hits }) {
              const [bestBuyHits] = hits;

              return bestBuyHits.map((hit) =&gt; ({
                ...hit,
                comments: hit.popularity % 100,
                sale: hit.free_shipping,
                // eslint-disable-next-line @typescript-eslint/camelcase
                sale_price: hit.free_shipping
                  ? (hit.price - hit.price / 10).toFixed(2)
                  : hit.price.toString(),
              }));
            },
          });
        },
        templates: {
          header() {
            return (
              &lt;Fragment&gt;
                &lt;span className=&quot;aa-SourceHeaderTitle&quot;&gt;Products&lt;/span&gt;
                &lt;div className=&quot;aa-SourceHeaderLine&quot; /&gt;
              &lt;/Fragment&gt;
            );
          },
          item({ item, components }) {
            return (
              &lt;ProductItem
                hit={item}
                components={components}
                insights={state.context.algoliaInsightsPlugin.insights}
              /&gt;
            );
          },
          noResults() {
            return &#39;No products for this query.&#39;;
          },
        },
      },
    ];
  },
});

type ProductItemProps = {
  hit: ProductHit;
  insights: AutocompleteInsightsApi;
  components: AutocompleteComponents;
};

function ProductItem({ hit, insights, components }: ProductItemProps) {
  return (
    &lt;a href={hit.url} className=&quot;aa-ItemLink&quot;&gt;
      &lt;div className=&quot;aa-ItemContent&quot;&gt;
        &lt;div className=&quot;aa-ItemIcon aa-ItemIcon--picture aa-ItemIcon--alignTop&quot;&gt;
          &lt;img src={hit.image} alt={hit.name} width=&quot;40&quot; height=&quot;40&quot; /&gt;
        &lt;/div&gt;

        &lt;div className=&quot;aa-ItemContentBody&quot;&gt;
          &lt;div className=&quot;aa-ItemContentTitle&quot;&gt;
            &lt;components.Snippet hit={hit} attribute=&quot;name&quot; /&gt;
          &lt;/div&gt;
          &lt;div className=&quot;aa-ItemContentDescription&quot;&gt;
            By &lt;strong&gt;{hit.brand}&lt;/strong&gt; in{&#39; &#39;}
            &lt;strong&gt;{hit.categories[0]}&lt;/strong&gt;
          &lt;/div&gt;

          &lt;div
            className=&quot;aa-ItemContentDescription&quot;
            style={{
              display: &#39;grid&#39;,
              gridAutoFlow: &#39;column&#39;,
              justifyContent: &#39;start&#39;,
              alignItems: &#39;center&#39;,
              gap: 8,
            }}
          &gt;
            {hit.rating &gt; 0 &amp;&amp; (
              &lt;div className=&quot;aa-ItemContentDescription&quot;&gt;
                &lt;div
                  style={{
                    color: &#39;rgba(var(--aa-muted-color-rgb), 0.5)&#39;,
                  }}
                &gt;
                  {Array.from({ length: 5 }, (_value, index) =&gt; {
                    const isFilled = hit.rating &gt;= index + 1;

                    return (
                      &lt;svg
                        key={index}
                        width=&quot;16&quot;
                        height=&quot;16&quot;
                        viewBox=&quot;0 0 24 24&quot;
                        fill={isFilled ? &#39;currentColor&#39; : &#39;none&#39;}
                        stroke=&quot;currentColor&quot;
                        strokeWidth=&quot;1&quot;
                        strokeLinecap=&quot;round&quot;
                        strokeLinejoin=&quot;round&quot;
                      &gt;
                        &lt;polygon points=&quot;12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2&quot; /&gt;
                      &lt;/svg&gt;
                    );
                  })}
                &lt;/div&gt;
              &lt;/div&gt;
            )}
            &lt;div
              style={{
                display: &#39;grid&#39;,
                gridAutoFlow: &#39;column&#39;,
                justifyContent: &#39;start&#39;,
                alignItems: &#39;center&#39;,
                gap: 4,
              }}
            &gt;
              &lt;svg
                width=&quot;16&quot;
                height=&quot;16&quot;
                viewBox=&quot;0 0 24 24&quot;
                fill=&quot;none&quot;
                stroke=&quot;currentColor&quot;
                strokeWidth=&quot;2&quot;
                strokeLinecap=&quot;round&quot;
                strokeLinejoin=&quot;round&quot;
                style={{
                  position: &#39;relative&#39;,
                  top: &#39;1px&#39;,
                }}
              &gt;
                &lt;path d=&quot;M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z&quot;&gt;&lt;/path&gt;
              &lt;/svg&gt;
              &lt;span&gt;{hit.comments.toLocaleString()}&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;

          &lt;div
            style={{
              display: &#39;flex&#39;,
              alignItems: &#39;center&#39;,
              gap: 8,
            }}
          &gt;
            &lt;div
              style={{
                display: &#39;grid&#39;,
                gridAutoFlow: &#39;column&#39;,
                justifyContent: &#39;start&#39;,
                alignItems: &#39;center&#39;,
                gap: 4,
              }}
            &gt;
              &lt;div&gt;
                &lt;span
                  style={{
                    color: &#39;#000&#39;,
                    fontSize: &#39;0.9em&#39;,
                    fontWeight: &#39;bold&#39;,
                  }}
                &gt;
                  ${hit.sale_price.toLocaleString()}
                &lt;/span&gt;{&#39; &#39;}
                {hit.sale &amp;&amp; (
                  &lt;span
                    style={{
                      color: &#39;rgb(var(--aa-muted-color-rgb))&#39;,
                      fontSize: &#39;0.9em&#39;,
                      textDecoration: &#39;line-through&#39;,
                    }}
                  &gt;
                    ${hit.price.toLocaleString()}
                  &lt;/span&gt;
                )}
              &lt;/div&gt;
              {hit.sale &amp;&amp; (
                &lt;span
                  style={{
                    textTransform: &#39;uppercase&#39;,
                    fontSize: &#39;0.64em&#39;,
                    background: &#39;#539753&#39;,
                    color: &#39;#fff&#39;,
                    fontWeight: 600,
                    borderRadius: 9999,
                    padding: &#39;2px 6px&#39;,
                    display: &#39;inline-block&#39;,
                    lineHeight: &#39;1.25em&#39;,
                  }}
                &gt;
                  On sale
                &lt;/span&gt;
              )}
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div className=&quot;aa-ItemActions&quot;&gt;
        &lt;button
          className=&quot;aa-ItemActionButton aa-DesktopOnly aa-ActiveOnly&quot;
          type=&quot;button&quot;
          title=&quot;Select&quot;
          disabled={true}
          style={{ pointerEvents: &#39;none&#39; }}
        &gt;
          &lt;svg viewBox=&quot;0 0 24 24&quot; fill=&quot;currentColor&quot;&gt;
            &lt;path d=&quot;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&quot; /&gt;
          &lt;/svg&gt;
        &lt;/button&gt;
        &lt;button
          className=&quot;aa-ItemActionButton&quot;
          type=&quot;button&quot;
          title=&quot;Add to cart&quot;
          onClick={(event) =&gt; {
            event.preventDefault();
            event.stopPropagation();

            insights.convertedObjectIDsAfterSearch({
              eventName: &#39;Added to cart&#39;,
              index: hit.__autocomplete_indexName,
              objectIDs: [hit.objectID],
              queryID: hit.__autocomplete_queryID,
            });
          }}
        &gt;
          &lt;svg viewBox=&quot;0 0 24 24&quot; fill=&quot;currentColor&quot;&gt;
            &lt;path d=&quot;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&quot; /&gt;
          &lt;/svg&gt;
        &lt;/button&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  );
}
">
<input type="hidden" name="project[files][capture.png]" value="https://pkg.pr.new/template/505261ab-cb91-41e5-8a86-6d432e0d4bf3">
<input type="hidden" name="project[files][categoriesPlugin.tsx]" value="/** @jsxRuntime classic */
/** @jsx h */
import { AutocompletePlugin, getAlgoliaFacets } from &#39;@algolia/autocomplete-js&#39;;
import { SearchClient } from &#39;algoliasearch/lite&#39;;
import { h, Fragment } from &#39;preact&#39;;

type CategoryRecord = {
  label: string;
  count: number;
};

type CreateCategoriesPluginProps = {
  searchClient: SearchClient;
};

export function createCategoriesPlugin({
  searchClient,
}: CreateCategoriesPluginProps): AutocompletePlugin&lt;CategoryRecord, undefined&gt; {
  return {
    getSources({ query }) {
      return [
        {
          sourceId: &#39;categoriesPlugin&#39;,
          getItems() {
            return getAlgoliaFacets({
              searchClient,
              queries: [
                {
                  indexName: &#39;instant_search&#39;,
                  facet: &#39;categories&#39;,
                  params: {
                    facetQuery: query,
                    maxFacetHits: query ? 3 : 5,
                  },
                },
              ],
            });
          },
          templates: {
            header() {
              return (
                &lt;Fragment&gt;
                  &lt;span className=&quot;aa-SourceHeaderTitle&quot;&gt;Categories&lt;/span&gt;
                  &lt;div className=&quot;aa-SourceHeaderLine&quot; /&gt;
                &lt;/Fragment&gt;
              );
            },
            item({ item, components }) {
              return (
                &lt;div className=&quot;aa-ItemWrapper&quot;&gt;
                  &lt;div className=&quot;aa-ItemContent&quot;&gt;
                    &lt;div className=&quot;aa-ItemIcon aa-ItemIcon--noBorder&quot;&gt;
                      &lt;svg
                        viewBox=&quot;0 0 24 24&quot;
                        width=&quot;18&quot;
                        height=&quot;18&quot;
                        fill=&quot;none&quot;
                        stroke=&quot;currentColor&quot;
                        strokeWidth=&quot;2&quot;
                        strokeLinecap=&quot;round&quot;
                        strokeLinejoin=&quot;round&quot;
                      &gt;
                        &lt;path d=&quot;M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z&quot; /&gt;
                        &lt;polyline points=&quot;3.27 6.96 12 12.01 20.73 6.96&quot; /&gt;
                        &lt;line x1=&quot;12&quot; y1=&quot;22.08&quot; x2=&quot;12&quot; y2=&quot;12&quot; /&gt;
                      &lt;/svg&gt;
                    &lt;/div&gt;

                    &lt;div className=&quot;aa-ItemContentBody&quot;&gt;
                      &lt;div className=&quot;aa-ItemContentTitle&quot;&gt;
                        &lt;components.Highlight hit={item} attribute=&quot;label&quot; /&gt;
                      &lt;/div&gt;
                    &lt;/div&gt;
                  &lt;/div&gt;
                &lt;/div&gt;
              );
            },
          },
        },
      ];
    },
  };
}
">
<input type="hidden" name="project[files][darkMode.ts]" value="function initTheme() {
  if (isDarkThemeSelected()) {
    applyDarkTheme();
  } else {
    applyLightTheme();
  }
}

export function isDarkThemeSelected() {
  return localStorage.getItem(&#39;darkMode&#39;) === &#39;dark&#39;;
}

function applyDarkTheme() {
  document.body.setAttribute(&#39;data-theme&#39;, &#39;dark&#39;);
  localStorage.setItem(&#39;darkMode&#39;, &#39;dark&#39;);
}

function applyLightTheme() {
  document.body.removeAttribute(&#39;data-theme&#39;);
  localStorage.removeItem(&#39;darkMode&#39;);
}

export function toggleTheme() {
  if (isDarkThemeSelected()) {
    applyLightTheme();
  } else {
    applyDarkTheme();
  }
}

initTheme();
">
<input type="hidden" name="project[files][env.ts]" value="import * as preact from &#39;preact&#39;;

// Parcel picks the `source` field of the monorepo packages and thus doesn&#39;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 !== &#39;production&#39;;
(global as any).__TEST__ = false;
(global as any).h = preact.h;
(global as any).React = preact;
">
<input type="hidden" name="project[files][favicon.png]" value="https://pkg.pr.new/template/5b39d578-60e6-4056-a74f-84873513cc2e">
<input type="hidden" name="project[files][index.html]" value="&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;

    &lt;link rel=&quot;shortcut icon&quot; href=&quot;favicon.png&quot; type=&quot;image/x-icon&quot; /&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;style.css&quot; /&gt;

    &lt;title&gt;Playground | Autocomplete&lt;/title&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;div class=&quot;container&quot;&gt;
      &lt;div id=&quot;autocomplete&quot;&gt;&lt;/div&gt;

      &lt;div class=&quot;ais-Hits&quot;&gt;
        &lt;ul class=&quot;ais-Hits-list&quot;&gt;
          &lt;li class=&quot;ais-Hits-item&quot;&gt;&lt;/li&gt;
          &lt;li class=&quot;ais-Hits-item&quot;&gt;&lt;/li&gt;
          &lt;li class=&quot;ais-Hits-item&quot;&gt;&lt;/li&gt;
        &lt;/ul&gt;
        &lt;ul class=&quot;ais-Hits-list&quot;&gt;
          &lt;li class=&quot;ais-Hits-item&quot;&gt;&lt;/li&gt;
          &lt;li class=&quot;ais-Hits-item&quot;&gt;&lt;/li&gt;
          &lt;li class=&quot;ais-Hits-item&quot;&gt;&lt;/li&gt;
        &lt;/ul&gt;
        &lt;ul class=&quot;ais-Hits-list&quot;&gt;
          &lt;li class=&quot;ais-Hits-item&quot;&gt;&lt;/li&gt;
          &lt;li class=&quot;ais-Hits-item&quot;&gt;&lt;/li&gt;
          &lt;li class=&quot;ais-Hits-item&quot;&gt;&lt;/li&gt;
        &lt;/ul&gt;
        &lt;ul class=&quot;ais-Hits-list&quot;&gt;
          &lt;li class=&quot;ais-Hits-item&quot;&gt;&lt;/li&gt;
          &lt;li class=&quot;ais-Hits-item&quot;&gt;&lt;/li&gt;
          &lt;li class=&quot;ais-Hits-item&quot;&gt;&lt;/li&gt;
        &lt;/ul&gt;
        &lt;ul class=&quot;ais-Hits-list&quot;&gt;
          &lt;li class=&quot;ais-Hits-item&quot;&gt;&lt;/li&gt;
          &lt;li class=&quot;ais-Hits-item&quot;&gt;&lt;/li&gt;
          &lt;li class=&quot;ais-Hits-item&quot;&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;script type=&quot;module&quot; src=&quot;env.ts&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;module&quot; src=&quot;darkMode.ts&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;module&quot; src=&quot;app.tsx&quot;&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
">
<input type="hidden" name="project[files][package.json]" value="{&quot;name&quot;:&quot;@algolia/autocomplete-example-playground&quot;,&quot;description&quot;:&quot;Autocomplete playground&quot;,&quot;version&quot;:&quot;1.19.8&quot;,&quot;private&quot;:true,&quot;license&quot;:&quot;MIT&quot;,&quot;scripts&quot;:{&quot;dev&quot;:&quot;vite&quot;,&quot;start&quot;:&quot;vite&quot;,&quot;build&quot;:&quot;vite build&quot;},&quot;dependencies&quot;:{&quot;@algolia/autocomplete-js&quot;:&quot;https://pkg.pr.new/algolia/autocomplete/@algolia/autocomplete-js@f9ecdbc&quot;,&quot;@algolia/autocomplete-plugin-query-suggestions&quot;:&quot;https://pkg.pr.new/algolia/autocomplete/@algolia/autocomplete-plugin-query-suggestions@f9ecdbc&quot;,&quot;@algolia/autocomplete-plugin-recent-searches&quot;:&quot;https://pkg.pr.new/algolia/autocomplete/@algolia/autocomplete-plugin-recent-searches@f9ecdbc&quot;,&quot;@algolia/autocomplete-preset-algolia&quot;:&quot;https://pkg.pr.new/algolia/autocomplete/@algolia/autocomplete-preset-algolia@f9ecdbc&quot;,&quot;@algolia/autocomplete-theme-classic&quot;:&quot;https://pkg.pr.new/algolia/autocomplete/@algolia/autocomplete-theme-classic@f9ecdbc&quot;,&quot;@algolia/client-search&quot;:&quot;4.16.0&quot;,&quot;algoliasearch&quot;:&quot;4.16.0&quot;,&quot;preact&quot;:&quot;10.13.2&quot;,&quot;search-insights&quot;:&quot;^2.15.0&quot;},&quot;devDependencies&quot;:{&quot;vite&quot;:&quot;5.0.7&quot;},&quot;keywords&quot;:[&quot;algolia&quot;,&quot;autocomplete&quot;,&quot;javascript&quot;]}">
<input type="hidden" name="project[files][shortcutsPlugin.tsx]" value="import { AutocompletePlugin } from &#39;@algolia/autocomplete-js&#39;;

import { toggleTheme, isDarkThemeSelected } from &#39;./darkMode&#39;;

type DarkModeItem = {
  label: string;
};

export const shortcutsPlugin: AutocompletePlugin&lt;DarkModeItem, undefined&gt; = {
  getSources({ query }) {
    if (query !== &#39;/&#39; &amp;&amp; query !== &#39;dark&#39; &amp;&amp; query !== &#39;light&#39;) {
      return [];
    }

    return [
      {
        sourceId: &#39;shortcutsPlugin&#39;,
        getItems() {
          return [
            {
              label: &#39;Toggle dark mode&#39;,
            },
          ];
        },
        onSelect({ setIsOpen, setQuery, refresh }) {
          toggleTheme();
          setQuery(&#39;&#39;);
          setIsOpen(true);
          refresh();
        },
        templates: {
          header({ createElement, Fragment }) {
            return createElement(
              Fragment,
              {},
              createElement(
                &#39;span&#39;,
                { className: &#39;aa-SourceHeaderTitle&#39; },
                &#39;Shortcuts&#39;
              ),
              createElement(&#39;div&#39;, { className: &#39;aa-SourceHeaderLine&#39; })
            );
          },
          item({ item, createElement }) {
            const darkIcon = createElement(
              &#39;svg&#39;,
              {
                xmlns: &#39;http://www.w3.org/2000/svg&#39;,
                fill: &#39;none&#39;,
                viewBox: &#39;0 0 24 24&#39;,
                stroke: &#39;currentColor&#39;,
              },
              createElement(&#39;path&#39;, {
                strokeLinecap: &#39;round&#39;,
                strokeLinejoin: &#39;round&#39;,
                strokeWidth: 2,
                d: &#39;M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z&#39;,
              })
            );
            const lightIcon = createElement(
              &#39;svg&#39;,
              {
                xmlns: &#39;http://www.w3.org/2000/svg&#39;,
                fill: &#39;none&#39;,
                viewBox: &#39;0 0 24 24&#39;,
                stroke: &#39;currentColor&#39;,
              },
              createElement(&#39;path&#39;, {
                strokeLinecap: &#39;round&#39;,
                strokeLinejoin: &#39;round&#39;,
                strokeWidth: 2,
                d: &#39;M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z&#39;,
              })
            );

            return createElement(
              &#39;div&#39;,
              { className: &#39;aa-ItemWrapper&#39; },
              createElement(
                &#39;div&#39;,
                { className: &#39;aa-ItemContent&#39; },
                createElement(
                  &#39;div&#39;,
                  { className: &#39;aa-ItemIcon&#39; },
                  isDarkThemeSelected() ? lightIcon : darkIcon
                ),
                createElement(
                  &#39;div&#39;,
                  { className: &#39;aa-ItemContentBody&#39; },
                  createElement(
                    &#39;div&#39;,
                    { className: &#39;aa-ItemContentTitle&#39; },
                    item.label
                  )
                )
              )
            );
          },
        },
      },
    ];
  },
};
">
<input type="hidden" name="project[files][style.css]" value="* {
  box-sizing: border-box;
}

body {
  background-color: rgb(244, 244, 249);
  color: rgb(65, 65, 65);
  font-family: -apple-system, BlinkMacSystemFont, &#39;Segoe UI&#39;, &#39;Roboto&#39;, &#39;Oxygen&#39;,
    &#39;Ubuntu&#39;, &#39;Cantarell&#39;, &#39;Fira Sans&#39;, &#39;Droid Sans&#39;, &#39;Helvetica Neue&#39;,
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  padding: 1rem;
}

.container {
  margin: 0 auto;
  max-width: 640px;
  width: 100%;
}

body[data-theme=&#39;dark&#39;] {
  background-color: rgb(0, 0, 0);
  color: rgb(183, 192, 199);
}

.ais-Hits {
  margin-top: 1rem;
}

.ais-Hits-list {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr 1fr 1fr;
  list-style: none;
  padding: 0;
}

.ais-Hits-item {
  background: rgba(128, 126, 163, 0.08);
  border-radius: 5px;
  height: 100%;
  min-height: 202px;
  padding: 1rem;
  width: 100%;
}
">
<input type="hidden" name="project[files][vite.config.mjs]" value="import { defineConfig } from &#39;vite&#39;;

export default defineConfig({
  server: {
    port: 1234,
  },
});
">
<input type="hidden" name="project[files][types/Highlighted.ts]" value="import { HighlightResult } from &#39;@algolia/client-search&#39;;

export type Highlighted&lt;TRecord&gt; = TRecord &amp; {
  _highlightResult: HighlightResult&lt;TRecord&gt;;
};
">
<input type="hidden" name="project[files][types/ProductHit.ts]" value="import { Hit } from &#39;@algolia/client-search&#39;;

export type ProductRecord = {
  brand: string;
  categories: string[];
  comments: number;
  description: string;
  free_shipping: boolean;
  hierarchicalCategories: {
    lvl0: string;
    lvl1?: string;
    lvl2?: string;
    lvl3?: string;
    lvl4?: string;
    lvl5?: string;
    lvl6?: string;
  };
  image: string;
  name: string;
  popularity: number;
  price: number;
  prince_range: string;
  rating: number;
  sale: boolean;
  sale_price: string;
  type: string;
  url: string;
};

type WithAutocompleteAnalytics&lt;THit&gt; = THit &amp; {
  __autocomplete_indexName: string;
  __autocomplete_queryID: string;
};

export type ProductHit = WithAutocompleteAnalytics&lt;Hit&lt;ProductRecord&gt;&gt;;
">
<input type="hidden" name="project[files][types/index.ts]" value="export * from &#39;./Highlighted&#39;;
export * from &#39;./ProductHit&#39;;
">
<input type="hidden" name="project[description]" value="generated by https://pkg.pr.new">
<input type="hidden" name="project[template]" value="node">
<input type="hidden" name="project[title]" value="@algolia/autocomplete-example-playground">
</form>
<script>document.getElementById("mainForm").submit();</script>

</body></html>