Skip to content

Select

Select gives you a customizable select box with support for searching, tagging, remote data sets, infinite scrolling, and many other highly used options.

Examples

Select

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

interface OptionInterface {
  id: number
  label: string
  value: string
}

const options: OptionInterface[] = [
  { id: 1, label: 'Durward Reynolds', value: 'durward-reynolds' },
  { id: 2, label: 'Kenton Towne', value: 'kenton-towne' },
  { id: 3, label: 'Therese Wunsch', value: 'therese-wunsch' },
  { id: 4, label: 'Benedict Kessler', value: 'benedict-kessler' }
]

const selected = ref()
const selectedLabel = ref('')
const selectedValue = ref('')
</script>

<template>
  <Demo>
    <form @submit.prevent="onSubmit()">
      <base-select v-model="selected" :options="options" v-model:selectedLabel="selectedLabel" v-model:selectedValue="selectedValue" />
      <div class="flex flex-col gap-4">
        <div><span class="font-bold">v-model = </span><span>{{ selected }}</span></div>
        <div><span class="font-bold">v-model:selectedLabel = </span><span>{{ selectedLabel }}</span></div>
        <div><span class="font-bold">v-model:selectedValue = </span><span>{{ selectedValue }}</span></div>
      </div>
    </form>
  </Demo>
</template>

Label

Code
vue
<script setup lang="ts">
import { ref } from 'vue'
import { type BaseSelectOptionInterface } from '@point-hub/papp'

interface OptionInterface extends BaseSelectOptionInterface {
  id: number
  label: string
}

const options: OptionInterface[] = [
  { id: 1, label: 'Durward Reynolds' },
  { id: 2, label: 'Kenton Towne' },
  { id: 3, label: 'Therese Wunsch' },
  { id: 4, label: 'Benedict Kessler' }
]

const selected1 = ref()
const selected2 = ref()

const form = ref<{
  name1: string | null
  name2: string | null
}>({
  name1: null,
  name2: null
})

const onSubmit = () => {
  form.value.name1 = selected1.value?.label ?? null
  form.value.name2 = selected2.value?.label ?? null
}
</script>

<template>
  <form @submit.prevent="onSubmit()">
    <base-select
      v-model="selected1"
      :options="options"
      label="Label"
      description="Vertical Layout"
      layout="vertical"
    />
    <base-select
      v-model="selected2"
      :options="options"
      label="Label"
      description="Horizontal Layout"
      layout="horizontal"
    />
  </form>
</template>

Border

Code
vue
<script setup lang="ts">
import { ref } from 'vue'
import { type BaseSelectOptionInterface } from '@point-hub/papp'

interface OptionInterface extends BaseSelectOptionInterface {
  id: number
  label: string
}

const options: OptionInterface[] = [
  { id: 1, label: 'Durward Reynolds' },
  { id: 2, label: 'Kenton Towne' },
  { id: 3, label: 'Therese Wunsch' },
  { id: 4, label: 'Benedict Kessler' }
]

const selected1 = ref<OptionInterface>()
const selected2 = ref<OptionInterface>()
const selected3 = ref<OptionInterface>()

const form = ref<{
  name1: string | null
  name2: string | null
  name3: string | null
}>({
  name1: null,
  name2: null,
  name3: null
})

const onSubmit = () => {
  form.value.name1 = selected1.value?.label ?? null
  form.value.name2 = selected2.value?.label ?? null
  form.value.name3 = selected3.value?.label ?? null
}
</script>

<template>
  <form @submit.prevent="onSubmit()">
    <base-select
      v-model="selected1"
      :options="options"
      label="Label"
      description="Without Border"
      border="none"
    />
    <base-select
      v-model="selected1"
      :options="options"
      label="Label"
      description="Border Simple"
      border="simple"
    />
    <base-select
      v-model="selected1"
      :options="options"
      label="Label"
      description="Border Full"
      border="full"
    />
  </form>
</template>

Helper

Code
vue
<script setup lang="ts">
import { ref } from 'vue'
import { type BaseSelectOptionInterface } from '@point-hub/papp'

interface OptionInterface extends BaseSelectOptionInterface {
  id: number
  label: string
}

const options: OptionInterface[] = [
  { id: 1, label: 'Durward Reynolds' },
  { id: 2, label: 'Kenton Towne' },
  { id: 3, label: 'Therese Wunsch' },
  { id: 4, label: 'Benedict Kessler' }
]

const selected1 = ref()
const selected2 = ref()
const selected3 = ref()
const selected4 = ref()
const selected5 = ref(options[1])

const form = ref<{
  name1: string | null
  name2: string | null
  name3: string | null
  name4: string | null
  name5: string | null
}>({
  name1: null,
  name2: null,
  name3: null,
  name4: null,
  name5: null
})

const onSubmit = () => {
  form.value.name1 = selected1.value?.label ?? null
  form.value.name2 = selected2.value?.label ?? null
  form.value.name3 = selected3.value?.label ?? null
  form.value.name4 = selected4.value?.label ?? null
  form.value.name5 = selected5.value?.label ?? null
}

const errors = ref(['Error 1 Example', 'Error 2 Example', 'Error 3 Example'])
</script>

<template>
  <form @submit.prevent="onSubmit()">
    <base-select v-model="selected1" :options="options" label="Label" required />
    <base-select
      v-model="selected2"
      :options="options"
      label="Label"
      description="Description Example"
    />
    <base-select
      v-model="selected3"
      :options="options"
      label="Label"
      :helpers="['Helper Example']"
    />
    <base-select
      v-model="selected4"
      :options="options"
      label="Label"
      v-model:errors="errors"
    />
    <base-select v-model="selected5" :options="options" label="Label" disabled />
  </form>
</template>

Select API

Types

ts
export type BaseSelectBorderType = 'none' | 'simple' | 'full'
export type BaseFormLayoutType = 'vertical' | 'horizontal'

Props

NameTypeDefaultDescription
v-modelobjectv-model is required.
v-model:selectedLabelstringv-model for label only.
v-model:selectedValuestringv-model for value only.
v-model:errorsstring[]Input error message.
idstringInput ID.
labelstringInput label.
descriptionstringInput description.
placeholderstringInput placeholder.
borderBaseSelectBorderTypesimpleInput border.
layoutBaseFormLayoutTypeverticalInput layout.
autofocusbooleanfalseFocus input on page load.
requiredbooleanfalseif true input is required.
disabledbooleanfalseif true input is disabled.
helpersstring[]Input helper message.
data-testidstringTesting ID.

Automated Test Guide

If you pass a data-testid to the <base-select> component, it will automatically generate unique data-testid attributes for testing:

For example, if you set data-testid="user-select", the component will generate the following attributes:

Elementdata-testid
Input Fielduser-select-input
Option with _id = 1user-select-1
Option with _id = 2user-select-2
Clear Buttonuser-select-clear-button

Gherkin Scenario

txt
When I type "Durward" into "user-select-input"
And I click select option "user-select-option-1"
And I click select clear button "user-select-clear-button"

Step Definition

ts
When('I click select input {string}', (selector: string) => {
  cy.get(`[data-testid="${selector}"]`).click()
})

When('I click select clear button {string}', (selector: string) => {
  cy.get(`[data-testid="${selector}"]`).click()
})

When('I type {string} into {string}', (value: string, selector: string) => {
  cy.get(`[data-testid="${selector}"]`).type(value)
})

Code Implementation

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

const userOptions = [
  { _id: '1', label: 'Durward Reynolds' },
  { _id: '2', label: 'Kenton Towne' },
  { _id: '3', label: 'Therese Wunsch' },
  { _id: '4', label: 'Benedict Kessler' }
]
const userSelected = ref()
</script>

<template>
  <base-select
    v-model="userSelected"
    :options="userOptions"
    data-testid="user-select"
  />
</template>

Released under the MIT License.