@ngneers/controls 0.0.1-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ngneers-controls-accordion.mjs +234 -0
- package/fesm2022/ngneers-controls-accordion.mjs.map +1 -0
- package/fesm2022/ngneers-controls-api-ng.mjs +959 -0
- package/fesm2022/ngneers-controls-api-ng.mjs.map +1 -0
- package/fesm2022/ngneers-controls-api-resize.mjs +712 -0
- package/fesm2022/ngneers-controls-api-resize.mjs.map +1 -0
- package/fesm2022/ngneers-controls-api.mjs +347 -0
- package/fesm2022/ngneers-controls-api.mjs.map +1 -0
- package/fesm2022/ngneers-controls-avatar.mjs +77 -0
- package/fesm2022/ngneers-controls-avatar.mjs.map +1 -0
- package/fesm2022/ngneers-controls-base.mjs +620 -0
- package/fesm2022/ngneers-controls-base.mjs.map +1 -0
- package/fesm2022/ngneers-controls-breadcrumb.mjs +100 -0
- package/fesm2022/ngneers-controls-breadcrumb.mjs.map +1 -0
- package/fesm2022/ngneers-controls-button-group.mjs +110 -0
- package/fesm2022/ngneers-controls-button-group.mjs.map +1 -0
- package/fesm2022/ngneers-controls-button.mjs +83 -0
- package/fesm2022/ngneers-controls-button.mjs.map +1 -0
- package/fesm2022/ngneers-controls-calendar-time-CJT5AFlA.mjs +74 -0
- package/fesm2022/ngneers-controls-calendar-time-CJT5AFlA.mjs.map +1 -0
- package/fesm2022/ngneers-controls-calendar.mjs +801 -0
- package/fesm2022/ngneers-controls-calendar.mjs.map +1 -0
- package/fesm2022/ngneers-controls-checkbox.mjs +63 -0
- package/fesm2022/ngneers-controls-checkbox.mjs.map +1 -0
- package/fesm2022/ngneers-controls-chip.mjs +55 -0
- package/fesm2022/ngneers-controls-chip.mjs.map +1 -0
- package/fesm2022/ngneers-controls-default-icons.mjs +82 -0
- package/fesm2022/ngneers-controls-default-icons.mjs.map +1 -0
- package/fesm2022/ngneers-controls-defer.mjs +72 -0
- package/fesm2022/ngneers-controls-defer.mjs.map +1 -0
- package/fesm2022/ngneers-controls-dialog.mjs +407 -0
- package/fesm2022/ngneers-controls-dialog.mjs.map +1 -0
- package/fesm2022/ngneers-controls-directives.mjs +498 -0
- package/fesm2022/ngneers-controls-directives.mjs.map +1 -0
- package/fesm2022/ngneers-controls-drawer.mjs +271 -0
- package/fesm2022/ngneers-controls-drawer.mjs.map +1 -0
- package/fesm2022/ngneers-controls-edit-inplace.mjs +127 -0
- package/fesm2022/ngneers-controls-edit-inplace.mjs.map +1 -0
- package/fesm2022/ngneers-controls-errors.mjs +329 -0
- package/fesm2022/ngneers-controls-errors.mjs.map +1 -0
- package/fesm2022/ngneers-controls-filter.mjs +708 -0
- package/fesm2022/ngneers-controls-filter.mjs.map +1 -0
- package/fesm2022/ngneers-controls-hint.mjs +153 -0
- package/fesm2022/ngneers-controls-hint.mjs.map +1 -0
- package/fesm2022/ngneers-controls-i18n-translations-de.mjs +170 -0
- package/fesm2022/ngneers-controls-i18n-translations-de.mjs.map +1 -0
- package/fesm2022/ngneers-controls-i18n-translations-en.mjs +170 -0
- package/fesm2022/ngneers-controls-i18n-translations-en.mjs.map +1 -0
- package/fesm2022/ngneers-controls-i18n.mjs +57 -0
- package/fesm2022/ngneers-controls-i18n.mjs.map +1 -0
- package/fesm2022/ngneers-controls-icon.mjs +195 -0
- package/fesm2022/ngneers-controls-icon.mjs.map +1 -0
- package/fesm2022/ngneers-controls-inplace.mjs +150 -0
- package/fesm2022/ngneers-controls-inplace.mjs.map +1 -0
- package/fesm2022/ngneers-controls-input-field.mjs +165 -0
- package/fesm2022/ngneers-controls-input-field.mjs.map +1 -0
- package/fesm2022/ngneers-controls-input.mjs +72 -0
- package/fesm2022/ngneers-controls-input.mjs.map +1 -0
- package/fesm2022/ngneers-controls-item-view.mjs +473 -0
- package/fesm2022/ngneers-controls-item-view.mjs.map +1 -0
- package/fesm2022/ngneers-controls-list-box.mjs +281 -0
- package/fesm2022/ngneers-controls-list-box.mjs.map +1 -0
- package/fesm2022/ngneers-controls-mask-input.mjs +888 -0
- package/fesm2022/ngneers-controls-mask-input.mjs.map +1 -0
- package/fesm2022/ngneers-controls-menu.mjs +371 -0
- package/fesm2022/ngneers-controls-menu.mjs.map +1 -0
- package/fesm2022/ngneers-controls-message.mjs +30 -0
- package/fesm2022/ngneers-controls-message.mjs.map +1 -0
- package/fesm2022/ngneers-controls-number-input.mjs +366 -0
- package/fesm2022/ngneers-controls-number-input.mjs.map +1 -0
- package/fesm2022/ngneers-controls-paginator.mjs +129 -0
- package/fesm2022/ngneers-controls-paginator.mjs.map +1 -0
- package/fesm2022/ngneers-controls-popover.mjs +215 -0
- package/fesm2022/ngneers-controls-popover.mjs.map +1 -0
- package/fesm2022/ngneers-controls-progress.mjs +98 -0
- package/fesm2022/ngneers-controls-progress.mjs.map +1 -0
- package/fesm2022/ngneers-controls-radio.mjs +152 -0
- package/fesm2022/ngneers-controls-radio.mjs.map +1 -0
- package/fesm2022/ngneers-controls-roving-focus.mjs +323 -0
- package/fesm2022/ngneers-controls-roving-focus.mjs.map +1 -0
- package/fesm2022/ngneers-controls-scroll-shadow.mjs +65 -0
- package/fesm2022/ngneers-controls-scroll-shadow.mjs.map +1 -0
- package/fesm2022/ngneers-controls-scroller.mjs +308 -0
- package/fesm2022/ngneers-controls-scroller.mjs.map +1 -0
- package/fesm2022/ngneers-controls-select-button.mjs +58 -0
- package/fesm2022/ngneers-controls-select-button.mjs.map +1 -0
- package/fesm2022/ngneers-controls-select.mjs +417 -0
- package/fesm2022/ngneers-controls-select.mjs.map +1 -0
- package/fesm2022/ngneers-controls-slider.mjs +167 -0
- package/fesm2022/ngneers-controls-slider.mjs.map +1 -0
- package/fesm2022/ngneers-controls-snackbar.mjs +414 -0
- package/fesm2022/ngneers-controls-snackbar.mjs.map +1 -0
- package/fesm2022/ngneers-controls-spin-buttons.mjs +126 -0
- package/fesm2022/ngneers-controls-spin-buttons.mjs.map +1 -0
- package/fesm2022/ngneers-controls-spinner.mjs +184 -0
- package/fesm2022/ngneers-controls-spinner.mjs.map +1 -0
- package/fesm2022/ngneers-controls-splitter.mjs +604 -0
- package/fesm2022/ngneers-controls-splitter.mjs.map +1 -0
- package/fesm2022/ngneers-controls-state.mjs +185 -0
- package/fesm2022/ngneers-controls-state.mjs.map +1 -0
- package/fesm2022/ngneers-controls-switch.mjs +39 -0
- package/fesm2022/ngneers-controls-switch.mjs.map +1 -0
- package/fesm2022/ngneers-controls-table.mjs +2634 -0
- package/fesm2022/ngneers-controls-table.mjs.map +1 -0
- package/fesm2022/ngneers-controls-tabs.mjs +336 -0
- package/fesm2022/ngneers-controls-tabs.mjs.map +1 -0
- package/fesm2022/ngneers-controls-tag.mjs +30 -0
- package/fesm2022/ngneers-controls-tag.mjs.map +1 -0
- package/fesm2022/ngneers-controls-toast.mjs +350 -0
- package/fesm2022/ngneers-controls-toast.mjs.map +1 -0
- package/fesm2022/ngneers-controls-toggle-button.mjs +70 -0
- package/fesm2022/ngneers-controls-toggle-button.mjs.map +1 -0
- package/fesm2022/ngneers-controls-tooltip.mjs +506 -0
- package/fesm2022/ngneers-controls-tooltip.mjs.map +1 -0
- package/fesm2022/ngneers-controls-tree.mjs +599 -0
- package/fesm2022/ngneers-controls-tree.mjs.map +1 -0
- package/fesm2022/ngneers-controls-upload.mjs +377 -0
- package/fesm2022/ngneers-controls-upload.mjs.map +1 -0
- package/fesm2022/ngneers-controls-utils-ng.mjs +411 -0
- package/fesm2022/ngneers-controls-utils-ng.mjs.map +1 -0
- package/fesm2022/ngneers-controls-utils.mjs +261 -0
- package/fesm2022/ngneers-controls-utils.mjs.map +1 -0
- package/fesm2022/ngneers-controls.mjs +6 -0
- package/fesm2022/ngneers-controls.mjs.map +1 -0
- package/package.json +302 -0
- package/types/ngneers-controls-accordion.d.ts +139 -0
- package/types/ngneers-controls-api-ng.d.ts +364 -0
- package/types/ngneers-controls-api-resize.d.ts +318 -0
- package/types/ngneers-controls-api.d.ts +145 -0
- package/types/ngneers-controls-avatar.d.ts +54 -0
- package/types/ngneers-controls-base.d.ts +277 -0
- package/types/ngneers-controls-breadcrumb.d.ts +272 -0
- package/types/ngneers-controls-button-group.d.ts +46 -0
- package/types/ngneers-controls-button.d.ts +48 -0
- package/types/ngneers-controls-calendar.d.ts +466 -0
- package/types/ngneers-controls-checkbox.d.ts +40 -0
- package/types/ngneers-controls-chip.d.ts +202 -0
- package/types/ngneers-controls-default-icons.d.ts +5 -0
- package/types/ngneers-controls-defer.d.ts +48 -0
- package/types/ngneers-controls-dialog.d.ts +399 -0
- package/types/ngneers-controls-directives.d.ts +171 -0
- package/types/ngneers-controls-drawer.d.ts +308 -0
- package/types/ngneers-controls-edit-inplace.d.ts +263 -0
- package/types/ngneers-controls-errors.d.ts +155 -0
- package/types/ngneers-controls-filter.d.ts +609 -0
- package/types/ngneers-controls-hint.d.ts +88 -0
- package/types/ngneers-controls-i18n-translations-de.d.ts +164 -0
- package/types/ngneers-controls-i18n-translations-en.d.ts +164 -0
- package/types/ngneers-controls-i18n.d.ts +186 -0
- package/types/ngneers-controls-icon.d.ts +68 -0
- package/types/ngneers-controls-inplace.d.ts +98 -0
- package/types/ngneers-controls-input-field.d.ts +248 -0
- package/types/ngneers-controls-input.d.ts +30 -0
- package/types/ngneers-controls-item-view.d.ts +215 -0
- package/types/ngneers-controls-list-box.d.ts +334 -0
- package/types/ngneers-controls-mask-input.d.ts +434 -0
- package/types/ngneers-controls-menu.d.ts +192 -0
- package/types/ngneers-controls-message.d.ts +21 -0
- package/types/ngneers-controls-number-input.d.ts +146 -0
- package/types/ngneers-controls-paginator.d.ts +255 -0
- package/types/ngneers-controls-popover.d.ts +116 -0
- package/types/ngneers-controls-progress.d.ts +49 -0
- package/types/ngneers-controls-radio.d.ts +91 -0
- package/types/ngneers-controls-roving-focus.d.ts +107 -0
- package/types/ngneers-controls-scroll-shadow.d.ts +25 -0
- package/types/ngneers-controls-scroller.d.ts +151 -0
- package/types/ngneers-controls-select-button.d.ts +51 -0
- package/types/ngneers-controls-select.d.ts +409 -0
- package/types/ngneers-controls-slider.d.ts +57 -0
- package/types/ngneers-controls-snackbar.d.ts +330 -0
- package/types/ngneers-controls-spin-buttons.d.ts +69 -0
- package/types/ngneers-controls-spinner.d.ts +117 -0
- package/types/ngneers-controls-splitter.d.ts +465 -0
- package/types/ngneers-controls-state.d.ts +102 -0
- package/types/ngneers-controls-switch.d.ts +18 -0
- package/types/ngneers-controls-table.d.ts +3127 -0
- package/types/ngneers-controls-tabs.d.ts +118 -0
- package/types/ngneers-controls-tag.d.ts +21 -0
- package/types/ngneers-controls-toast.d.ts +298 -0
- package/types/ngneers-controls-toggle-button.d.ts +48 -0
- package/types/ngneers-controls-tooltip.d.ts +189 -0
- package/types/ngneers-controls-tree.d.ts +409 -0
- package/types/ngneers-controls-upload.d.ts +347 -0
- package/types/ngneers-controls-utils-ng.d.ts +129 -0
- package/types/ngneers-controls-utils.d.ts +130 -0
- package/types/ngneers-controls.d.ts +2 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { NgTemplateOutlet } from '@angular/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { viewChild, contentChild, input, computed, Directive, inject, booleanAttribute, output, signal, effect, afterRenderEffect, untracked, Component } from '@angular/core';
|
|
4
|
+
import { flatItems, filterOptions, mapToItems } from '@ngneers/controls/api';
|
|
5
|
+
import { templateTypesFn, NgnTemplate } from '@ngneers/controls/api/ng';
|
|
6
|
+
import { ValueControlBase, NgnPt, provideSelf } from '@ngneers/controls/base';
|
|
7
|
+
import { NgnCheckbox } from '@ngneers/controls/checkbox';
|
|
8
|
+
import { I18n } from '@ngneers/controls/i18n';
|
|
9
|
+
import { NgnScroller, NgnScrollerItem } from '@ngneers/controls/scroller';
|
|
10
|
+
import { createConditionalSpinner } from '@ngneers/controls/spinner';
|
|
11
|
+
import { maybeCallback } from '@ngneers/controls/utils';
|
|
12
|
+
import { asyncComputed } from '@ngneers/controls/utils-ng';
|
|
13
|
+
import { listBoxControlTemplate } from '@ngneers/controls-themes/templates/list-box';
|
|
14
|
+
|
|
15
|
+
class ListBoxTemplates extends ValueControlBase {
|
|
16
|
+
// Item template
|
|
17
|
+
_defaultItemTemplate = viewChild.required('defaultItemTemplate');
|
|
18
|
+
_userItemTemplate = contentChild('item', /* @ts-ignore */
|
|
19
|
+
...(ngDevMode ? [{ debugName: "_userItemTemplate" }] : /* istanbul ignore next */ []));
|
|
20
|
+
/**
|
|
21
|
+
* Set a custom template for an item of the list box.
|
|
22
|
+
* Can also be set using an `<ng-template>` element with `#item` template reference variable.
|
|
23
|
+
*/
|
|
24
|
+
templateItem = input(null, /* @ts-ignore */
|
|
25
|
+
...(ngDevMode ? [{ debugName: "templateItem" }] : /* istanbul ignore next */ []));
|
|
26
|
+
itemTemplate = computed(() => this._userItemTemplate() ?? this.templateItem() ?? this._defaultItemTemplate(), /* @ts-ignore */
|
|
27
|
+
...(ngDevMode ? [{ debugName: "itemTemplate" }] : /* istanbul ignore next */ []));
|
|
28
|
+
// Group template
|
|
29
|
+
_defaultGroupTemplate = viewChild.required('defaultGroupTemplate');
|
|
30
|
+
_userGroupTemplate = contentChild('group', /* @ts-ignore */
|
|
31
|
+
...(ngDevMode ? [{ debugName: "_userGroupTemplate" }] : /* istanbul ignore next */ []));
|
|
32
|
+
/**
|
|
33
|
+
* Set a custom template for a group in the list box.
|
|
34
|
+
* Can also be set using an `<ng-template>` element with `#group` template reference variable.
|
|
35
|
+
*/
|
|
36
|
+
templateGroup = input(null, /* @ts-ignore */
|
|
37
|
+
...(ngDevMode ? [{ debugName: "templateGroup" }] : /* istanbul ignore next */ []));
|
|
38
|
+
groupTemplate = computed(() => this._userGroupTemplate() ?? this.templateGroup() ?? this._defaultGroupTemplate(), /* @ts-ignore */
|
|
39
|
+
...(ngDevMode ? [{ debugName: "groupTemplate" }] : /* istanbul ignore next */ []));
|
|
40
|
+
// Empty template
|
|
41
|
+
_defaultEmptyTemplate = viewChild.required('defaultEmptyTemplate');
|
|
42
|
+
_userEmptyTemplate = contentChild('empty', /* @ts-ignore */
|
|
43
|
+
...(ngDevMode ? [{ debugName: "_userEmptyTemplate" }] : /* istanbul ignore next */ []));
|
|
44
|
+
/**
|
|
45
|
+
* Set a custom template for the empty state in the list box.
|
|
46
|
+
* Can also be set using an `<ng-template>` element with `#empty` template reference variable.
|
|
47
|
+
*/
|
|
48
|
+
templateEmpty = input(null, /* @ts-ignore */
|
|
49
|
+
...(ngDevMode ? [{ debugName: "templateEmpty" }] : /* istanbul ignore next */ []));
|
|
50
|
+
emptyTemplate = computed(() => this._userEmptyTemplate() ?? this.templateEmpty() ?? this._defaultEmptyTemplate(), /* @ts-ignore */
|
|
51
|
+
...(ngDevMode ? [{ debugName: "emptyTemplate" }] : /* istanbul ignore next */ []));
|
|
52
|
+
/**
|
|
53
|
+
* Types for the dialog templates.
|
|
54
|
+
*/
|
|
55
|
+
templateTypes = templateTypesFn();
|
|
56
|
+
templateTypesInternal = templateTypesFn();
|
|
57
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ListBoxTemplates, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
58
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "22.0.5", type: ListBoxTemplates, isStandalone: true, inputs: { templateItem: { classPropertyName: "templateItem", publicName: "templateItem", isSignal: true, isRequired: false, transformFunction: null }, templateGroup: { classPropertyName: "templateGroup", publicName: "templateGroup", isSignal: true, isRequired: false, transformFunction: null }, templateEmpty: { classPropertyName: "templateEmpty", publicName: "templateEmpty", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "_userItemTemplate", first: true, predicate: ["item"], descendants: true, isSignal: true }, { propertyName: "_userGroupTemplate", first: true, predicate: ["group"], descendants: true, isSignal: true }, { propertyName: "_userEmptyTemplate", first: true, predicate: ["empty"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "_defaultItemTemplate", first: true, predicate: ["defaultItemTemplate"], descendants: true, isSignal: true }, { propertyName: "_defaultGroupTemplate", first: true, predicate: ["defaultGroupTemplate"], descendants: true, isSignal: true }, { propertyName: "_defaultEmptyTemplate", first: true, predicate: ["defaultEmptyTemplate"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0 });
|
|
59
|
+
}
|
|
60
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ListBoxTemplates, decorators: [{
|
|
61
|
+
type: Directive
|
|
62
|
+
}], propDecorators: { _defaultItemTemplate: [{ type: i0.ViewChild, args: ['defaultItemTemplate', { isSignal: true }] }], _userItemTemplate: [{ type: i0.ContentChild, args: ['item', { isSignal: true }] }], templateItem: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateItem", required: false }] }], _defaultGroupTemplate: [{ type: i0.ViewChild, args: ['defaultGroupTemplate', { isSignal: true }] }], _userGroupTemplate: [{ type: i0.ContentChild, args: ['group', { isSignal: true }] }], templateGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateGroup", required: false }] }], _defaultEmptyTemplate: [{ type: i0.ViewChild, args: ['defaultEmptyTemplate', { isSignal: true }] }], _userEmptyTemplate: [{ type: i0.ContentChild, args: ['empty', { isSignal: true }] }], templateEmpty: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateEmpty", required: false }] }] } });
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @category control
|
|
66
|
+
*/
|
|
67
|
+
class NgnListBox extends ListBoxTemplates {
|
|
68
|
+
i18n = inject(I18n).translations;
|
|
69
|
+
theme = this.injectThemeTemplate(listBoxControlTemplate, {
|
|
70
|
+
root: true,
|
|
71
|
+
invalid: () => this.invalid(),
|
|
72
|
+
empty: () => !this.displayedItems().length,
|
|
73
|
+
});
|
|
74
|
+
_scroller = viewChild.required(NgnScroller);
|
|
75
|
+
/**
|
|
76
|
+
* The items to display in the list box.
|
|
77
|
+
*/
|
|
78
|
+
items = input.required(/* @ts-ignore */
|
|
79
|
+
...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
80
|
+
/**
|
|
81
|
+
* Whether to scroll to the selected item when the list box is first rendered.
|
|
82
|
+
* Pass a `ScrollLogicalPosition` to control where the item lands in the viewport.
|
|
83
|
+
* @default false
|
|
84
|
+
*/
|
|
85
|
+
scrollToSelectedItemOnInit = input(false, /* @ts-ignore */
|
|
86
|
+
...(ngDevMode ? [{ debugName: "scrollToSelectedItemOnInit" }] : /* istanbul ignore next */ []));
|
|
87
|
+
/**
|
|
88
|
+
* Whether items can be selected by the user.
|
|
89
|
+
* @default false
|
|
90
|
+
*/
|
|
91
|
+
selectable = input(false, { ...(ngDevMode ? { debugName: "selectable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
92
|
+
/**
|
|
93
|
+
* Whether hovering an item selects it.
|
|
94
|
+
* @default false
|
|
95
|
+
*/
|
|
96
|
+
selectOnHover = input(false, { ...(ngDevMode ? { debugName: "selectOnHover" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
97
|
+
/**
|
|
98
|
+
* Whether the list box itself is focusable and participates in keyboard navigation.
|
|
99
|
+
* @default true
|
|
100
|
+
*/
|
|
101
|
+
focussable = input(true, { ...(ngDevMode ? { debugName: "focussable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
102
|
+
/**
|
|
103
|
+
* Whether the list is virtualized.
|
|
104
|
+
* @default false
|
|
105
|
+
*/
|
|
106
|
+
virtual = input(false, { ...(ngDevMode ? { debugName: "virtual" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
107
|
+
/**
|
|
108
|
+
* When {@link virtual} is enabled, this defines the height of each item in the list.
|
|
109
|
+
*/
|
|
110
|
+
itemHeight = input(/* @ts-ignore */
|
|
111
|
+
...(ngDevMode ? [undefined, { debugName: "itemHeight" }] : /* istanbul ignore next */ []));
|
|
112
|
+
/**
|
|
113
|
+
* Enable this to allow the user to select multiple values.
|
|
114
|
+
* When enabled, the value of the control becomes an array of selected items.
|
|
115
|
+
*/
|
|
116
|
+
multiple = input(/* @ts-ignore */
|
|
117
|
+
...(ngDevMode ? [undefined, { debugName: "multiple" }] : /* istanbul ignore next */ []));
|
|
118
|
+
/**
|
|
119
|
+
* Whether to use a checkbox to indicate selection state.
|
|
120
|
+
*
|
|
121
|
+
* This option is true per default when {@link multiple} is `true`.
|
|
122
|
+
* @default multiple()
|
|
123
|
+
*/
|
|
124
|
+
checkbox = input(/* @ts-ignore */
|
|
125
|
+
...(ngDevMode ? [undefined, { debugName: "checkbox" }] : /* istanbul ignore next */ []));
|
|
126
|
+
/**
|
|
127
|
+
* Accepts a boolean value that determines whether the filter is enabled.
|
|
128
|
+
* Alternatively, you can provide `FilterConfig` to customize the filter behavior.
|
|
129
|
+
* @default `false`
|
|
130
|
+
*/
|
|
131
|
+
filter = input(false, /* @ts-ignore */
|
|
132
|
+
...(ngDevMode ? [{ debugName: "filter" }] : /* istanbul ignore next */ []));
|
|
133
|
+
/**
|
|
134
|
+
* Manually set the filter text.
|
|
135
|
+
*/
|
|
136
|
+
filterText = input(null, /* @ts-ignore */
|
|
137
|
+
...(ngDevMode ? [{ debugName: "filterText" }] : /* istanbul ignore next */ []));
|
|
138
|
+
/**
|
|
139
|
+
* Emitted when an item is clicked, carrying the value of that item.
|
|
140
|
+
*/
|
|
141
|
+
itemClicked = output();
|
|
142
|
+
maybeCallback = maybeCallback;
|
|
143
|
+
displayedItems = computed(() => flatItems(this.filteredItems()), /* @ts-ignore */
|
|
144
|
+
...(ngDevMode ? [{ debugName: "displayedItems" }] : /* istanbul ignore next */ []));
|
|
145
|
+
valueArray = computed(() => {
|
|
146
|
+
const v = this.value();
|
|
147
|
+
return (Array.isArray(v) ? v : v ? [v] : []);
|
|
148
|
+
}, /* @ts-ignore */
|
|
149
|
+
...(ngDevMode ? [{ debugName: "valueArray" }] : /* istanbul ignore next */ []));
|
|
150
|
+
currentHighlightedValue = signal(null, /* @ts-ignore */
|
|
151
|
+
...(ngDevMode ? [{ debugName: "currentHighlightedValue" }] : /* istanbul ignore next */ []));
|
|
152
|
+
filteredItems = asyncComputed(async () => {
|
|
153
|
+
const filter = !!this.filter();
|
|
154
|
+
const appliedFilterOptions = this._appliedFilterOptions();
|
|
155
|
+
const filterText = this.filterText();
|
|
156
|
+
if (!filter || !filterText) {
|
|
157
|
+
return this.items();
|
|
158
|
+
}
|
|
159
|
+
return await filterOptions(this.items(), filterText, appliedFilterOptions);
|
|
160
|
+
}, []);
|
|
161
|
+
_appliedFilterOptions = computed(() => {
|
|
162
|
+
const filter = this.filter();
|
|
163
|
+
const providedFilterArgs = typeof filter === 'boolean' ? {} : filter;
|
|
164
|
+
const options = {
|
|
165
|
+
filterFieldsCallback: item => item.label,
|
|
166
|
+
fieldItems: 'items',
|
|
167
|
+
splitWords: true,
|
|
168
|
+
caseSensitive: false,
|
|
169
|
+
filterFn: 'contains',
|
|
170
|
+
...providedFilterArgs,
|
|
171
|
+
};
|
|
172
|
+
return options;
|
|
173
|
+
}, /* @ts-ignore */
|
|
174
|
+
...(ngDevMode ? [{ debugName: "_appliedFilterOptions" }] : /* istanbul ignore next */ []));
|
|
175
|
+
filterIsExecuting = this.filteredItems.isRunning;
|
|
176
|
+
showCheckboxes = computed(() => this.checkbox() ?? this.multiple() ?? false, /* @ts-ignore */
|
|
177
|
+
...(ngDevMode ? [{ debugName: "showCheckboxes" }] : /* istanbul ignore next */ []));
|
|
178
|
+
constructor() {
|
|
179
|
+
super();
|
|
180
|
+
createConditionalSpinner(this.filterIsExecuting);
|
|
181
|
+
effect(() => {
|
|
182
|
+
const currentHighlightedValue = this.currentHighlightedValue();
|
|
183
|
+
if (!currentHighlightedValue) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const index = flatItems(this.filteredItems()).findIndex(option => option.value === currentHighlightedValue);
|
|
187
|
+
this._scroller().scrollToIndex(index);
|
|
188
|
+
});
|
|
189
|
+
afterRenderEffect(() => {
|
|
190
|
+
const pos = this.scrollToSelectedItemOnInit();
|
|
191
|
+
const filterDone = this.filteredItems.firstRunCompleted();
|
|
192
|
+
if (pos && filterDone) {
|
|
193
|
+
const val = untracked(this.value);
|
|
194
|
+
const index = flatItems(untracked(this.filteredItems)).findIndex(option => option.value === val);
|
|
195
|
+
this._scroller().scrollToIndex(index, pos === true ? 'nearest' : pos);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
onKeyDown(event) {
|
|
200
|
+
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
201
|
+
event.stopPropagation();
|
|
202
|
+
event.preventDefault();
|
|
203
|
+
const flattenedItems = mapToItems(this.filteredItems());
|
|
204
|
+
this.currentHighlightedValue.update(currentValue => {
|
|
205
|
+
const enabledItems = flattenedItems.filter(item => !item.disabled);
|
|
206
|
+
if (enabledItems.length === 0) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
const currentHighlightIndex = enabledItems.findIndex(option => option.value === currentValue);
|
|
210
|
+
const currentIndex = currentHighlightIndex >= 0
|
|
211
|
+
? currentHighlightIndex
|
|
212
|
+
: enabledItems.findIndex(option => option.value === this.valueArray()[this.valueArray().length - 1]);
|
|
213
|
+
if (currentIndex === -1) {
|
|
214
|
+
return event.key === 'ArrowDown'
|
|
215
|
+
? enabledItems[0]?.value
|
|
216
|
+
: enabledItems[enabledItems.length - 1]?.value;
|
|
217
|
+
}
|
|
218
|
+
const nextIndex = event.key === 'ArrowDown' ? currentIndex + 1 : currentIndex - 1;
|
|
219
|
+
if (nextIndex < 0) {
|
|
220
|
+
return enabledItems[enabledItems.length - 1]?.value;
|
|
221
|
+
}
|
|
222
|
+
if (nextIndex >= enabledItems.length) {
|
|
223
|
+
return enabledItems[0]?.value;
|
|
224
|
+
}
|
|
225
|
+
return enabledItems[nextIndex]?.value;
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
else if (this.selectable() && (event.key === 'Enter' || event.key === ' ')) {
|
|
229
|
+
const currentHighlightedValue = this.currentHighlightedValue();
|
|
230
|
+
if (currentHighlightedValue !== null) {
|
|
231
|
+
event.stopImmediatePropagation();
|
|
232
|
+
event.preventDefault();
|
|
233
|
+
this.onSelect(currentHighlightedValue);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
scrollToIndex(index) {
|
|
238
|
+
this._scroller().scrollToIndex(index);
|
|
239
|
+
}
|
|
240
|
+
onSelect(value) {
|
|
241
|
+
if (this.multiple()) {
|
|
242
|
+
const currentValue = this.value() ?? [];
|
|
243
|
+
if (!currentValue.includes(value)) {
|
|
244
|
+
this.value.set([...currentValue, value]);
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
this.value.set(currentValue.filter(item => item !== value));
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
if (this.value() !== value) {
|
|
252
|
+
this.value.set(value);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
this.itemClicked.emit(value);
|
|
256
|
+
this.touched.set(true);
|
|
257
|
+
}
|
|
258
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnListBox, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
259
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: NgnListBox, isStandalone: true, selector: "ngn-list-box", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, scrollToSelectedItemOnInit: { classPropertyName: "scrollToSelectedItemOnInit", publicName: "scrollToSelectedItemOnInit", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, selectOnHover: { classPropertyName: "selectOnHover", publicName: "selectOnHover", isSignal: true, isRequired: false, transformFunction: null }, focussable: { classPropertyName: "focussable", publicName: "focussable", isSignal: true, isRequired: false, transformFunction: null }, virtual: { classPropertyName: "virtual", publicName: "virtual", isSignal: true, isRequired: false, transformFunction: null }, itemHeight: { classPropertyName: "itemHeight", publicName: "itemHeight", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, checkbox: { classPropertyName: "checkbox", publicName: "checkbox", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, filterText: { classPropertyName: "filterText", publicName: "filterText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClicked: "itemClicked" }, host: { attributes: { "role": "listbox" }, listeners: { "keydown": "onKeyDown($event)", "focusout": "currentHighlightedValue.set(null)" }, properties: { "attr.tabIndex": "focussable() ? 0 : null", "attr.aria-activedescendant": "currentHighlightedValue() ? inputId() + \"_option_\" + currentHighlightedValue() : null", "aria-multiselectable": "!!multiple()", "attr.aria-label": "label()", "attr.aria-labelledby": "labelledBy()", "id": "inputId()" } }, providers: [provideSelf(NgnListBox)], viewQueries: [{ propertyName: "_scroller", first: true, predicate: NgnScroller, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ngn-scroller\n [ptInt]=\"this\"\n [ptDep]=\"'scroller'\"\n [virtual]=\"virtual()\"\n [itemHeight]=\"itemHeight()\"\n [items]=\"displayedItems()\"\n [templateItem]=\"usedItemTemplate\"\n [fieldSticky]=\"'items'\"\n #scroller\n/>\n\n@if (!displayedItems().length) {\n <div role=\"status\">\n <ng-container\n *ngTemplateOutlet=\"emptyTemplate() || defaultEmptyTemplate; context: {}\"\n ></ng-container>\n </div>\n}\n\n<ng-template #usedItemTemplate [ngnTemplate]=\"scroller.templateTypes.item\" let-itemOrGroup>\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n [ngnScrollerItem]=\"itemOrGroup\"\n [id]=\"inputId() + '_option_' + itemOrGroup.value\"\n [attr.role]=\"itemOrGroup.items ? 'group' : 'option'\"\n [attr.aria-label]=\"itemOrGroup.items ? maybeCallback(itemOrGroup.label) : null\"\n [aria-selected]=\"\n selectable() && !itemOrGroup.items ? valueArray().includes(itemOrGroup.value) : null\n \"\n [attr.aria-disabled]=\"itemOrGroup.disabled ? 'true' : null\"\n [ptInt]=\"this\"\n [ptClass]=\"{\n item: !itemOrGroup.items,\n group: !!itemOrGroup.items,\n 'item-selected': valueArray().includes(itemOrGroup.value),\n 'item-highlighted': itemOrGroup.value === currentHighlightedValue(),\n 'item-disabled': !!itemOrGroup.disabled,\n }\"\n (click)=\"\n !itemOrGroup.items && !itemOrGroup.disabled && selectable() && onSelect(itemOrGroup.value)\n \"\n (mouseenter)=\"\n !itemOrGroup.items &&\n !itemOrGroup.disabled &&\n selectable() &&\n selectOnHover() &&\n onSelect(itemOrGroup.value)\n \"\n >\n @if (showCheckboxes() && !itemOrGroup.items) {\n <ngn-checkbox\n [ptInt]=\"this\"\n [ptDep]=\"'checkbox'\"\n [value]=\"valueArray().includes(itemOrGroup.value)\"\n aria-hidden=\"true\"\n inert=\"true\"\n />\n }\n <ng-container\n *ngTemplateOutlet=\"\n itemOrGroup.items ? groupTemplate() : itemTemplate();\n context: { $implicit: itemOrGroup }\n \"\n ></ng-container>\n </div>\n</ng-template>\n\n<ng-template #defaultItemTemplate [ngnTemplate]=\"templateTypes.item\" let-item>\n <span [attr.data-testid]=\"item?.testId\" [ptInt]=\"this\" [ptClass]=\"'default-item'\">\n @let label = item?.label;\n @if (label) {\n <span [attr.data-testid]=\"item?.testId\">{{ maybeCallback(label) }}</span>\n } @else {\n <span [attr.data-testid]=\"item?.testId\">​</span>\n }\n </span>\n</ng-template>\n\n<ng-template #defaultGroupTemplate [ngnTemplate]=\"templateTypes.item\" let-group>\n <span [attr.data-testid]=\"group?.testId\" [ptInt]=\"this\" [ptClass]=\"'default-group'\">\n @let label = group?.label;\n @if (label) {\n <span [attr.data-testid]=\"group?.testId\">{{ maybeCallback(label) }}</span>\n } @else {\n <span [attr.data-testid]=\"group?.testId\">​</span>\n }\n </span>\n</ng-template>\n\n<ng-template #defaultEmptyTemplate>\n <span [ptInt]=\"this\" [ptClass]=\"'empty'\" [attr.data-testid]=\"'empty'\">{{\n i18n['listBox_noItemsFound']()\n }}</span>\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NgnScroller, selector: "ngn-scroller, [ngn-scroller]", inputs: ["items", "fieldId", "virtual", "itemHeight", "virtualPadding", "focusable", "fieldSticky"] }, { kind: "directive", type: NgnScrollerItem, selector: "[ngnScrollerItem]", inputs: ["ngnScrollerItem"] }, { kind: "component", type: NgnCheckbox, selector: "ngn-checkbox", inputs: ["iconChecked", "iconUnchecked", "iconIndeterminate", "allowIndeterminate"] }, { kind: "directive", type: NgnTemplate, selector: "ng-template[ngnTemplate]", inputs: ["ngnTemplate"] }, { kind: "directive", type: NgnPt, selector: "[ptInt]", inputs: ["ptInt", "ptClass", "ptDep"] }] });
|
|
260
|
+
}
|
|
261
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnListBox, decorators: [{
|
|
262
|
+
type: Component,
|
|
263
|
+
args: [{ selector: 'ngn-list-box', imports: [NgTemplateOutlet, NgnScroller, NgnScrollerItem, NgnCheckbox, NgnTemplate, NgnPt], providers: [provideSelf(NgnListBox)], host: {
|
|
264
|
+
'[attr.tabIndex]': 'focussable() ? 0 : null',
|
|
265
|
+
'(keydown)': 'onKeyDown($event)',
|
|
266
|
+
'(focusout)': 'currentHighlightedValue.set(null)',
|
|
267
|
+
role: 'listbox',
|
|
268
|
+
'[attr.aria-activedescendant]': 'currentHighlightedValue() ? inputId() + "_option_" + currentHighlightedValue() : null',
|
|
269
|
+
'[aria-multiselectable]': '!!multiple()',
|
|
270
|
+
'[attr.aria-label]': 'label()',
|
|
271
|
+
'[attr.aria-labelledby]': 'labelledBy()',
|
|
272
|
+
'[id]': 'inputId()',
|
|
273
|
+
}, template: "<ngn-scroller\n [ptInt]=\"this\"\n [ptDep]=\"'scroller'\"\n [virtual]=\"virtual()\"\n [itemHeight]=\"itemHeight()\"\n [items]=\"displayedItems()\"\n [templateItem]=\"usedItemTemplate\"\n [fieldSticky]=\"'items'\"\n #scroller\n/>\n\n@if (!displayedItems().length) {\n <div role=\"status\">\n <ng-container\n *ngTemplateOutlet=\"emptyTemplate() || defaultEmptyTemplate; context: {}\"\n ></ng-container>\n </div>\n}\n\n<ng-template #usedItemTemplate [ngnTemplate]=\"scroller.templateTypes.item\" let-itemOrGroup>\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n [ngnScrollerItem]=\"itemOrGroup\"\n [id]=\"inputId() + '_option_' + itemOrGroup.value\"\n [attr.role]=\"itemOrGroup.items ? 'group' : 'option'\"\n [attr.aria-label]=\"itemOrGroup.items ? maybeCallback(itemOrGroup.label) : null\"\n [aria-selected]=\"\n selectable() && !itemOrGroup.items ? valueArray().includes(itemOrGroup.value) : null\n \"\n [attr.aria-disabled]=\"itemOrGroup.disabled ? 'true' : null\"\n [ptInt]=\"this\"\n [ptClass]=\"{\n item: !itemOrGroup.items,\n group: !!itemOrGroup.items,\n 'item-selected': valueArray().includes(itemOrGroup.value),\n 'item-highlighted': itemOrGroup.value === currentHighlightedValue(),\n 'item-disabled': !!itemOrGroup.disabled,\n }\"\n (click)=\"\n !itemOrGroup.items && !itemOrGroup.disabled && selectable() && onSelect(itemOrGroup.value)\n \"\n (mouseenter)=\"\n !itemOrGroup.items &&\n !itemOrGroup.disabled &&\n selectable() &&\n selectOnHover() &&\n onSelect(itemOrGroup.value)\n \"\n >\n @if (showCheckboxes() && !itemOrGroup.items) {\n <ngn-checkbox\n [ptInt]=\"this\"\n [ptDep]=\"'checkbox'\"\n [value]=\"valueArray().includes(itemOrGroup.value)\"\n aria-hidden=\"true\"\n inert=\"true\"\n />\n }\n <ng-container\n *ngTemplateOutlet=\"\n itemOrGroup.items ? groupTemplate() : itemTemplate();\n context: { $implicit: itemOrGroup }\n \"\n ></ng-container>\n </div>\n</ng-template>\n\n<ng-template #defaultItemTemplate [ngnTemplate]=\"templateTypes.item\" let-item>\n <span [attr.data-testid]=\"item?.testId\" [ptInt]=\"this\" [ptClass]=\"'default-item'\">\n @let label = item?.label;\n @if (label) {\n <span [attr.data-testid]=\"item?.testId\">{{ maybeCallback(label) }}</span>\n } @else {\n <span [attr.data-testid]=\"item?.testId\">​</span>\n }\n </span>\n</ng-template>\n\n<ng-template #defaultGroupTemplate [ngnTemplate]=\"templateTypes.item\" let-group>\n <span [attr.data-testid]=\"group?.testId\" [ptInt]=\"this\" [ptClass]=\"'default-group'\">\n @let label = group?.label;\n @if (label) {\n <span [attr.data-testid]=\"group?.testId\">{{ maybeCallback(label) }}</span>\n } @else {\n <span [attr.data-testid]=\"group?.testId\">​</span>\n }\n </span>\n</ng-template>\n\n<ng-template #defaultEmptyTemplate>\n <span [ptInt]=\"this\" [ptClass]=\"'empty'\" [attr.data-testid]=\"'empty'\">{{\n i18n['listBox_noItemsFound']()\n }}</span>\n</ng-template>\n" }]
|
|
274
|
+
}], ctorParameters: () => [], propDecorators: { _scroller: [{ type: i0.ViewChild, args: [i0.forwardRef(() => NgnScroller), { isSignal: true }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], scrollToSelectedItemOnInit: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollToSelectedItemOnInit", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], selectOnHover: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectOnHover", required: false }] }], focussable: [{ type: i0.Input, args: [{ isSignal: true, alias: "focussable", required: false }] }], virtual: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtual", required: false }] }], itemHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemHeight", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], checkbox: [{ type: i0.Input, args: [{ isSignal: true, alias: "checkbox", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], filterText: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterText", required: false }] }], itemClicked: [{ type: i0.Output, args: ["itemClicked"] }] } });
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Generated bundle index. Do not edit.
|
|
278
|
+
*/
|
|
279
|
+
|
|
280
|
+
export { NgnListBox };
|
|
281
|
+
//# sourceMappingURL=ngneers-controls-list-box.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ngneers-controls-list-box.mjs","sources":["../../src/list-box/list-box-templates.ts","../../src/list-box/list-box.ts","../../src/list-box/list-box.html","../../src/list-box/ngneers-controls-list-box.ts"],"sourcesContent":["import { computed, contentChild, Directive, input, TemplateRef, viewChild } from '@angular/core';\nimport { templateTypesFn } from '@ngneers/controls/api/ng';\nimport { ValueControlBase } from '@ngneers/controls/base';\n\nimport type { NgnItem, NgnItemsValue } from '@ngneers/controls/api';\nimport type { InputGeneric } from '@ngneers/controls/utils';\n\n/**\n * This type determines the value type for the select control.\n * * If `multiple` is `true`, the value is an array of items: `T[K][]`.\n * * Else it is the item's value type `T[K]`.\n */\nexport type ValueType<Items extends readonly NgnItem[], Multiple extends boolean> =\n InputGeneric<Multiple, false> extends true ? NgnItemsValue<Items>[] : NgnItemsValue<Items>;\n\n@Directive()\nexport abstract class ListBoxTemplates<\n Items extends readonly NgnItem[],\n Multiple extends boolean,\n> extends ValueControlBase<'listBox', ValueType<Items, Multiple> | null> {\n // Item template\n private readonly _defaultItemTemplate =\n viewChild.required<TemplateRef<typeof this.templateTypes.item>>('defaultItemTemplate');\n private readonly _userItemTemplate =\n contentChild<TemplateRef<typeof this.templateTypes.item>>('item');\n /**\n * Set a custom template for an item of the list box.\n * Can also be set using an `<ng-template>` element with `#item` template reference variable.\n */\n public readonly templateItem = input<TemplateRef<typeof this.templateTypes.item> | null>(null);\n protected readonly itemTemplate = computed(\n () => this._userItemTemplate() ?? this.templateItem() ?? this._defaultItemTemplate()\n );\n // Group template\n private readonly _defaultGroupTemplate =\n viewChild.required<TemplateRef<typeof this.templateTypes.item>>('defaultGroupTemplate');\n private readonly _userGroupTemplate =\n contentChild<TemplateRef<typeof this.templateTypes.item>>('group');\n /**\n * Set a custom template for a group in the list box.\n * Can also be set using an `<ng-template>` element with `#group` template reference variable.\n */\n public readonly templateGroup = input<TemplateRef<typeof this.templateTypes.item> | null>(null);\n protected readonly groupTemplate = computed(\n () => this._userGroupTemplate() ?? this.templateGroup() ?? this._defaultGroupTemplate()\n );\n\n // Empty template\n private readonly _defaultEmptyTemplate =\n viewChild.required<TemplateRef<unknown>>('defaultEmptyTemplate');\n private readonly _userEmptyTemplate = contentChild<TemplateRef<unknown>>('empty');\n /**\n * Set a custom template for the empty state in the list box.\n * Can also be set using an `<ng-template>` element with `#empty` template reference variable.\n */\n public readonly templateEmpty = input<TemplateRef<unknown> | null>(null);\n protected readonly emptyTemplate = computed(\n () => this._userEmptyTemplate() ?? this.templateEmpty() ?? this._defaultEmptyTemplate()\n );\n\n /**\n * Types for the dialog templates.\n */\n public readonly templateTypes = templateTypesFn<{\n item: {\n $implicit: Items[number] | undefined;\n };\n }>();\n\n protected readonly templateTypesInternal = templateTypesFn<{\n item: {\n $implicit: Items[number] | undefined;\n index: number;\n };\n }>();\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n afterRenderEffect,\n booleanAttribute,\n Component,\n computed,\n effect,\n input,\n signal,\n untracked,\n viewChild,\n inject,\n output,\n} from '@angular/core';\nimport {\n type FilterConfig,\n type FilterConfigInternal,\n filterOptions,\n flatItems,\n mapToItems,\n type NgnItem,\n type NgnItemsValue,\n} from '@ngneers/controls/api';\nimport { NgnTemplate } from '@ngneers/controls/api/ng';\nimport { NgnPt, provideSelf } from '@ngneers/controls/base';\nimport { NgnCheckbox } from '@ngneers/controls/checkbox';\nimport { I18n } from '@ngneers/controls/i18n';\nimport { NgnScroller, NgnScrollerItem } from '@ngneers/controls/scroller';\nimport { createConditionalSpinner } from '@ngneers/controls/spinner';\nimport { maybeCallback } from '@ngneers/controls/utils';\nimport { asyncComputed } from '@ngneers/controls/utils-ng';\nimport { listBoxControlTemplate } from '@ngneers/controls-themes/templates/list-box';\n\nimport { ListBoxTemplates, type ValueType } from './list-box-templates';\n\n/**\n * @category control\n */\n@Component({\n selector: 'ngn-list-box',\n templateUrl: './list-box.html',\n imports: [NgTemplateOutlet, NgnScroller, NgnScrollerItem, NgnCheckbox, NgnTemplate, NgnPt],\n providers: [provideSelf(NgnListBox)],\n host: {\n '[attr.tabIndex]': 'focussable() ? 0 : null',\n '(keydown)': 'onKeyDown($event)',\n '(focusout)': 'currentHighlightedValue.set(null)',\n role: 'listbox',\n '[attr.aria-activedescendant]':\n 'currentHighlightedValue() ? inputId() + \"_option_\" + currentHighlightedValue() : null',\n '[aria-multiselectable]': '!!multiple()',\n '[attr.aria-label]': 'label()',\n '[attr.aria-labelledby]': 'labelledBy()',\n '[id]': 'inputId()',\n },\n})\nexport class NgnListBox<\n Items extends readonly NgnItem[],\n Multiple extends boolean = false,\n> extends ListBoxTemplates<Items, Multiple> {\n protected readonly i18n = inject(I18n).translations;\n protected readonly theme = this.injectThemeTemplate(listBoxControlTemplate, {\n root: true,\n invalid: () => this.invalid(),\n empty: () => !this.displayedItems().length,\n });\n\n private readonly _scroller = viewChild.required<NgnScroller<NgnItemsValue<Items>>>(NgnScroller);\n\n /**\n * The items to display in the list box.\n */\n public readonly items = input.required<Items>();\n\n /**\n * Whether to scroll to the selected item when the list box is first rendered.\n * Pass a `ScrollLogicalPosition` to control where the item lands in the viewport.\n * @default false\n */\n public readonly scrollToSelectedItemOnInit = input<boolean | ScrollLogicalPosition>(false);\n /**\n * Whether items can be selected by the user.\n * @default false\n */\n public readonly selectable = input(false, { transform: booleanAttribute });\n /**\n * Whether hovering an item selects it.\n * @default false\n */\n public readonly selectOnHover = input(false, { transform: booleanAttribute });\n /**\n * Whether the list box itself is focusable and participates in keyboard navigation.\n * @default true\n */\n public readonly focussable = input(true, { transform: booleanAttribute });\n /**\n * Whether the list is virtualized.\n * @default false\n */\n public readonly virtual = input(false, { transform: booleanAttribute });\n /**\n * When {@link virtual} is enabled, this defines the height of each item in the list.\n */\n public readonly itemHeight = input<number>();\n /**\n * Enable this to allow the user to select multiple values.\n * When enabled, the value of the control becomes an array of selected items.\n */\n public readonly multiple = input<Multiple>();\n /**\n * Whether to use a checkbox to indicate selection state.\n *\n * This option is true per default when {@link multiple} is `true`.\n * @default multiple()\n */\n public readonly checkbox = input<boolean>();\n /**\n * Accepts a boolean value that determines whether the filter is enabled.\n * Alternatively, you can provide `FilterConfig` to customize the filter behavior.\n * @default `false`\n */\n public readonly filter = input<FilterConfig<Items[number]> | boolean>(false);\n /**\n * Manually set the filter text.\n */\n public readonly filterText = input<string | null>(null);\n\n /**\n * Emitted when an item is clicked, carrying the value of that item.\n */\n public readonly itemClicked = output<NgnItemsValue<Items>>();\n\n protected readonly maybeCallback = maybeCallback;\n\n public readonly displayedItems = computed(() => flatItems(this.filteredItems()));\n\n protected readonly valueArray = computed(() => {\n const v = this.value();\n return (Array.isArray(v) ? v : v ? [v] : []) as NgnItemsValue<Items>[];\n });\n public readonly currentHighlightedValue = signal<NgnItemsValue<Items> | null>(null);\n protected readonly filteredItems = asyncComputed(async () => {\n const filter = !!this.filter();\n const appliedFilterOptions = this._appliedFilterOptions();\n const filterText = this.filterText();\n\n if (!filter || !filterText) {\n return this.items();\n }\n return await filterOptions(this.items(), filterText, appliedFilterOptions);\n }, []);\n\n private readonly _appliedFilterOptions = computed(() => {\n const filter = this.filter();\n const providedFilterArgs = typeof filter === 'boolean' ? {} : filter;\n const options: FilterConfigInternal<NgnItem> = {\n filterFieldsCallback: item => item.label,\n fieldItems: 'items',\n splitWords: true,\n caseSensitive: false,\n filterFn: 'contains',\n ...providedFilterArgs,\n };\n return options;\n });\n\n protected readonly filterIsExecuting = this.filteredItems.isRunning;\n\n protected readonly showCheckboxes = computed(() => this.checkbox() ?? this.multiple() ?? false);\n\n constructor() {\n super();\n createConditionalSpinner(this.filterIsExecuting);\n\n effect(() => {\n const currentHighlightedValue = this.currentHighlightedValue();\n if (!currentHighlightedValue) {\n return;\n }\n const index = flatItems(this.filteredItems()).findIndex(\n option => option.value === currentHighlightedValue\n );\n this._scroller().scrollToIndex(index);\n });\n\n afterRenderEffect(() => {\n const pos = this.scrollToSelectedItemOnInit();\n const filterDone = this.filteredItems.firstRunCompleted();\n if (pos && filterDone) {\n const val = untracked(this.value);\n const index = flatItems(untracked(this.filteredItems)).findIndex(\n option => option.value === val\n );\n this._scroller().scrollToIndex(index, pos === true ? 'nearest' : pos);\n }\n });\n }\n\n public onKeyDown(event: KeyboardEvent) {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.stopPropagation();\n event.preventDefault();\n const flattenedItems = mapToItems(this.filteredItems());\n this.currentHighlightedValue.update(currentValue => {\n const enabledItems = flattenedItems.filter(item => !item.disabled);\n if (enabledItems.length === 0) {\n return null;\n }\n const currentHighlightIndex = enabledItems.findIndex(\n option => option.value === currentValue\n );\n const currentIndex =\n currentHighlightIndex >= 0\n ? currentHighlightIndex\n : enabledItems.findIndex(\n option => option.value === this.valueArray()[this.valueArray().length - 1]\n );\n\n if (currentIndex === -1) {\n return event.key === 'ArrowDown'\n ? enabledItems[0]?.value\n : enabledItems[enabledItems.length - 1]?.value;\n }\n\n const nextIndex = event.key === 'ArrowDown' ? currentIndex + 1 : currentIndex - 1;\n if (nextIndex < 0) {\n return enabledItems[enabledItems.length - 1]?.value;\n }\n if (nextIndex >= enabledItems.length) {\n return enabledItems[0]?.value;\n }\n return enabledItems[nextIndex]?.value;\n });\n } else if (this.selectable() && (event.key === 'Enter' || event.key === ' ')) {\n const currentHighlightedValue = this.currentHighlightedValue();\n if (currentHighlightedValue !== null) {\n event.stopImmediatePropagation();\n event.preventDefault();\n this.onSelect(currentHighlightedValue);\n }\n }\n }\n\n public scrollToIndex(index: number) {\n this._scroller().scrollToIndex(index);\n }\n\n protected onSelect(value: NgnItemsValue<Items>) {\n if (this.multiple()) {\n const currentValue = (this.value() as Array<NgnItemsValue<Items>>) ?? [];\n if (!currentValue.includes(value)) {\n this.value.set([...currentValue, value] as ValueType<Items, Multiple>);\n } else {\n this.value.set(currentValue.filter(item => item !== value) as ValueType<Items, Multiple>);\n }\n } else {\n if (this.value() !== value) {\n this.value.set(value as ValueType<Items, Multiple>);\n }\n }\n this.itemClicked.emit(value);\n this.touched.set(true);\n }\n}\n","<ngn-scroller\n [ptInt]=\"this\"\n [ptDep]=\"'scroller'\"\n [virtual]=\"virtual()\"\n [itemHeight]=\"itemHeight()\"\n [items]=\"displayedItems()\"\n [templateItem]=\"usedItemTemplate\"\n [fieldSticky]=\"'items'\"\n #scroller\n/>\n\n@if (!displayedItems().length) {\n <div role=\"status\">\n <ng-container\n *ngTemplateOutlet=\"emptyTemplate() || defaultEmptyTemplate; context: {}\"\n ></ng-container>\n </div>\n}\n\n<ng-template #usedItemTemplate [ngnTemplate]=\"scroller.templateTypes.item\" let-itemOrGroup>\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n [ngnScrollerItem]=\"itemOrGroup\"\n [id]=\"inputId() + '_option_' + itemOrGroup.value\"\n [attr.role]=\"itemOrGroup.items ? 'group' : 'option'\"\n [attr.aria-label]=\"itemOrGroup.items ? maybeCallback(itemOrGroup.label) : null\"\n [aria-selected]=\"\n selectable() && !itemOrGroup.items ? valueArray().includes(itemOrGroup.value) : null\n \"\n [attr.aria-disabled]=\"itemOrGroup.disabled ? 'true' : null\"\n [ptInt]=\"this\"\n [ptClass]=\"{\n item: !itemOrGroup.items,\n group: !!itemOrGroup.items,\n 'item-selected': valueArray().includes(itemOrGroup.value),\n 'item-highlighted': itemOrGroup.value === currentHighlightedValue(),\n 'item-disabled': !!itemOrGroup.disabled,\n }\"\n (click)=\"\n !itemOrGroup.items && !itemOrGroup.disabled && selectable() && onSelect(itemOrGroup.value)\n \"\n (mouseenter)=\"\n !itemOrGroup.items &&\n !itemOrGroup.disabled &&\n selectable() &&\n selectOnHover() &&\n onSelect(itemOrGroup.value)\n \"\n >\n @if (showCheckboxes() && !itemOrGroup.items) {\n <ngn-checkbox\n [ptInt]=\"this\"\n [ptDep]=\"'checkbox'\"\n [value]=\"valueArray().includes(itemOrGroup.value)\"\n aria-hidden=\"true\"\n inert=\"true\"\n />\n }\n <ng-container\n *ngTemplateOutlet=\"\n itemOrGroup.items ? groupTemplate() : itemTemplate();\n context: { $implicit: itemOrGroup }\n \"\n ></ng-container>\n </div>\n</ng-template>\n\n<ng-template #defaultItemTemplate [ngnTemplate]=\"templateTypes.item\" let-item>\n <span [attr.data-testid]=\"item?.testId\" [ptInt]=\"this\" [ptClass]=\"'default-item'\">\n @let label = item?.label;\n @if (label) {\n <span [attr.data-testid]=\"item?.testId\">{{ maybeCallback(label) }}</span>\n } @else {\n <span [attr.data-testid]=\"item?.testId\">​</span>\n }\n </span>\n</ng-template>\n\n<ng-template #defaultGroupTemplate [ngnTemplate]=\"templateTypes.item\" let-group>\n <span [attr.data-testid]=\"group?.testId\" [ptInt]=\"this\" [ptClass]=\"'default-group'\">\n @let label = group?.label;\n @if (label) {\n <span [attr.data-testid]=\"group?.testId\">{{ maybeCallback(label) }}</span>\n } @else {\n <span [attr.data-testid]=\"group?.testId\">​</span>\n }\n </span>\n</ng-template>\n\n<ng-template #defaultEmptyTemplate>\n <span [ptInt]=\"this\" [ptClass]=\"'empty'\" [attr.data-testid]=\"'empty'\">{{\n i18n['listBox_noItemsFound']()\n }}</span>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|