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

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

const options = ref([
  {
    _id: '1',
    label: 'Jane',
    value: 'jane'
  },
  {
    _id: '2',
    label: 'John Doe',
    value: 'john-doe'
  }
])

const modelId = ref()
const selected = ref()
const search = ref()

function onSelect(option?: BaseSelectOptionInterface) {
  selected.value = option ?? null
}
</script>

<template>
  <base-select
    title="Example"
    placeholder="Select"
    v-model="modelId" 
    v-model:search="search"
    :options="options"
    @select="onSelect"
  />
  <div class="flex flex-col gap-4">
    <div class="space-x-4">
      <span class="font-bold">options</span>
      <span>{{ options }}</span>
    </div>
    <div class="space-x-4">
      <span class="font-bold">v-model</span>
      <span>{{ modelId }}</span>
    </div>
    <div class="space-x-4">
      <span class="font-bold">search</span>
      <span>{{ search }}</span>
    </div>
    <div class="space-x-4">
      <span class="font-bold">selected</span>
      <span>{{ selected }}</span>
    </div>
  </div>
</template>

Select API

Types

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

Props

NameTypeDefaultDescription
v-modelstring | nullRequired. Selected option value.
v-model:searchstring''Search keyword (optional, controlled).
v-model:errorsstring[]Input error messages.
optionsBaseSelectOptionInterface[][]Available options (can be partial / paginated).
resolveOption(value: string) => BaseSelectOptionInterface | undefinedResolve full option when value exists but option is not loaded yet.
labelstringInput label.
descriptionstringInput description.
placeholderstringInput placeholder.
borderBaseSelectBorderTypefullInput border style.
layoutBaseFormLayoutTypehorizontalForm layout.
autofocusbooleanfalseFocus input on mount.
requiredbooleanfalseMark input as required.
disabledbooleanfalseDisable input interaction.
readonlybooleanfalseRead-only mode.
helpersstring[]Helper messages below input.
isLoadingbooleanfalseShow loading state in options list.
data-testidstringTesting identifier.

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.