> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ais-state-results

> Provides the current search state and results to components.

export const FlavorSwitcher = ({current, baseHref = "", options = [], label = "InstantSearch framework"}) => {
  if (options.length === 0) {
    return <div className="not-prose" role="alert" style={{
      margin: "0.25rem 0 1.5rem",
      padding: "0.75rem",
      border: "1px solid #f59e0b",
      borderRadius: "0.625rem",
      color: "inherit",
      fontSize: "0.875rem"
    }}>
        FlavorSwitcher requires at least one option.
      </div>;
  }
  const selected = options.find(option => option.value === current) ?? options[0];
  return <div className="not-prose mint-flavor-switcher">
      <style>{`
        .mint-flavor-switcher {
          --mfs-bg: #ffffff;
          --mfs-bg-hover: #f4f4f5;
          --mfs-bg-current: #eef2ff;
          --mfs-border: #d4d4d8;
          --mfs-fg: #18181b;
          --mfs-muted: #71717a;
          --mfs-accent: #4f46e5;
          position: relative;
          width: min(100%, 19rem);
          margin: 0.25rem 0 1.5rem;
          color: var(--mfs-fg);
          font-size: 0.875rem;
          line-height: 1.25rem;
        }

        .dark .mint-flavor-switcher {
          --mfs-bg: #18181b;
          --mfs-bg-hover: #27272a;
          --mfs-bg-current: #272747;
          --mfs-border: #3f3f46;
          --mfs-fg: #fafafa;
          --mfs-muted: #a1a1aa;
          --mfs-accent: #a5b4fc;
        }

        .mint-flavor-switcher details {
          position: relative;
        }

        .mint-flavor-switcher summary {
          display: flex;
          min-height: 2.75rem;
          box-sizing: border-box;
          align-items: center;
          justify-content: space-between;
          gap: 0.75rem;
          padding: 0.625rem 0.75rem;
          border: 1px solid var(--mfs-border);
          border-radius: 0.625rem;
          background: var(--mfs-bg);
          color: var(--mfs-fg);
          cursor: pointer;
          font-weight: 600;
          list-style: none;
          transition: border-color 150ms ease, box-shadow 150ms ease;
        }

        .mint-flavor-switcher summary::-webkit-details-marker {
          display: none;
        }

        .mint-flavor-switcher summary:hover {
          border-color: var(--mfs-accent);
        }

        .mint-flavor-switcher summary:focus-visible {
          outline: 2px solid var(--mfs-accent);
          outline-offset: 2px;
        }

        .mint-flavor-switcher__label {
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }

        .mint-flavor-switcher__chevron {
          flex: none;
          transition: transform 150ms ease;
        }

        .mint-flavor-switcher details[open] .mint-flavor-switcher__chevron {
          transform: rotate(180deg);
        }

        .mint-flavor-switcher__menu {
          position: absolute;
          z-index: 50;
          top: calc(100% + 0.375rem);
          left: 0;
          width: 100%;
          box-sizing: border-box;
          margin: 0;
          padding: 0.375rem;
          border: 1px solid var(--mfs-border);
          border-radius: 0.625rem;
          background: var(--mfs-bg);
          box-shadow: 0 12px 30px rgb(0 0 0 / 16%);
          list-style: none;
        }

        .mint-flavor-switcher__menu li {
          margin: 0;
          padding: 0;
        }

        .mint-flavor-switcher__option {
          display: grid;
          gap: 0.125rem;
          padding: 0.625rem 0.75rem;
          border-radius: 0.4rem;
          color: var(--mfs-fg);
          text-decoration: none;
        }

        .mint-flavor-switcher__option:hover {
          background: var(--mfs-bg-hover);
        }

        .mint-flavor-switcher__option:focus-visible {
          outline: 2px solid var(--mfs-accent);
          outline-offset: -2px;
        }

        .mint-flavor-switcher__option[aria-current="page"] {
          background: var(--mfs-bg-current);
          color: var(--mfs-accent);
        }

        .mint-flavor-switcher__name {
          font-weight: 600;
        }

        .mint-flavor-switcher__description {
          color: var(--mfs-muted);
          font-size: 0.8125rem;
        }

        @media (prefers-reduced-motion: reduce) {
          .mint-flavor-switcher summary,
          .mint-flavor-switcher__chevron {
            transition: none;
          }
        }
      `}</style>

      <details>
        <summary aria-label={`${label}: ${selected.label}`}>
          <span className="mint-flavor-switcher__label">{selected.label}</span>
          <svg className="mint-flavor-switcher__chevron" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
            <path d="m6 9 6 6 6-6" />
          </svg>
        </summary>

        <ul className="mint-flavor-switcher__menu" aria-label={label}>
          {options.map(option => {
    const isCurrent = option.value === selected.value;
    const href = option.href ?? `${baseHref.replace(/\/$/, "")}/${encodeURIComponent(option.value)}`;
    return <li key={option.value}>
                <a className="mint-flavor-switcher__option" href={href} aria-current={isCurrent ? "page" : undefined}>
                  <span className="mint-flavor-switcher__name">
                    {option.label}
                  </span>
                  {option.description ? <span className="mint-flavor-switcher__description">
                      {option.description}
                    </span> : null}
                </a>
              </li>;
  })}
        </ul>
      </details>
    </div>;
};

<div className="mint-flavor-switcher-slot not-prose">
  <FlavorSwitcher
    current="vue"
    baseHref="/doc/api-reference/widgets/state-results"
    options={[
{ value: "react", label: "React", description: "React InstantSearch" },
{ value: "vue", label: "Vue", description: "Vue InstantSearch" },
]}
  />
</div>

```vue Signature theme={"system"}
<ais-state-results
  // Optional parameters
  :catch-error="boolean"
/>
```

## Import

<Tabs>
  <Tab title="Component">
    To ensure optimal bundle sizes,
    see [Optimize build size](/doc/guides/building-search-ui/going-further/improve-performance/vue#optimize-build-size).

    ```js Vue icon=code theme={"system"}
    import { AisStateResults } from "vue-instantsearch";
    // Use "vue-instantsearch/vue3/es" for Vue 3

    export default {
      components: {
        AisStateResults
      },
      // ...
    };
    ```
  </Tab>

  <Tab title="Plugin">
    This imports all widgets, even the ones you don't use.
    For more information, see [Get started with Vue InstantSearch](/doc/guides/building-search-ui/getting-started/vue).

    ```js JavaScript icon="code" theme={"system"}
    import Vue from "vue";
    import InstantSearch from "vue-instantsearch";
    // Use "vue-instantsearch/vue3/es" for Vue 3

    Vue.use(InstantSearch);
    ```
  </Tab>
</Tabs>

<Card title="See this widget in action" icon="monitor-play" href="https://instantsearchjs.netlify.app/stories/vue/?selectedKind=ais-state-results" horizontal>
  Preview this widget and its behavior.
</Card>

## About this widget

The `ais-state-results` allows you reach into the current search state,
for example, for conditional rendering or other rendering that depends on what the current refinement or results are.

## Examples

```vue Vue icon=code theme={"system"}
<ais-state-results />
```

## Props

<ParamField path="catch-error" type="boolean">
  If `true`, errors thrown by InstantSearch are handled by InstantSearch and are available in the `error` property from the slot.
  Set `catch-error` to `false` if you want to handle these errors elsewhere.
</ParamField>

## Customize the UI

<ParamField body="default">
  The slot to override the complete DOM output of the widget.

  When you implement this slot,
  none of the other slots will change the output,
  as the default slot surrounds them.

  **Scope**

  The scope is an object with the keys `state` and `results`.

  **`state`**

  * `query: string`. The current value of the query.
  * `page: number`. The currently applied page.
  * ... any other currently applied search parameters.

  You can find all regular parameters on the [search parameters page](/doc/api-reference/api-parameters).

  This also includes parameters from the [Helper](https://community.algolia.com/algoliasearch-helper-js/reference.html#query-parameters),
  such as, `disjunctiveFacetsRefinements`.

  **`results`**

  * `_rawResults: object[]`. The raw response from the Algolia API.
  * `query: string`. The value of the query from the latest response.
  * `hits: object[]`. Matching hits from the latest response.
  * ... other values from the latest response.

  You can find all regular response parameters on [the response format page](/doc/guides/building-search-ui/going-further/backend-search/in-depth/understanding-the-api-response).

  This also includes parameters from the [Helper](https://community.algolia.com/algoliasearch-helper-js/reference.html#query-parameters), e.g. `disjunctiveFacetsRefinements`.

  **`status`**

  The status is a string which can be `idle`, `loading`, `stalled`, or `error`.
  To display a loading indicator, prefer using `stalled`, as `loading` happens for a short amount of time only.

  **`error`**

  If the status is `error`, there is also an error object available in the scope.

  <CodeGroup>
    ```vue No results theme={"system"}
    <ais-state-results>
      <template v-slot="{ state: { query }, results: { hits } }">
        <div v-show="!hits.length">
          No results found for the query: <q>{{ query }}</q>
        </div> 
      </template>
    </ais-state-results>
    ```

    ```vue Banner from rules theme={"system"}
    <ais-state-results>
      <template v-slot="{ results: { userData } }">
        <img
          v-for="item in userData"
          :key="item.source"
          :src="'https://example.com/images/' + item.source"
        />
      </template>
    </ais-state-results>
    ```

    ```vue Loading indicator theme={"system"}
    <ais-state-results>
      <template v-slot="{ status }">
        <p v-if="status === 'stalled'">Loading…</p>
      </template>
    </ais-state-results>
    ```
  </CodeGroup>
</ParamField>
