or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration-services.mdindex.mdng-option-highlight.mdng-select-component.mdtemplate-directives.mdtypes-interfaces.md

ng-select-component.mddocs/

0

# Core Select Component

1

2

The `NgSelectComponent` is the main component providing comprehensive select functionality including single-select, multi-select, autocomplete, virtual scrolling, and extensive customization options.

3

4

## Type Definitions

5

6

```typescript { .api }

7

/**

8

* Function type for comparing items for selection state

9

*/

10

export type CompareWithFn = (a: any, b: any) => boolean;

11

12

/**

13

* Function type for adding custom tags

14

*/

15

export type AddTagFn = (term: string) => any | Promise<any>;

16

17

/**

18

* Function type for generating group values from grouped items

19

*/

20

export type GroupValueFn = (key: string | any, children: any[]) => string | any;

21

22

/**

23

* Dropdown positioning options

24

*/

25

export type DropdownPosition = 'top' | 'right' | 'bottom' | 'left' | 'auto';

26

```

27

28

## Capabilities

29

30

### NgSelectComponent

31

32

Main select component implementing Angular's `ControlValueAccessor` for seamless form integration.

33

34

```typescript { .api }

35

/**

36

* Main select component with support for single/multi-select, autocomplete, virtual scrolling

37

* Implements ControlValueAccessor for reactive and template-driven forms integration

38

*/

39

@Component({

40

selector: 'ng-select',

41

providers: [

42

{

43

provide: NG_VALUE_ACCESSOR,

44

useExisting: forwardRef(() => NgSelectComponent),

45

multi: true

46

}

47

]

48

})

49

export class NgSelectComponent implements ControlValueAccessor, OnInit, OnDestroy, OnChanges, AfterViewInit {

50

// Data binding properties

51

/** Array of items to display in dropdown */

52

@Input() items: any[];

53

/** Property name to use for display labels (e.g., 'name') */

54

@Input() bindLabel: string;

55

/** Property name to use for values (e.g., 'id') */

56

@Input() bindValue: string;

57

/** Function to compare items for selection state */

58

@Input() compareWith: CompareWithFn;

59

60

// Selection mode properties

61

/** Enable multiple selection mode */

62

@Input() multiple: boolean = false;

63

/** Enable adding custom tags/items */

64

@Input() addTag: boolean | AddTagFn = false;

65

/** Maximum number of items that can be selected */

66

@Input() maxSelectedItems: number;

67

68

// Display properties

69

/** Placeholder text when no selection */

70

@Input() placeholder: string = '';

71

/** Keep placeholder visible even when item is selected */

72

@Input() fixedPlaceholder: boolean = false;

73

/** Text shown when no matching results found */

74

@Input() notFoundText: string = 'No items found';

75

/** Text shown when search term is required */

76

@Input() typeToSearchText: string = 'Type to search';

77

/** Text shown when adding new tags */

78

@Input() addTagText: string = 'Add item';

79

/** Text shown during loading state */

80

@Input() loadingText: string = 'Loading...';

81

/** Text shown for clear all action */

82

@Input() clearAllText: string = 'Clear all';

83

/** Visual appearance style */

84

@Input() appearance: string;

85

86

// Behavior properties

87

/** Enable search/filter functionality */

88

@Input() searchable: boolean = true;

89

/** Show clear button when item is selected */

90

@Input() clearable: boolean = true;

91

/** Component is in loading state */

92

@Input() loading: boolean = false;

93

/** Component is disabled */

94

@Input() disabled: boolean = false;

95

/** Component is readonly */

96

@Input() readonly: boolean = false;

97

/** Close dropdown after making selection */

98

@Input() closeOnSelect: boolean = true;

99

/** Hide selected items from dropdown options */

100

@Input() hideSelected: boolean = false;

101

/** Select marked item when Tab key is pressed */

102

@Input() selectOnTab: boolean = false;

103

/** Open dropdown when Enter key is pressed */

104

@Input() openOnEnter: boolean;

105

/** Clear selection when backspace is pressed */

106

@Input() clearOnBackspace: boolean = true;

107

/** Prevent dropdown toggle on right mouse click */

108

@Input() preventToggleOnRightClick: boolean = false;

109

/** Mark first item as highlighted by default */

110

@Input() markFirst: boolean = true;

111

/** Allow search while composing (IME) */

112

@Input() searchWhileComposing: boolean = true;

113

/** Minimum search term length before searching */

114

@Input() minTermLength: number = 0;

115

/** Allow editing the search term */

116

@Input() editableSearchTerm: boolean = false;

117

118

// Dropdown positioning properties

119

/** Control dropdown open state */

120

@Input() isOpen: boolean;

121

/** Position of dropdown panel */

122

@Input() dropdownPosition: DropdownPosition = 'auto';

123

/** Element to append dropdown to (CSS selector or 'body') */

124

@Input() appendTo: string;

125

126

// Virtual scrolling properties

127

/** Enable virtual scrolling for large datasets */

128

@Input() virtualScroll: boolean = false;

129

/** Number of items to buffer when virtual scrolling */

130

@Input() bufferAmount: number = 4;

131

132

// Grouping properties

133

/** Group items by property name or function */

134

@Input() groupBy: string | ((item: any) => any);

135

/** Function to generate group values */

136

@Input() groupValue: GroupValueFn;

137

/** Allow selecting entire groups */

138

@Input() selectableGroup: boolean = false;

139

/** Include groups as part of the model */

140

@Input() selectableGroupAsModel: boolean = true;

141

/** Clear search term when adding new item */

142

@Input() get clearSearchOnAdd(): boolean { /* computed */ };

143

/** Allow deselecting items by clicking them again */

144

@Input() get deselectOnClick(): boolean { /* computed */ };

145

146

// Advanced properties

147

/** Custom search function */

148

@Input() searchFn: (term: string, item: any) => boolean;

149

/** TrackBy function for ngFor performance */

150

@Input() trackByFn: (index: number, item: any) => any;

151

/** Custom keydown handler function */

152

@Input() keyDownFn: (event: KeyboardEvent) => boolean;

153

/** Observable for typeahead functionality */

154

@Input() typeahead: Subject<string>;

155

/** Additional CSS classes */

156

@Input() ngClass: any;

157

/** Tab index for accessibility */

158

@Input() tabIndex: number;

159

/** Label ID for accessibility */

160

@Input() labelForId: string;

161

/** Additional input element attributes */

162

@Input() inputAttrs: {[key: string]: string} = {};

163

/** Enable tab focus on clear button */

164

@Input() tabFocusOnClearButton: boolean; // signal input

165

166

// Accessibility properties

167

/** ARIA label for the component */

168

@Input() ariaLabel: string | undefined;

169

/** ARIA labelledby attribute for accessibility */

170

@Input() ariaLabelledBy: string;

171

/** ARIA label for the dropdown */

172

@Input() ariaLabelDropdown: string = 'Options List';

173

174

// Events

175

/** Emitted when component loses focus */

176

@Output() blur: EventEmitter<any> = new EventEmitter();

177

/** Emitted when component gains focus */

178

@Output() focus: EventEmitter<any> = new EventEmitter();

179

/** Emitted when selection changes */

180

@Output() change: EventEmitter<any> = new EventEmitter();

181

/** Emitted when dropdown opens */

182

@Output() open: EventEmitter<void> = new EventEmitter();

183

/** Emitted when dropdown closes */

184

@Output() close: EventEmitter<void> = new EventEmitter();

185

/** Emitted when search term changes */

186

@Output() search: EventEmitter<{term: string, items: any[]}> = new EventEmitter();

187

/** Emitted when selection is cleared */

188

@Output() clear: EventEmitter<void> = new EventEmitter();

189

/** Emitted when item is added (including tags) */

190

@Output() add: EventEmitter<any> = new EventEmitter();

191

/** Emitted when item is removed */

192

@Output() remove: EventEmitter<any> = new EventEmitter();

193

/** Emitted during virtual scroll */

194

@Output() scroll: EventEmitter<{start: number, end: number}> = new EventEmitter();

195

/** Emitted when scrolled to end of list */

196

@Output() scrollToEnd: EventEmitter<void> = new EventEmitter();

197

198

// Public Properties

199

/** Array of currently selected items as NgOption objects */

200

selectedItems: NgOption[];

201

/** Array of raw selected values */

202

selectedValues: any[];

203

/** Whether the component currently has any selected values */

204

hasValue: boolean;

205

/** Current position of the dropdown panel */

206

currentPanelPosition: DropdownPosition;

207

/** Whether to show the add tag option */

208

showAddTag: boolean;

209

210

// Public Methods

211

/**

212

* Toggle the dropdown open/closed state

213

*/

214

toggle(): void;

215

216

/**

217

* Clear all selected items from the model

218

*/

219

clearModel(): void;

220

221

/**

222

* Select a specific item

223

* @param item - The NgOption to select

224

*/

225

select(item: NgOption): void;

226

227

/**

228

* Unselect a specific item

229

* @param item - The NgOption to unselect

230

*/

231

unselect(item: NgOption): void;

232

233

/**

234

* Toggle selection state of an item

235

* @param item - The NgOption to toggle

236

*/

237

toggleItem(item: NgOption): void;

238

239

/**

240

* Select the current tag being created

241

*/

242

selectTag(): void;

243

244

/**

245

* Determine if the clear button should be shown

246

* @returns true if clear button should be visible

247

*/

248

showClear(): boolean;

249

250

/**

251

* Focus on the clear button element

252

*/

253

focusOnClear(): void;

254

255

/**

256

* Determine if "no items found" message should be shown

257

* @returns true if no items message should be visible

258

*/

259

showNoItemsFound(): boolean;

260

261

/**

262

* Determine if "type to search" message should be shown

263

* @returns true if type to search message should be visible

264

*/

265

showTypeToSearch(): boolean;

266

267

/**

268

* Filter items based on search term

269

* @param term - The search term to filter by

270

*/

271

filter(term: string): void;

272

273

/**

274

* Handle composition start event (for IME input)

275

*/

276

onCompositionStart(): void;

277

278

/**

279

* Handle composition end event (for IME input)

280

* @param term - The composed search term

281

*/

282

onCompositionEnd(term: string): void;

283

284

/**

285

* Trigger change detection manually

286

*/

287

detectChanges(): void;

288

289

/**

290

* Clear a specific item from selection

291

* @param item - The item to clear

292

*/

293

clearItem(item: any): void;

294

295

/**

296

* TrackBy function for ngFor performance optimization

297

* @param index - The index of the item

298

* @param item - The NgOption item

299

* @returns Unique identifier for tracking

300

*/

301

trackByOption(index: number, item: NgOption): any;

302

}

303

```

304

305

**Usage Examples:**

306

307

```typescript

308

import { Component } from '@angular/core';

309

import { NgSelectComponent, NgOptionComponent } from '@ng-select/ng-select';

310

311

// Basic single select

312

@Component({

313

selector: 'app-basic-select',

314

standalone: true,

315

imports: [NgSelectComponent, NgOptionComponent],

316

template: `

317

<ng-select [(ngModel)]="selectedUser" bindLabel="name" bindValue="id">

318

<ng-option *ngFor="let user of users" [value]="user.id">

319

{{ user.name }}

320

</ng-option>

321

</ng-select>

322

`

323

})

324

export class BasicSelectComponent {

325

selectedUser: number;

326

users = [

327

{id: 1, name: 'Alice'},

328

{id: 2, name: 'Bob'}

329

];

330

}

331

332

// Multi-select with custom templates

333

@Component({

334

template: `

335

<ng-select

336

[(ngModel)]="selectedUsers"

337

[multiple]="true"

338

[closeOnSelect]="false"

339

[clearable]="true"

340

placeholder="Select users">

341

342

<ng-option *ngFor="let user of users" [value]="user">

343

<img [src]="user.avatar" width="20"> {{ user.name }}

344

</ng-option>

345

346

<ng-label-tmp let-item="item" let-clear="clear">

347

<span class="ng-value-label">{{ item.name }}</span>

348

<span class="ng-value-icon right" (click)="clear(item)">×</span>

349

</ng-label-tmp>

350

</ng-select>

351

`

352

})

353

export class MultiSelectComponent {

354

selectedUsers: any[] = [];

355

users = [

356

{id: 1, name: 'Alice', avatar: 'alice.jpg'},

357

{id: 2, name: 'Bob', avatar: 'bob.jpg'}

358

];

359

}

360

361

// Virtual scrolling for large datasets

362

@Component({

363

template: `

364

<ng-select

365

[(ngModel)]="selectedItems"

366

[items]="largeDataset"

367

bindLabel="name"

368

bindValue="id"

369

[virtualScroll]="true"

370

[bufferAmount]="20"

371

placeholder="Search in 10,000 items...">

372

</ng-select>

373

`

374

})

375

export class VirtualScrollComponent {

376

selectedItems: any[];

377

largeDataset = Array.from({length: 10000}, (_, i) => ({

378

id: i,

379

name: `Item ${i + 1}`

380

}));

381

}

382

```

383

384

## Host Bindings and CSS Classes

385

386

The NgSelectComponent automatically applies CSS classes and attributes through @HostBinding decorators:

387

388

```typescript { .api }

389

/**

390

* CSS classes automatically applied by the component:

391

* - 'ng-select': Base component class

392

* - 'ng-select-single': Applied when multiple=false

393

* - 'ng-select-multiple': Applied when multiple=true

394

* - 'ng-select-searchable': Applied when searchable=true

395

* - 'ng-select-clearable': Applied when clearable=true

396

* - 'ng-select-opened': Applied when dropdown is open

397

* - 'ng-select-disabled': Applied when disabled=true

398

* - 'ng-select-focused': Applied when component has focus

399

* - 'ng-select-loading': Applied when loading=true

400

* - 'ng-select-readonly': Applied when readonly=true

401

* - 'ng-select-filtered': Applied when items are filtered

402

*

403

* Attributes:

404

* - 'role': Set to 'combobox' for accessibility

405

* - 'aria-expanded': Reflects dropdown open state

406

* - 'aria-haspopup': Set to 'listbox'

407

* - 'tabindex': Controlled by tabIndex input

408

*/

409

```

410

411

## Advanced Usage Examples

412

413

**Custom Search and Tag Management:**

414

415

```typescript

416

@Component({

417

template: `

418

<ng-select

419

[(ngModel)]="selectedItems"

420

[items]="filteredItems"

421

[addTag]="addTagFn"

422

[clearSearchOnAdd]="true"

423

[deselectOnClick]="true"

424

[editableSearchTerm]="true"

425

[searchWhileComposing]="false"

426

bindLabel="name"

427

bindValue="id"

428

placeholder="Search or add new items...">

429

</ng-select>

430

`

431

})

432

export class AdvancedSelectComponent {

433

selectedItems: any[] = [];

434

allItems = [

435

{id: 1, name: 'Existing Item 1'},

436

{id: 2, name: 'Existing Item 2'}

437

];

438

439

get filteredItems() {

440

// Custom filtering logic

441

return this.allItems;

442

}

443

444

addTagFn = (term: string) => {

445

return { id: Date.now(), name: term, isNew: true };

446

};

447

}

448

```

449

450

**Accessibility and Keyboard Navigation:**

451

452

```typescript

453

@Component({

454

template: `

455

<ng-select

456

[(ngModel)]="selected"

457

[items]="items"

458

[keyDownFn]="customKeyHandler"

459

[tabFocusOnClearButton]="true"

460

[ariaLabel]="'Select your preferred option'"

461

[ariaLabelDropdown]="'Available options list'"

462

bindLabel="label"

463

bindValue="value">

464

</ng-select>

465

`

466

})

467

export class AccessibleSelectComponent {

468

selected: any;

469

items = [

470

{value: 'option1', label: 'First Option'},

471

{value: 'option2', label: 'Second Option'}

472

];

473

474

customKeyHandler = (event: KeyboardEvent): boolean => {

475

// Custom keyboard handling

476

if (event.key === 'F2') {

477

// Custom behavior for F2 key

478

return false; // Prevent default

479

}

480

return true; // Allow default behavior

481

};

482

}

483

```

484

485

**Programmatic Control:**

486

487

```typescript

488

@Component({

489

template: `

490

<ng-select #selectRef [(ngModel)]="selected" [items]="items" bindLabel="name">

491

</ng-select>

492

493

<button (click)="toggleDropdown()">Toggle Dropdown</button>

494

<button (click)="clearAll()">Clear All</button>

495

<button (click)="selectFirst()">Select First Item</button>

496

<button (click)="focusClear()" [disabled]="!selectRef.showClear()">Focus Clear</button>

497

498

<div>

499

Selected Items: {{ selectRef.selectedItems?.length || 0 }}

500

Has Value: {{ selectRef.hasValue }}

501

Current Position: {{ selectRef.currentPanelPosition }}

502

</div>

503

`

504

})

505

export class ProgrammaticControlComponent {

506

@ViewChild('selectRef') selectComponent: NgSelectComponent;

507

508

selected: any;

509

items = [

510

{id: 1, name: 'Item 1'},

511

{id: 2, name: 'Item 2'},

512

{id: 3, name: 'Item 3'}

513

];

514

515

toggleDropdown() {

516

this.selectComponent.toggle();

517

}

518

519

clearAll() {

520

this.selectComponent.clearModel();

521

}

522

523

selectFirst() {

524

if (this.items.length > 0) {

525

this.selectComponent.select(this.items[0]);

526

}

527

}

528

529

focusClear() {

530

this.selectComponent.focusOnClear();

531

}

532

}

533

```

534

535

### NgOptionComponent

536

537

Individual option component for dropdown items.

538

539

```typescript { .api }

540

/**

541

* Component representing an individual option in the dropdown

542

*/

543

@Component({

544

selector: 'ng-option'

545

})

546

export class NgOptionComponent {

547

/** Value of this option */

548

@Input() value: any;

549

/** Whether this option is disabled */

550

@Input() disabled: boolean = false;

551

}

552

```

553

554

**Usage Example:**

555

556

```typescript

557

@Component({

558

template: `

559

<ng-select [(ngModel)]="selected">

560

<ng-option value="option1">Option 1</ng-option>

561

<ng-option value="option2" [disabled]="true">Option 2 (Disabled)</ng-option>

562

<ng-option value="option3">Option 3</ng-option>

563

</ng-select>

564

`

565

})

566

export class OptionsComponent {

567

selected: string;

568

}

569

```

570

571

### NgDropdownPanelComponent

572

573

Dropdown panel container component handling the display and positioning of options.

574

575

```typescript { .api }

576

/**

577

* Dropdown panel container component

578

*/

579

@Component({

580

selector: 'ng-dropdown-panel'

581

})

582

export class NgDropdownPanelComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit {

583

/** Items to display in the panel */

584

@Input() items: NgOption[];

585

/** Currently marked/highlighted item */

586

@Input() markedItem: NgOption;

587

/** Position of the panel relative to select */

588

@Input() position: DropdownPosition = 'auto';

589

/** Element to append panel to */

590

@Input() appendTo: string;

591

/** Buffer amount for virtual scrolling */

592

@Input() bufferAmount: number = 4;

593

/** Enable virtual scrolling */

594

@Input() virtualScroll: boolean = false;

595

/** Template for panel header */

596

@Input() headerTemplate: TemplateRef<any>;

597

/** Template for panel footer */

598

@Input() footerTemplate: TemplateRef<any>;

599

/** Current filter/search value */

600

@Input() filterValue: string;

601

602

/** Emitted when panel items are updated */

603

@Output() update: EventEmitter<any[]> = new EventEmitter();

604

/** Emitted during scrolling */

605

@Output() scroll: EventEmitter<{start: number, end: number}> = new EventEmitter();

606

/** Emitted when scrolled to end */

607

@Output() scrollToEnd: EventEmitter<void> = new EventEmitter();

608

/** Emitted when clicked outside panel */

609

@Output() outsideClick: EventEmitter<void> = new EventEmitter();

610

}

611

```