quang 19.3.15-4 → 19.3.15-5
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/components/autocomplete/autocomplete.component.d.ts +8 -1
- package/components/select/select.component.d.ts +3 -3
- package/fesm2022/quang-components-autocomplete.mjs +12 -5
- package/fesm2022/quang-components-autocomplete.mjs.map +1 -1
- package/fesm2022/quang-components-select.mjs +9 -20
- package/fesm2022/quang-components-select.mjs.map +1 -1
- package/fesm2022/quang-components-shared.mjs +23 -44
- package/fesm2022/quang-components-shared.mjs.map +1 -1
- package/package.json +16 -16
|
@@ -80,6 +80,13 @@ export declare class QuangAutocompleteComponent extends QuangBaseComponent<strin
|
|
|
80
80
|
* @default 'vertical'
|
|
81
81
|
*/
|
|
82
82
|
multiSelectDisplayMode: import("@angular/core").InputSignal<"vertical" | "horizontal">;
|
|
83
|
+
/**
|
|
84
|
+
* Position of chips relative to the input in multiple selection mode.
|
|
85
|
+
* - 'top': Chips are displayed above the input (default)
|
|
86
|
+
* - 'bottom': Chips are displayed below the input
|
|
87
|
+
* @default 'top'
|
|
88
|
+
*/
|
|
89
|
+
chipsPosition: import("@angular/core").InputSignal<"top" | "bottom">;
|
|
83
90
|
/**
|
|
84
91
|
* Debounce time in milliseconds for search text changes.
|
|
85
92
|
* @default 300
|
|
@@ -280,5 +287,5 @@ export declare class QuangAutocompleteComponent extends QuangBaseComponent<strin
|
|
|
280
287
|
*/
|
|
281
288
|
private updateValueWithoutExitingSearchMode;
|
|
282
289
|
static ɵfac: i0.ɵɵFactoryDeclaration<QuangAutocompleteComponent, never>;
|
|
283
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<QuangAutocompleteComponent, "quang-autocomplete", never, { "selectOptions": { "alias": "selectOptions"; "required": true; "isSignal": true; }; "allowFreeText": { "alias": "allowFreeText"; "required": false; "isSignal": true; }; "autoSelectOnExactMatch": { "alias": "autoSelectOnExactMatch"; "required": false; "isSignal": true; }; "updateValueOnType": { "alias": "updateValueOnType"; "required": false; "isSignal": true; }; "syncFormWithText": { "alias": "syncFormWithText"; "required": false; "isSignal": true; }; "optionListMaxHeight": { "alias": "optionListMaxHeight"; "required": false; "isSignal": true; }; "translateValue": { "alias": "translateValue"; "required": false; "isSignal": true; }; "scrollBehaviorOnOpen": { "alias": "scrollBehaviorOnOpen"; "required": false; "isSignal": true; }; "emitOnly": { "alias": "emitOnly"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "chipMaxLength": { "alias": "chipMaxLength"; "required": false; "isSignal": true; }; "multiSelectDisplayMode": { "alias": "multiSelectDisplayMode"; "required": false; "isSignal": true; }; "searchTextDebounce": { "alias": "searchTextDebounce"; "required": false; "isSignal": true; }; "internalFilterOptions": { "alias": "internalFilterOptions"; "required": false; "isSignal": true; }; }, { "selectedOption": "selectedOption"; "searchTextChange": "searchTextChange"; }, never, never, true, never>;
|
|
290
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<QuangAutocompleteComponent, "quang-autocomplete", never, { "selectOptions": { "alias": "selectOptions"; "required": true; "isSignal": true; }; "allowFreeText": { "alias": "allowFreeText"; "required": false; "isSignal": true; }; "autoSelectOnExactMatch": { "alias": "autoSelectOnExactMatch"; "required": false; "isSignal": true; }; "updateValueOnType": { "alias": "updateValueOnType"; "required": false; "isSignal": true; }; "syncFormWithText": { "alias": "syncFormWithText"; "required": false; "isSignal": true; }; "optionListMaxHeight": { "alias": "optionListMaxHeight"; "required": false; "isSignal": true; }; "translateValue": { "alias": "translateValue"; "required": false; "isSignal": true; }; "scrollBehaviorOnOpen": { "alias": "scrollBehaviorOnOpen"; "required": false; "isSignal": true; }; "emitOnly": { "alias": "emitOnly"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "chipMaxLength": { "alias": "chipMaxLength"; "required": false; "isSignal": true; }; "multiSelectDisplayMode": { "alias": "multiSelectDisplayMode"; "required": false; "isSignal": true; }; "chipsPosition": { "alias": "chipsPosition"; "required": false; "isSignal": true; }; "searchTextDebounce": { "alias": "searchTextDebounce"; "required": false; "isSignal": true; }; "internalFilterOptions": { "alias": "internalFilterOptions"; "required": false; "isSignal": true; }; }, { "selectedOption": "selectedOption"; "searchTextChange": "searchTextChange"; }, never, never, true, never>;
|
|
284
291
|
}
|
|
@@ -12,17 +12,17 @@ export declare class QuangSelectComponent extends QuangBaseComponent<string | nu
|
|
|
12
12
|
selectOptions: import("@angular/core").InputSignal<SelectOption[]>;
|
|
13
13
|
scrollBehaviorOnOpen: import("@angular/core").InputSignal<ScrollBehavior>;
|
|
14
14
|
selectButton: import("@angular/core").Signal<ElementRef<HTMLButtonElement> | undefined>;
|
|
15
|
+
/** Whether the option list is currently visible */
|
|
15
16
|
_showOptions: import("@angular/core").WritableSignal<boolean>;
|
|
16
|
-
_optionHideTimeout: import("@angular/core").WritableSignal<any>;
|
|
17
17
|
_selectedItems: import("@angular/core").Signal<SelectOption[] | null>;
|
|
18
18
|
translateValue: import("@angular/core").InputSignal<boolean>;
|
|
19
19
|
nullOption: import("@angular/core").InputSignal<boolean>;
|
|
20
20
|
autoSelectSingleOption: import("@angular/core").InputSignal<boolean>;
|
|
21
21
|
readonly ParentType = OptionListParentType.SELECT;
|
|
22
22
|
constructor();
|
|
23
|
-
changeOptionsVisibility(
|
|
23
|
+
changeOptionsVisibility(): void;
|
|
24
24
|
showOptionVisibility(): void;
|
|
25
|
-
hideOptionVisibility(
|
|
25
|
+
hideOptionVisibility(): void;
|
|
26
26
|
onBlurHandler(): void;
|
|
27
27
|
onChangedHandler(value: string | number | string[] | number[] | null): void;
|
|
28
28
|
onMouseLeaveCallback(): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NgClass, NgStyle } from '@angular/common';
|
|
1
|
+
import { NgClass, NgTemplateOutlet, NgStyle } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
3
|
import { input, output, viewChild, signal, computed, effect, forwardRef, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
4
|
import { toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
@@ -106,6 +106,13 @@ class QuangAutocompleteComponent extends QuangBaseComponent {
|
|
|
106
106
|
* @default 'vertical'
|
|
107
107
|
*/
|
|
108
108
|
this.multiSelectDisplayMode = input('vertical');
|
|
109
|
+
/**
|
|
110
|
+
* Position of chips relative to the input in multiple selection mode.
|
|
111
|
+
* - 'top': Chips are displayed above the input (default)
|
|
112
|
+
* - 'bottom': Chips are displayed below the input
|
|
113
|
+
* @default 'top'
|
|
114
|
+
*/
|
|
115
|
+
this.chipsPosition = input('top');
|
|
109
116
|
/**
|
|
110
117
|
* Debounce time in milliseconds for search text changes.
|
|
111
118
|
* @default 300
|
|
@@ -712,7 +719,7 @@ class QuangAutocompleteComponent extends QuangBaseComponent {
|
|
|
712
719
|
}
|
|
713
720
|
}
|
|
714
721
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: QuangAutocompleteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
715
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: QuangAutocompleteComponent, isStandalone: true, selector: "quang-autocomplete", inputs: { selectOptions: { classPropertyName: "selectOptions", publicName: "selectOptions", isSignal: true, isRequired: true, transformFunction: null }, allowFreeText: { classPropertyName: "allowFreeText", publicName: "allowFreeText", isSignal: true, isRequired: false, transformFunction: null }, autoSelectOnExactMatch: { classPropertyName: "autoSelectOnExactMatch", publicName: "autoSelectOnExactMatch", isSignal: true, isRequired: false, transformFunction: null }, updateValueOnType: { classPropertyName: "updateValueOnType", publicName: "updateValueOnType", isSignal: true, isRequired: false, transformFunction: null }, syncFormWithText: { classPropertyName: "syncFormWithText", publicName: "syncFormWithText", isSignal: true, isRequired: false, transformFunction: null }, optionListMaxHeight: { classPropertyName: "optionListMaxHeight", publicName: "optionListMaxHeight", isSignal: true, isRequired: false, transformFunction: null }, translateValue: { classPropertyName: "translateValue", publicName: "translateValue", isSignal: true, isRequired: false, transformFunction: null }, scrollBehaviorOnOpen: { classPropertyName: "scrollBehaviorOnOpen", publicName: "scrollBehaviorOnOpen", isSignal: true, isRequired: false, transformFunction: null }, emitOnly: { classPropertyName: "emitOnly", publicName: "emitOnly", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, chipMaxLength: { classPropertyName: "chipMaxLength", publicName: "chipMaxLength", isSignal: true, isRequired: false, transformFunction: null }, multiSelectDisplayMode: { classPropertyName: "multiSelectDisplayMode", publicName: "multiSelectDisplayMode", isSignal: true, isRequired: false, transformFunction: null }, searchTextDebounce: { classPropertyName: "searchTextDebounce", publicName: "searchTextDebounce", isSignal: true, isRequired: false, transformFunction: null }, internalFilterOptions: { classPropertyName: "internalFilterOptions", publicName: "internalFilterOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedOption: "selectedOption", searchTextChange: "searchTextChange" }, providers: [
|
|
722
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: QuangAutocompleteComponent, isStandalone: true, selector: "quang-autocomplete", inputs: { selectOptions: { classPropertyName: "selectOptions", publicName: "selectOptions", isSignal: true, isRequired: true, transformFunction: null }, allowFreeText: { classPropertyName: "allowFreeText", publicName: "allowFreeText", isSignal: true, isRequired: false, transformFunction: null }, autoSelectOnExactMatch: { classPropertyName: "autoSelectOnExactMatch", publicName: "autoSelectOnExactMatch", isSignal: true, isRequired: false, transformFunction: null }, updateValueOnType: { classPropertyName: "updateValueOnType", publicName: "updateValueOnType", isSignal: true, isRequired: false, transformFunction: null }, syncFormWithText: { classPropertyName: "syncFormWithText", publicName: "syncFormWithText", isSignal: true, isRequired: false, transformFunction: null }, optionListMaxHeight: { classPropertyName: "optionListMaxHeight", publicName: "optionListMaxHeight", isSignal: true, isRequired: false, transformFunction: null }, translateValue: { classPropertyName: "translateValue", publicName: "translateValue", isSignal: true, isRequired: false, transformFunction: null }, scrollBehaviorOnOpen: { classPropertyName: "scrollBehaviorOnOpen", publicName: "scrollBehaviorOnOpen", isSignal: true, isRequired: false, transformFunction: null }, emitOnly: { classPropertyName: "emitOnly", publicName: "emitOnly", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, chipMaxLength: { classPropertyName: "chipMaxLength", publicName: "chipMaxLength", isSignal: true, isRequired: false, transformFunction: null }, multiSelectDisplayMode: { classPropertyName: "multiSelectDisplayMode", publicName: "multiSelectDisplayMode", isSignal: true, isRequired: false, transformFunction: null }, chipsPosition: { classPropertyName: "chipsPosition", publicName: "chipsPosition", isSignal: true, isRequired: false, transformFunction: null }, searchTextDebounce: { classPropertyName: "searchTextDebounce", publicName: "searchTextDebounce", isSignal: true, isRequired: false, transformFunction: null }, internalFilterOptions: { classPropertyName: "internalFilterOptions", publicName: "internalFilterOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedOption: "selectedOption", searchTextChange: "searchTextChange" }, providers: [
|
|
716
723
|
{
|
|
717
724
|
provide: NG_VALUE_ACCESSOR,
|
|
718
725
|
useExisting: forwardRef(() => QuangAutocompleteComponent),
|
|
@@ -722,11 +729,11 @@ class QuangAutocompleteComponent extends QuangBaseComponent {
|
|
|
722
729
|
provide: QuangOptionListComponent,
|
|
723
730
|
multi: false,
|
|
724
731
|
},
|
|
725
|
-
], viewQueries: [{ propertyName: "optionList", first: true, predicate: ["optionList"], descendants: true, isSignal: true }, { propertyName: "selectInput", first: true, predicate: ["selectInput"], descendants: true, isSignal: true }, { propertyName: "chipContainer", first: true, predicate: ["chipContainer"], descendants: true, isSignal: true }, { propertyName: "autocompleteContainer", first: true, predicate: ["autocompleteContainer"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n [ngStyle]=\"{ '--chip-max-length': chipMaxLength() ? chipMaxLength() + 'ch' : 'none' }\"\n #autocompleteContainer\n class=\"autocomplete-container\"\n>\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n <div\n [ngClass]=\"multiSelectDisplayMode() === 'horizontal'
|
|
732
|
+
], viewQueries: [{ propertyName: "optionList", first: true, predicate: ["optionList"], descendants: true, isSignal: true }, { propertyName: "selectInput", first: true, predicate: ["selectInput"], descendants: true, isSignal: true }, { propertyName: "chipContainer", first: true, predicate: ["chipContainer"], descendants: true, isSignal: true }, { propertyName: "autocompleteContainer", first: true, predicate: ["autocompleteContainer"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n [ngStyle]=\"{ '--chip-max-length': chipMaxLength() ? chipMaxLength() + 'ch' : 'none' }\"\n #autocompleteContainer\n class=\"autocomplete-container\"\n>\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n <div\n [ngClass]=\"{\n horizontal: multiSelectDisplayMode() === 'horizontal',\n 'form-control': multiSelectDisplayMode() === 'horizontal',\n 'chips-bottom': chipsPosition() === 'bottom',\n }\"\n #chipContainer\n class=\"container-wrap\"\n >\n @if (multiple() && _chipList().length > 0 && chipsPosition() === 'top') {\n <ng-container *ngTemplateOutlet=\"chipsTemplate\" />\n }\n\n <input\n [attr.aria-activedescendant]=\"_showOptions() ? optionList()?.getActiveDescendantId() : null\"\n [attr.aria-controls]=\"_showOptions() ? 'optionList' : null\"\n [attr.aria-expanded]=\"_showOptions()\"\n [attr.required]=\"getIsRequiredControl()\"\n [class.form-control]=\"multiSelectDisplayMode() !== 'horizontal'\"\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n [disabled]=\"_isDisabled() || isReadonly()\"\n [id]=\"componentId()\"\n [ngClass]=\"componentClass()\"\n [placeholder]=\"componentPlaceholder() | transloco\"\n [tabIndex]=\"componentTabIndex()\"\n [value]=\"_inputValue()\"\n (blur)=\"onBlurInput($event)\"\n (input)=\"onChangeInput($event)\"\n (keydown)=\"onInputKeydown($event)\"\n (mousedown)=\"showOptionVisibility()\"\n #selectInput\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n autocomplete=\"off\"\n role=\"combobox\"\n type=\"text\"\n />\n\n @if (multiple() && _chipList().length > 0 && chipsPosition() === 'bottom') {\n <ng-container *ngTemplateOutlet=\"chipsTemplate\" />\n }\n </div>\n @if (_showOptions()) {\n <quang-option-list\n [_isDisabled]=\"_isDisabled()\"\n [_value]=\"_highlightedValue()\"\n [componentClass]=\"componentClass()\"\n [componentLabel]=\"componentLabel()\"\n [componentTabIndex]=\"componentTabIndex()\"\n [nullOption]=\"false\"\n [optionListMaxHeight]=\"optionListMaxHeight()\"\n [parentID]=\"componentId()\"\n [parentType]=\"ParentType\"\n [scrollBehaviorOnOpen]=\"scrollBehaviorOnOpen()\"\n [selectButtonRef]=\"autocompleteContainer\"\n [selectOptions]=\"_filteredOptions()\"\n [translateValue]=\"translateValue()\"\n (blurHandler)=\"onBlurOptionList($event)\"\n (changedHandler)=\"onValueChange($event)\"\n (escapePressed)=\"onEscapePressed()\"\n (tabPressed)=\"onTabPressed($event)\"\n #optionList\n selectionMode=\"single\"\n />\n }\n <div class=\"valid-feedback\">\n {{ successMessage() | transloco }}\n </div>\n <div class=\"invalid-feedback\">\n {{ _currentErrorMessage() | transloco: _currentErrorMessageExtraData() }}\n </div>\n @if (helpMessage()) {\n <small\n [hidden]=\"_showSuccess() || _showErrors()\"\n aria-live=\"assertive\"\n class=\"form-text text-muted\"\n >\n {{ helpMessage() | transloco }}\n </small>\n }\n</div>\n\n<!-- Chips template for reuse in top/bottom positions -->\n<ng-template #chipsTemplate>\n <div class=\"chips-container\">\n @for (chip of _chipList(); track chip) {\n @if (getDescription(chip)) {\n <div\n [quangTooltip]=\"chipMaxLength() ? getDescription(chip) : ''\"\n class=\"chip chip-hover\"\n >\n <p [ngClass]=\"{ 'm-0': isReadonly() || _isDisabled() }\">\n {{ getDescription(chip) }}\n </p>\n @if (!isReadonly() && !_isDisabled()) {\n <button\n [tabIndex]=\"$index + 1\"\n (click)=\"deleteChip(chip)\"\n class=\"btn btn-chip\"\n type=\"button\"\n >\n <svg\n class=\"ionicon\"\n fill=\"currentColor\"\n height=\"24\"\n viewBox=\"0 0 512 512\"\n width=\"24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M368 368L144 144M368 144L144 368\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"32\"\n />\n </svg>\n </button>\n }\n </div>\n }\n }\n </div>\n</ng-template>\n", styles: [":host{display:block;--chip-max-length: none}.autocomplete-container{margin-bottom:1rem;position:relative}.chip:has(.btn-chip:disabled):hover{filter:unset;cursor:unset}.container-wrap,.container-wrap .chips-container{display:flex;flex-wrap:wrap;gap:.5rem}.container-wrap.chips-bottom{flex-direction:column}.container-wrap.chips-bottom input{order:-1}.container-wrap.horizontal{display:flex}.container-wrap.horizontal .chip-container{max-width:70%;margin-bottom:0;margin-left:.5rem;flex-wrap:nowrap;white-space:nowrap;overflow-x:auto;position:absolute;align-items:center}.container-wrap.horizontal .chip-container .chip{white-space:nowrap}.container-wrap.horizontal input{min-width:30%;flex:1 1 0;width:auto;border:none}.container-wrap.horizontal input:focus-visible{outline:none}.chip{display:flex;justify-content:space-between;align-items:center;padding:.25rem .5rem;border-radius:16px;color:var(--bs-btn-color);background-color:rgba(var(--bs-primary-rgb),.1);border-width:1px;border-style:solid;border-color:var(--bs-primary-border-subtle);height:2rem}.chip p{margin:0;max-width:var(--chip-max-length);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.chip .btn-chip{text-align:end;padding:0;min-width:unset}.chip .btn-chip:hover{opacity:80%}.chip .btn-chip:active{border-color:transparent}.chip .btn-chip svg{color:var(--bs-primary);vertical-align:sub}.chip:has(.btn-chip:focus-visible){border-width:2px;filter:brightness(80%)}\n"], dependencies: [{ kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: QuangOptionListComponent, selector: "quang-option-list", inputs: ["selectionMode", "optionListMaxHeight", "selectOptions", "selectButtonRef", "_value", "_isDisabled", "componentClass", "componentLabel", "componentTabIndex", "translateValue", "nullOption", "scrollBehaviorOnOpen", "parentType", "parentID"], outputs: ["changedHandler", "blurHandler", "escapePressed", "tabPressed"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: QuangTooltipDirective, selector: "[quangTooltip]", inputs: ["quangTooltip", "showMethod"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
726
733
|
}
|
|
727
734
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: QuangAutocompleteComponent, decorators: [{
|
|
728
735
|
type: Component,
|
|
729
|
-
args: [{ selector: 'quang-autocomplete', imports: [TranslocoPipe, NgClass, QuangOptionListComponent, NgStyle, QuangTooltipDirective], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
736
|
+
args: [{ selector: 'quang-autocomplete', imports: [TranslocoPipe, NgClass, NgTemplateOutlet, QuangOptionListComponent, NgStyle, QuangTooltipDirective], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
730
737
|
{
|
|
731
738
|
provide: NG_VALUE_ACCESSOR,
|
|
732
739
|
useExisting: forwardRef(() => QuangAutocompleteComponent),
|
|
@@ -736,7 +743,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
736
743
|
provide: QuangOptionListComponent,
|
|
737
744
|
multi: false,
|
|
738
745
|
},
|
|
739
|
-
], template: "<div\n [ngStyle]=\"{ '--chip-max-length': chipMaxLength() ? chipMaxLength() + 'ch' : 'none' }\"\n #autocompleteContainer\n class=\"autocomplete-container\"\n>\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n <div\n [ngClass]=\"multiSelectDisplayMode() === 'horizontal'
|
|
746
|
+
], template: "<div\n [ngStyle]=\"{ '--chip-max-length': chipMaxLength() ? chipMaxLength() + 'ch' : 'none' }\"\n #autocompleteContainer\n class=\"autocomplete-container\"\n>\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n <div\n [ngClass]=\"{\n horizontal: multiSelectDisplayMode() === 'horizontal',\n 'form-control': multiSelectDisplayMode() === 'horizontal',\n 'chips-bottom': chipsPosition() === 'bottom',\n }\"\n #chipContainer\n class=\"container-wrap\"\n >\n @if (multiple() && _chipList().length > 0 && chipsPosition() === 'top') {\n <ng-container *ngTemplateOutlet=\"chipsTemplate\" />\n }\n\n <input\n [attr.aria-activedescendant]=\"_showOptions() ? optionList()?.getActiveDescendantId() : null\"\n [attr.aria-controls]=\"_showOptions() ? 'optionList' : null\"\n [attr.aria-expanded]=\"_showOptions()\"\n [attr.required]=\"getIsRequiredControl()\"\n [class.form-control]=\"multiSelectDisplayMode() !== 'horizontal'\"\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n [disabled]=\"_isDisabled() || isReadonly()\"\n [id]=\"componentId()\"\n [ngClass]=\"componentClass()\"\n [placeholder]=\"componentPlaceholder() | transloco\"\n [tabIndex]=\"componentTabIndex()\"\n [value]=\"_inputValue()\"\n (blur)=\"onBlurInput($event)\"\n (input)=\"onChangeInput($event)\"\n (keydown)=\"onInputKeydown($event)\"\n (mousedown)=\"showOptionVisibility()\"\n #selectInput\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n autocomplete=\"off\"\n role=\"combobox\"\n type=\"text\"\n />\n\n @if (multiple() && _chipList().length > 0 && chipsPosition() === 'bottom') {\n <ng-container *ngTemplateOutlet=\"chipsTemplate\" />\n }\n </div>\n @if (_showOptions()) {\n <quang-option-list\n [_isDisabled]=\"_isDisabled()\"\n [_value]=\"_highlightedValue()\"\n [componentClass]=\"componentClass()\"\n [componentLabel]=\"componentLabel()\"\n [componentTabIndex]=\"componentTabIndex()\"\n [nullOption]=\"false\"\n [optionListMaxHeight]=\"optionListMaxHeight()\"\n [parentID]=\"componentId()\"\n [parentType]=\"ParentType\"\n [scrollBehaviorOnOpen]=\"scrollBehaviorOnOpen()\"\n [selectButtonRef]=\"autocompleteContainer\"\n [selectOptions]=\"_filteredOptions()\"\n [translateValue]=\"translateValue()\"\n (blurHandler)=\"onBlurOptionList($event)\"\n (changedHandler)=\"onValueChange($event)\"\n (escapePressed)=\"onEscapePressed()\"\n (tabPressed)=\"onTabPressed($event)\"\n #optionList\n selectionMode=\"single\"\n />\n }\n <div class=\"valid-feedback\">\n {{ successMessage() | transloco }}\n </div>\n <div class=\"invalid-feedback\">\n {{ _currentErrorMessage() | transloco: _currentErrorMessageExtraData() }}\n </div>\n @if (helpMessage()) {\n <small\n [hidden]=\"_showSuccess() || _showErrors()\"\n aria-live=\"assertive\"\n class=\"form-text text-muted\"\n >\n {{ helpMessage() | transloco }}\n </small>\n }\n</div>\n\n<!-- Chips template for reuse in top/bottom positions -->\n<ng-template #chipsTemplate>\n <div class=\"chips-container\">\n @for (chip of _chipList(); track chip) {\n @if (getDescription(chip)) {\n <div\n [quangTooltip]=\"chipMaxLength() ? getDescription(chip) : ''\"\n class=\"chip chip-hover\"\n >\n <p [ngClass]=\"{ 'm-0': isReadonly() || _isDisabled() }\">\n {{ getDescription(chip) }}\n </p>\n @if (!isReadonly() && !_isDisabled()) {\n <button\n [tabIndex]=\"$index + 1\"\n (click)=\"deleteChip(chip)\"\n class=\"btn btn-chip\"\n type=\"button\"\n >\n <svg\n class=\"ionicon\"\n fill=\"currentColor\"\n height=\"24\"\n viewBox=\"0 0 512 512\"\n width=\"24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M368 368L144 144M368 144L144 368\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"32\"\n />\n </svg>\n </button>\n }\n </div>\n }\n }\n </div>\n</ng-template>\n", styles: [":host{display:block;--chip-max-length: none}.autocomplete-container{margin-bottom:1rem;position:relative}.chip:has(.btn-chip:disabled):hover{filter:unset;cursor:unset}.container-wrap,.container-wrap .chips-container{display:flex;flex-wrap:wrap;gap:.5rem}.container-wrap.chips-bottom{flex-direction:column}.container-wrap.chips-bottom input{order:-1}.container-wrap.horizontal{display:flex}.container-wrap.horizontal .chip-container{max-width:70%;margin-bottom:0;margin-left:.5rem;flex-wrap:nowrap;white-space:nowrap;overflow-x:auto;position:absolute;align-items:center}.container-wrap.horizontal .chip-container .chip{white-space:nowrap}.container-wrap.horizontal input{min-width:30%;flex:1 1 0;width:auto;border:none}.container-wrap.horizontal input:focus-visible{outline:none}.chip{display:flex;justify-content:space-between;align-items:center;padding:.25rem .5rem;border-radius:16px;color:var(--bs-btn-color);background-color:rgba(var(--bs-primary-rgb),.1);border-width:1px;border-style:solid;border-color:var(--bs-primary-border-subtle);height:2rem}.chip p{margin:0;max-width:var(--chip-max-length);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.chip .btn-chip{text-align:end;padding:0;min-width:unset}.chip .btn-chip:hover{opacity:80%}.chip .btn-chip:active{border-color:transparent}.chip .btn-chip svg{color:var(--bs-primary);vertical-align:sub}.chip:has(.btn-chip:focus-visible){border-width:2px;filter:brightness(80%)}\n"] }]
|
|
740
747
|
}], ctorParameters: () => [] });
|
|
741
748
|
|
|
742
749
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quang-components-autocomplete.mjs","sources":["../../../projects/quang/components/autocomplete/autocomplete.component.ts","../../../projects/quang/components/autocomplete/autocomplete.component.html","../../../projects/quang/components/autocomplete/quang-components-autocomplete.ts"],"sourcesContent":["import { NgClass, NgStyle } from '@angular/common'\nimport {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n computed,\n effect,\n forwardRef,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core'\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop'\nimport { NG_VALUE_ACCESSOR } from '@angular/forms'\n\nimport { TranslocoPipe } from '@jsverse/transloco'\nimport { QuangTooltipDirective } from 'quang/overlay/tooltip'\nimport { Subscription } from 'rxjs'\n\nimport {\n OptionListParentType,\n QuangBaseComponent,\n QuangOptionListComponent,\n SelectOption,\n} from 'quang/components/shared'\n\n/**\n * Autocomplete component for providing suggestion options {@link SelectOption} as the user types.\n *\n * @usageNotes\n * This component displays a list of filtered options based on user input.\n * It allows users to select an option from the suggestions and emits the event `selectedOption` when an option is selected.\n *\n * `searchTextDebounce` is by default set to 300ms.\n */\n@Component({\n selector: 'quang-autocomplete',\n imports: [TranslocoPipe, NgClass, QuangOptionListComponent, NgStyle, QuangTooltipDirective],\n templateUrl: './autocomplete.component.html',\n styleUrl: './autocomplete.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => QuangAutocompleteComponent),\n multi: true,\n },\n {\n provide: QuangOptionListComponent,\n multi: false,\n },\n ],\n})\nexport class QuangAutocompleteComponent extends QuangBaseComponent<string | number | string[] | number[] | null> {\n // ============================================\n // INPUTS - Configuration properties\n // ============================================\n\n /**\n * The list of options to display in the autocomplete dropdown.\n */\n selectOptions = input.required<SelectOption[]>()\n\n /**\n * When true, allows any text input as a valid form value, not just option values.\n * The form value will sync with whatever text the user types.\n * When false (default), the form value must match one of the option values.\n * @default false\n */\n allowFreeText = input<boolean>(false)\n\n /**\n * When true and allowFreeText is false, automatically selects an option if the user's\n * input text matches an option's label exactly (case-insensitive, trimmed).\n * This provides a better UX by auto-selecting when users type a complete option label.\n * @default true\n */\n autoSelectOnExactMatch = input<boolean>(true)\n\n /**\n * When true, updates the form value as the user types (after debounce).\n * When false (default), the form value is only updated when:\n * - User selects an option from the dropdown\n * - User stops typing and the input loses focus (blur)\n * @default false\n */\n updateValueOnType = input<boolean>(false)\n\n /**\n * Whether the form value can be any text or must match one of the options.\n * When true, the form value syncs with the input text.\n * When false (default), the form value must be one of the option values.\n * @default false\n * @deprecated Use `allowFreeText` instead. This input will be removed in a future version.\n */\n syncFormWithText = input<boolean>(false)\n\n /**\n * Maximum height of the option list before scrolling.\n * @default '200px'\n */\n optionListMaxHeight = input<string>('200px')\n\n /**\n * Whether to translate option labels.\n * @default true\n */\n translateValue = input<boolean>(true)\n\n /**\n * Scroll behavior when the option list opens.\n * @default 'smooth'\n */\n scrollBehaviorOnOpen = input<ScrollBehavior>('smooth')\n\n /**\n * When true, only emits the value without saving it to ngControl.\n * @default false\n */\n emitOnly = input<boolean>(false)\n\n /**\n * Enable multiple selection mode with chips.\n * @default false\n */\n multiple = input<boolean>(false)\n\n /**\n * Maximum length in characters for chip display text.\n * When set, chips will be truncated and show a tooltip with full text.\n * @default 0 (no limit)\n */\n chipMaxLength = input<number>(0)\n\n /**\n * Layout direction for chips in multiple selection mode.\n * @default 'vertical'\n */\n multiSelectDisplayMode = input<'vertical' | 'horizontal'>('vertical')\n\n /**\n * Debounce time in milliseconds for search text changes.\n * @default 300\n */\n searchTextDebounce = input<number>(300)\n\n /**\n * Whether to filter options internally based on input text.\n * When false, filtering should be handled externally via searchTextChange event.\n * @default true\n */\n internalFilterOptions = input<boolean>(true)\n\n // ============================================\n // OUTPUTS - Event emitters\n // ============================================\n\n /**\n * Emitted when an option is selected.\n * Emits the selected option's value, or null when cleared.\n */\n selectedOption = output<string | number | null>()\n\n /**\n * Emitted when the search text changes (after debounce).\n * Useful for external filtering or API calls.\n */\n searchTextChange = output<string>()\n\n // ============================================\n // VIEW CHILDREN - Template references\n // ============================================\n\n /** Reference to the option list component */\n protected readonly optionList = viewChild<QuangOptionListComponent>('optionList')\n\n /** Reference to the input element */\n private readonly selectInput = viewChild<ElementRef<HTMLInputElement>>('selectInput')\n\n /** Reference to the chip container element */\n private readonly chipContainer = viewChild<ElementRef<HTMLDivElement>>('chipContainer')\n\n /** Reference to the main autocomplete container */\n private readonly autocompleteContainer = viewChild<ElementRef<HTMLDivElement>>('autocompleteContainer')\n\n // ============================================\n // PUBLIC STATE - Used in template\n // ============================================\n\n /** Constant for option list parent type */\n readonly ParentType = OptionListParentType.AUTOCOMPLETE\n\n /** Height of the input element (used for positioning) */\n readonly inputHeight = signal<number>(0)\n\n /**\n * The display text for the input field.\n * - When searching: shows what the user typed\n * - When allowFreeText/syncFormWithText is true and no matching option: shows the raw value\n * - When not searching: shows the selected option's label (derived from _value)\n */\n readonly _inputValue = computed<string>(() => {\n if (this._isSearching()) {\n return this._userSearchText()\n }\n // Derive display text from _value by finding the matching option\n const value = this._value()\n if (value === null || value === undefined || value === '' || Array.isArray(value)) {\n return ''\n }\n const option = this.selectOptions().find((x) => x.value === value)\n // When free text is allowed and no matching option found, display the value itself\n // (since the value IS the text the user typed)\n if (!option && this._allowFreeTextInternal()) {\n return String(value)\n }\n return option?.label ?? ''\n })\n\n /** Whether the option list is currently visible */\n readonly _showOptions = signal<boolean | null>(null)\n\n /** List of selected chip values (for multiple mode) */\n readonly _chipList = signal<string[]>([])\n\n /** List of selected option objects (for multiple mode) */\n readonly _selectedOptions = signal<SelectOption[]>([])\n\n /** Filtered options based on search text and chip selection */\n readonly _filteredOptions = computed<SelectOption[]>(() => {\n const searchText = this._isSearching() ? this._userSearchText() : ''\n if (this.multiple()) {\n return this.filterOptions(searchText).filter((x) => !this._chipList().some((chip) => chip === x.value))\n }\n return searchText?.length ? this.filterOptions(searchText) : this.selectOptions()\n })\n\n /**\n * The value to use for highlighting in the option list.\n * When searching: shows the matched option (if any) based on exact label match\n * When not searching: shows the current form value\n * This keeps highlighting in sync with what will be selected on blur.\n */\n readonly _highlightedValue = computed<string | number | string[] | number[] | null>(() => {\n if (this._isSearching() && !this.multiple()) {\n const searchText = this._userSearchText()\n if (!searchText?.trim()) {\n // If search text is empty, don't highlight anything\n return null\n }\n // Find exact match for highlighting\n const matchingOption = this.findMatchingOption(searchText)\n if (matchingOption && this.autoSelectOnExactMatch()) {\n return matchingOption.value\n }\n // If free text is allowed, don't highlight any option\n // (the typed text itself will be the value)\n return null\n }\n // When not searching, use the current value\n return this._value()\n })\n\n // ============================================\n // PROTECTED STATE - Internal but accessible to subclasses\n // ============================================\n\n /** Whether the user is actively typing/searching */\n protected readonly _isSearching = signal<boolean>(false)\n\n /** The text the user is currently typing while searching */\n protected readonly _userSearchText = signal<string>('')\n\n /**\n * Internal computed that returns true if free text input is allowed.\n * Combines both `allowFreeText` and deprecated `syncFormWithText` inputs.\n */\n protected readonly _allowFreeTextInternal = computed<boolean>(() => {\n return this.allowFreeText() || this.syncFormWithText()\n })\n\n /**\n * Finds an option whose label exactly matches the given text (case-insensitive, trimmed).\n * @param text The text to match against option labels\n * @returns The matching option, or undefined if no match\n */\n protected findMatchingOption(text: string | null | undefined): SelectOption | undefined {\n if (!text) return undefined\n const searchTextLower = text.trim().toLowerCase()\n return this.selectOptions().find((x) => x.label.trim().toLowerCase() === searchTextLower)\n }\n\n // ============================================\n // PRIVATE STATE - Internal implementation details\n // ============================================\n\n /** Timer for search text debounce */\n private _searchDebounceTimer: ReturnType<typeof setTimeout> | null = null\n\n /** Last emitted search text (for distinctUntilChanged behavior) */\n private _lastEmittedSearchText: string | null = null\n\n /** Whether the component has been destroyed */\n private _isDestroyed = false\n\n /** Subscription to form value changes */\n private formValueChangeSubscription: Subscription | undefined = undefined\n\n // ============================================\n // EFFECTS - Reactive side effects\n // ============================================\n\n /** Effect to handle input element setup and keyboard events */\n private readonly onChangeSelectInputEffect = effect(() => {\n const selectInput = this.selectInput()\n if (!selectInput) return\n this.inputHeight.set(selectInput.nativeElement.getBoundingClientRect().height)\n selectInput.nativeElement.addEventListener('keydown', (e: KeyboardEvent) => {\n this.handleInputKeydown(e, selectInput.nativeElement)\n })\n })\n\n /** Subscription to options changes */\n private readonly selectOptionsChangeSubscription = toObservable(this.selectOptions)\n .pipe(takeUntilDestroyed())\n .subscribe(() => {\n this.handleOptionsChange()\n })\n\n /** Subscription to show options changes */\n private readonly showOptionsChangeSubscription = toObservable(this._showOptions)\n .pipe(takeUntilDestroyed())\n .subscribe((data) => {\n // Note: Form value processing is now handled directly in onBlurHandler\n // for immediate processing. This subscription is kept for backwards compatibility\n // but the _isSearching check prevents double-processing since onBlurHandler\n // already sets _isSearching to false before this subscription fires.\n if (!(!data && data !== null && this._isSearching())) return\n // Only process if still in search mode (which means onBlurHandler didn't run)\n this.processTextToFormValue(this._userSearchText(), {\n exitSearchMode: true,\n updateOnMatch: true,\n clearSearchText: true,\n })\n })\n\n // ============================================\n // CONSTRUCTOR\n // ============================================\n\n constructor() {\n super()\n this.destroyRef.onDestroy(() => {\n this._isDestroyed = true\n if (!this._searchDebounceTimer) return\n clearTimeout(this._searchDebounceTimer)\n })\n }\n\n // ============================================\n // LIFECYCLE HOOKS / OVERRIDES\n // ============================================\n\n override setupFormControl(): void {\n super.setupFormControl()\n const formControl = this._ngControl()?.control\n\n if (this.formValueChangeSubscription) {\n this.formValueChangeSubscription.unsubscribe()\n this.formValueChangeSubscription = undefined\n }\n\n if (!formControl) return\n\n this.formValueChangeSubscription = formControl.valueChanges\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((value: string | number | string[] | number[] | null) => {\n this.handleFormValueChange(value)\n })\n }\n\n override writeValue(val: string | number | string[] | number[] | null): void {\n // Simply update the value - _inputValue is computed and will automatically\n // show the correct display text based on _value and _isSearching state.\n super.writeValue(val)\n\n // Handle array values for multiple mode\n if (Array.isArray(val)) {\n val.forEach((x) => {\n this.handleSelectValue(x)\n })\n }\n }\n\n override onChangedHandler(value: string | number | string[] | number[] | null): void {\n super.onChangedHandler(value)\n // Exit search mode - _inputValue will now derive from _value\n // Note: Don't clear _userSearchText here - it's needed for processTextToFormValue matching\n this._isSearching.set(false)\n }\n\n override onBlurHandler(): void {\n // Process form value and exit search mode immediately to avoid visual glitches\n this.processTextToFormValue(this._userSearchText(), {\n exitSearchMode: true,\n updateOnMatch: true,\n clearSearchText: true,\n })\n\n // Hide dropdown immediately - click events on options are protected by onBlurInput\n // which checks if focus moved to the option list before calling this handler\n this.hideOptionVisibility()\n super.onBlurHandler()\n }\n\n // ============================================\n // PUBLIC METHODS - Used in template\n // ============================================\n\n /**\n * Shows the option list dropdown.\n */\n showOptionVisibility(): void {\n this._showOptions.set(true)\n\n // Initialize _userSearchText with current input value when showing options\n // This ensures that if user focuses and blurs without typing, the value is preserved\n // Also enter search mode to enable filtering\n if (this._isSearching()) return\n const currentInputValue = this._inputValue()\n this._userSearchText.set(currentInputValue || '')\n this._isSearching.set(true)\n }\n\n /**\n * Hides the option list dropdown.\n */\n hideOptionVisibility(): void {\n this._showOptions.set(false)\n }\n\n /**\n * Handles input text changes (typing).\n * @param event The input event\n */\n onChangeInput(event: Event): void {\n this.showOptionVisibility()\n const value = (event.target as HTMLInputElement)?.value ?? ''\n this._isSearching.set(true)\n this._userSearchText.set(value)\n this.emitDebouncedSearchText(value)\n }\n\n /**\n * Handles option selection from the dropdown.\n * @param value The selected option's value\n * @param hideOptions Whether to hide the dropdown after selection\n */\n onValueChange(value: string | number | null, hideOptions = true): void {\n // When allowFreeText is true and a null/undefined value is received (e.g., from selecting\n // a non-existent option in the dropdown), use the typed text as the value instead of clearing\n if ((value === null || value === undefined) && this._allowFreeTextInternal()) {\n const typedText = this._userSearchText()?.trim()\n if (typedText) {\n this.onChangedHandler(typedText)\n if (hideOptions) {\n this.hideOptionVisibility()\n this.focusInput()\n }\n this.selectedOption.emit(typedText)\n return\n }\n }\n\n if (this.multiple()) {\n this.handleSelectValue(value as string | number)\n this.onChangedHandler(this._chipList())\n if (this._chipList().some((x) => x === value)) {\n this._userSearchText.set('')\n this._isSearching.set(false)\n }\n return\n }\n\n // Update _userSearchText to the selected option's label\n // This enables processTextToFormValue to match correctly on blur\n const selectedOption = this.selectOptions().find((x) => x.value === value)\n if (selectedOption) {\n this._userSearchText.set(selectedOption.label)\n }\n this.onChangedHandler(value)\n if (hideOptions) {\n this.hideOptionVisibility()\n // Return focus to input after selection\n this.focusInput()\n }\n this.selectedOption.emit(value)\n }\n\n /**\n * Handles keydown events on the input element for accessibility.\n * @param event The keyboard event\n */\n onInputKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'ArrowDown':\n // Open dropdown if closed, or let option-list handle navigation\n if (!this._showOptions()) {\n event.preventDefault()\n this.showOptionVisibility()\n }\n break\n case 'ArrowUp':\n // Open dropdown if closed\n if (!this._showOptions()) {\n event.preventDefault()\n this.showOptionVisibility()\n }\n break\n case 'Escape':\n // Close dropdown and keep focus on input\n if (this._showOptions()) {\n event.preventDefault()\n this.onEscapePressed()\n }\n break\n case 'Enter':\n // When allowFreeText is true and dropdown is open, handle Enter specially\n if (this._showOptions() && this._allowFreeTextInternal()) {\n // Check if there are any filtered options\n const filteredOptions = this._filteredOptions()\n if (filteredOptions.length === 0) {\n // No options to select - use the typed text as the value\n event.preventDefault()\n this.processTextToFormValue(this._userSearchText(), {\n exitSearchMode: true,\n updateOnMatch: true,\n clearSearchText: false,\n })\n this.hideOptionVisibility()\n }\n // If there are filtered options, let option-list handle the selection\n }\n break\n }\n }\n\n /**\n * Handles Escape key press from option list.\n * Closes dropdown and returns focus to input.\n */\n onEscapePressed(): void {\n this.hideOptionVisibility()\n this.focusInput()\n }\n\n /**\n * Handles Tab key press from option list.\n * Closes dropdown and allows natural tab navigation.\n */\n onTabPressed(_event: { shiftKey: boolean }): void {\n // Close the dropdown, tab will naturally move focus\n this.hideOptionVisibility()\n // Process any pending input value\n this.processTextToFormValue(this._userSearchText(), {\n exitSearchMode: true,\n updateOnMatch: true,\n clearSearchText: true,\n })\n }\n\n /**\n * Sets focus to the input element.\n */\n focusInput(): void {\n const inputEl = this.selectInput()?.nativeElement\n if (!inputEl) return\n inputEl.focus()\n }\n\n /**\n * Handles input blur event.\n * @param event The focus event\n */\n onBlurInput(event: FocusEvent): void {\n const relatedTarget = event.relatedTarget as HTMLElement | null\n const optionListId = this.optionList()?.optionListContainer()?.nativeElement?.id\n if (relatedTarget?.id === optionListId) return\n this.onBlurHandler()\n }\n\n /**\n * Handles blur event on the option list.\n * @param event The blur event (truthy if should hide)\n */\n onBlurOptionList(event: FocusEvent | boolean): void {\n if (!event) return\n this.hideOptionVisibility()\n }\n\n /**\n * Gets the display description for a chip value.\n * @param chipValue The chip's value\n * @returns The chip's display label\n */\n getDescription(chipValue: string | number): string {\n const option = this.selectOptions().find((x) => x.value === chipValue)\n return option?.label?.toString() ?? ''\n }\n\n /**\n * Removes a chip from the selection (multiple mode).\n * @param chipValue The chip value to remove\n */\n deleteChip(chipValue: string | number): void {\n const stringChipValue = chipValue?.toString()\n const index = this._chipList().findIndex((x) => x.toString() === stringChipValue)\n if (index < 0) return\n this._chipList.update((list) => list.filter((_, i) => i !== index))\n this.onChangedHandler(this._chipList())\n }\n\n // ============================================\n // PROTECTED METHODS - Internal logic, accessible to subclasses\n // ============================================\n\n /**\n * Filters options based on input text.\n * @param value The search text\n * @returns Filtered options\n */\n protected filterOptions(value: string): SelectOption[] {\n const options = this.selectOptions()\n const trimmedValue = value?.trim()\n return this.internalFilterOptions() && trimmedValue\n ? options.filter((x) => x.label.toLowerCase().includes(trimmedValue.toLowerCase()))\n : options\n }\n\n // ============================================\n // PRIVATE METHODS - Internal implementation\n // ============================================\n\n /**\n * Core method that processes text input and updates form value accordingly.\n *\n * Matching logic:\n * - If text matches an option label (case-insensitive, trimmed) and autoSelectOnExactMatch is true, select that option\n * - If no match and allowFreeText is true, use the typed text as value\n * - If no match and allowFreeText is false, clear the value\n *\n * @param text The text to process\n * @param options Configuration options:\n * - exitSearchMode: If true, uses onChangedHandler which exits search mode. If false, stays in search mode.\n * - updateOnMatch: If true, updates form when match found. If false, only clears on no-match.\n * - clearSearchText: If true, clears _userSearchText after processing.\n */\n private processTextToFormValue(\n text: string,\n options: { exitSearchMode: boolean; updateOnMatch: boolean; clearSearchText: boolean }\n ): void {\n const searchText = text?.trim()\n\n // Find matching option: exact match (case-insensitive, trimmed)\n const matchingOption = this.findMatchingOption(text)\n\n if (!this.multiple()) {\n // If the found option is already selected, nothing to do except exit search mode\n if (matchingOption?.value === this._value()) {\n if (options.exitSearchMode) {\n this._isSearching.set(false)\n }\n if (options.clearSearchText) {\n this._userSearchText.set('')\n }\n return\n }\n\n // Determine what action to take based on match status and settings\n const shouldAutoSelect = matchingOption && this.autoSelectOnExactMatch() && options.updateOnMatch\n const shouldUseFreeText = this._allowFreeTextInternal() && searchText && options.updateOnMatch\n\n // Clear logic differs between typing and blur:\n // - On blur (exitSearchMode=true): clear when input is empty (regardless of allowFreeText setting)\n // - On blur: also clear when no valid selection and free text not allowed\n // - During typing (exitSearchMode=false): only clear when updateOnMatch is true and text doesn't match\n const shouldClearOnBlurEmpty = options.exitSearchMode && !searchText\n const shouldClearOnBlurNoMatch =\n options.exitSearchMode && !this._allowFreeTextInternal() && (!matchingOption || !this.autoSelectOnExactMatch())\n const shouldClearWhileTyping =\n !options.exitSearchMode && options.updateOnMatch && !matchingOption && !this._allowFreeTextInternal()\n\n if (shouldAutoSelect) {\n // Auto-select the matching option\n if (options.exitSearchMode) {\n this.onChangedHandler(matchingOption.value ?? '')\n } else {\n this.onValueChange(matchingOption.value ?? '', false)\n }\n } else if (shouldUseFreeText) {\n // Free text allowed: use the typed text as value\n if (options.exitSearchMode) {\n this.onChangedHandler(searchText)\n } else {\n this.onValueChange(searchText, false)\n }\n } else if (shouldClearOnBlurEmpty || shouldClearOnBlurNoMatch) {\n // On blur with empty input or no valid selection: clear the value to null\n this.onChangedHandler(null)\n } else if (shouldClearWhileTyping) {\n // While typing, text doesn't match any option: clear the value but stay in search mode\n this.updateValueWithoutExitingSearchMode('')\n }\n }\n\n if (options.clearSearchText) {\n this._userSearchText.set('')\n }\n }\n\n /**\n * Handles keyboard events on the input element.\n */\n private handleInputKeydown(e: KeyboardEvent, inputElement: HTMLInputElement): void {\n if (!(this.multiple() && this._chipList().length > 0 && !this._inputValue()?.length && e.key === 'Backspace')) {\n return\n }\n e.preventDefault()\n const chipContainerEl = this.chipContainer()?.nativeElement\n if (chipContainerEl) {\n const chips = chipContainerEl.querySelectorAll('.chip button.btn-chip') as NodeListOf<HTMLButtonElement>\n if (chips.length > 0) {\n const lastChip = chips[chips.length - 1]\n lastChip.focus()\n lastChip.addEventListener('keydown', (event: KeyboardEvent) => {\n if (event.key === 'Backspace') {\n event.preventDefault()\n this.deleteChip(this._chipList()[this._chipList().length - 1])\n inputElement.focus()\n return\n }\n event.preventDefault()\n })\n }\n }\n }\n\n /**\n * Handles changes to the select options input.\n */\n private handleOptionsChange(): void {\n const value = this._value()\n if (this.multiple() && Array.isArray(value) && value.length > 0) {\n for (const valueElement of value) {\n this.handleSelectValue(valueElement)\n }\n }\n // For single mode: _inputValue is computed, so it automatically updates\n }\n\n /**\n * Handles form value changes from external sources.\n */\n private handleFormValueChange(value: string | number | string[] | number[] | null): void {\n if (!(this.multiple() && Array.isArray(value))) {\n return\n }\n this._chipList.set([])\n this._selectedOptions.set([])\n value.forEach((x) => {\n this.handleSelectValue(x)\n })\n // Note: Don't clear _userSearchText here - it's managed by processTextToFormValue\n // which runs when options are hidden and needs _userSearchText for matching.\n }\n\n /**\n * Handles selecting a value (adding to chip list in multiple mode).\n */\n private handleSelectValue(value: string | number): void {\n const option = this.selectOptions().find((x) => x.value === value)\n if (option && !this._chipList().some((x) => x === option.value)) {\n this._chipList.update((list) => [...list, option.value as string])\n this._selectedOptions.update((list) => [...list, option])\n }\n }\n\n /**\n * Emits search text change after debounce.\n * When `updateValueOnType` is true, also updates the form value using the same\n * matching logic as processTextToFormValue (auto-select matching options, or use free text).\n */\n private emitDebouncedSearchText(value: string): void {\n if (this._searchDebounceTimer) {\n clearTimeout(this._searchDebounceTimer)\n }\n\n this._searchDebounceTimer = setTimeout(() => {\n if (this._isDestroyed) {\n return\n }\n\n if (value === this._lastEmittedSearchText) {\n return\n }\n this._lastEmittedSearchText = value\n this.searchTextChange.emit(value || '')\n\n // Update form value based on what the user typed\n // - When updateValueOnType is true: update on both match and no-match\n // - When updateValueOnType is false: only clear the value when text doesn't match\n this.processTextToFormValue(value, {\n exitSearchMode: false,\n updateOnMatch: this.updateValueOnType(),\n clearSearchText: false,\n })\n }, this.searchTextDebounce())\n }\n\n /**\n * Updates the form value and internal _value signal without exiting search mode.\n * This is used when clearing the value during typing - we want to update the form\n * but keep the user in search mode so they can continue typing.\n */\n private updateValueWithoutExitingSearchMode(value: string | number | string[] | number[] | null): void {\n this._value.set(value)\n if (this.onChange) {\n this.onChange(value as string)\n }\n }\n}\n","<div\n [ngStyle]=\"{ '--chip-max-length': chipMaxLength() ? chipMaxLength() + 'ch' : 'none' }\"\n #autocompleteContainer\n class=\"autocomplete-container\"\n>\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n <div\n [ngClass]=\"multiSelectDisplayMode() === 'horizontal' ? 'horizontal form-control' : ''\"\n #chipContainer\n class=\"container-wrap\"\n >\n @if (multiple() && _chipList().length > 0) {\n @for (chip of _chipList(); track chip) {\n @if (getDescription(chip)) {\n <div\n [quangTooltip]=\"chipMaxLength() ? getDescription(chip) : ''\"\n class=\"chip chip-hover\"\n >\n <p [ngClass]=\"{ 'm-0': isReadonly() || _isDisabled() }\">\n {{ getDescription(chip) }}\n </p>\n @if (!isReadonly() && !_isDisabled()) {\n <button\n [tabIndex]=\"$index + 1\"\n (click)=\"deleteChip(chip)\"\n class=\"btn btn-chip\"\n type=\"button\"\n >\n <svg\n class=\"ionicon\"\n fill=\"currentColor\"\n height=\"24\"\n viewBox=\"0 0 512 512\"\n width=\"24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M368 368L144 144M368 144L144 368\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"32\"\n />\n </svg>\n </button>\n }\n </div>\n }\n }\n }\n\n <input\n [attr.aria-activedescendant]=\"_showOptions() ? optionList()?.getActiveDescendantId() : null\"\n [attr.aria-controls]=\"_showOptions() ? 'optionList' : null\"\n [attr.aria-expanded]=\"_showOptions()\"\n [attr.required]=\"getIsRequiredControl()\"\n [class.form-control]=\"multiSelectDisplayMode() !== 'horizontal'\"\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n [disabled]=\"_isDisabled() || isReadonly()\"\n [id]=\"componentId()\"\n [ngClass]=\"componentClass()\"\n [placeholder]=\"componentPlaceholder() | transloco\"\n [tabIndex]=\"componentTabIndex()\"\n [value]=\"_inputValue()\"\n (blur)=\"onBlurInput($event)\"\n (input)=\"onChangeInput($event)\"\n (keydown)=\"onInputKeydown($event)\"\n (mousedown)=\"showOptionVisibility()\"\n #selectInput\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n autocomplete=\"off\"\n role=\"combobox\"\n type=\"text\"\n />\n </div>\n @if (_showOptions()) {\n <quang-option-list\n [_isDisabled]=\"_isDisabled()\"\n [_value]=\"_highlightedValue()\"\n [componentClass]=\"componentClass()\"\n [componentLabel]=\"componentLabel()\"\n [componentTabIndex]=\"componentTabIndex()\"\n [nullOption]=\"false\"\n [optionListMaxHeight]=\"optionListMaxHeight()\"\n [parentID]=\"componentId()\"\n [parentType]=\"ParentType\"\n [scrollBehaviorOnOpen]=\"scrollBehaviorOnOpen()\"\n [selectButtonRef]=\"autocompleteContainer\"\n [selectOptions]=\"_filteredOptions()\"\n [translateValue]=\"translateValue()\"\n (blurHandler)=\"onBlurOptionList($event)\"\n (changedHandler)=\"onValueChange($event)\"\n (escapePressed)=\"onEscapePressed()\"\n (tabPressed)=\"onTabPressed($event)\"\n #optionList\n selectionMode=\"single\"\n />\n }\n <div class=\"valid-feedback\">\n {{ successMessage() | transloco }}\n </div>\n <div class=\"invalid-feedback\">\n {{ _currentErrorMessage() | transloco: _currentErrorMessageExtraData() }}\n </div>\n @if (helpMessage()) {\n <small\n [hidden]=\"_showSuccess() || _showErrors()\"\n aria-live=\"assertive\"\n class=\"form-text text-muted\"\n >\n {{ helpMessage() | transloco }}\n </small>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"quang-components-autocomplete.mjs","sources":["../../../projects/quang/components/autocomplete/autocomplete.component.ts","../../../projects/quang/components/autocomplete/autocomplete.component.html","../../../projects/quang/components/autocomplete/quang-components-autocomplete.ts"],"sourcesContent":["import { NgClass, NgStyle, NgTemplateOutlet } from '@angular/common'\nimport {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n computed,\n effect,\n forwardRef,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core'\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop'\nimport { NG_VALUE_ACCESSOR } from '@angular/forms'\n\nimport { TranslocoPipe } from '@jsverse/transloco'\nimport { QuangTooltipDirective } from 'quang/overlay/tooltip'\nimport { Subscription } from 'rxjs'\n\nimport {\n OptionListParentType,\n QuangBaseComponent,\n QuangOptionListComponent,\n SelectOption,\n} from 'quang/components/shared'\n\n/**\n * Autocomplete component for providing suggestion options {@link SelectOption} as the user types.\n *\n * @usageNotes\n * This component displays a list of filtered options based on user input.\n * It allows users to select an option from the suggestions and emits the event `selectedOption` when an option is selected.\n *\n * `searchTextDebounce` is by default set to 300ms.\n */\n@Component({\n selector: 'quang-autocomplete',\n imports: [TranslocoPipe, NgClass, NgTemplateOutlet, QuangOptionListComponent, NgStyle, QuangTooltipDirective],\n templateUrl: './autocomplete.component.html',\n styleUrl: './autocomplete.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => QuangAutocompleteComponent),\n multi: true,\n },\n {\n provide: QuangOptionListComponent,\n multi: false,\n },\n ],\n})\nexport class QuangAutocompleteComponent extends QuangBaseComponent<string | number | string[] | number[] | null> {\n // ============================================\n // INPUTS - Configuration properties\n // ============================================\n\n /**\n * The list of options to display in the autocomplete dropdown.\n */\n selectOptions = input.required<SelectOption[]>()\n\n /**\n * When true, allows any text input as a valid form value, not just option values.\n * The form value will sync with whatever text the user types.\n * When false (default), the form value must match one of the option values.\n * @default false\n */\n allowFreeText = input<boolean>(false)\n\n /**\n * When true and allowFreeText is false, automatically selects an option if the user's\n * input text matches an option's label exactly (case-insensitive, trimmed).\n * This provides a better UX by auto-selecting when users type a complete option label.\n * @default true\n */\n autoSelectOnExactMatch = input<boolean>(true)\n\n /**\n * When true, updates the form value as the user types (after debounce).\n * When false (default), the form value is only updated when:\n * - User selects an option from the dropdown\n * - User stops typing and the input loses focus (blur)\n * @default false\n */\n updateValueOnType = input<boolean>(false)\n\n /**\n * Whether the form value can be any text or must match one of the options.\n * When true, the form value syncs with the input text.\n * When false (default), the form value must be one of the option values.\n * @default false\n * @deprecated Use `allowFreeText` instead. This input will be removed in a future version.\n */\n syncFormWithText = input<boolean>(false)\n\n /**\n * Maximum height of the option list before scrolling.\n * @default '200px'\n */\n optionListMaxHeight = input<string>('200px')\n\n /**\n * Whether to translate option labels.\n * @default true\n */\n translateValue = input<boolean>(true)\n\n /**\n * Scroll behavior when the option list opens.\n * @default 'smooth'\n */\n scrollBehaviorOnOpen = input<ScrollBehavior>('smooth')\n\n /**\n * When true, only emits the value without saving it to ngControl.\n * @default false\n */\n emitOnly = input<boolean>(false)\n\n /**\n * Enable multiple selection mode with chips.\n * @default false\n */\n multiple = input<boolean>(false)\n\n /**\n * Maximum length in characters for chip display text.\n * When set, chips will be truncated and show a tooltip with full text.\n * @default 0 (no limit)\n */\n chipMaxLength = input<number>(0)\n\n /**\n * Layout direction for chips in multiple selection mode.\n * @default 'vertical'\n */\n multiSelectDisplayMode = input<'vertical' | 'horizontal'>('vertical')\n\n /**\n * Position of chips relative to the input in multiple selection mode.\n * - 'top': Chips are displayed above the input (default)\n * - 'bottom': Chips are displayed below the input\n * @default 'top'\n */\n chipsPosition = input<'top' | 'bottom'>('top')\n\n /**\n * Debounce time in milliseconds for search text changes.\n * @default 300\n */\n searchTextDebounce = input<number>(300)\n\n /**\n * Whether to filter options internally based on input text.\n * When false, filtering should be handled externally via searchTextChange event.\n * @default true\n */\n internalFilterOptions = input<boolean>(true)\n\n // ============================================\n // OUTPUTS - Event emitters\n // ============================================\n\n /**\n * Emitted when an option is selected.\n * Emits the selected option's value, or null when cleared.\n */\n selectedOption = output<string | number | null>()\n\n /**\n * Emitted when the search text changes (after debounce).\n * Useful for external filtering or API calls.\n */\n searchTextChange = output<string>()\n\n // ============================================\n // VIEW CHILDREN - Template references\n // ============================================\n\n /** Reference to the option list component */\n protected readonly optionList = viewChild<QuangOptionListComponent>('optionList')\n\n /** Reference to the input element */\n private readonly selectInput = viewChild<ElementRef<HTMLInputElement>>('selectInput')\n\n /** Reference to the chip container element */\n private readonly chipContainer = viewChild<ElementRef<HTMLDivElement>>('chipContainer')\n\n /** Reference to the main autocomplete container */\n private readonly autocompleteContainer = viewChild<ElementRef<HTMLDivElement>>('autocompleteContainer')\n\n // ============================================\n // PUBLIC STATE - Used in template\n // ============================================\n\n /** Constant for option list parent type */\n readonly ParentType = OptionListParentType.AUTOCOMPLETE\n\n /** Height of the input element (used for positioning) */\n readonly inputHeight = signal<number>(0)\n\n /**\n * The display text for the input field.\n * - When searching: shows what the user typed\n * - When allowFreeText/syncFormWithText is true and no matching option: shows the raw value\n * - When not searching: shows the selected option's label (derived from _value)\n */\n readonly _inputValue = computed<string>(() => {\n if (this._isSearching()) {\n return this._userSearchText()\n }\n // Derive display text from _value by finding the matching option\n const value = this._value()\n if (value === null || value === undefined || value === '' || Array.isArray(value)) {\n return ''\n }\n const option = this.selectOptions().find((x) => x.value === value)\n // When free text is allowed and no matching option found, display the value itself\n // (since the value IS the text the user typed)\n if (!option && this._allowFreeTextInternal()) {\n return String(value)\n }\n return option?.label ?? ''\n })\n\n /** Whether the option list is currently visible */\n readonly _showOptions = signal<boolean | null>(null)\n\n /** List of selected chip values (for multiple mode) */\n readonly _chipList = signal<string[]>([])\n\n /** List of selected option objects (for multiple mode) */\n readonly _selectedOptions = signal<SelectOption[]>([])\n\n /** Filtered options based on search text and chip selection */\n readonly _filteredOptions = computed<SelectOption[]>(() => {\n const searchText = this._isSearching() ? this._userSearchText() : ''\n if (this.multiple()) {\n return this.filterOptions(searchText).filter((x) => !this._chipList().some((chip) => chip === x.value))\n }\n return searchText?.length ? this.filterOptions(searchText) : this.selectOptions()\n })\n\n /**\n * The value to use for highlighting in the option list.\n * When searching: shows the matched option (if any) based on exact label match\n * When not searching: shows the current form value\n * This keeps highlighting in sync with what will be selected on blur.\n */\n readonly _highlightedValue = computed<string | number | string[] | number[] | null>(() => {\n if (this._isSearching() && !this.multiple()) {\n const searchText = this._userSearchText()\n if (!searchText?.trim()) {\n // If search text is empty, don't highlight anything\n return null\n }\n // Find exact match for highlighting\n const matchingOption = this.findMatchingOption(searchText)\n if (matchingOption && this.autoSelectOnExactMatch()) {\n return matchingOption.value\n }\n // If free text is allowed, don't highlight any option\n // (the typed text itself will be the value)\n return null\n }\n // When not searching, use the current value\n return this._value()\n })\n\n // ============================================\n // PROTECTED STATE - Internal but accessible to subclasses\n // ============================================\n\n /** Whether the user is actively typing/searching */\n protected readonly _isSearching = signal<boolean>(false)\n\n /** The text the user is currently typing while searching */\n protected readonly _userSearchText = signal<string>('')\n\n /**\n * Internal computed that returns true if free text input is allowed.\n * Combines both `allowFreeText` and deprecated `syncFormWithText` inputs.\n */\n protected readonly _allowFreeTextInternal = computed<boolean>(() => {\n return this.allowFreeText() || this.syncFormWithText()\n })\n\n /**\n * Finds an option whose label exactly matches the given text (case-insensitive, trimmed).\n * @param text The text to match against option labels\n * @returns The matching option, or undefined if no match\n */\n protected findMatchingOption(text: string | null | undefined): SelectOption | undefined {\n if (!text) return undefined\n const searchTextLower = text.trim().toLowerCase()\n return this.selectOptions().find((x) => x.label.trim().toLowerCase() === searchTextLower)\n }\n\n // ============================================\n // PRIVATE STATE - Internal implementation details\n // ============================================\n\n /** Timer for search text debounce */\n private _searchDebounceTimer: ReturnType<typeof setTimeout> | null = null\n\n /** Last emitted search text (for distinctUntilChanged behavior) */\n private _lastEmittedSearchText: string | null = null\n\n /** Whether the component has been destroyed */\n private _isDestroyed = false\n\n /** Subscription to form value changes */\n private formValueChangeSubscription: Subscription | undefined = undefined\n\n // ============================================\n // EFFECTS - Reactive side effects\n // ============================================\n\n /** Effect to handle input element setup and keyboard events */\n private readonly onChangeSelectInputEffect = effect(() => {\n const selectInput = this.selectInput()\n if (!selectInput) return\n this.inputHeight.set(selectInput.nativeElement.getBoundingClientRect().height)\n selectInput.nativeElement.addEventListener('keydown', (e: KeyboardEvent) => {\n this.handleInputKeydown(e, selectInput.nativeElement)\n })\n })\n\n /** Subscription to options changes */\n private readonly selectOptionsChangeSubscription = toObservable(this.selectOptions)\n .pipe(takeUntilDestroyed())\n .subscribe(() => {\n this.handleOptionsChange()\n })\n\n /** Subscription to show options changes */\n private readonly showOptionsChangeSubscription = toObservable(this._showOptions)\n .pipe(takeUntilDestroyed())\n .subscribe((data) => {\n // Note: Form value processing is now handled directly in onBlurHandler\n // for immediate processing. This subscription is kept for backwards compatibility\n // but the _isSearching check prevents double-processing since onBlurHandler\n // already sets _isSearching to false before this subscription fires.\n if (!(!data && data !== null && this._isSearching())) return\n // Only process if still in search mode (which means onBlurHandler didn't run)\n this.processTextToFormValue(this._userSearchText(), {\n exitSearchMode: true,\n updateOnMatch: true,\n clearSearchText: true,\n })\n })\n\n // ============================================\n // CONSTRUCTOR\n // ============================================\n\n constructor() {\n super()\n this.destroyRef.onDestroy(() => {\n this._isDestroyed = true\n if (!this._searchDebounceTimer) return\n clearTimeout(this._searchDebounceTimer)\n })\n }\n\n // ============================================\n // LIFECYCLE HOOKS / OVERRIDES\n // ============================================\n\n override setupFormControl(): void {\n super.setupFormControl()\n const formControl = this._ngControl()?.control\n\n if (this.formValueChangeSubscription) {\n this.formValueChangeSubscription.unsubscribe()\n this.formValueChangeSubscription = undefined\n }\n\n if (!formControl) return\n\n this.formValueChangeSubscription = formControl.valueChanges\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((value: string | number | string[] | number[] | null) => {\n this.handleFormValueChange(value)\n })\n }\n\n override writeValue(val: string | number | string[] | number[] | null): void {\n // Simply update the value - _inputValue is computed and will automatically\n // show the correct display text based on _value and _isSearching state.\n super.writeValue(val)\n\n // Handle array values for multiple mode\n if (Array.isArray(val)) {\n val.forEach((x) => {\n this.handleSelectValue(x)\n })\n }\n }\n\n override onChangedHandler(value: string | number | string[] | number[] | null): void {\n super.onChangedHandler(value)\n // Exit search mode - _inputValue will now derive from _value\n // Note: Don't clear _userSearchText here - it's needed for processTextToFormValue matching\n this._isSearching.set(false)\n }\n\n override onBlurHandler(): void {\n // Process form value and exit search mode immediately to avoid visual glitches\n this.processTextToFormValue(this._userSearchText(), {\n exitSearchMode: true,\n updateOnMatch: true,\n clearSearchText: true,\n })\n\n // Hide dropdown immediately - click events on options are protected by onBlurInput\n // which checks if focus moved to the option list before calling this handler\n this.hideOptionVisibility()\n super.onBlurHandler()\n }\n\n // ============================================\n // PUBLIC METHODS - Used in template\n // ============================================\n\n /**\n * Shows the option list dropdown.\n */\n showOptionVisibility(): void {\n this._showOptions.set(true)\n\n // Initialize _userSearchText with current input value when showing options\n // This ensures that if user focuses and blurs without typing, the value is preserved\n // Also enter search mode to enable filtering\n if (this._isSearching()) return\n const currentInputValue = this._inputValue()\n this._userSearchText.set(currentInputValue || '')\n this._isSearching.set(true)\n }\n\n /**\n * Hides the option list dropdown.\n */\n hideOptionVisibility(): void {\n this._showOptions.set(false)\n }\n\n /**\n * Handles input text changes (typing).\n * @param event The input event\n */\n onChangeInput(event: Event): void {\n this.showOptionVisibility()\n const value = (event.target as HTMLInputElement)?.value ?? ''\n this._isSearching.set(true)\n this._userSearchText.set(value)\n this.emitDebouncedSearchText(value)\n }\n\n /**\n * Handles option selection from the dropdown.\n * @param value The selected option's value\n * @param hideOptions Whether to hide the dropdown after selection\n */\n onValueChange(value: string | number | null, hideOptions = true): void {\n // When allowFreeText is true and a null/undefined value is received (e.g., from selecting\n // a non-existent option in the dropdown), use the typed text as the value instead of clearing\n if ((value === null || value === undefined) && this._allowFreeTextInternal()) {\n const typedText = this._userSearchText()?.trim()\n if (typedText) {\n this.onChangedHandler(typedText)\n if (hideOptions) {\n this.hideOptionVisibility()\n this.focusInput()\n }\n this.selectedOption.emit(typedText)\n return\n }\n }\n\n if (this.multiple()) {\n this.handleSelectValue(value as string | number)\n this.onChangedHandler(this._chipList())\n if (this._chipList().some((x) => x === value)) {\n this._userSearchText.set('')\n this._isSearching.set(false)\n }\n return\n }\n\n // Update _userSearchText to the selected option's label\n // This enables processTextToFormValue to match correctly on blur\n const selectedOption = this.selectOptions().find((x) => x.value === value)\n if (selectedOption) {\n this._userSearchText.set(selectedOption.label)\n }\n this.onChangedHandler(value)\n if (hideOptions) {\n this.hideOptionVisibility()\n // Return focus to input after selection\n this.focusInput()\n }\n this.selectedOption.emit(value)\n }\n\n /**\n * Handles keydown events on the input element for accessibility.\n * @param event The keyboard event\n */\n onInputKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'ArrowDown':\n // Open dropdown if closed, or let option-list handle navigation\n if (!this._showOptions()) {\n event.preventDefault()\n this.showOptionVisibility()\n }\n break\n case 'ArrowUp':\n // Open dropdown if closed\n if (!this._showOptions()) {\n event.preventDefault()\n this.showOptionVisibility()\n }\n break\n case 'Escape':\n // Close dropdown and keep focus on input\n if (this._showOptions()) {\n event.preventDefault()\n this.onEscapePressed()\n }\n break\n case 'Enter':\n // When allowFreeText is true and dropdown is open, handle Enter specially\n if (this._showOptions() && this._allowFreeTextInternal()) {\n // Check if there are any filtered options\n const filteredOptions = this._filteredOptions()\n if (filteredOptions.length === 0) {\n // No options to select - use the typed text as the value\n event.preventDefault()\n this.processTextToFormValue(this._userSearchText(), {\n exitSearchMode: true,\n updateOnMatch: true,\n clearSearchText: false,\n })\n this.hideOptionVisibility()\n }\n // If there are filtered options, let option-list handle the selection\n }\n break\n }\n }\n\n /**\n * Handles Escape key press from option list.\n * Closes dropdown and returns focus to input.\n */\n onEscapePressed(): void {\n this.hideOptionVisibility()\n this.focusInput()\n }\n\n /**\n * Handles Tab key press from option list.\n * Closes dropdown and allows natural tab navigation.\n */\n onTabPressed(_event: { shiftKey: boolean }): void {\n // Close the dropdown, tab will naturally move focus\n this.hideOptionVisibility()\n // Process any pending input value\n this.processTextToFormValue(this._userSearchText(), {\n exitSearchMode: true,\n updateOnMatch: true,\n clearSearchText: true,\n })\n }\n\n /**\n * Sets focus to the input element.\n */\n focusInput(): void {\n const inputEl = this.selectInput()?.nativeElement\n if (!inputEl) return\n inputEl.focus()\n }\n\n /**\n * Handles input blur event.\n * @param event The focus event\n */\n onBlurInput(event: FocusEvent): void {\n const relatedTarget = event.relatedTarget as HTMLElement | null\n const optionListId = this.optionList()?.optionListContainer()?.nativeElement?.id\n if (relatedTarget?.id === optionListId) return\n this.onBlurHandler()\n }\n\n /**\n * Handles blur event on the option list.\n * @param event The blur event (truthy if should hide)\n */\n onBlurOptionList(event: FocusEvent | boolean): void {\n if (!event) return\n this.hideOptionVisibility()\n }\n\n /**\n * Gets the display description for a chip value.\n * @param chipValue The chip's value\n * @returns The chip's display label\n */\n getDescription(chipValue: string | number): string {\n const option = this.selectOptions().find((x) => x.value === chipValue)\n return option?.label?.toString() ?? ''\n }\n\n /**\n * Removes a chip from the selection (multiple mode).\n * @param chipValue The chip value to remove\n */\n deleteChip(chipValue: string | number): void {\n const stringChipValue = chipValue?.toString()\n const index = this._chipList().findIndex((x) => x.toString() === stringChipValue)\n if (index < 0) return\n this._chipList.update((list) => list.filter((_, i) => i !== index))\n this.onChangedHandler(this._chipList())\n }\n\n // ============================================\n // PROTECTED METHODS - Internal logic, accessible to subclasses\n // ============================================\n\n /**\n * Filters options based on input text.\n * @param value The search text\n * @returns Filtered options\n */\n protected filterOptions(value: string): SelectOption[] {\n const options = this.selectOptions()\n const trimmedValue = value?.trim()\n return this.internalFilterOptions() && trimmedValue\n ? options.filter((x) => x.label.toLowerCase().includes(trimmedValue.toLowerCase()))\n : options\n }\n\n // ============================================\n // PRIVATE METHODS - Internal implementation\n // ============================================\n\n /**\n * Core method that processes text input and updates form value accordingly.\n *\n * Matching logic:\n * - If text matches an option label (case-insensitive, trimmed) and autoSelectOnExactMatch is true, select that option\n * - If no match and allowFreeText is true, use the typed text as value\n * - If no match and allowFreeText is false, clear the value\n *\n * @param text The text to process\n * @param options Configuration options:\n * - exitSearchMode: If true, uses onChangedHandler which exits search mode. If false, stays in search mode.\n * - updateOnMatch: If true, updates form when match found. If false, only clears on no-match.\n * - clearSearchText: If true, clears _userSearchText after processing.\n */\n private processTextToFormValue(\n text: string,\n options: { exitSearchMode: boolean; updateOnMatch: boolean; clearSearchText: boolean }\n ): void {\n const searchText = text?.trim()\n\n // Find matching option: exact match (case-insensitive, trimmed)\n const matchingOption = this.findMatchingOption(text)\n\n if (!this.multiple()) {\n // If the found option is already selected, nothing to do except exit search mode\n if (matchingOption?.value === this._value()) {\n if (options.exitSearchMode) {\n this._isSearching.set(false)\n }\n if (options.clearSearchText) {\n this._userSearchText.set('')\n }\n return\n }\n\n // Determine what action to take based on match status and settings\n const shouldAutoSelect = matchingOption && this.autoSelectOnExactMatch() && options.updateOnMatch\n const shouldUseFreeText = this._allowFreeTextInternal() && searchText && options.updateOnMatch\n\n // Clear logic differs between typing and blur:\n // - On blur (exitSearchMode=true): clear when input is empty (regardless of allowFreeText setting)\n // - On blur: also clear when no valid selection and free text not allowed\n // - During typing (exitSearchMode=false): only clear when updateOnMatch is true and text doesn't match\n const shouldClearOnBlurEmpty = options.exitSearchMode && !searchText\n const shouldClearOnBlurNoMatch =\n options.exitSearchMode && !this._allowFreeTextInternal() && (!matchingOption || !this.autoSelectOnExactMatch())\n const shouldClearWhileTyping =\n !options.exitSearchMode && options.updateOnMatch && !matchingOption && !this._allowFreeTextInternal()\n\n if (shouldAutoSelect) {\n // Auto-select the matching option\n if (options.exitSearchMode) {\n this.onChangedHandler(matchingOption.value ?? '')\n } else {\n this.onValueChange(matchingOption.value ?? '', false)\n }\n } else if (shouldUseFreeText) {\n // Free text allowed: use the typed text as value\n if (options.exitSearchMode) {\n this.onChangedHandler(searchText)\n } else {\n this.onValueChange(searchText, false)\n }\n } else if (shouldClearOnBlurEmpty || shouldClearOnBlurNoMatch) {\n // On blur with empty input or no valid selection: clear the value to null\n this.onChangedHandler(null)\n } else if (shouldClearWhileTyping) {\n // While typing, text doesn't match any option: clear the value but stay in search mode\n this.updateValueWithoutExitingSearchMode('')\n }\n }\n\n if (options.clearSearchText) {\n this._userSearchText.set('')\n }\n }\n\n /**\n * Handles keyboard events on the input element.\n */\n private handleInputKeydown(e: KeyboardEvent, inputElement: HTMLInputElement): void {\n if (!(this.multiple() && this._chipList().length > 0 && !this._inputValue()?.length && e.key === 'Backspace')) {\n return\n }\n e.preventDefault()\n const chipContainerEl = this.chipContainer()?.nativeElement\n if (chipContainerEl) {\n const chips = chipContainerEl.querySelectorAll('.chip button.btn-chip') as NodeListOf<HTMLButtonElement>\n if (chips.length > 0) {\n const lastChip = chips[chips.length - 1]\n lastChip.focus()\n lastChip.addEventListener('keydown', (event: KeyboardEvent) => {\n if (event.key === 'Backspace') {\n event.preventDefault()\n this.deleteChip(this._chipList()[this._chipList().length - 1])\n inputElement.focus()\n return\n }\n event.preventDefault()\n })\n }\n }\n }\n\n /**\n * Handles changes to the select options input.\n */\n private handleOptionsChange(): void {\n const value = this._value()\n if (this.multiple() && Array.isArray(value) && value.length > 0) {\n for (const valueElement of value) {\n this.handleSelectValue(valueElement)\n }\n }\n // For single mode: _inputValue is computed, so it automatically updates\n }\n\n /**\n * Handles form value changes from external sources.\n */\n private handleFormValueChange(value: string | number | string[] | number[] | null): void {\n if (!(this.multiple() && Array.isArray(value))) {\n return\n }\n this._chipList.set([])\n this._selectedOptions.set([])\n value.forEach((x) => {\n this.handleSelectValue(x)\n })\n // Note: Don't clear _userSearchText here - it's managed by processTextToFormValue\n // which runs when options are hidden and needs _userSearchText for matching.\n }\n\n /**\n * Handles selecting a value (adding to chip list in multiple mode).\n */\n private handleSelectValue(value: string | number): void {\n const option = this.selectOptions().find((x) => x.value === value)\n if (option && !this._chipList().some((x) => x === option.value)) {\n this._chipList.update((list) => [...list, option.value as string])\n this._selectedOptions.update((list) => [...list, option])\n }\n }\n\n /**\n * Emits search text change after debounce.\n * When `updateValueOnType` is true, also updates the form value using the same\n * matching logic as processTextToFormValue (auto-select matching options, or use free text).\n */\n private emitDebouncedSearchText(value: string): void {\n if (this._searchDebounceTimer) {\n clearTimeout(this._searchDebounceTimer)\n }\n\n this._searchDebounceTimer = setTimeout(() => {\n if (this._isDestroyed) {\n return\n }\n\n if (value === this._lastEmittedSearchText) {\n return\n }\n this._lastEmittedSearchText = value\n this.searchTextChange.emit(value || '')\n\n // Update form value based on what the user typed\n // - When updateValueOnType is true: update on both match and no-match\n // - When updateValueOnType is false: only clear the value when text doesn't match\n this.processTextToFormValue(value, {\n exitSearchMode: false,\n updateOnMatch: this.updateValueOnType(),\n clearSearchText: false,\n })\n }, this.searchTextDebounce())\n }\n\n /**\n * Updates the form value and internal _value signal without exiting search mode.\n * This is used when clearing the value during typing - we want to update the form\n * but keep the user in search mode so they can continue typing.\n */\n private updateValueWithoutExitingSearchMode(value: string | number | string[] | number[] | null): void {\n this._value.set(value)\n if (this.onChange) {\n this.onChange(value as string)\n }\n }\n}\n","<div\n [ngStyle]=\"{ '--chip-max-length': chipMaxLength() ? chipMaxLength() + 'ch' : 'none' }\"\n #autocompleteContainer\n class=\"autocomplete-container\"\n>\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n <div\n [ngClass]=\"{\n horizontal: multiSelectDisplayMode() === 'horizontal',\n 'form-control': multiSelectDisplayMode() === 'horizontal',\n 'chips-bottom': chipsPosition() === 'bottom',\n }\"\n #chipContainer\n class=\"container-wrap\"\n >\n @if (multiple() && _chipList().length > 0 && chipsPosition() === 'top') {\n <ng-container *ngTemplateOutlet=\"chipsTemplate\" />\n }\n\n <input\n [attr.aria-activedescendant]=\"_showOptions() ? optionList()?.getActiveDescendantId() : null\"\n [attr.aria-controls]=\"_showOptions() ? 'optionList' : null\"\n [attr.aria-expanded]=\"_showOptions()\"\n [attr.required]=\"getIsRequiredControl()\"\n [class.form-control]=\"multiSelectDisplayMode() !== 'horizontal'\"\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n [disabled]=\"_isDisabled() || isReadonly()\"\n [id]=\"componentId()\"\n [ngClass]=\"componentClass()\"\n [placeholder]=\"componentPlaceholder() | transloco\"\n [tabIndex]=\"componentTabIndex()\"\n [value]=\"_inputValue()\"\n (blur)=\"onBlurInput($event)\"\n (input)=\"onChangeInput($event)\"\n (keydown)=\"onInputKeydown($event)\"\n (mousedown)=\"showOptionVisibility()\"\n #selectInput\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n autocomplete=\"off\"\n role=\"combobox\"\n type=\"text\"\n />\n\n @if (multiple() && _chipList().length > 0 && chipsPosition() === 'bottom') {\n <ng-container *ngTemplateOutlet=\"chipsTemplate\" />\n }\n </div>\n @if (_showOptions()) {\n <quang-option-list\n [_isDisabled]=\"_isDisabled()\"\n [_value]=\"_highlightedValue()\"\n [componentClass]=\"componentClass()\"\n [componentLabel]=\"componentLabel()\"\n [componentTabIndex]=\"componentTabIndex()\"\n [nullOption]=\"false\"\n [optionListMaxHeight]=\"optionListMaxHeight()\"\n [parentID]=\"componentId()\"\n [parentType]=\"ParentType\"\n [scrollBehaviorOnOpen]=\"scrollBehaviorOnOpen()\"\n [selectButtonRef]=\"autocompleteContainer\"\n [selectOptions]=\"_filteredOptions()\"\n [translateValue]=\"translateValue()\"\n (blurHandler)=\"onBlurOptionList($event)\"\n (changedHandler)=\"onValueChange($event)\"\n (escapePressed)=\"onEscapePressed()\"\n (tabPressed)=\"onTabPressed($event)\"\n #optionList\n selectionMode=\"single\"\n />\n }\n <div class=\"valid-feedback\">\n {{ successMessage() | transloco }}\n </div>\n <div class=\"invalid-feedback\">\n {{ _currentErrorMessage() | transloco: _currentErrorMessageExtraData() }}\n </div>\n @if (helpMessage()) {\n <small\n [hidden]=\"_showSuccess() || _showErrors()\"\n aria-live=\"assertive\"\n class=\"form-text text-muted\"\n >\n {{ helpMessage() | transloco }}\n </small>\n }\n</div>\n\n<!-- Chips template for reuse in top/bottom positions -->\n<ng-template #chipsTemplate>\n <div class=\"chips-container\">\n @for (chip of _chipList(); track chip) {\n @if (getDescription(chip)) {\n <div\n [quangTooltip]=\"chipMaxLength() ? getDescription(chip) : ''\"\n class=\"chip chip-hover\"\n >\n <p [ngClass]=\"{ 'm-0': isReadonly() || _isDisabled() }\">\n {{ getDescription(chip) }}\n </p>\n @if (!isReadonly() && !_isDisabled()) {\n <button\n [tabIndex]=\"$index + 1\"\n (click)=\"deleteChip(chip)\"\n class=\"btn btn-chip\"\n type=\"button\"\n >\n <svg\n class=\"ionicon\"\n fill=\"currentColor\"\n height=\"24\"\n viewBox=\"0 0 512 512\"\n width=\"24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M368 368L144 144M368 144L144 368\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"32\"\n />\n </svg>\n </button>\n }\n </div>\n }\n }\n </div>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -27,8 +27,8 @@ class QuangSelectComponent extends QuangBaseComponent {
|
|
|
27
27
|
this.selectOptions = input.required();
|
|
28
28
|
this.scrollBehaviorOnOpen = input('smooth');
|
|
29
29
|
this.selectButton = viewChild('selectButton');
|
|
30
|
+
/** Whether the option list is currently visible */
|
|
30
31
|
this._showOptions = signal(false);
|
|
31
|
-
this._optionHideTimeout = signal(undefined);
|
|
32
32
|
this._selectedItems = computed(() => {
|
|
33
33
|
if (this._value() !== null) {
|
|
34
34
|
const targetValue = this._value();
|
|
@@ -53,37 +53,26 @@ class QuangSelectComponent extends QuangBaseComponent {
|
|
|
53
53
|
}
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
|
-
changeOptionsVisibility(
|
|
56
|
+
changeOptionsVisibility() {
|
|
57
57
|
if (this.isReadonly())
|
|
58
58
|
return;
|
|
59
59
|
if (this._showOptions()) {
|
|
60
|
-
this.
|
|
60
|
+
this.hideOptionVisibility();
|
|
61
61
|
}
|
|
62
62
|
else {
|
|
63
63
|
this.showOptionVisibility();
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
showOptionVisibility() {
|
|
67
|
-
if (this._optionHideTimeout()) {
|
|
68
|
-
clearTimeout(this._optionHideTimeout());
|
|
69
|
-
this._optionHideTimeout.set(null);
|
|
70
|
-
}
|
|
71
67
|
this._showOptions.set(true);
|
|
72
68
|
}
|
|
73
|
-
hideOptionVisibility(
|
|
74
|
-
|
|
75
|
-
clearTimeout(this._optionHideTimeout());
|
|
76
|
-
}
|
|
77
|
-
this._optionHideTimeout.set(setTimeout(() => {
|
|
78
|
-
this._showOptions.set(false);
|
|
79
|
-
}, skipTimeout ? 0 : 50));
|
|
69
|
+
hideOptionVisibility() {
|
|
70
|
+
this._showOptions.set(false);
|
|
80
71
|
}
|
|
81
72
|
onBlurHandler() {
|
|
82
73
|
if (this.selectionMode() === 'single') {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
super.onBlurHandler();
|
|
86
|
-
}, 100);
|
|
74
|
+
this.hideOptionVisibility();
|
|
75
|
+
super.onBlurHandler();
|
|
87
76
|
}
|
|
88
77
|
}
|
|
89
78
|
onChangedHandler(value) {
|
|
@@ -135,7 +124,7 @@ class QuangSelectComponent extends QuangBaseComponent {
|
|
|
135
124
|
* Closes dropdown and returns focus to button.
|
|
136
125
|
*/
|
|
137
126
|
onEscapePressed() {
|
|
138
|
-
this.hideOptionVisibility(
|
|
127
|
+
this.hideOptionVisibility();
|
|
139
128
|
this.focusButton();
|
|
140
129
|
}
|
|
141
130
|
/**
|
|
@@ -143,7 +132,7 @@ class QuangSelectComponent extends QuangBaseComponent {
|
|
|
143
132
|
* Closes dropdown and allows natural tab navigation.
|
|
144
133
|
*/
|
|
145
134
|
onTabPressed(_event) {
|
|
146
|
-
this.hideOptionVisibility(
|
|
135
|
+
this.hideOptionVisibility();
|
|
147
136
|
}
|
|
148
137
|
/**
|
|
149
138
|
* Sets focus to the select button element.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quang-components-select.mjs","sources":["../../../projects/quang/components/select/select.component.ts","../../../projects/quang/components/select/select.component.html","../../../projects/quang/components/select/quang-components-select.ts"],"sourcesContent":["import { NgClass } from '@angular/common'\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n computed,\n forwardRef,\n input,\n signal,\n viewChild,\n} from '@angular/core'\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop'\nimport { NG_VALUE_ACCESSOR } from '@angular/forms'\n\nimport { TranslocoPipe } from '@jsverse/transloco'\nimport { combineLatest, filter } from 'rxjs'\n\nimport {\n OptionListParentType,\n QuangBaseComponent,\n QuangOptionListComponent,\n SelectOption,\n} from 'quang/components/shared'\n\n@Component({\n selector: 'quang-select',\n templateUrl: './select.component.html',\n styleUrl: './select.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => QuangSelectComponent),\n multi: true,\n },\n {\n provide: QuangOptionListComponent,\n multi: false,\n },\n ],\n imports: [TranslocoPipe, NgClass, QuangOptionListComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\n/**\n * Select component for choosing one or multiple options from a dropdown.\n *\n * @usageNotes\n * This component supports both single and multiple selection modes. It can be configured\n * to display a list of options and allows users to select one or more of them by setting the `selectionMode` property to either `single` or `multiple`.\n */\nexport class QuangSelectComponent\n extends QuangBaseComponent<string | number | string[] | number[] | null>\n implements AfterViewInit\n{\n selectionMode = input<'single' | 'multiple'>('single')\n\n /**\n * Set the max height of the selection list before scrolling.\n * Default: 18rem\n * @default 18rem\n */\n optionListMaxHeight = input<string>('18rem')\n\n selectOptions = input.required<SelectOption[]>()\n\n scrollBehaviorOnOpen = input<ScrollBehavior>('smooth')\n\n selectButton = viewChild<ElementRef<HTMLButtonElement>>('selectButton')\n\n _showOptions = signal<boolean>(false)\n\n _optionHideTimeout = signal<any | undefined>(undefined)\n\n _selectedItems = computed(() => {\n if (this._value() !== null) {\n const targetValue = this._value()\n return this.selectOptions().filter((x) => {\n if (Array.isArray(targetValue)) {\n return targetValue.some((k) => k === x.value)\n }\n return targetValue === x.value\n })\n }\n return null\n })\n\n translateValue = input<boolean>(true)\n\n nullOption = input<boolean>(true)\n\n autoSelectSingleOption = input<boolean>(false)\n\n readonly ParentType = OptionListParentType.SELECT\n\n constructor() {\n super()\n combineLatest([toObservable(this.autoSelectSingleOption), toObservable(this.selectOptions)])\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n filter(([autoselect, options]) => autoselect === true && options.length === 1)\n )\n .subscribe(([_, options]) => {\n if (this._value() === null || this._value() === undefined || this._value() === '') {\n this.onChangedHandler(options[0].value)\n }\n })\n }\n\n changeOptionsVisibility(skipTimeout = false): void {\n if (this.isReadonly()) return\n if (this._showOptions()) {\n this._showOptions.set(skipTimeout)\n } else {\n this.showOptionVisibility()\n }\n }\n\n showOptionVisibility(): void {\n if (this._optionHideTimeout()) {\n clearTimeout(this._optionHideTimeout())\n this._optionHideTimeout.set(null)\n }\n this._showOptions.set(true)\n }\n\n hideOptionVisibility(skipTimeout = false): void {\n if (this._optionHideTimeout()) {\n clearTimeout(this._optionHideTimeout())\n }\n this._optionHideTimeout.set(\n setTimeout(\n () => {\n this._showOptions.set(false)\n },\n skipTimeout ? 0 : 50\n )\n )\n }\n\n override onBlurHandler() {\n if (this.selectionMode() === 'single') {\n setTimeout(() => {\n this.hideOptionVisibility()\n super.onBlurHandler()\n }, 100)\n }\n }\n\n override onChangedHandler(value: string | number | string[] | number[] | null): void {\n super.onChangedHandler(value)\n if (this.selectionMode() === 'single') {\n this.hideOptionVisibility()\n // Return focus to button after selection\n this.focusButton()\n }\n }\n\n onMouseLeaveCallback() {\n if (this.selectionMode() === 'multiple') {\n this.hideOptionVisibility()\n }\n }\n\n /**\n * Handles keydown events on the select button for accessibility.\n * @param event The keyboard event\n */\n onButtonKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp':\n // Open dropdown if closed\n if (!this._showOptions()) {\n event.preventDefault()\n this.showOptionVisibility()\n }\n break\n case ' ':\n case 'Enter':\n // Toggle dropdown with Space or Enter\n if (!this._showOptions()) {\n event.preventDefault()\n this.showOptionVisibility()\n }\n break\n case 'Escape':\n // Close dropdown and keep focus on button\n if (this._showOptions()) {\n event.preventDefault()\n this.onEscapePressed()\n }\n break\n }\n }\n\n /**\n * Handles Escape key press from option list.\n * Closes dropdown and returns focus to button.\n */\n onEscapePressed(): void {\n this.hideOptionVisibility(true)\n this.focusButton()\n }\n\n /**\n * Handles Tab key press from option list.\n * Closes dropdown and allows natural tab navigation.\n */\n onTabPressed(_event: { shiftKey: boolean }): void {\n this.hideOptionVisibility(true)\n }\n\n /**\n * Sets focus to the select button element.\n */\n focusButton(): void {\n const buttonEl = this.selectButton()?.nativeElement\n if (buttonEl) {\n buttonEl.focus()\n }\n }\n}\n","<div\n (mouseleave)=\"onMouseLeaveCallback()\"\n class=\"mb-3\"\n>\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label w-100\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n <div\n [class.is-invalid]=\"_ngControl()?.invalid && (_ngControl()?.dirty || _ngControl()?.touched) && errorMap().length\"\n [class.is-valid]=\"_ngControl()?.valid && (_ngControl()?.dirty || _ngControl()?.touched) && successMessage()\"\n class=\"option-list-container\"\n >\n <button\n [attr.aria-controls]=\"_showOptions() ? 'optionList' : null\"\n [attr.aria-expanded]=\"_showOptions()\"\n [attr.required]=\"getIsRequiredControl()\"\n [class.is-invalid]=\"_ngControl()?.invalid && (_ngControl()?.dirty || _ngControl()?.touched) && errorMap().length\"\n [class.is-valid]=\"_ngControl()?.valid && (_ngControl()?.dirty || _ngControl()?.touched) && successMessage()\"\n [disabled]=\"_isDisabled()\"\n [id]=\"componentId()\"\n [ngClass]=\"componentClass()\"\n [tabIndex]=\"componentTabIndex()\"\n (click)=\"changeOptionsVisibility()\"\n (keydown)=\"onButtonKeydown($event)\"\n #selectButton\n aria-haspopup=\"listbox\"\n class=\"form-select\"\n type=\"button\"\n >\n <div class=\"content\">\n @if (_selectedItems()?.length) {\n @for (val of _selectedItems(); track val; let last = $last) {\n {{ translateValue() ? (val.label | transloco) : val.label }}{{ !last ? ', ' : '' }}\n }\n } @else {\n <ng-container>{{ componentPlaceholder() | transloco }}</ng-container>\n }\n </div>\n </button>\n\n @if (_showOptions()) {\n <quang-option-list\n [_isDisabled]=\"_isDisabled()\"\n [_value]=\"_value()\"\n [componentClass]=\"componentClass()\"\n [componentLabel]=\"componentLabel()\"\n [componentTabIndex]=\"componentTabIndex()\"\n [nullOption]=\"nullOption()\"\n [optionListMaxHeight]=\"optionListMaxHeight()\"\n [parentType]=\"ParentType\"\n [scrollBehaviorOnOpen]=\"scrollBehaviorOnOpen()\"\n [selectButtonRef]=\"selectButton\"\n [selectionMode]=\"selectionMode()\"\n [selectOptions]=\"selectOptions()\"\n [translateValue]=\"translateValue()\"\n (blurHandler)=\"onBlurHandler()\"\n (changedHandler)=\"onChangedHandler($event)\"\n (escapePressed)=\"onEscapePressed()\"\n (tabPressed)=\"onTabPressed($event)\"\n #optionList\n ></quang-option-list>\n }\n </div>\n <div class=\"valid-feedback\">\n {{ successMessage() | transloco }}\n </div>\n <div class=\"invalid-feedback\">\n {{ _currentErrorMessage() | transloco: _currentErrorMessageExtraData() }}\n </div>\n @if (helpMessage()) {\n <small\n [hidden]=\"_showSuccess() || _showErrors()\"\n aria-live=\"assertive\"\n class=\"form-text text-muted\"\n >\n {{ helpMessage() | transloco }}\n </small>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"quang-components-select.mjs","sources":["../../../projects/quang/components/select/select.component.ts","../../../projects/quang/components/select/select.component.html","../../../projects/quang/components/select/quang-components-select.ts"],"sourcesContent":["import { NgClass } from '@angular/common'\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n computed,\n forwardRef,\n input,\n signal,\n viewChild,\n} from '@angular/core'\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop'\nimport { NG_VALUE_ACCESSOR } from '@angular/forms'\n\nimport { TranslocoPipe } from '@jsverse/transloco'\nimport { combineLatest, filter } from 'rxjs'\n\nimport {\n OptionListParentType,\n QuangBaseComponent,\n QuangOptionListComponent,\n SelectOption,\n} from 'quang/components/shared'\n\n@Component({\n selector: 'quang-select',\n templateUrl: './select.component.html',\n styleUrl: './select.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => QuangSelectComponent),\n multi: true,\n },\n {\n provide: QuangOptionListComponent,\n multi: false,\n },\n ],\n imports: [TranslocoPipe, NgClass, QuangOptionListComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\n/**\n * Select component for choosing one or multiple options from a dropdown.\n *\n * @usageNotes\n * This component supports both single and multiple selection modes. It can be configured\n * to display a list of options and allows users to select one or more of them by setting the `selectionMode` property to either `single` or `multiple`.\n */\nexport class QuangSelectComponent\n extends QuangBaseComponent<string | number | string[] | number[] | null>\n implements AfterViewInit\n{\n selectionMode = input<'single' | 'multiple'>('single')\n\n /**\n * Set the max height of the selection list before scrolling.\n * Default: 18rem\n * @default 18rem\n */\n optionListMaxHeight = input<string>('18rem')\n\n selectOptions = input.required<SelectOption[]>()\n\n scrollBehaviorOnOpen = input<ScrollBehavior>('smooth')\n\n selectButton = viewChild<ElementRef<HTMLButtonElement>>('selectButton')\n\n /** Whether the option list is currently visible */\n _showOptions = signal<boolean>(false)\n\n _selectedItems = computed(() => {\n if (this._value() !== null) {\n const targetValue = this._value()\n return this.selectOptions().filter((x) => {\n if (Array.isArray(targetValue)) {\n return targetValue.some((k) => k === x.value)\n }\n return targetValue === x.value\n })\n }\n return null\n })\n\n translateValue = input<boolean>(true)\n\n nullOption = input<boolean>(true)\n\n autoSelectSingleOption = input<boolean>(false)\n\n readonly ParentType = OptionListParentType.SELECT\n\n constructor() {\n super()\n combineLatest([toObservable(this.autoSelectSingleOption), toObservable(this.selectOptions)])\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n filter(([autoselect, options]) => autoselect === true && options.length === 1)\n )\n .subscribe(([_, options]) => {\n if (this._value() === null || this._value() === undefined || this._value() === '') {\n this.onChangedHandler(options[0].value)\n }\n })\n }\n\n changeOptionsVisibility(): void {\n if (this.isReadonly()) return\n if (this._showOptions()) {\n this.hideOptionVisibility()\n } else {\n this.showOptionVisibility()\n }\n }\n\n showOptionVisibility(): void {\n this._showOptions.set(true)\n }\n\n hideOptionVisibility(): void {\n this._showOptions.set(false)\n }\n\n override onBlurHandler() {\n if (this.selectionMode() === 'single') {\n this.hideOptionVisibility()\n super.onBlurHandler()\n }\n }\n\n override onChangedHandler(value: string | number | string[] | number[] | null): void {\n super.onChangedHandler(value)\n if (this.selectionMode() === 'single') {\n this.hideOptionVisibility()\n // Return focus to button after selection\n this.focusButton()\n }\n }\n\n onMouseLeaveCallback() {\n if (this.selectionMode() === 'multiple') {\n this.hideOptionVisibility()\n }\n }\n\n /**\n * Handles keydown events on the select button for accessibility.\n * @param event The keyboard event\n */\n onButtonKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp':\n // Open dropdown if closed\n if (!this._showOptions()) {\n event.preventDefault()\n this.showOptionVisibility()\n }\n break\n case ' ':\n case 'Enter':\n // Toggle dropdown with Space or Enter\n if (!this._showOptions()) {\n event.preventDefault()\n this.showOptionVisibility()\n }\n break\n case 'Escape':\n // Close dropdown and keep focus on button\n if (this._showOptions()) {\n event.preventDefault()\n this.onEscapePressed()\n }\n break\n }\n }\n\n /**\n * Handles Escape key press from option list.\n * Closes dropdown and returns focus to button.\n */\n onEscapePressed(): void {\n this.hideOptionVisibility()\n this.focusButton()\n }\n\n /**\n * Handles Tab key press from option list.\n * Closes dropdown and allows natural tab navigation.\n */\n onTabPressed(_event: { shiftKey: boolean }): void {\n this.hideOptionVisibility()\n }\n\n /**\n * Sets focus to the select button element.\n */\n focusButton(): void {\n const buttonEl = this.selectButton()?.nativeElement\n if (buttonEl) {\n buttonEl.focus()\n }\n }\n}\n","<div\n (mouseleave)=\"onMouseLeaveCallback()\"\n class=\"mb-3\"\n>\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label w-100\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n <div\n [class.is-invalid]=\"_ngControl()?.invalid && (_ngControl()?.dirty || _ngControl()?.touched) && errorMap().length\"\n [class.is-valid]=\"_ngControl()?.valid && (_ngControl()?.dirty || _ngControl()?.touched) && successMessage()\"\n class=\"option-list-container\"\n >\n <button\n [attr.aria-controls]=\"_showOptions() ? 'optionList' : null\"\n [attr.aria-expanded]=\"_showOptions()\"\n [attr.required]=\"getIsRequiredControl()\"\n [class.is-invalid]=\"_ngControl()?.invalid && (_ngControl()?.dirty || _ngControl()?.touched) && errorMap().length\"\n [class.is-valid]=\"_ngControl()?.valid && (_ngControl()?.dirty || _ngControl()?.touched) && successMessage()\"\n [disabled]=\"_isDisabled()\"\n [id]=\"componentId()\"\n [ngClass]=\"componentClass()\"\n [tabIndex]=\"componentTabIndex()\"\n (click)=\"changeOptionsVisibility()\"\n (keydown)=\"onButtonKeydown($event)\"\n #selectButton\n aria-haspopup=\"listbox\"\n class=\"form-select\"\n type=\"button\"\n >\n <div class=\"content\">\n @if (_selectedItems()?.length) {\n @for (val of _selectedItems(); track val; let last = $last) {\n {{ translateValue() ? (val.label | transloco) : val.label }}{{ !last ? ', ' : '' }}\n }\n } @else {\n <ng-container>{{ componentPlaceholder() | transloco }}</ng-container>\n }\n </div>\n </button>\n\n @if (_showOptions()) {\n <quang-option-list\n [_isDisabled]=\"_isDisabled()\"\n [_value]=\"_value()\"\n [componentClass]=\"componentClass()\"\n [componentLabel]=\"componentLabel()\"\n [componentTabIndex]=\"componentTabIndex()\"\n [nullOption]=\"nullOption()\"\n [optionListMaxHeight]=\"optionListMaxHeight()\"\n [parentType]=\"ParentType\"\n [scrollBehaviorOnOpen]=\"scrollBehaviorOnOpen()\"\n [selectButtonRef]=\"selectButton\"\n [selectionMode]=\"selectionMode()\"\n [selectOptions]=\"selectOptions()\"\n [translateValue]=\"translateValue()\"\n (blurHandler)=\"onBlurHandler()\"\n (changedHandler)=\"onChangedHandler($event)\"\n (escapePressed)=\"onEscapePressed()\"\n (tabPressed)=\"onTabPressed($event)\"\n #optionList\n ></quang-option-list>\n }\n </div>\n <div class=\"valid-feedback\">\n {{ successMessage() | transloco }}\n </div>\n <div class=\"invalid-feedback\">\n {{ _currentErrorMessage() | transloco: _currentErrorMessageExtraData() }}\n </div>\n @if (helpMessage()) {\n <small\n [hidden]=\"_showSuccess() || _showErrors()\"\n aria-live=\"assertive\"\n class=\"form-text text-muted\"\n >\n {{ helpMessage() | transloco }}\n </small>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;AA2CA;;;;;;AAMG;AACG,MAAO,oBACX,SAAQ,kBAAgE,CAAA;AA0CxE,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;AAxCT,QAAA,IAAA,CAAA,aAAa,GAAG,KAAK,CAAwB,QAAQ,CAAC;AAEtD;;;;AAIG;AACH,QAAA,IAAA,CAAA,mBAAmB,GAAG,KAAK,CAAS,OAAO,CAAC;AAE5C,QAAA,IAAA,CAAA,aAAa,GAAG,KAAK,CAAC,QAAQ,EAAkB;AAEhD,QAAA,IAAA,CAAA,oBAAoB,GAAG,KAAK,CAAiB,QAAQ,CAAC;AAEtD,QAAA,IAAA,CAAA,YAAY,GAAG,SAAS,CAAgC,cAAc,CAAC;;AAGvE,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAU,KAAK,CAAC;AAErC,QAAA,IAAA,CAAA,cAAc,GAAG,QAAQ,CAAC,MAAK;AAC7B,YAAA,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE;AAC1B,gBAAA,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE;gBACjC,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAI;AACvC,oBAAA,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;AAC9B,wBAAA,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC;;AAE/C,oBAAA,OAAO,WAAW,KAAK,CAAC,CAAC,KAAK;AAChC,iBAAC,CAAC;;AAEJ,YAAA,OAAO,IAAI;AACb,SAAC,CAAC;AAEF,QAAA,IAAA,CAAA,cAAc,GAAG,KAAK,CAAU,IAAI,CAAC;AAErC,QAAA,IAAA,CAAA,UAAU,GAAG,KAAK,CAAU,IAAI,CAAC;AAEjC,QAAA,IAAA,CAAA,sBAAsB,GAAG,KAAK,CAAU,KAAK,CAAC;AAErC,QAAA,IAAA,CAAA,UAAU,GAAG,oBAAoB,CAAC,MAAM;AAI/C,QAAA,aAAa,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,sBAAsB,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACxF,aAAA,IAAI,CACH,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,EACnC,MAAM,CAAC,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,KAAK,UAAU,KAAK,IAAI,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC;aAE/E,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,KAAI;YAC1B,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;gBACjF,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;;AAE3C,SAAC,CAAC;;IAGN,uBAAuB,GAAA;QACrB,IAAI,IAAI,CAAC,UAAU,EAAE;YAAE;AACvB,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE,EAAE;YACvB,IAAI,CAAC,oBAAoB,EAAE;;aACtB;YACL,IAAI,CAAC,oBAAoB,EAAE;;;IAI/B,oBAAoB,GAAA;AAClB,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;;IAG7B,oBAAoB,GAAA;AAClB,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;;IAGrB,aAAa,GAAA;AACpB,QAAA,IAAI,IAAI,CAAC,aAAa,EAAE,KAAK,QAAQ,EAAE;YACrC,IAAI,CAAC,oBAAoB,EAAE;YAC3B,KAAK,CAAC,aAAa,EAAE;;;AAIhB,IAAA,gBAAgB,CAAC,KAAmD,EAAA;AAC3E,QAAA,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC;AAC7B,QAAA,IAAI,IAAI,CAAC,aAAa,EAAE,KAAK,QAAQ,EAAE;YACrC,IAAI,CAAC,oBAAoB,EAAE;;YAE3B,IAAI,CAAC,WAAW,EAAE;;;IAItB,oBAAoB,GAAA;AAClB,QAAA,IAAI,IAAI,CAAC,aAAa,EAAE,KAAK,UAAU,EAAE;YACvC,IAAI,CAAC,oBAAoB,EAAE;;;AAI/B;;;AAGG;AACH,IAAA,eAAe,CAAC,KAAoB,EAAA;AAClC,QAAA,QAAQ,KAAK,CAAC,GAAG;AACf,YAAA,KAAK,WAAW;AAChB,YAAA,KAAK,SAAS;;AAEZ,gBAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE;oBACxB,KAAK,CAAC,cAAc,EAAE;oBACtB,IAAI,CAAC,oBAAoB,EAAE;;gBAE7B;AACF,YAAA,KAAK,GAAG;AACR,YAAA,KAAK,OAAO;;AAEV,gBAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE;oBACxB,KAAK,CAAC,cAAc,EAAE;oBACtB,IAAI,CAAC,oBAAoB,EAAE;;gBAE7B;AACF,YAAA,KAAK,QAAQ;;AAEX,gBAAA,IAAI,IAAI,CAAC,YAAY,EAAE,EAAE;oBACvB,KAAK,CAAC,cAAc,EAAE;oBACtB,IAAI,CAAC,eAAe,EAAE;;gBAExB;;;AAIN;;;AAGG;IACH,eAAe,GAAA;QACb,IAAI,CAAC,oBAAoB,EAAE;QAC3B,IAAI,CAAC,WAAW,EAAE;;AAGpB;;;AAGG;AACH,IAAA,YAAY,CAAC,MAA6B,EAAA;QACxC,IAAI,CAAC,oBAAoB,EAAE;;AAG7B;;AAEG;IACH,WAAW,GAAA;QACT,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa;QACnD,IAAI,QAAQ,EAAE;YACZ,QAAQ,CAAC,KAAK,EAAE;;;+GAvJT,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAApB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,oBAAoB,EArBpB,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,mBAAA,EAAA,EAAA,iBAAA,EAAA,qBAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,oBAAA,EAAA,EAAA,iBAAA,EAAA,sBAAA,EAAA,UAAA,EAAA,sBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,sBAAA,EAAA,EAAA,iBAAA,EAAA,wBAAA,EAAA,UAAA,EAAA,wBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,SAAA,EAAA;AACT,YAAA;AACE,gBAAA,OAAO,EAAE,iBAAiB;AAC1B,gBAAA,WAAW,EAAE,UAAU,CAAC,MAAM,oBAAoB,CAAC;AACnD,gBAAA,KAAK,EAAE,IAAI;AACZ,aAAA;AACD,YAAA;AACE,gBAAA,OAAO,EAAE,wBAAwB;AACjC,gBAAA,KAAK,EAAE,KAAK;AACb,aAAA;AACF,SAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,cAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,cAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECvCH,0hGAqFA,ED7CY,MAAA,EAAA,CAAA,oOAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,aAAa,EAAE,IAAA,EAAA,WAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,OAAO,oFAAE,wBAAwB,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,eAAA,EAAA,qBAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,mBAAA,EAAA,gBAAA,EAAA,YAAA,EAAA,sBAAA,EAAA,YAAA,EAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gBAAA,EAAA,aAAA,EAAA,eAAA,EAAA,YAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAU/C,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAzBhC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,cAAc,EAGb,SAAA,EAAA;AACT,wBAAA;AACE,4BAAA,OAAO,EAAE,iBAAiB;AAC1B,4BAAA,WAAW,EAAE,UAAU,CAAC,0BAA0B,CAAC;AACnD,4BAAA,KAAK,EAAE,IAAI;AACZ,yBAAA;AACD,wBAAA;AACE,4BAAA,OAAO,EAAE,wBAAwB;AACjC,4BAAA,KAAK,EAAE,KAAK;AACb,yBAAA;qBACF,EACQ,OAAA,EAAA,CAAC,aAAa,EAAE,OAAO,EAAE,wBAAwB,CAAC,EAAA,eAAA,EAC1C,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,0hGAAA,EAAA,MAAA,EAAA,CAAA,oOAAA,CAAA,EAAA;;;AEzCjD;;AAEG;;;;"}
|
|
@@ -199,18 +199,10 @@ class QuangOptionListComponent {
|
|
|
199
199
|
this.focusedItemIndex = signal(-1);
|
|
200
200
|
this.optionList$ = effect(() => {
|
|
201
201
|
const optionListContainer = this.optionListContainer();
|
|
202
|
-
|
|
202
|
+
const parentType = this.parentType();
|
|
203
|
+
// Focus the option list container when opened (only for SELECT)
|
|
204
|
+
if (optionListContainer && parentType === OptionListParentType.SELECT) {
|
|
203
205
|
optionListContainer?.nativeElement.focus();
|
|
204
|
-
const optionListContainerNativeElement = optionListContainer?.nativeElement;
|
|
205
|
-
if (optionListContainerNativeElement) {
|
|
206
|
-
const ul = optionListContainerNativeElement?.children[0];
|
|
207
|
-
const listItem = ul?.children.item(this.selectedElementIndex());
|
|
208
|
-
if (listItem) {
|
|
209
|
-
setTimeout(() => {
|
|
210
|
-
listItem.scrollIntoView({ behavior: this.scrollBehaviorOnOpen() });
|
|
211
|
-
}, 0);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
206
|
}
|
|
215
207
|
const ul = optionListContainer?.nativeElement?.children[0];
|
|
216
208
|
const listItems = (ul?.children ?? []);
|
|
@@ -218,6 +210,13 @@ class QuangOptionListComponent {
|
|
|
218
210
|
listItems?.[currentIndex]?.classList.add('selected');
|
|
219
211
|
// Initialize focusedItemIndex with current selection
|
|
220
212
|
this.focusedItemIndex.set(currentIndex);
|
|
213
|
+
// Scroll to selected item when option list opens
|
|
214
|
+
const listItem = listItems[currentIndex];
|
|
215
|
+
if (listItem) {
|
|
216
|
+
setTimeout(() => {
|
|
217
|
+
listItem.scrollIntoView({ behavior: this.scrollBehaviorOnOpen(), block: 'nearest' });
|
|
218
|
+
}, 0);
|
|
219
|
+
}
|
|
221
220
|
if (this.onKeyDown) {
|
|
222
221
|
this.onKeyDown.unsubscribe();
|
|
223
222
|
}
|
|
@@ -238,27 +237,12 @@ class QuangOptionListComponent {
|
|
|
238
237
|
else {
|
|
239
238
|
currentIndex += 1;
|
|
240
239
|
}
|
|
241
|
-
|
|
242
|
-
event.preventDefault();
|
|
243
|
-
optionListContainer?.nativeElement?.scroll(0, 0);
|
|
244
|
-
}
|
|
245
|
-
const optionListBottom = optionListContainer?.nativeElement?.getBoundingClientRect()?.bottom ?? 0;
|
|
246
|
-
const itemListHeight = optionListContainer?.nativeElement?.children?.[0]?.children
|
|
247
|
-
?.item(currentIndex)
|
|
248
|
-
?.getBoundingClientRect()?.height;
|
|
249
|
-
const itemListBottom = optionListContainer?.nativeElement?.children?.[0]?.children
|
|
250
|
-
?.item(currentIndex)
|
|
251
|
-
?.getBoundingClientRect()?.bottom;
|
|
252
|
-
if (optionListBottom > (itemListBottom ?? 0) + (itemListHeight ?? 0))
|
|
253
|
-
event.preventDefault();
|
|
240
|
+
event.preventDefault();
|
|
254
241
|
listItems[currentIndex]?.classList.add('selected');
|
|
242
|
+
// Scroll item into view if not visible
|
|
243
|
+
listItems[currentIndex]?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
255
244
|
// Update focusedItemIndex for aria-activedescendant
|
|
256
245
|
this.focusedItemIndex.set(currentIndex);
|
|
257
|
-
if ((optionListContainer?.nativeElement?.scrollTop ?? 0) >=
|
|
258
|
-
(optionListContainer?.nativeElement?.scrollHeight ?? 0) -
|
|
259
|
-
(optionListContainer?.nativeElement?.offsetHeight ?? 0)) {
|
|
260
|
-
event.preventDefault();
|
|
261
|
-
}
|
|
262
246
|
break;
|
|
263
247
|
}
|
|
264
248
|
case 'ArrowUp': {
|
|
@@ -268,21 +252,12 @@ class QuangOptionListComponent {
|
|
|
268
252
|
listItems[currentIndex]?.classList.remove('selected');
|
|
269
253
|
if (currentIndex !== 0)
|
|
270
254
|
currentIndex -= 1;
|
|
271
|
-
|
|
272
|
-
const itemListHeight = optionListContainer?.nativeElement?.children?.[0]?.children
|
|
273
|
-
?.item(currentIndex)
|
|
274
|
-
?.getBoundingClientRect()?.height;
|
|
275
|
-
const itemListTop = optionListContainer?.nativeElement?.children?.[0]?.children
|
|
276
|
-
?.item(currentIndex)
|
|
277
|
-
?.getBoundingClientRect()?.top;
|
|
278
|
-
if (optionListTop < (itemListTop ?? 0) - (itemListHeight ?? 0))
|
|
279
|
-
event.preventDefault();
|
|
255
|
+
event.preventDefault();
|
|
280
256
|
listItems[currentIndex]?.classList.add('selected');
|
|
257
|
+
// Scroll item into view if not visible
|
|
258
|
+
listItems[currentIndex]?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
281
259
|
// Update focusedItemIndex for aria-activedescendant
|
|
282
260
|
this.focusedItemIndex.set(currentIndex);
|
|
283
|
-
if (!optionListContainer?.nativeElement?.scrollTop) {
|
|
284
|
-
event.preventDefault();
|
|
285
|
-
}
|
|
286
261
|
break;
|
|
287
262
|
}
|
|
288
263
|
case 'Enter': {
|
|
@@ -296,9 +271,13 @@ class QuangOptionListComponent {
|
|
|
296
271
|
break;
|
|
297
272
|
}
|
|
298
273
|
case 'Tab': {
|
|
299
|
-
//
|
|
300
|
-
//
|
|
301
|
-
|
|
274
|
+
// Only handle Tab when focus is on the option list itself
|
|
275
|
+
// If focus is on the parent input, let the input's blur handler deal with it
|
|
276
|
+
if (document.activeElement?.id === optionListContainer?.nativeElement?.id) {
|
|
277
|
+
// Allow Tab to close dropdown and move focus naturally
|
|
278
|
+
// Emit event so parent can handle focus transition
|
|
279
|
+
this.tabPressed.emit({ shiftKey: event.shiftKey });
|
|
280
|
+
}
|
|
302
281
|
break;
|
|
303
282
|
}
|
|
304
283
|
default: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quang-components-shared.mjs","sources":["../../../projects/quang/components/shared/makeId.ts","../../../projects/quang/components/shared/quang-base-component.directive.ts","../../../projects/quang/components/shared/option-list/option-list.component.ts","../../../projects/quang/components/shared/option-list/option-list.component.html","../../../projects/quang/components/shared/quang-components-shared.ts"],"sourcesContent":["export const makeId = (length: number) => {\n let result = ''\n const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'\n const charactersLength = characters.length\n for (let i = 0; i < length; i++) {\n result += characters.charAt(Math.floor(Math.random() * charactersLength))\n }\n return result\n}\n","import { AfterViewInit, DestroyRef, Directive, Injector, computed, inject, input, output, signal } from '@angular/core'\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop'\nimport { ControlValueAccessor, FormControl, NgControl, Validators } from '@angular/forms'\n\nimport { Subscription } from 'rxjs'\n\nimport { ErrorData } from './ErrorData'\nimport { makeId } from './makeId'\n\n@Directive()\nexport abstract class QuangBaseComponent<T = any> implements ControlValueAccessor, AfterViewInit {\n componentId = input<string>(makeId(10))\n\n isReadonly = input<boolean>(false)\n\n isReadonly$ = toObservable(this.isReadonly)\n\n componentTabIndex = input<number>(0)\n\n componentClass = input<string | string[]>('')\n\n componentLabel = input<string>('')\n\n componentPlaceholder = input<string>('')\n\n errorMap = input<ErrorData[]>([])\n\n _errorMessagesByKey = computed(\n () => new Map((this.errorMap() ?? []).map((errorData) => [errorData.error, errorData.message]))\n )\n\n successMessage = input<string>('')\n\n helpMessage = input<string>('')\n\n formControl = input<FormControl>()\n\n componentBlur = output<void>()\n\n _value = signal<T | null>(null)\n\n _isRequired = signal<boolean>(false)\n\n _isDisabled = signal<boolean>(false)\n\n _isTouched = signal<boolean>(false)\n\n _isValid = signal<boolean>(false)\n\n _showSuccess = computed(() => this.successMessage() && this._isValid() && this._isTouched() && !this._isDisabled())\n\n _showErrors = computed(\n () => this.errorMap()?.length > 0 && !this._isValid() && this._isTouched() && !this._isDisabled()\n )\n\n _currentErrorMessage = signal<string>('')\n\n _currentErrorMessageExtraData = signal<Record<string, any>>({})\n\n _ngControl = signal<NgControl | null>(null)\n\n _injector = signal<Injector>(inject(Injector))\n\n _statusChange$?: Subscription\n\n getIsRequiredControl = computed(\n () => !!(this._ngControl()?.control as any)?._rawValidators?.find((x: any) => x.name === 'required')\n )\n\n onChange?: (value: T) => void\n\n onTouched?: () => void\n\n destroyRef = inject(DestroyRef)\n\n constructor() {\n toObservable(this.formControl)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((form) => {\n if (form) {\n this.setupFormControl()\n }\n })\n }\n\n registerOnChange(fn: (value: T) => void): void {\n this.onChange = fn\n }\n\n writeValue(val: T): void {\n this._value.set(val)\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = () => {\n this._isTouched.set(true)\n fn()\n }\n }\n\n onChangedEventHandler($event: Event) {\n const inputElement = $event.target as HTMLInputElement\n this.onChangedHandler(inputElement.value as T)\n }\n\n onChangedHandler(value: T) {\n this._value.set(value)\n if (this.onChange) {\n this.onChange(value)\n }\n\n if (this.onTouched) {\n this.onTouched()\n }\n }\n\n onBlurHandler() {\n if (this.onTouched) {\n this.onTouched()\n }\n this.componentBlur.emit()\n }\n\n setupFormControl() {\n if (this._statusChange$) {\n this._statusChange$.unsubscribe()\n this._statusChange$ = undefined\n }\n\n this._ngControl.set(this._injector().get(NgControl))\n this._statusChange$ = this._ngControl()\n ?.control?.statusChanges.pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n this.checkFormErrors()\n })\n\n this._isTouched.set(this._ngControl()?.touched ?? false)\n this._isDisabled.set(this.isReadonly() || this._ngControl()?.disabled || false)\n this.checkFormErrors()\n }\n\n onChangeIsReadonly = this.isReadonly$.pipe(takeUntilDestroyed()).subscribe((isReadonly: boolean) => {\n this._isDisabled.set(isReadonly || this._ngControl()?.disabled || false)\n })\n\n setDisabledState(isDisabled: boolean) {\n this._isDisabled.set(isDisabled)\n }\n\n checkFormErrors() {\n const control = this._ngControl()?.control\n this._isValid.set(control?.valid ?? false)\n this._isTouched.set(!control?.pristine)\n\n const validationErrors = control?.errors\n\n this._isRequired.set(validationErrors?.[Validators.required.name])\n\n let errorName = ''\n let errorMessage = ''\n let errorData = true\n\n for (const [validationErrorName, validationErrorData] of Object.entries(validationErrors ?? {})) {\n const relatedErrorMessage = this._errorMessagesByKey().get(validationErrorName)\n if (relatedErrorMessage) {\n errorName = validationErrorName\n errorMessage = relatedErrorMessage\n errorData = validationErrorData\n }\n }\n\n this._currentErrorMessage.set(errorMessage)\n this._currentErrorMessageExtraData.set({ [errorName]: errorData })\n }\n\n ngAfterViewInit(): void {\n this.setupFormControl()\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { NgClass, NgStyle } from '@angular/common'\nimport {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n HostListener,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core'\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop'\n\nimport { TranslocoPipe } from '@jsverse/transloco'\nimport { QUANG_LOGGING_BEHAVIOR } from 'quang'\nimport { Subscription, fromEvent } from 'rxjs'\n\nexport interface SelectOption {\n label: string\n value: string | number | null\n}\n\nexport enum OptionListParentType {\n SELECT = 'select',\n AUTOCOMPLETE = 'autocomplete',\n}\n\n@Component({\n selector: 'quang-option-list',\n imports: [NgStyle, NgClass, TranslocoPipe],\n templateUrl: './option-list.component.html',\n styleUrl: './option-list.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class QuangOptionListComponent {\n logLevel = inject(QUANG_LOGGING_BEHAVIOR, { optional: true })\n\n selectionMode = input<'single' | 'multiple'>('single')\n\n optionListMaxHeight = input<string>('201px')\n\n selectOptions = input<SelectOption[]>([])\n\n selectButtonRef = input.required<HTMLButtonElement | HTMLInputElement | HTMLDivElement>()\n\n _value = input<any>()\n\n _isDisabled = input<boolean>()\n\n componentClass = input<string | string[]>('')\n\n componentLabel = input<string>('')\n\n componentTabIndex = input<number>(0)\n\n translateValue = input<boolean>(false)\n\n nullOption = input<boolean>(true)\n\n elementWidth = signal<string>('0px')\n\n elementTop = signal<string>('0px')\n\n elementBottom = signal<string>('0px')\n\n scrollBehaviorOnOpen = input<ScrollBehavior>('smooth')\n\n changedHandler = output<any>()\n\n blurHandler = output<any>()\n\n /** Emitted when user presses Escape - parent should close dropdown and return focus to trigger */\n escapePressed = output<void>()\n\n /** Emitted when user presses Tab - parent should handle focus transition */\n tabPressed = output<{ shiftKey: boolean }>()\n\n optionListContainer = viewChild<ElementRef<HTMLDivElement>>('optionListContainer')\n\n destroyRef = inject(DestroyRef)\n\n parentType = input.required<OptionListParentType>()\n\n parentID = input<string>('')\n\n searchString = signal<string>('')\n\n searchResetTimer: ReturnType<typeof setTimeout> | null = null\n\n selectButtonRef$ = toObservable(this.selectButtonRef)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n this.getOptionListWidth()\n this.getOptionListTop()\n this.getScrollParent(this.selectButtonRef())?.addEventListener('scroll', () => {\n this.getOptionListWidth()\n this.getOptionListTop()\n })\n })\n\n selectOptionsList = computed(() => {\n if (this.nullOption() && this.selectionMode() === 'single') {\n return [\n {\n label: '',\n value: null,\n },\n ...this.selectOptions(),\n ]\n }\n return [...this.selectOptions()]\n })\n\n onKeyDown: Subscription | null = null\n\n selectedElementIndex = computed<number>(\n () => this.selectOptionsList()?.findIndex((x) => x?.value === this._value()) ?? 0\n )\n\n /** Signal to track currently focused item index for aria-activedescendant */\n focusedItemIndex = signal<number>(-1)\n\n /**\n * Returns the ID of the currently focused item for aria-activedescendant\n */\n getActiveDescendantId(): string | null {\n const index = this.focusedItemIndex()\n if (index >= 0 && index < this.selectOptionsList().length) {\n return `item-${index}`\n }\n return null\n }\n\n optionList$ = effect(() => {\n const optionListContainer = this.optionListContainer()\n if (optionListContainer && this.parentType() === OptionListParentType.SELECT) {\n optionListContainer?.nativeElement.focus()\n const optionListContainerNativeElement = optionListContainer?.nativeElement\n if (optionListContainerNativeElement) {\n const ul = optionListContainerNativeElement?.children[0] as HTMLUListElement\n const listItem = ul?.children.item(this.selectedElementIndex()) as HTMLLIElement | undefined\n if (listItem) {\n setTimeout(() => {\n listItem.scrollIntoView({ behavior: this.scrollBehaviorOnOpen() })\n }, 0)\n }\n }\n }\n const ul = optionListContainer?.nativeElement?.children[0] as HTMLUListElement | undefined\n const listItems = (ul?.children ?? []) as HTMLLIElement[]\n let currentIndex = this.selectedElementIndex()\n listItems?.[currentIndex]?.classList.add('selected')\n // Initialize focusedItemIndex with current selection\n this.focusedItemIndex.set(currentIndex)\n\n if (this.onKeyDown) {\n this.onKeyDown.unsubscribe()\n }\n\n this.onKeyDown = fromEvent(document, 'keydown', {\n capture: true,\n })\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((event) => {\n switch ((event as KeyboardEvent).key) {\n case 'ArrowDown': {\n if (this.parentType() === OptionListParentType.AUTOCOMPLETE) optionListContainer?.nativeElement.focus()\n if (currentIndex !== this.selectedElementIndex()) listItems[currentIndex]?.classList.remove('selected')\n if (currentIndex === listItems.length - 1) {\n currentIndex = listItems.length - 1\n } else {\n currentIndex += 1\n }\n if (currentIndex === 0) {\n event.preventDefault()\n optionListContainer?.nativeElement?.scroll(0, 0)\n }\n const optionListBottom = optionListContainer?.nativeElement?.getBoundingClientRect()?.bottom ?? 0\n const itemListHeight = optionListContainer?.nativeElement?.children?.[0]?.children\n ?.item(currentIndex)\n ?.getBoundingClientRect()?.height\n const itemListBottom = optionListContainer?.nativeElement?.children?.[0]?.children\n ?.item(currentIndex)\n ?.getBoundingClientRect()?.bottom\n if (optionListBottom > (itemListBottom ?? 0) + (itemListHeight ?? 0)) event.preventDefault()\n\n listItems[currentIndex]?.classList.add('selected')\n // Update focusedItemIndex for aria-activedescendant\n this.focusedItemIndex.set(currentIndex)\n if (\n (optionListContainer?.nativeElement?.scrollTop ?? 0) >=\n (optionListContainer?.nativeElement?.scrollHeight ?? 0) -\n (optionListContainer?.nativeElement?.offsetHeight ?? 0)\n ) {\n event.preventDefault()\n }\n break\n }\n case 'ArrowUp': {\n if (this.parentType() === OptionListParentType.AUTOCOMPLETE) optionListContainer?.nativeElement.focus()\n if (currentIndex !== this.selectedElementIndex()) listItems[currentIndex]?.classList.remove('selected')\n if (currentIndex !== 0) currentIndex -= 1\n const optionListTop = optionListContainer?.nativeElement?.getBoundingClientRect()?.top ?? 0\n const itemListHeight = optionListContainer?.nativeElement?.children?.[0]?.children\n ?.item(currentIndex)\n ?.getBoundingClientRect()?.height\n const itemListTop = optionListContainer?.nativeElement?.children?.[0]?.children\n ?.item(currentIndex)\n ?.getBoundingClientRect()?.top\n if (optionListTop < (itemListTop ?? 0) - (itemListHeight ?? 0)) event.preventDefault()\n listItems[currentIndex]?.classList.add('selected')\n // Update focusedItemIndex for aria-activedescendant\n this.focusedItemIndex.set(currentIndex)\n if (!optionListContainer?.nativeElement?.scrollTop) {\n event.preventDefault()\n }\n break\n }\n case 'Enter': {\n event.preventDefault()\n this.onSelectItem(this.selectOptionsList()[currentIndex])\n break\n }\n case 'Escape': {\n event.preventDefault()\n this.escapePressed.emit()\n break\n }\n case 'Tab': {\n // Allow Tab to close dropdown and move focus naturally\n // Emit event so parent can handle focus transition\n this.tabPressed.emit({ shiftKey: (event as KeyboardEvent).shiftKey })\n break\n }\n default: {\n if (\n ((event as KeyboardEvent)?.key?.length === 1 || (event as KeyboardEvent)?.key === 'Backspace') &&\n this.parentType() === OptionListParentType.AUTOCOMPLETE &&\n document.activeElement?.id === optionListContainer?.nativeElement?.id\n ) {\n currentIndex = 0\n document.getElementById(this.parentID())?.focus()\n document.getElementById(this.parentID())?.click()\n } else if (\n (event as KeyboardEvent)?.key?.length === 1 &&\n this.parentType() === OptionListParentType.SELECT\n ) {\n const key = (event as KeyboardEvent).key\n currentIndex = this.handleSearch(key, listItems, currentIndex)\n event.preventDefault()\n }\n break\n }\n }\n })\n })\n\n handleSearch(key: string, listItems: HTMLLIElement[], currentIndex: number): number {\n if (this.searchResetTimer) {\n clearTimeout(this.searchResetTimer)\n }\n\n this.searchString.update((current) => current + key)\n\n this.searchResetTimer = setTimeout(() => {\n this.searchString.set('')\n this.searchResetTimer = null\n }, 500)\n\n const searchStr = this.searchString().toLowerCase()\n const matchIndex = this.selectOptionsList().findIndex((option) => option.label.toLowerCase().includes(searchStr))\n\n if (matchIndex !== -1 && matchIndex !== currentIndex) {\n listItems[currentIndex]?.classList.remove('selected')\n listItems[matchIndex]?.classList.add('selected')\n listItems[matchIndex]?.scrollIntoView({ behavior: this.scrollBehaviorOnOpen() })\n return matchIndex\n }\n\n return currentIndex\n }\n\n @HostListener('window:scroll') changePosition() {\n this.getOptionListWidth()\n this.getOptionListTop()\n }\n\n isScrollable(ele: Element): boolean {\n if (!ele) return false\n\n let result = false\n\n try {\n const hasScrollableContent = ele.scrollHeight > ele.clientHeight\n\n const overflowYStyle = window.getComputedStyle(ele).overflowY\n const isOverflowHidden = overflowYStyle.includes('hidden')\n\n result = hasScrollableContent && !isOverflowHidden\n } catch (_error) {\n if (this.logLevel === 'verbose') console.error('captured error isScrollable', _error)\n }\n\n return result\n }\n\n getScrollParent(node: unknown): Element {\n if (!node || node === document.body || !(node instanceof Element)) return document.body\n return this.isScrollable(node) ? node : this.getScrollParent(node.parentNode)\n }\n\n onSelectItem(item: SelectOption | null): void {\n if (this.selectionMode() === 'single') {\n this.changedHandler.emit(item?.value ?? null)\n } else {\n let targetValue = this._value()\n if (!Array.isArray(targetValue) && targetValue) {\n targetValue = [targetValue]\n }\n const values: string[] | number[] | null = targetValue as string[] | number[] | null\n if (values) {\n if (values.some((x) => x === item?.value)) {\n this.changedHandler.emit(values.filter((x) => x !== item?.value) as string[] | number[])\n } else if (item) {\n this.changedHandler.emit([...values, item.value] as string[] | number[])\n } else {\n this.changedHandler.emit([...values] as string[] | number[])\n }\n } else if (item?.value) {\n this.changedHandler.emit([item.value] as string[] | number[])\n } else {\n this.changedHandler.emit(null)\n }\n }\n this.getOptionListTop()\n }\n\n getSelected(item: SelectOption): boolean {\n if (this.selectionMode() === 'single' || !Array.isArray(this._value())) {\n return this._value() === item.value\n }\n return this._value()?.some((x: number | string | null) => x === item?.value)\n }\n\n onBlurHandler(e: Event): void {\n this.blurHandler.emit(e)\n }\n\n getOptionListWidth() {\n this.elementWidth.set(`${this.selectButtonRef()?.offsetWidth}px`)\n }\n\n getOptionListTop() {\n const nativeElement = this.optionListContainer()?.nativeElement\n const diff =\n window.innerHeight -\n (nativeElement?.getBoundingClientRect()?.height ?? 0) -\n (this.selectButtonRef()?.getBoundingClientRect()?.top ?? 0) -\n (this.selectButtonRef()?.getBoundingClientRect()?.height ?? 0)\n let topValue = 'unset'\n let bottomValue = 'unset'\n const isTop = diff >= 0\n if (isTop) {\n topValue = `${(this.selectButtonRef()?.getBoundingClientRect()?.top ?? 0) + (this.selectButtonRef()?.getBoundingClientRect()?.height ?? 0)}px`\n } else {\n bottomValue = `${window.innerHeight - (this.selectButtonRef()?.getBoundingClientRect()?.bottom ?? 0) + (this.selectButtonRef()?.getBoundingClientRect()?.height ?? 0)}px`\n }\n nativeElement?.classList.toggle('option-list-top', !isTop)\n this.elementTop.set(topValue)\n this.elementBottom.set(bottomValue)\n setTimeout(() => {\n this.getOptionListTop()\n })\n }\n}\n","<div\n [attr.aria-activedescendant]=\"getActiveDescendantId()\"\n [attr.aria-label]=\"componentLabel()\"\n [ngStyle]=\"{\n 'max-height': optionListMaxHeight(),\n '--option-list-width': elementWidth(),\n '--option-list-top': elementTop(),\n '--option-list-bottom': elementBottom(),\n }\"\n (blur)=\"onBlurHandler($event)\"\n #optionListContainer\n aria-orientation=\"vertical\"\n class=\"option-list\"\n id=\"optionList\"\n role=\"listbox\"\n tabindex=\"0\"\n>\n <ul role=\"presentation\">\n @for (\n item of selectOptionsList();\n track (item.value ?? '') + (item.label ?? '');\n let i = $index;\n let last = $last\n ) {\n <li\n [attr.aria-selected]=\"getSelected(item)\"\n [class.m-0]=\"last\"\n [class.selected]=\"selectionMode() === 'single' ? getSelected(item) : null\"\n [id]=\"'item-' + i\"\n (mousedown)=\"$event.stopImmediatePropagation(); onSelectItem(item)\"\n class=\"item\"\n role=\"option\"\n >\n <input\n [checked]=\"getSelected(item)\"\n [class.d-none]=\"selectionMode() === 'single' || !item?.value\"\n [disabled]=\"true\"\n [id]=\"i + '-' + item.value + '-checkbox'\"\n [name]=\"i + '-' + item.value + '-checkbox'\"\n [ngClass]=\"componentClass()\"\n [value]=\"getSelected(item)\"\n (blur)=\"onBlurHandler($event)\"\n #inputCheckbox\n aria-hidden=\"true\"\n class=\"form-check-input opacity-100\"\n tabindex=\"-1\"\n type=\"checkbox\"\n />\n <label\n [class.ms-3]=\"selectionMode() === 'multiple' && item?.value\"\n [for]=\"i + '-' + item.value + '-checkbox'\"\n class=\"form-check-label checkbox-label w-100 opacity-100\"\n >\n {{ translateValue() ? (item.label | transloco) : item.label }}\n </label>\n </li>\n }\n </ul>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"quang-components-shared.mjs","sources":["../../../projects/quang/components/shared/makeId.ts","../../../projects/quang/components/shared/quang-base-component.directive.ts","../../../projects/quang/components/shared/option-list/option-list.component.ts","../../../projects/quang/components/shared/option-list/option-list.component.html","../../../projects/quang/components/shared/quang-components-shared.ts"],"sourcesContent":["export const makeId = (length: number) => {\n let result = ''\n const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'\n const charactersLength = characters.length\n for (let i = 0; i < length; i++) {\n result += characters.charAt(Math.floor(Math.random() * charactersLength))\n }\n return result\n}\n","import { AfterViewInit, DestroyRef, Directive, Injector, computed, inject, input, output, signal } from '@angular/core'\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop'\nimport { ControlValueAccessor, FormControl, NgControl, Validators } from '@angular/forms'\n\nimport { Subscription } from 'rxjs'\n\nimport { ErrorData } from './ErrorData'\nimport { makeId } from './makeId'\n\n@Directive()\nexport abstract class QuangBaseComponent<T = any> implements ControlValueAccessor, AfterViewInit {\n componentId = input<string>(makeId(10))\n\n isReadonly = input<boolean>(false)\n\n isReadonly$ = toObservable(this.isReadonly)\n\n componentTabIndex = input<number>(0)\n\n componentClass = input<string | string[]>('')\n\n componentLabel = input<string>('')\n\n componentPlaceholder = input<string>('')\n\n errorMap = input<ErrorData[]>([])\n\n _errorMessagesByKey = computed(\n () => new Map((this.errorMap() ?? []).map((errorData) => [errorData.error, errorData.message]))\n )\n\n successMessage = input<string>('')\n\n helpMessage = input<string>('')\n\n formControl = input<FormControl>()\n\n componentBlur = output<void>()\n\n _value = signal<T | null>(null)\n\n _isRequired = signal<boolean>(false)\n\n _isDisabled = signal<boolean>(false)\n\n _isTouched = signal<boolean>(false)\n\n _isValid = signal<boolean>(false)\n\n _showSuccess = computed(() => this.successMessage() && this._isValid() && this._isTouched() && !this._isDisabled())\n\n _showErrors = computed(\n () => this.errorMap()?.length > 0 && !this._isValid() && this._isTouched() && !this._isDisabled()\n )\n\n _currentErrorMessage = signal<string>('')\n\n _currentErrorMessageExtraData = signal<Record<string, any>>({})\n\n _ngControl = signal<NgControl | null>(null)\n\n _injector = signal<Injector>(inject(Injector))\n\n _statusChange$?: Subscription\n\n getIsRequiredControl = computed(\n () => !!(this._ngControl()?.control as any)?._rawValidators?.find((x: any) => x.name === 'required')\n )\n\n onChange?: (value: T) => void\n\n onTouched?: () => void\n\n destroyRef = inject(DestroyRef)\n\n constructor() {\n toObservable(this.formControl)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((form) => {\n if (form) {\n this.setupFormControl()\n }\n })\n }\n\n registerOnChange(fn: (value: T) => void): void {\n this.onChange = fn\n }\n\n writeValue(val: T): void {\n this._value.set(val)\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = () => {\n this._isTouched.set(true)\n fn()\n }\n }\n\n onChangedEventHandler($event: Event) {\n const inputElement = $event.target as HTMLInputElement\n this.onChangedHandler(inputElement.value as T)\n }\n\n onChangedHandler(value: T) {\n this._value.set(value)\n if (this.onChange) {\n this.onChange(value)\n }\n\n if (this.onTouched) {\n this.onTouched()\n }\n }\n\n onBlurHandler() {\n if (this.onTouched) {\n this.onTouched()\n }\n this.componentBlur.emit()\n }\n\n setupFormControl() {\n if (this._statusChange$) {\n this._statusChange$.unsubscribe()\n this._statusChange$ = undefined\n }\n\n this._ngControl.set(this._injector().get(NgControl))\n this._statusChange$ = this._ngControl()\n ?.control?.statusChanges.pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n this.checkFormErrors()\n })\n\n this._isTouched.set(this._ngControl()?.touched ?? false)\n this._isDisabled.set(this.isReadonly() || this._ngControl()?.disabled || false)\n this.checkFormErrors()\n }\n\n onChangeIsReadonly = this.isReadonly$.pipe(takeUntilDestroyed()).subscribe((isReadonly: boolean) => {\n this._isDisabled.set(isReadonly || this._ngControl()?.disabled || false)\n })\n\n setDisabledState(isDisabled: boolean) {\n this._isDisabled.set(isDisabled)\n }\n\n checkFormErrors() {\n const control = this._ngControl()?.control\n this._isValid.set(control?.valid ?? false)\n this._isTouched.set(!control?.pristine)\n\n const validationErrors = control?.errors\n\n this._isRequired.set(validationErrors?.[Validators.required.name])\n\n let errorName = ''\n let errorMessage = ''\n let errorData = true\n\n for (const [validationErrorName, validationErrorData] of Object.entries(validationErrors ?? {})) {\n const relatedErrorMessage = this._errorMessagesByKey().get(validationErrorName)\n if (relatedErrorMessage) {\n errorName = validationErrorName\n errorMessage = relatedErrorMessage\n errorData = validationErrorData\n }\n }\n\n this._currentErrorMessage.set(errorMessage)\n this._currentErrorMessageExtraData.set({ [errorName]: errorData })\n }\n\n ngAfterViewInit(): void {\n this.setupFormControl()\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { NgClass, NgStyle } from '@angular/common'\nimport {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n HostListener,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core'\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop'\n\nimport { TranslocoPipe } from '@jsverse/transloco'\nimport { QUANG_LOGGING_BEHAVIOR } from 'quang'\nimport { Subscription, fromEvent } from 'rxjs'\n\nexport interface SelectOption {\n label: string\n value: string | number | null\n}\n\nexport enum OptionListParentType {\n SELECT = 'select',\n AUTOCOMPLETE = 'autocomplete',\n}\n\n@Component({\n selector: 'quang-option-list',\n imports: [NgStyle, NgClass, TranslocoPipe],\n templateUrl: './option-list.component.html',\n styleUrl: './option-list.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class QuangOptionListComponent {\n logLevel = inject(QUANG_LOGGING_BEHAVIOR, { optional: true })\n\n selectionMode = input<'single' | 'multiple'>('single')\n\n optionListMaxHeight = input<string>('201px')\n\n selectOptions = input<SelectOption[]>([])\n\n selectButtonRef = input.required<HTMLButtonElement | HTMLInputElement | HTMLDivElement>()\n\n _value = input<any>()\n\n _isDisabled = input<boolean>()\n\n componentClass = input<string | string[]>('')\n\n componentLabel = input<string>('')\n\n componentTabIndex = input<number>(0)\n\n translateValue = input<boolean>(false)\n\n nullOption = input<boolean>(true)\n\n elementWidth = signal<string>('0px')\n\n elementTop = signal<string>('0px')\n\n elementBottom = signal<string>('0px')\n\n scrollBehaviorOnOpen = input<ScrollBehavior>('smooth')\n\n changedHandler = output<any>()\n\n blurHandler = output<any>()\n\n /** Emitted when user presses Escape - parent should close dropdown and return focus to trigger */\n escapePressed = output<void>()\n\n /** Emitted when user presses Tab - parent should handle focus transition */\n tabPressed = output<{ shiftKey: boolean }>()\n\n optionListContainer = viewChild<ElementRef<HTMLDivElement>>('optionListContainer')\n\n destroyRef = inject(DestroyRef)\n\n parentType = input.required<OptionListParentType>()\n\n parentID = input<string>('')\n\n searchString = signal<string>('')\n\n searchResetTimer: ReturnType<typeof setTimeout> | null = null\n\n selectButtonRef$ = toObservable(this.selectButtonRef)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n this.getOptionListWidth()\n this.getOptionListTop()\n this.getScrollParent(this.selectButtonRef())?.addEventListener('scroll', () => {\n this.getOptionListWidth()\n this.getOptionListTop()\n })\n })\n\n selectOptionsList = computed(() => {\n if (this.nullOption() && this.selectionMode() === 'single') {\n return [\n {\n label: '',\n value: null,\n },\n ...this.selectOptions(),\n ]\n }\n return [...this.selectOptions()]\n })\n\n onKeyDown: Subscription | null = null\n\n selectedElementIndex = computed<number>(\n () => this.selectOptionsList()?.findIndex((x) => x?.value === this._value()) ?? 0\n )\n\n /** Signal to track currently focused item index for aria-activedescendant */\n focusedItemIndex = signal<number>(-1)\n\n /**\n * Returns the ID of the currently focused item for aria-activedescendant\n */\n getActiveDescendantId(): string | null {\n const index = this.focusedItemIndex()\n if (index >= 0 && index < this.selectOptionsList().length) {\n return `item-${index}`\n }\n return null\n }\n\n optionList$ = effect(() => {\n const optionListContainer = this.optionListContainer()\n const parentType = this.parentType()\n\n // Focus the option list container when opened (only for SELECT)\n if (optionListContainer && parentType === OptionListParentType.SELECT) {\n optionListContainer?.nativeElement.focus()\n }\n\n const ul = optionListContainer?.nativeElement?.children[0] as HTMLUListElement | undefined\n const listItems = (ul?.children ?? []) as HTMLLIElement[]\n let currentIndex = this.selectedElementIndex()\n listItems?.[currentIndex]?.classList.add('selected')\n // Initialize focusedItemIndex with current selection\n this.focusedItemIndex.set(currentIndex)\n\n // Scroll to selected item when option list opens\n const listItem = listItems[currentIndex]\n if (listItem) {\n setTimeout(() => {\n listItem.scrollIntoView({ behavior: this.scrollBehaviorOnOpen(), block: 'nearest' })\n }, 0)\n }\n\n if (this.onKeyDown) {\n this.onKeyDown.unsubscribe()\n }\n\n this.onKeyDown = fromEvent(document, 'keydown', {\n capture: true,\n })\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((event) => {\n switch ((event as KeyboardEvent).key) {\n case 'ArrowDown': {\n if (this.parentType() === OptionListParentType.AUTOCOMPLETE) optionListContainer?.nativeElement.focus()\n if (currentIndex !== this.selectedElementIndex()) listItems[currentIndex]?.classList.remove('selected')\n if (currentIndex === listItems.length - 1) {\n currentIndex = listItems.length - 1\n } else {\n currentIndex += 1\n }\n event.preventDefault()\n\n listItems[currentIndex]?.classList.add('selected')\n // Scroll item into view if not visible\n listItems[currentIndex]?.scrollIntoView({ behavior: 'smooth', block: 'nearest' })\n // Update focusedItemIndex for aria-activedescendant\n this.focusedItemIndex.set(currentIndex)\n break\n }\n case 'ArrowUp': {\n if (this.parentType() === OptionListParentType.AUTOCOMPLETE) optionListContainer?.nativeElement.focus()\n if (currentIndex !== this.selectedElementIndex()) listItems[currentIndex]?.classList.remove('selected')\n if (currentIndex !== 0) currentIndex -= 1\n event.preventDefault()\n\n listItems[currentIndex]?.classList.add('selected')\n // Scroll item into view if not visible\n listItems[currentIndex]?.scrollIntoView({ behavior: 'smooth', block: 'nearest' })\n // Update focusedItemIndex for aria-activedescendant\n this.focusedItemIndex.set(currentIndex)\n break\n }\n case 'Enter': {\n event.preventDefault()\n this.onSelectItem(this.selectOptionsList()[currentIndex])\n break\n }\n case 'Escape': {\n event.preventDefault()\n this.escapePressed.emit()\n break\n }\n case 'Tab': {\n // Only handle Tab when focus is on the option list itself\n // If focus is on the parent input, let the input's blur handler deal with it\n if (document.activeElement?.id === optionListContainer?.nativeElement?.id) {\n // Allow Tab to close dropdown and move focus naturally\n // Emit event so parent can handle focus transition\n this.tabPressed.emit({ shiftKey: (event as KeyboardEvent).shiftKey })\n }\n break\n }\n default: {\n if (\n ((event as KeyboardEvent)?.key?.length === 1 || (event as KeyboardEvent)?.key === 'Backspace') &&\n this.parentType() === OptionListParentType.AUTOCOMPLETE &&\n document.activeElement?.id === optionListContainer?.nativeElement?.id\n ) {\n currentIndex = 0\n document.getElementById(this.parentID())?.focus()\n document.getElementById(this.parentID())?.click()\n } else if (\n (event as KeyboardEvent)?.key?.length === 1 &&\n this.parentType() === OptionListParentType.SELECT\n ) {\n const key = (event as KeyboardEvent).key\n currentIndex = this.handleSearch(key, listItems, currentIndex)\n event.preventDefault()\n }\n break\n }\n }\n })\n })\n\n handleSearch(key: string, listItems: HTMLLIElement[], currentIndex: number): number {\n if (this.searchResetTimer) {\n clearTimeout(this.searchResetTimer)\n }\n\n this.searchString.update((current) => current + key)\n\n this.searchResetTimer = setTimeout(() => {\n this.searchString.set('')\n this.searchResetTimer = null\n }, 500)\n\n const searchStr = this.searchString().toLowerCase()\n const matchIndex = this.selectOptionsList().findIndex((option) => option.label.toLowerCase().includes(searchStr))\n\n if (matchIndex !== -1 && matchIndex !== currentIndex) {\n listItems[currentIndex]?.classList.remove('selected')\n listItems[matchIndex]?.classList.add('selected')\n listItems[matchIndex]?.scrollIntoView({ behavior: this.scrollBehaviorOnOpen() })\n return matchIndex\n }\n\n return currentIndex\n }\n\n @HostListener('window:scroll') changePosition() {\n this.getOptionListWidth()\n this.getOptionListTop()\n }\n\n isScrollable(ele: Element): boolean {\n if (!ele) return false\n\n let result = false\n\n try {\n const hasScrollableContent = ele.scrollHeight > ele.clientHeight\n\n const overflowYStyle = window.getComputedStyle(ele).overflowY\n const isOverflowHidden = overflowYStyle.includes('hidden')\n\n result = hasScrollableContent && !isOverflowHidden\n } catch (_error) {\n if (this.logLevel === 'verbose') console.error('captured error isScrollable', _error)\n }\n\n return result\n }\n\n getScrollParent(node: unknown): Element {\n if (!node || node === document.body || !(node instanceof Element)) return document.body\n return this.isScrollable(node) ? node : this.getScrollParent(node.parentNode)\n }\n\n onSelectItem(item: SelectOption | null): void {\n if (this.selectionMode() === 'single') {\n this.changedHandler.emit(item?.value ?? null)\n } else {\n let targetValue = this._value()\n if (!Array.isArray(targetValue) && targetValue) {\n targetValue = [targetValue]\n }\n const values: string[] | number[] | null = targetValue as string[] | number[] | null\n if (values) {\n if (values.some((x) => x === item?.value)) {\n this.changedHandler.emit(values.filter((x) => x !== item?.value) as string[] | number[])\n } else if (item) {\n this.changedHandler.emit([...values, item.value] as string[] | number[])\n } else {\n this.changedHandler.emit([...values] as string[] | number[])\n }\n } else if (item?.value) {\n this.changedHandler.emit([item.value] as string[] | number[])\n } else {\n this.changedHandler.emit(null)\n }\n }\n this.getOptionListTop()\n }\n\n getSelected(item: SelectOption): boolean {\n if (this.selectionMode() === 'single' || !Array.isArray(this._value())) {\n return this._value() === item.value\n }\n return this._value()?.some((x: number | string | null) => x === item?.value)\n }\n\n onBlurHandler(e: Event): void {\n this.blurHandler.emit(e)\n }\n\n getOptionListWidth() {\n this.elementWidth.set(`${this.selectButtonRef()?.offsetWidth}px`)\n }\n\n getOptionListTop() {\n const nativeElement = this.optionListContainer()?.nativeElement\n const diff =\n window.innerHeight -\n (nativeElement?.getBoundingClientRect()?.height ?? 0) -\n (this.selectButtonRef()?.getBoundingClientRect()?.top ?? 0) -\n (this.selectButtonRef()?.getBoundingClientRect()?.height ?? 0)\n let topValue = 'unset'\n let bottomValue = 'unset'\n const isTop = diff >= 0\n if (isTop) {\n topValue = `${(this.selectButtonRef()?.getBoundingClientRect()?.top ?? 0) + (this.selectButtonRef()?.getBoundingClientRect()?.height ?? 0)}px`\n } else {\n bottomValue = `${window.innerHeight - (this.selectButtonRef()?.getBoundingClientRect()?.bottom ?? 0) + (this.selectButtonRef()?.getBoundingClientRect()?.height ?? 0)}px`\n }\n nativeElement?.classList.toggle('option-list-top', !isTop)\n this.elementTop.set(topValue)\n this.elementBottom.set(bottomValue)\n setTimeout(() => {\n this.getOptionListTop()\n })\n }\n}\n","<div\n [attr.aria-activedescendant]=\"getActiveDescendantId()\"\n [attr.aria-label]=\"componentLabel()\"\n [ngStyle]=\"{\n 'max-height': optionListMaxHeight(),\n '--option-list-width': elementWidth(),\n '--option-list-top': elementTop(),\n '--option-list-bottom': elementBottom(),\n }\"\n (blur)=\"onBlurHandler($event)\"\n #optionListContainer\n aria-orientation=\"vertical\"\n class=\"option-list\"\n id=\"optionList\"\n role=\"listbox\"\n tabindex=\"0\"\n>\n <ul role=\"presentation\">\n @for (\n item of selectOptionsList();\n track (item.value ?? '') + (item.label ?? '');\n let i = $index;\n let last = $last\n ) {\n <li\n [attr.aria-selected]=\"getSelected(item)\"\n [class.m-0]=\"last\"\n [class.selected]=\"selectionMode() === 'single' ? getSelected(item) : null\"\n [id]=\"'item-' + i\"\n (mousedown)=\"$event.stopImmediatePropagation(); onSelectItem(item)\"\n class=\"item\"\n role=\"option\"\n >\n <input\n [checked]=\"getSelected(item)\"\n [class.d-none]=\"selectionMode() === 'single' || !item?.value\"\n [disabled]=\"true\"\n [id]=\"i + '-' + item.value + '-checkbox'\"\n [name]=\"i + '-' + item.value + '-checkbox'\"\n [ngClass]=\"componentClass()\"\n [value]=\"getSelected(item)\"\n (blur)=\"onBlurHandler($event)\"\n #inputCheckbox\n aria-hidden=\"true\"\n class=\"form-check-input opacity-100\"\n tabindex=\"-1\"\n type=\"checkbox\"\n />\n <label\n [class.ms-3]=\"selectionMode() === 'multiple' && item?.value\"\n [for]=\"i + '-' + item.value + '-checkbox'\"\n class=\"form-check-label checkbox-label w-100 opacity-100\"\n >\n {{ translateValue() ? (item.label | transloco) : item.label }}\n </label>\n </li>\n }\n </ul>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "quang",
|
|
3
3
|
"sideEffects": false,
|
|
4
|
-
"version": "19.3.15-
|
|
4
|
+
"version": "19.3.15-5",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"tslib": "^2.3.0"
|
|
7
7
|
},
|
|
@@ -67,14 +67,14 @@
|
|
|
67
67
|
"types": "./auth/index.d.ts",
|
|
68
68
|
"default": "./fesm2022/quang-auth.mjs"
|
|
69
69
|
},
|
|
70
|
-
"./data-handling": {
|
|
71
|
-
"types": "./data-handling/index.d.ts",
|
|
72
|
-
"default": "./fesm2022/quang-data-handling.mjs"
|
|
73
|
-
},
|
|
74
70
|
"./device": {
|
|
75
71
|
"types": "./device/index.d.ts",
|
|
76
72
|
"default": "./fesm2022/quang-device.mjs"
|
|
77
73
|
},
|
|
74
|
+
"./data-handling": {
|
|
75
|
+
"types": "./data-handling/index.d.ts",
|
|
76
|
+
"default": "./fesm2022/quang-data-handling.mjs"
|
|
77
|
+
},
|
|
78
78
|
"./forms": {
|
|
79
79
|
"types": "./forms/index.d.ts",
|
|
80
80
|
"default": "./fesm2022/quang-forms.mjs"
|
|
@@ -103,22 +103,22 @@
|
|
|
103
103
|
"types": "./components/checkbox/index.d.ts",
|
|
104
104
|
"default": "./fesm2022/quang-components-checkbox.mjs"
|
|
105
105
|
},
|
|
106
|
-
"./components/input": {
|
|
107
|
-
"types": "./components/input/index.d.ts",
|
|
108
|
-
"default": "./fesm2022/quang-components-input.mjs"
|
|
109
|
-
},
|
|
110
106
|
"./components/date": {
|
|
111
107
|
"types": "./components/date/index.d.ts",
|
|
112
108
|
"default": "./fesm2022/quang-components-date.mjs"
|
|
113
109
|
},
|
|
114
|
-
"./components/
|
|
115
|
-
"types": "./components/
|
|
116
|
-
"default": "./fesm2022/quang-components-
|
|
110
|
+
"./components/input": {
|
|
111
|
+
"types": "./components/input/index.d.ts",
|
|
112
|
+
"default": "./fesm2022/quang-components-input.mjs"
|
|
117
113
|
},
|
|
118
114
|
"./components/paginator": {
|
|
119
115
|
"types": "./components/paginator/index.d.ts",
|
|
120
116
|
"default": "./fesm2022/quang-components-paginator.mjs"
|
|
121
117
|
},
|
|
118
|
+
"./components/shared": {
|
|
119
|
+
"types": "./components/shared/index.d.ts",
|
|
120
|
+
"default": "./fesm2022/quang-components-shared.mjs"
|
|
121
|
+
},
|
|
122
122
|
"./components/select": {
|
|
123
123
|
"types": "./components/select/index.d.ts",
|
|
124
124
|
"default": "./fesm2022/quang-components-select.mjs"
|
|
@@ -131,6 +131,10 @@
|
|
|
131
131
|
"types": "./components/wysiwyg/index.d.ts",
|
|
132
132
|
"default": "./fesm2022/quang-components-wysiwyg.mjs"
|
|
133
133
|
},
|
|
134
|
+
"./overlay/shared": {
|
|
135
|
+
"types": "./overlay/shared/index.d.ts",
|
|
136
|
+
"default": "./fesm2022/quang-overlay-shared.mjs"
|
|
137
|
+
},
|
|
134
138
|
"./overlay/modal": {
|
|
135
139
|
"types": "./overlay/modal/index.d.ts",
|
|
136
140
|
"default": "./fesm2022/quang-overlay-modal.mjs"
|
|
@@ -139,10 +143,6 @@
|
|
|
139
143
|
"types": "./overlay/popover/index.d.ts",
|
|
140
144
|
"default": "./fesm2022/quang-overlay-popover.mjs"
|
|
141
145
|
},
|
|
142
|
-
"./overlay/shared": {
|
|
143
|
-
"types": "./overlay/shared/index.d.ts",
|
|
144
|
-
"default": "./fesm2022/quang-overlay-shared.mjs"
|
|
145
|
-
},
|
|
146
146
|
"./overlay/toast": {
|
|
147
147
|
"types": "./overlay/toast/index.d.ts",
|
|
148
148
|
"default": "./fesm2022/quang-overlay-toast.mjs"
|