Skip to content

Select ​

A neo-brutalist style dropdown select built on top of reka-ui's Select primitive, with full sub-component support.

Demo ​

Preview

Installation ​

pnpm dlx brutx-vue@latest add select

Usage ​

vue
<script setup>
import { Select, SelectTrigger, SelectContent, SelectItem, SelectLabel } from 'brutx-ui-vue'
import { SelectGroup, SelectValue } from 'reka-ui'
</script>

<template>
    <Select>
        <SelectTrigger class="w-[280px]">
            <SelectValue placeholder="Select a fruit" />
        </SelectTrigger>
        <SelectContent>
            <SelectGroup>
                <SelectLabel>Fruits</SelectLabel>
                <SelectItem value="apple">Apple</SelectItem>
                <SelectItem value="banana">Banana</SelectItem>
                <SelectItem value="orange">Orange</SelectItem>
                <SelectItem value="grape">Grape</SelectItem>
            </SelectGroup>
        </SelectContent>
    </Select>
</template>

Custom Slot Composition and Attribute Binding ​

The default slot replaces the full selector and does not provide scoped slot arguments. When composing atomic controls, pass form name, required, and disabled to Select; bind the trigger id and disabled state directly in the slot content.

vue
<script setup>
import { ref } from 'vue'
import { Select, SelectTrigger, SelectContent, SelectItem } from 'brutx-ui-vue'
import { SelectValue } from 'reka-ui'
const isDisabled = ref(false)
</script>

<template>
    <Select name="fruit" required :disabled="isDisabled">
        <SelectTrigger id="fruit-select" :disabled="isDisabled" class="w-[280px]">
            <SelectValue placeholder="Select a fruit" />
        </SelectTrigger>
        <SelectContent>
            <SelectItem value="apple">Apple</SelectItem>
            <SelectItem value="banana">Banana</SelectItem>
        </SelectContent>
    </Select>
</template>

Unified Usage ​

In addition to using individual atomic components, you can use the pre-packaged unified Select component, which supports passing an options array and automatically grouping items.

vue
<script setup>
import { ref } from 'vue'
import { Select } from 'brutx-ui-vue'

const selectedValue = ref('')

const foodOptions = [
    { label: 'Apple', value: 'apple', category: 'fruits', categoryName: 'Fruits' },
    { label: 'Banana', value: 'banana', category: 'fruits', categoryName: 'Fruits' },
    { label: 'Carrot', value: 'carrot', category: 'vegetables', categoryName: 'Vegetables' },
    { label: 'Potato', value: 'potato', category: 'vegetables', categoryName: 'Vegetables' },
    { label: 'Milk', value: 'milk' } // ungrouped
]
</script>

<template>
    <!-- Basic Usage -->
    <Select
        v-model="selectedValue"
        :options="foodOptions"
        placeholder="Select your food"
        class="w-[280px]"
    />

    <!-- Auto Grouping Usage -->
    <Select
        v-model="selectedValue"
        :options="foodOptions"
        group-field="category"
        group-label="categoryName"
        placeholder="Select food (Grouped)"
        class="w-[280px]"
    />
</template>

Using v-model ​

vue
<script setup>
import { ref } from 'vue'
import {
    Select,
    SelectTrigger,
    SelectContent,
    SelectItem,
} from 'brutx-ui-vue'
import { SelectValue } from 'reka-ui'

const selectedFruit = ref('')
</script>

<template>
    <Select v-model="selectedFruit">
        <SelectTrigger class="w-[280px]">
            <SelectValue placeholder="Select a fruit" />
        </SelectTrigger>
        <SelectContent>
            <SelectItem value="apple">Apple</SelectItem>
            <SelectItem value="banana">Banana</SelectItem>
            <SelectItem value="orange">Orange</SelectItem>
        </SelectContent>
    </Select>
</template>

Sub-components ​

ComponentDescription
SelectUnified selector with an options data source and slot composition, built on Reka UI primitives
SelectRootReka UI root primitive that provides context for atomic composition (import from reka-ui)
SelectValueReka UI primitive that displays the selected value or placeholder (import from reka-ui)
SelectGroupReka UI primitive that groups options (import from reka-ui)
SelectTriggerButton that opens the dropdown
SelectContentDropdown content panel
SelectItemSelectable option
SelectLabelGroup label
SelectSeparatorVisual separator
SelectScrollUpButtonScroll up indicator
SelectScrollDownButtonScroll down indicator

API Reference ​

Select

Select — Props
NameTypeDefaultDescription
options
SelectOption[] | undefined
[]
The unified select option list. Each option has a label and non-empty value, may be disabled, and can include custom fields used for grouping.
Details

Declared type

SelectOption[] | undefined

Referenced types

SelectOption
Type definition — SelectOption
export interface SelectOption {
    label: string
    value: string
    disabled?: boolean
    [key: string]: unknown
}

Default value details

Resolved value
[]

Source

types.ts:9

packages/ui/src/components/select/types.ts

groupField
string | undefined
undefined
The option field used to group items. When omitted, options are displayed as a flat list.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

types.ts:10

packages/ui/src/components/select/types.ts

groupLabel
string | undefined
undefined
The field on the first option of each group used as its heading; when omitted or absent, the groupField value is used.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

types.ts:11

packages/ui/src/components/select/types.ts

placeholder
string | undefined
undefined
Placeholder text shown before an option is selected; when omitted, the localized select.placeholder message is used.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

types.ts:12

packages/ui/src/components/select/types.ts

disabled
boolean | undefined
false
Disables the select root state and its built-in trigger.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

types.ts:13

packages/ui/src/components/select/types.ts

required
boolean | undefined
false
Marks the select as required; the unified trigger hides its clear action while required is true.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

types.ts:14

packages/ui/src/components/select/types.ts

name
string | undefined
undefined
The form field name passed to SelectRoot.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

types.ts:15

packages/ui/src/components/select/types.ts

id
string | undefined
undefined
The DOM ID for the built-in trigger. With a custom trigger slot, the slot content supplies its own ID.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

types.ts:16

packages/ui/src/components/select/types.ts

size
"default" | "lg" | "sm" | undefined
"default"
The size variant of the built-in trigger.
Details

Declared type

"default" | "lg" | "sm" | undefined

Literal values

  • "default"
  • "lg"
  • "sm"

Default value details

Resolved value
"default"

Source

types.ts:17

packages/ui/src/components/select/types.ts

variant
"default" | "success" | "error" | undefined
"default"
The border and state variant of the built-in trigger.
Details

Declared type

"default" | "success" | "error" | undefined

Literal values

  • "default"
  • "error"
  • "success"

Default value details

Resolved value
"default"

Source

types.ts:18

packages/ui/src/components/select/types.ts

errorMessage
string | undefined
undefined
The error message passed to the built-in trigger for its error-state semantics.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

types.ts:19

packages/ui/src/components/select/types.ts

clearable
boolean | undefined
false
Allows the built-in trigger to show a clear action when a value is selected; the action is disabled when required is true.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

types.ts:20

packages/ui/src/components/select/types.ts

position
"popper" | "item-aligned" | undefined
"popper"
Sets how the options panel is positioned relative to the trigger.
Details

Declared type

"popper" | "item-aligned" | undefined

Literal values

  • "item-aligned"
  • "popper"

Default value details

Resolved value
"popper"

Source

types.ts:21

packages/ui/src/components/select/types.ts

class
string | undefined
—
Custom CSS classes merged onto the built-in trigger together with triggerClass.
Details

Declared type

string | undefined

Default value details

Not declared
—

Source

types.ts:22

packages/ui/src/components/select/types.ts

triggerClass
string | undefined
undefined
Custom CSS classes added to the built-in trigger.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

types.ts:23

packages/ui/src/components/select/types.ts

contentClass
string | undefined
undefined
Custom CSS classes added to the options panel.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

types.ts:24

packages/ui/src/components/select/types.ts

itemVariant
"default" | "primary" | "secondary" | undefined
"default"
The variant applied to each SelectItem generated from options.
Details

Declared type

"default" | "primary" | "secondary" | undefined

Literal values

  • "default"
  • "primary"
  • "secondary"

Default value details

Resolved value
"default"

Source

types.ts:25

packages/ui/src/components/select/types.ts

modelValue
string | undefined
—
The currently selected string value, controlled with v-model; it may be undefined when nothing is selected.
Details

Declared type

string | undefined

Default value details

Not declared
—

Source

Select.vue

packages/ui/src/components/select/Select.vue

Select — Events
NameSignature or typeDescription
@update:modelValue
[value: string | undefined]
Emits the new value when the selection changes; the built-in clear action emits undefined.
Details

Declared type

[value: string | undefined]

Source

Select.vue

packages/ui/src/components/select/Select.vue

Select — Slots
NameSignature or typeDescription
#default
{}
Replaces the entire Select content. When provided, the component renders neither its built-in trigger nor the options panel, so the slot must compose the primitives itself.
Details

Declared type

{}

Source

Select.vue

packages/ui/src/components/select/Select.vue

#trigger
{}
Replaces the built-in trigger while the options panel is still generated from options. The slot receives no arguments.
Details

Declared type

{}

Source

Select.vue

packages/ui/src/components/select/Select.vue

SelectContent

SelectContent — Props
NameTypeDefaultDescription
position
"popper" | "item-aligned" | undefined
"popper"
Controls how the content panel is positioned relative to its trigger.
Details

Declared type

"popper" | "item-aligned" | undefined

Literal values

  • "item-aligned"
  • "popper"

Default value details

Resolved value
"popper"

Source

SelectContent.vue:18

packages/ui/src/components/select/SelectContent.vue

class
string | undefined
undefined
Custom CSS classes added to the floating content panel.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

SelectContent.vue:19

packages/ui/src/components/select/SelectContent.vue

SelectContent — Slots
NameSignature or typeDescription
#default
{}
Renders options, groups, and other content-panel children.
Details

Declared type

{}

Source

SelectContent.vue

packages/ui/src/components/select/SelectContent.vue

SelectItem

SelectItem — Props
NameTypeDefaultDescription
value
Required
string
—
The non-empty, unique string value of this option, used as the selection result.
Details

Declared type

string

Default value details

Not declared
—

Source

SelectItem.vue:14

packages/ui/src/components/select/SelectItem.vue

disabled
boolean | undefined
false
Prevents the user from selecting this option.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

SelectItem.vue:15

packages/ui/src/components/select/SelectItem.vue

variant
"default" | "primary" | "secondary" | undefined
"default"
The visual variant for this option.
Details

Declared type

NonNullable<"default" | "primary" | "secondary" | null | undefined> | undefined

Literal values

  • "default"
  • "primary"
  • "secondary"

Default value details

Resolved value
"default"

Source

SelectItem.vue:16

packages/ui/src/components/select/SelectItem.vue

class
string | undefined
undefined
Custom CSS classes added to the option root element.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

SelectItem.vue:17

packages/ui/src/components/select/SelectItem.vue

indicatorClass
string | undefined
undefined
Custom CSS classes added to the selected-state indicator.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

SelectItem.vue:18

packages/ui/src/components/select/SelectItem.vue

iconClass
string | undefined
undefined
Custom CSS classes added to the selected check icon.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

SelectItem.vue:19

packages/ui/src/components/select/SelectItem.vue

iconSize
IconSize | undefined
"md"
Sets the size of the selected check icon.
Details

Declared type

IconSize | undefined

Literal values

  • "2xl"
  • "lg"
  • "md"
  • "sm"
  • "xl"
  • "xs"

Referenced types

IconSize
Type definition — IconSize
export type IconSize = NonNullable<VariantProps<typeof iconSizeVariants>['size']>

Default value details

Resolved value
"md"

Source

SelectItem.vue:20

packages/ui/src/components/select/SelectItem.vue

SelectItem — Slots
NameSignature or typeDescription
#default
{}
The content displayed in the option text area.
Details

Declared type

{}

Source

SelectItem.vue

packages/ui/src/components/select/SelectItem.vue

SelectLabel

SelectLabel — Props
NameTypeDefaultDescription
class
string | undefined
—
Custom CSS classes added to the group heading element.
Details

Declared type

string | undefined

Default value details

Not declared
—

Source

SelectLabel.vue:7

packages/ui/src/components/select/SelectLabel.vue

SelectLabel — Slots
NameSignature or typeDescription
#default
{}
The group heading text or other heading content.
Details

Declared type

{}

Source

SelectLabel.vue

packages/ui/src/components/select/SelectLabel.vue

SelectScrollDownButton

SelectScrollDownButton — Props
NameTypeDefaultDescription
class
string | undefined
undefined
Custom CSS classes added to the scroll-down indicator control.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

SelectScrollDownButton.vue:9

packages/ui/src/components/select/SelectScrollDownButton.vue

iconSize
IconSize | undefined
"md"
Sets the size of the scroll-down arrow icon.
Details

Declared type

IconSize | undefined

Literal values

  • "2xl"
  • "lg"
  • "md"
  • "sm"
  • "xl"
  • "xs"

Referenced types

IconSize
Type definition — IconSize
export type IconSize = NonNullable<VariantProps<typeof iconSizeVariants>['size']>

Default value details

Resolved value
"md"

Source

SelectScrollDownButton.vue:10

packages/ui/src/components/select/SelectScrollDownButton.vue

SelectScrollUpButton

SelectScrollUpButton — Props
NameTypeDefaultDescription
class
string | undefined
undefined
Custom CSS classes added to the scroll-up indicator control.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

SelectScrollUpButton.vue:9

packages/ui/src/components/select/SelectScrollUpButton.vue

iconSize
IconSize | undefined
"md"
Sets the size of the scroll-up arrow icon.
Details

Declared type

IconSize | undefined

Literal values

  • "2xl"
  • "lg"
  • "md"
  • "sm"
  • "xl"
  • "xs"

Referenced types

IconSize
Type definition — IconSize
export type IconSize = NonNullable<VariantProps<typeof iconSizeVariants>['size']>

Default value details

Resolved value
"md"

Source

SelectScrollUpButton.vue:10

packages/ui/src/components/select/SelectScrollUpButton.vue

SelectSeparator

SelectSeparator — Props
NameTypeDefaultDescription
decorative
boolean | undefined
true
Declares whether the separator is decorative; the primitive hides decorative separators from the accessibility tree.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
true

Source

SelectSeparator.vue:7

packages/ui/src/components/select/SelectSeparator.vue

class
string | undefined
undefined
Custom CSS classes added to the separator element.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

SelectSeparator.vue:8

packages/ui/src/components/select/SelectSeparator.vue

SelectTrigger

SelectTrigger — Props
NameTypeDefaultDescription
size
"default" | "lg" | "sm" | undefined
"default"
The trigger size variant, which also determines the mapped dropdown icon size.
Details

Declared type

NonNullable<"default" | "lg" | "sm" | null | undefined> | undefined

Literal values

  • "default"
  • "lg"
  • "sm"

Default value details

Resolved value
"default"

Source

SelectTrigger.vue:14

packages/ui/src/components/select/SelectTrigger.vue

variant
"default" | "error" | "success" | undefined
"default"
The trigger border and state variant.
Details

Declared type

NonNullable<"default" | "success" | "error" | null | undefined> | undefined

Literal values

  • "default"
  • "error"
  • "success"

Default value details

Resolved value
"default"

Source

SelectTrigger.vue:15

packages/ui/src/components/select/SelectTrigger.vue

errorMessage
string | undefined
undefined
The error-state message associated with the trigger when it is invalid.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

SelectTrigger.vue:16

packages/ui/src/components/select/SelectTrigger.vue

disabled
boolean | undefined
false
Disables the trigger and its clear action.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

SelectTrigger.vue:17

packages/ui/src/components/select/SelectTrigger.vue

id
string | undefined
undefined
The DOM ID of the native trigger button.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

SelectTrigger.vue:18

packages/ui/src/components/select/SelectTrigger.vue

clearable
boolean | undefined
false
Allows the clear button to appear when a value is selected and the trigger is enabled.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

SelectTrigger.vue:20

packages/ui/src/components/select/SelectTrigger.vue

modelValue
unknown
undefined
The current value, used to determine whether there is a selection to clear.
Details

Declared type

unknown

Default value details

Resolved value
undefined

Source

SelectTrigger.vue:22

packages/ui/src/components/select/SelectTrigger.vue

class
string | undefined
undefined
Custom CSS classes added to the trigger button.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

SelectTrigger.vue:23

packages/ui/src/components/select/SelectTrigger.vue

iconClass
string | undefined
undefined
Custom CSS classes added to the dropdown indicator icon.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

SelectTrigger.vue:24

packages/ui/src/components/select/SelectTrigger.vue

SelectTrigger — Events
NameSignature or typeDescription
@clear
[]
Emitted when the user activates the clear action; the event carries no payload.
Details

Declared type

[]

Source

SelectTrigger.vue

packages/ui/src/components/select/SelectTrigger.vue

SelectTrigger — Slots
NameSignature or typeDescription
#default
{}
The trigger content, usually including SelectValue.
Details

Declared type

{}

Source

SelectTrigger.vue

packages/ui/src/components/select/SelectTrigger.vue

Reka UI Primitives ​

The unified Select props, events, and slots are listed above. When composing atomic controls, headless primitives such as SelectRoot and SelectValue come from reka-ui and should be imported from reka-ui; their remaining prop and slot contracts are defined by Reka UI.

Accessibility ​

  • Keyboard: Supports Space / Enter to open the dropdown, Escape to close, and arrow keys to navigate options
  • ARIA Attributes: Automatically manages aria-expanded, aria-haspopup, aria-activedescendant, etc.
  • Focus Management: Focus is trapped within the dropdown when open; focus returns to the trigger when closed

Brute force builds.