<script setup>
import { computed, ref } from 'vue'

import Pills from '~/components/ui/Pills.vue';
import Spacer from '~/components/ui/Spacer.vue';
import Layout from '~/components/ui/Layout.vue';
import Input from '~/components/ui/Input.vue';

const nullModel = ref({
  current: [],
});

const staticModel = ref({
  current: ["#Noise", "#FieldRecording", "#Experiment"],
});

const interactiveModel = ref({
  current: ["#Noise", "#FieldRecording", "#Experiment"],
  others: ["#Melody", "#Rhythm"],
});

const customModel = ref({
  current: ["custom", "#FieldRecording", "#Experiment"],
  others: ["#Melody", "#Rhythm"],
  custom: ["custom"],
});

const search = ref()
</script>

```ts
import Pills from "~/components/ui/Pills.vue";
```

# Pills

Show a dense list of pills representing tags, categories or options.
Users can select a subset of given options and create new ones.

The model you provide will be mutated by this component:

- `current`: these pills are currently selected
- `others`: these pills are currently not selected (but can be selected by the user). This prop is optional. By adding it, you allow users to change the selection.
- `custom`: these pills were created by the user. This prop is optional. Users can edit, add and remove any pill defined in this array. Note that the `custom` array should only contain pills that are either in `current` or in `others`.

::: warning

If you place custom pills into `others`, the user will be able to select, edit and delete them but not to deselect them. If there is a use case for this, we have to design a good UX for deselecting custom pills.

:::

## No pills

```ts
const nullModel = ref({
  current: [],
});
```

```vue-html
<Pills v-model="nullModel" />
```

<Layout class="preview" style="padding:16px">
  <Pills v-model="nullModel" />
</Layout>

## Predefined list of pills

```ts
const staticModel = ref({
  current: ["#Noise", "#FieldRecording", "#Experiment"],
});
```

```vue-html
<Pills v-model="staticModel" label="Tags" />
```

<Layout class="preview" style="padding:16px">
  <Pills v-model="staticModel" label="Tags" />
</Layout>

## Let users select and unselect pills

Select a set of pills from presets, and add and remove custom ones

```ts
const interactiveModel = ref({
  current: ["#Noise", "#FieldRecording", "#Experiment"],
  others: ["#Melody", "#Rhythm"],
});
```

```vue-html
<Pills v-model="interactiveModel" label="Tags" />
```

<Layout class="preview" style="padding:16px">
  <Pills v-model="interactiveModel" label="Tags" />
</Layout>

## Let users add, remove and edit custom pills

Use [reactive](https://vuejs.org/guide/essentials/reactivity-fundamentals.html#reactive-variables-with-ref) methods [such as `computed(...)`](https://vuejs.org/guide/essentials/computed.html) and `watch(...)` to query the model.

```ts
const customModel = ref({
  current: ["custom", "#FieldRecording", "#Experiment"],
  others: ["#Melody", "#Rhythm"],
  custom: ["custom"],
});
```

```vue-html
<Pills v-model="customModel" label="Custom" />
```

<Layout class="preview" style="padding:16px">
  <Pills v-model="customModel" label="Custom" />
</Layout>

## Combine Pills with other input fields

<Spacer />
<Layout form flex>
  <Input
    v-model="search"
    label="Search"
    style="max-width: 150px;"
  />
  <Pills
    v-model="customModel"
    label="Filter by tags"
    style="max-width: 250px;"
  />
  <Layout stack noGap label>
    <span class="label"> Ordering </span>
    <select>
      <option
        v-for="key in ['by date', 'by duration']"
        :value="key"
      >
        key
      </option>
    </select>
  </Layout>
  <Input
    v-model="search"
    label="Option"
    style="max-width: 50px;"
  />
</Layout>
