select

Displays a list of options for the user to pick from—triggered by a button.

PreviousNext
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';

import { ZardSelectImports } from '@/shared/components/select/select.imports';

@Component({
  selector: 'z-demo-select-default',
  imports: [ZardSelectImports],
  template: `
    <z-select class="w-full min-w-48" zPlaceholder="Select a fruit" [(zValue)]="selectedFruit">
      <z-select-label>Fruits</z-select-label>
      <z-select-item zValue="apple">Apple</z-select-item>
      <z-select-item zValue="banana">Banana</z-select-item>
      <z-select-item zValue="blueberry">Blueberry</z-select-item>
      <z-select-item zValue="grapes">Grapes</z-select-item>
      <z-select-item zValue="pineapple">Pineapple</z-select-item>
    </z-select>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoSelectDefaultComponent {
  readonly selectedFruit = signal('');
}

Installation

Copy
npx zard-cli@latest add select

Usage

import { ZardSelectImports } from '@/shared/components/select/select.imports';
Copy
<z-select zPlaceholder="Select a fruit">
  <z-select-item zValue="apple">Apple</z-select-item>
  <z-select-item zValue="banana">Banana</z-select-item>
  <z-select-item zValue="blueberry">Blueberry</z-select-item>
</z-select>
Copy

Composition

Use the following composition to build a select:

z-select
├── z-select-label
├── z-select-item
├── z-select-group
│   ├── z-select-label
│   ├── z-select-item
│   └── z-select-item
├── z-select-separator
└── z-select-group
    ├── z-select-label
    ├── z-select-item
    └── z-select-item
Copy

Examples

align item

Use the position prop on SelectContent to control alignment. When position="item-aligned" (default), the popup positions so the selected item appears over the trigger. When position="popper", the popup aligns to the trigger edge.

Toggle to align the item with the trigger.

import { ChangeDetectionStrategy, Component, computed, signal } from '@angular/core';

import { ZardFieldImports } from '@/shared/components/field/field.imports';
import { ZardSelectImports, type ZardSelectPositionVariants } from '@/shared/components/select';
import { ZardSwitchComponent } from '@/shared/components/switch';

@Component({
  selector: 'z-demo-select-align-item',
  imports: [ZardSelectImports, ZardSwitchComponent, ...ZardFieldImports],
  template: `
    <div z-field-group class="w-full min-w-xs">
      <div z-field zOrientation="horizontal">
        <div z-field-content>
          <label z-field-label for="align-item">Align Item</label>
          <p z-field-description>Toggle to align the item with the trigger.</p>
        </div>
        <z-switch id="align-item" [(zChecked)]="alignItem" />
      </div>

      <div z-field>
        <z-select [zPosition]="position()" [(zValue)]="selectedFruit">
          <z-select-group>
            <z-select-item zValue="apple">Apple</z-select-item>
            <z-select-item zValue="banana">Banana</z-select-item>
            <z-select-item zValue="blueberry">Blueberry</z-select-item>
            <z-select-item zValue="grapes">Grapes</z-select-item>
            <z-select-item zValue="pineapple">Pineapple</z-select-item>
          </z-select-group>
        </z-select>
      </div>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoSelectAlignItemComponent {
  readonly alignItem = signal(true);
  readonly selectedFruit = signal('banana');

  protected readonly position = computed<ZardSelectPositionVariants>(() =>
    this.alignItem() ? 'item-aligned' : 'popper',
  );
}

groups

Use SelectGroup, SelectLabel, and SelectSeparator to organize items.

import { ChangeDetectionStrategy, Component, signal } from '@angular/core';

import { ZardSelectImports } from '@/shared/components/select/select.imports';

@Component({
  selector: 'z-demo-select-groups',
  imports: [ZardSelectImports],
  template: `
    <z-select class="w-full min-w-48" zPlaceholder="Select a fruit" [(zValue)]="selectedFood">
      <z-select-group>
        <z-select-label>Fruits</z-select-label>
        <z-select-item zValue="apple">Apple</z-select-item>
        <z-select-item zValue="banana">Banana</z-select-item>
        <z-select-item zValue="blueberry">Blueberry</z-select-item>
        <z-select-item zValue="grapes">Grapes</z-select-item>
      </z-select-group>
      <z-select-separator />
      <z-select-group>
        <z-select-label>Vegetables</z-select-label>
        <z-select-item zValue="aubergine">Aubergine</z-select-item>
        <z-select-item zValue="broccoli">Broccoli</z-select-item>
        <z-select-item zValue="carrot">Carrot</z-select-item>
        <z-select-item zValue="courgette">Courgette</z-select-item>
      </z-select-group>
    </z-select>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoSelectGroupsComponent {
  readonly selectedFood = signal('');
}

scrollable

A select with many items that scrolls.

import { ChangeDetectionStrategy, Component, signal } from '@angular/core';

import { ZardSelectImports } from '@/shared/components/select/select.imports';

@Component({
  selector: 'z-demo-select-scrollable',
  imports: [ZardSelectImports],
  template: `
    <z-select class="w-full min-w-64" zPlaceholder="Select a timezone" zPosition="popper" [(zValue)]="selectedTimezone">
      <z-select-group>
        <z-select-label>North America</z-select-label>
        <z-select-item zValue="est">Eastern Standard Time (EST)</z-select-item>
        <z-select-item zValue="cst">Central Standard Time (CST)</z-select-item>
        <z-select-item zValue="mst">Mountain Standard Time (MST)</z-select-item>
        <z-select-item zValue="pst">Pacific Standard Time (PST)</z-select-item>
        <z-select-item zValue="akst">Alaska Standard Time (AKST)</z-select-item>
        <z-select-item zValue="hst">Hawaii Standard Time (HST)</z-select-item>
      </z-select-group>
      <z-select-separator />
      <z-select-group>
        <z-select-label>Europe & Africa</z-select-label>
        <z-select-item zValue="gmt">Greenwich Mean Time (GMT)</z-select-item>
        <z-select-item zValue="cet">Central European Time (CET)</z-select-item>
        <z-select-item zValue="eet">Eastern European Time (EET)</z-select-item>
        <z-select-item zValue="west">Western European Summer Time (WEST)</z-select-item>
        <z-select-item zValue="cat">Central Africa Time (CAT)</z-select-item>
        <z-select-item zValue="eat">East Africa Time (EAT)</z-select-item>
      </z-select-group>
      <z-select-separator />
      <z-select-group>
        <z-select-label>Asia</z-select-label>
        <z-select-item zValue="msk">Moscow Time (MSK)</z-select-item>
        <z-select-item zValue="ist">India Standard Time (IST)</z-select-item>
        <z-select-item zValue="cst_china">China Standard Time (CST)</z-select-item>
        <z-select-item zValue="jst">Japan Standard Time (JST)</z-select-item>
        <z-select-item zValue="kst">Korea Standard Time (KST)</z-select-item>
        <z-select-item zValue="ist_indonesia">Indonesia Central Standard Time (WITA)</z-select-item>
      </z-select-group>
      <z-select-separator />
      <z-select-group>
        <z-select-label>Australia & Pacific</z-select-label>
        <z-select-item zValue="awst">Australian Western Standard Time (AWST)</z-select-item>
        <z-select-item zValue="acst">Australian Central Standard Time (ACST)</z-select-item>
        <z-select-item zValue="aest">Australian Eastern Standard Time (AEST)</z-select-item>
        <z-select-item zValue="nzst">New Zealand Standard Time (NZST)</z-select-item>
        <z-select-item zValue="fjt">Fiji Time (FJT)</z-select-item>
      </z-select-group>
    </z-select>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoSelectScrollableComponent {
  readonly selectedTimezone = signal('');
}

disabled

import { ChangeDetectionStrategy, Component, signal } from '@angular/core';

import { ZardSelectImports } from '@/shared/components/select/select.imports';

@Component({
  selector: 'z-demo-select-disabled',
  imports: [ZardSelectImports],
  template: `
    <z-select class="w-full min-w-48" zPlaceholder="Select a fruit" [(zValue)]="selectedFruit" zDisabled>
      <z-select-item zValue="apple">Apple</z-select-item>
      <z-select-item zValue="banana">Banana</z-select-item>
      <z-select-item zValue="blueberry">Blueberry</z-select-item>
      <z-select-item zValue="grapes">Grapes</z-select-item>
      <z-select-item zValue="pineapple">Pineapple</z-select-item>
    </z-select>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoSelectDisabledComponent {
  readonly selectedFruit = signal('');
}

invalid

Add the data-invalid attribute to the Field component and the aria-invalid attribute to the SelectTrigger component to show an error state.

Please select a fruit.
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';

import { ZardFieldImports } from '@/shared/components/field/field.imports';
import { ZardSelectImports } from '@/shared/components/select/select.imports';

@Component({
  selector: 'z-demo-select-invalid',
  imports: [...ZardFieldImports, ZardSelectImports],
  template: `
    <div z-field class="w-full min-w-48" data-invalid="true">
      <label z-field-label for="select-invalid">Fruit</label>
      <z-select id="select-invalid" zPlaceholder="Select a fruit" zInvalid [(zValue)]="selectedFruit">
        <z-select-item zValue="apple">Apple</z-select-item>
        <z-select-item zValue="banana">Banana</z-select-item>
        <z-select-item zValue="blueberry">Blueberry</z-select-item>
        <z-select-item zValue="grapes">Grapes</z-select-item>
        <z-select-item zValue="pineapple">Pineapple</z-select-item>
      </z-select>
      <z-field-error>Please select a fruit.</z-field-error>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoSelectInvalidComponent {
  readonly selectedFruit = signal('');
}

multi select

Selected fruits:

import { ChangeDetectionStrategy, Component, signal } from '@angular/core';

import { ZardSelectImports } from '@/shared/components/select/select.imports';

@Component({
  selector: 'z-demo-multi-select-basic',
  imports: [ZardSelectImports],
  template: `
    <div class="flex h-100 w-75 flex-col gap-4">
      <p class="text-muted-foreground text-sm">Selected fruits: {{ selectedValues().join(', ') }}</p>
      <z-select
        zPlaceholder="Select multiple fruits"
        [zMultiple]="true"
        [zMaxLabelCount]="3"
        [(zValue)]="selectedValues"
      >
        <z-select-item zValue="apple">Apple</z-select-item>
        <z-select-item zValue="banana">Banana</z-select-item>
        <z-select-item zValue="blueberry">Blueberry</z-select-item>
        <z-select-item zValue="grapes">Grapes</z-select-item>
        <z-select-item zValue="pineapple">Pineapple</z-select-item>
        <z-select-item zValue="strawberry">Strawberry</z-select-item>
        <z-select-item zValue="watermelon">Watermelon</z-select-item>
        <z-select-item zValue="kiwi">Kiwi</z-select-item>
        <z-select-item zValue="mango">Mango</z-select-item>
      </z-select>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoMultiSelectBasicComponent {
  readonly selectedValues = signal<string[]>([]);
}

API Reference

z-selectComponent

A customizable select component that supports single and multiple value selection.

PropertyDescriptionTypeDefault
[class] Custom CSS classes ClassValue ''
[zAlign] Overlay alignment relative to the trigger 'start' | 'center' | 'end' 'center'
[zDisabled] Disables the select boolean false
[zInvalid] Applies invalid ARIA state and destructive styling boolean false
[zLabel] Optional label for the select string ''
[zMaxLabelCount] Limits visible labels in multiselect mode number 1
[zMultiple] Multiselect mode boolean false
[zPlaceholder] Placeholder text string 'Select an option...'
[zPosition] Overlay positioning mode 'item-aligned' | 'popper' 'popper'
[zSize] Trigger and item size 'sm' | 'default' | 'lg' 'default'
[(zValue)] Selected value string | string[] '' | []
(zSelectionChange) Emitted when the selected value changes string | string[] -

z-select-itemComponent

Represents an individual item inside a z-select component.

PropertyDescriptionTypeDefault
[class] Custom CSS classes ClassValue ''
[zValue] The value associated with this item string ''
[zDisabled] Disables selection for this item boolean false

z-select-groupComponent

Groups related select items.

PropertyDescriptionTypeDefault
[class] Custom CSS classes ClassValue ''

z-select-labelComponent

Displays a non-selectable label inside a select group.

PropertyDescriptionTypeDefault
[class] Custom CSS classes ClassValue ''

z-select-separatorComponent

Displays a separator between select groups.

PropertyDescriptionTypeDefault
[class] Custom CSS classes ClassValue ''
github iconwhatsapp icondiscord iconX icon

Made with in Brazil. Open source and available on GitHub .