{ /* This Source Code Form is subject to the terms of the Mozilla Public
  License, v. 2.0. If a copy of the MPL was not distributed with this
  file, You can obtain one at http://mozilla.org/MPL/2.0/.

  Copyright (c) KALEIDOS INC Sucursal en España SL */ }

import { Canvas, Meta } from "@storybook/addon-docs/blocks";
import * as ComboboxStories from "./combobox.stories";

<Meta title="Controls/Combobox" />

# Combobox

The `combobox*` component lets users choose one option from an options menu or enter a custom value that is not listed in the menu. It combines the functionality of a dropdown menu and an input field, allowing for both selection and free-form input.

## Variants

We will use the text-only variant when there are enough space and icons don't add any useful context.

<Canvas of={ComboboxStories.Default} />

We will use the icon and text variant when there are enough space and icons add any useful context.

<Canvas of={ComboboxStories.WithIcons} />

If we consider that empty options have a special meaning, we can move them to the end of the list, to a section separate from the rest.

<Canvas of={ComboboxStories.EmptyToEnd} />

## Technical notes

### Icons

Each option of `combobox*` accepts an optional `icon`, which must contain an [icon ID](../foundations/assets/icon.mdx).
These are available in the `app.main.ds.foundations.assets.icon` namespace.

```clj
(ns app.main.ui.foo
  (:require
   [app.main.ui.ds.foundations.assets.icon :as i]))
```

```clj
[:> combobox*
    {:options [{ :label "Code"
                 :id "option-code"
                 :icon i/fill-content }
               { :label "Design"
                 :id "option-design"
                 :icon i/pentool }
               { :label "Menu"
                 :id "option-menu" }
               ]}]
```


### Avatars

Each option of `combobox*` also accepts an optional `avatar` map.
Avatar rendering is defined per option with `:render-fn`, so each avatar type can provide its own UI. The renderer should be a component function that receives the full `avatar` map.

```clj
;; Example renderer for organization avatars
(mf/defc render-organization-avatar*
  [{:keys [avatar]}]
  (when (= :organization (:type avatar))
    [:> organization-avatar* {:organization (:organization avatar)
                              :size (:size avatar)}]))

[:> combobox*
    {:options [{:label "Design Team"
                :id "organization-design"
                :avatar {:render-fn render-organization-avatar*
                         :size "s"
                         :organization {:name "Design Team"
                                        :organization-avatar-bg-url "https://example.com/avatar-bg.svg"
                                        :organization-custom-photo nil}}}
               {:label "Engineering"
                :id "organization-engineering"
                :avatar {:render-fn render-organization-avatar*
                         :size "s"
                         :organization {:name "Engineering"
                                        :organization-avatar-bg-url nil
                                        :organization-custom-photo "https://example.com/custom-photo.png"}}}]}]
```

The same pattern can be used later for other avatar kinds, for example `:team`, by adding a different `:render-fn` in those options.

## Usage guidelines (design)

### Where to Use

Combobox is used in applications where users need to select from a range of text-based options or enter custom input.

### When to Use

Consider using a combobox when you have five or more options to present, and users may benefit from the ability to search or input a custom value that is not in the predefined list.

### Interaction / Behavior

- **Opening Options**: When the user clicks on the input area, a dropdown menu of options appears. Users can either scroll through the options, type to filter them, or input a new value directly.
- **Selecting an Option**: Once an option is selected or a custom value is entered, the dropdown closes, and the input field displays the chosen value.
- **Keyboard Support**: Combobox supports navigation using keyboard input, including arrow keys to navigate the list and Enter to make a selection.
