<script setup lang="ts">
import { ref } from 'vue'

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

type Item = { type: 'custom' | 'preset', label: string }
type Model = {
  currents: Item[],
  others?: Item[],
}

const nullModel = ref({
  currents: []
} satisfies Model)

const staticModel = ref({
  currents: [
    { label: "#noise", type: 'preset' },
    { label: "#fieldRecording", type: 'preset' },
    { label: "#experiment", type: 'preset' }
  ]
} satisfies Model);

const simpleCustomModel = ref({
  currents: [],
  others: []
})

const customModel = ref({
  ...staticModel.value,
  others: [
    { label: "#myTag1", type: 'custom' },
    { label: "#myTag2", type: 'custom' }
  ]
} satisfies Model);
</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:

- `currents`: these items are currently selected
- `others`: these items 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.

Each item has a `label` of type `string` as well as a `type` of either:

- `custom`: the user can edit its label or
- `preset`: the user cannot edit its label

```ts
type Item = { type: 'custom' | 'preset', label: string }
type Model = {
  currents: Item[],
  others?: Item[],
}
```

## No pills

```ts
const nullModel = ref({
  currents: []
}) satisfies Model;
```

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

<Pills v-model="nullModel" />

## Static list of pills

```ts
const staticModel = ref({
  currents: [
    { label: "#noise", type: 'preset' },
    { label: "#fieldRecording", type: 'preset' },
    { label: "#experiment", type: 'preset' }
  ]
} satisfies Model);
```

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

<Pills v-model="staticModel"/>

## Let users add, remove and edit custom pills

By adding `custom` options, you make the `Pills` instance interactive. 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 bind the model.

Note that this component will automatically add an empty pill to the end of the model because it made the implementation more straightforward. Use `filter(({ label }) => label !== '') to ignore it when reading the model.

### Minimal example

```ts
const simpleCustomModel = ref({
  currents: [],
  others: []
})
```

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

<Pills v-model="simpleCustomModel"/>

### Complex example

```ts
const customModel = ref({
  ...staticModel,
  others: [
    { label: "#MyTag1", type: 'custom' },
    { label: "#MyTag2", type: 'custom' }
  ]
} satisfies Model);
```

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

<Spacer />

<Pills
  v-model="customModel"
  label="Custom Tags"
  cancel="Cancel"
/>
