@sebgroup/green-angular 4.5.0 → 4.6.1
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/esm2022/index.mjs +1 -1
- package/esm2022/lib/shared/on-scroll.directive.mjs +2 -2
- package/esm2022/src/lib/shared/on-scroll.directive.mjs +2 -2
- package/esm2022/src/v-angular/base-control-value-accessor/base-control-value-accessor.component.mjs +287 -0
- package/esm2022/src/v-angular/base-control-value-accessor/base-control-value-accessor.module.mjs +17 -0
- package/esm2022/src/v-angular/base-control-value-accessor/index.mjs +3 -0
- package/esm2022/src/v-angular/base-control-value-accessor/sebgroup-green-angular-src-v-angular-base-control-value-accessor.mjs +5 -0
- package/esm2022/src/v-angular/breadcrumbs/breadcrumbs.component.mjs +25 -0
- package/esm2022/src/v-angular/breadcrumbs/breadcrumbs.module.mjs +20 -0
- package/esm2022/src/v-angular/breadcrumbs/index.mjs +3 -0
- package/esm2022/src/v-angular/breadcrumbs/sebgroup-green-angular-src-v-angular-breadcrumbs.mjs +5 -0
- package/esm2022/src/v-angular/button/button.component.mjs +108 -0
- package/esm2022/src/v-angular/button/button.module.mjs +20 -0
- package/esm2022/src/v-angular/button/index.mjs +3 -0
- package/esm2022/src/v-angular/button/sebgroup-green-angular-src-v-angular-button.mjs +5 -0
- package/esm2022/src/v-angular/card/card.component.mjs +11 -0
- package/esm2022/src/v-angular/card/card.module.mjs +18 -0
- package/esm2022/src/v-angular/card/index.mjs +3 -0
- package/esm2022/src/v-angular/card/sebgroup-green-angular-src-v-angular-card.mjs +5 -0
- package/esm2022/src/v-angular/character-countdown/character-countdown.directive.mjs +51 -0
- package/esm2022/src/v-angular/character-countdown/character-countdown.module.mjs +18 -0
- package/esm2022/src/v-angular/character-countdown/index.mjs +3 -0
- package/esm2022/src/v-angular/character-countdown/sebgroup-green-angular-src-v-angular-character-countdown.mjs +5 -0
- package/esm2022/src/v-angular/checkbox/checkbox.component.mjs +72 -0
- package/esm2022/src/v-angular/checkbox/checkbox.module.mjs +19 -0
- package/esm2022/src/v-angular/checkbox/index.mjs +3 -0
- package/esm2022/src/v-angular/checkbox/sebgroup-green-angular-src-v-angular-checkbox.mjs +5 -0
- package/esm2022/src/v-angular/core/core.globals.mjs +20 -0
- package/esm2022/src/v-angular/core/core.utils.mjs +28 -0
- package/esm2022/src/v-angular/core/index.mjs +3 -0
- package/esm2022/src/v-angular/core/sebgroup-green-angular-src-v-angular-core.mjs +5 -0
- package/esm2022/src/v-angular/dropdown/dropdown-list/dropdown-list.component.mjs +256 -0
- package/esm2022/src/v-angular/dropdown/dropdown-list/index.mjs +2 -0
- package/esm2022/src/v-angular/dropdown/dropdown.component.mjs +239 -0
- package/esm2022/src/v-angular/dropdown/dropdown.module.mjs +22 -0
- package/esm2022/src/v-angular/dropdown/index.mjs +6 -0
- package/esm2022/src/v-angular/dropdown/sebgroup-green-angular-src-v-angular-dropdown.mjs +5 -0
- package/esm2022/src/v-angular/dropdown/typeahead/index.mjs +3 -0
- package/esm2022/src/v-angular/dropdown/typeahead/typeahead-dropdown-list/typeahead-dropdown-list.component.mjs +98 -0
- package/esm2022/src/v-angular/dropdown/typeahead/typeahead-highlight/typeahead-highlight.component.mjs +85 -0
- package/esm2022/src/v-angular/dropdown/typeahead/typeahead-input/typeahead-input.component.mjs +132 -0
- package/esm2022/src/v-angular/dropdown/typeahead/typeahead.module.mjs +33 -0
- package/esm2022/src/v-angular/external-link/external-link.directive.mjs +37 -0
- package/esm2022/src/v-angular/external-link/external-link.module.mjs +18 -0
- package/esm2022/src/v-angular/external-link/index.mjs +3 -0
- package/esm2022/src/v-angular/external-link/sebgroup-green-angular-src-v-angular-external-link.mjs +5 -0
- package/esm2022/src/v-angular/i18n/i18n.json +12 -0
- package/esm2022/src/v-angular/i18n/i18n.module.mjs +83 -0
- package/esm2022/src/v-angular/i18n/i18n.test.module.mjs +89 -0
- package/esm2022/src/v-angular/i18n/index.mjs +3 -0
- package/esm2022/src/v-angular/i18n/sebgroup-green-angular-src-v-angular-i18n.mjs +5 -0
- package/esm2022/src/v-angular/info-circle/index.mjs +3 -0
- package/esm2022/src/v-angular/info-circle/info-circle.component.mjs +28 -0
- package/esm2022/src/v-angular/info-circle/info-circle.module.mjs +21 -0
- package/esm2022/src/v-angular/info-circle/sebgroup-green-angular-src-v-angular-info-circle.mjs +5 -0
- package/esm2022/src/v-angular/input/index.mjs +3 -0
- package/esm2022/src/v-angular/input/input.component.mjs +221 -0
- package/esm2022/src/v-angular/input/input.module.mjs +32 -0
- package/esm2022/src/v-angular/input/sebgroup-green-angular-src-v-angular-input.mjs +5 -0
- package/esm2022/src/v-angular/input-mask/config.mjs +9 -0
- package/esm2022/src/v-angular/input-mask/constants.mjs +2 -0
- package/esm2022/src/v-angular/input-mask/index.mjs +6 -0
- package/esm2022/src/v-angular/input-mask/input-mask-format.pipe.mjs +20 -0
- package/esm2022/src/v-angular/input-mask/input-mask.directive.mjs +165 -0
- package/esm2022/src/v-angular/input-mask/input-mask.module.mjs +35 -0
- package/esm2022/src/v-angular/input-mask/input-mask.types.mjs +2 -0
- package/esm2022/src/v-angular/input-mask/sebgroup-green-angular-src-v-angular-input-mask.mjs +5 -0
- package/esm2022/src/v-angular/modal/dialog/dialog.component.mjs +190 -0
- package/esm2022/src/v-angular/modal/fold-out/fold-out.component.mjs +56 -0
- package/esm2022/src/v-angular/modal/fold-out/fold-out.directive.mjs +19 -0
- package/esm2022/src/v-angular/modal/index.mjs +6 -0
- package/esm2022/src/v-angular/modal/modal.globals.mjs +20 -0
- package/esm2022/src/v-angular/modal/modal.module.mjs +40 -0
- package/esm2022/src/v-angular/modal/modal.types.mjs +2 -0
- package/esm2022/src/v-angular/modal/sebgroup-green-angular-src-v-angular-modal.mjs +5 -0
- package/esm2022/src/v-angular/modal/slide-out/slide-out.component.mjs +229 -0
- package/esm2022/src/v-angular/radio/index.mjs +3 -0
- package/esm2022/src/v-angular/radio/radio.component.mjs +130 -0
- package/esm2022/src/v-angular/radio/radio.module.mjs +20 -0
- package/esm2022/src/v-angular/radio/sebgroup-green-angular-src-v-angular-radio.mjs +5 -0
- package/esm2022/src/v-angular/slug/index.mjs +3 -0
- package/esm2022/src/v-angular/slug/sebgroup-green-angular-src-v-angular-slug.mjs +5 -0
- package/esm2022/src/v-angular/slug/slug.module.mjs +18 -0
- package/esm2022/src/v-angular/slug/slug.pipe.mjs +27 -0
- package/esm2022/src/v-angular/textarea/index.mjs +3 -0
- package/esm2022/src/v-angular/textarea/sebgroup-green-angular-src-v-angular-textarea.mjs +5 -0
- package/esm2022/src/v-angular/textarea/textarea.component.mjs +101 -0
- package/esm2022/src/v-angular/textarea/textarea.module.mjs +18 -0
- package/esm2022/src/v-angular/tooltip/index.mjs +3 -0
- package/esm2022/src/v-angular/tooltip/sebgroup-green-angular-src-v-angular-tooltip.mjs +5 -0
- package/esm2022/src/v-angular/tooltip/tooltip.directive.mjs +273 -0
- package/esm2022/src/v-angular/tooltip/tooltip.module.mjs +18 -0
- package/fesm2022/sebgroup-green-angular-src-lib-shared.mjs +1 -1
- package/fesm2022/sebgroup-green-angular-src-lib-shared.mjs.map +1 -1
- package/fesm2022/sebgroup-green-angular-src-v-angular-base-control-value-accessor.mjs +308 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-base-control-value-accessor.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-breadcrumbs.mjs +49 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-breadcrumbs.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-button.mjs +131 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-button.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-card.mjs +33 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-card.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-character-countdown.mjs +73 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-character-countdown.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-checkbox.mjs +94 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-checkbox.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-core.mjs +54 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-core.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-dropdown.mjs +830 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-dropdown.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-external-link.mjs +58 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-external-link.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-i18n.mjs +192 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-i18n.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-info-circle.mjs +53 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-info-circle.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-input-mask.mjs +226 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-input-mask.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-input.mjs +256 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-input.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-modal.mjs +545 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-modal.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-radio.mjs +153 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-radio.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-slug.mjs +49 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-slug.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-textarea.mjs +122 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-textarea.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-tooltip.mjs +295 -0
- package/fesm2022/sebgroup-green-angular-src-v-angular-tooltip.mjs.map +1 -0
- package/fesm2022/sebgroup-green-angular.mjs +1 -1
- package/fesm2022/sebgroup-green-angular.mjs.map +1 -1
- package/package.json +115 -4
- package/src/v-angular/base-control-value-accessor/base-control-value-accessor.component.d.ts +124 -0
- package/src/v-angular/base-control-value-accessor/base-control-value-accessor.module.d.ts +7 -0
- package/src/v-angular/base-control-value-accessor/index.d.ts +2 -0
- package/src/v-angular/breadcrumbs/breadcrumbs.component.d.ts +18 -0
- package/src/v-angular/breadcrumbs/breadcrumbs.module.d.ts +10 -0
- package/src/v-angular/breadcrumbs/index.d.ts +2 -0
- package/src/v-angular/button/button.component.d.ts +62 -0
- package/src/v-angular/button/button.module.d.ts +10 -0
- package/src/v-angular/button/index.d.ts +2 -0
- package/src/v-angular/card/card.component.d.ts +5 -0
- package/src/v-angular/card/card.module.d.ts +8 -0
- package/src/v-angular/card/index.d.ts +2 -0
- package/src/v-angular/character-countdown/character-countdown.directive.d.ts +17 -0
- package/src/v-angular/character-countdown/character-countdown.module.d.ts +8 -0
- package/src/v-angular/character-countdown/index.d.ts +2 -0
- package/src/v-angular/checkbox/checkbox.component.d.ts +27 -0
- package/src/v-angular/checkbox/checkbox.module.d.ts +9 -0
- package/src/v-angular/checkbox/index.d.ts +2 -0
- package/src/v-angular/core/core.globals.d.ts +13 -0
- package/src/v-angular/core/core.utils.d.ts +22 -0
- package/src/v-angular/core/index.d.ts +2 -0
- package/src/v-angular/dropdown/dropdown-list/dropdown-list.component.d.ts +89 -0
- package/src/v-angular/dropdown/dropdown-list/index.d.ts +1 -0
- package/src/v-angular/dropdown/dropdown.component.d.ts +99 -0
- package/src/v-angular/dropdown/dropdown.module.d.ts +12 -0
- package/src/v-angular/dropdown/index.d.ts +5 -0
- package/src/v-angular/dropdown/typeahead/index.d.ts +2 -0
- package/src/v-angular/dropdown/typeahead/typeahead-dropdown-list/typeahead-dropdown-list.component.d.ts +34 -0
- package/src/v-angular/dropdown/typeahead/typeahead-highlight/typeahead-highlight.component.d.ts +34 -0
- package/src/v-angular/dropdown/typeahead/typeahead-input/typeahead-input.component.d.ts +59 -0
- package/src/v-angular/dropdown/typeahead/typeahead.module.d.ts +11 -0
- package/src/v-angular/external-link/external-link.directive.d.ts +17 -0
- package/src/v-angular/external-link/external-link.module.d.ts +8 -0
- package/src/v-angular/external-link/index.d.ts +2 -0
- package/src/v-angular/i18n/i18n.module.d.ts +15 -0
- package/src/v-angular/i18n/i18n.test.module.d.ts +27 -0
- package/src/v-angular/i18n/index.d.ts +2 -0
- package/src/v-angular/info-circle/index.d.ts +2 -0
- package/src/v-angular/info-circle/info-circle.component.d.ts +16 -0
- package/src/v-angular/info-circle/info-circle.module.d.ts +10 -0
- package/src/v-angular/input/index.d.ts +2 -0
- package/src/v-angular/input/input.component.d.ts +90 -0
- package/src/v-angular/input/input.module.d.ts +11 -0
- package/src/v-angular/input-mask/config.d.ts +6 -0
- package/src/v-angular/input-mask/constants.d.ts +2 -0
- package/src/v-angular/input-mask/index.d.ts +5 -0
- package/src/v-angular/input-mask/input-mask-format.pipe.d.ts +8 -0
- package/src/v-angular/input-mask/input-mask.directive.d.ts +39 -0
- package/src/v-angular/input-mask/input-mask.module.d.ts +11 -0
- package/src/v-angular/input-mask/input-mask.types.d.ts +20 -0
- package/src/v-angular/modal/dialog/dialog.component.d.ts +55 -0
- package/src/v-angular/modal/fold-out/fold-out.component.d.ts +24 -0
- package/src/v-angular/modal/fold-out/fold-out.directive.d.ts +6 -0
- package/src/v-angular/modal/index.d.ts +5 -0
- package/src/v-angular/modal/modal.globals.d.ts +13 -0
- package/src/v-angular/modal/modal.module.d.ts +13 -0
- package/src/v-angular/modal/modal.types.d.ts +5 -0
- package/src/v-angular/modal/slide-out/slide-out.component.d.ts +76 -0
- package/src/v-angular/radio/index.d.ts +2 -0
- package/src/v-angular/radio/radio.component.d.ts +48 -0
- package/src/v-angular/radio/radio.module.d.ts +9 -0
- package/src/v-angular/slug/index.d.ts +2 -0
- package/src/v-angular/slug/slug.module.d.ts +8 -0
- package/src/v-angular/slug/slug.pipe.d.ts +12 -0
- package/src/v-angular/textarea/index.d.ts +2 -0
- package/src/v-angular/textarea/textarea.component.d.ts +44 -0
- package/src/v-angular/textarea/textarea.module.d.ts +8 -0
- package/src/v-angular/tooltip/index.d.ts +2 -0
- package/src/v-angular/tooltip/tooltip.directive.d.ts +106 -0
- package/src/v-angular/tooltip/tooltip.module.d.ts +8 -0
|
@@ -0,0 +1,830 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Component, Input, EventEmitter, Optional, Inject, ViewChildren, HostBinding, Output, HostListener, TemplateRef, Self, ContentChild, SkipSelf, NgModule } from '@angular/core';
|
|
3
|
+
import * as i1$1 from '@angular/forms';
|
|
4
|
+
import { Subject, fromEvent, takeUntil } from 'rxjs';
|
|
5
|
+
import * as i4 from '@ngneat/transloco';
|
|
6
|
+
import { TRANSLOCO_SCOPE } from '@ngneat/transloco';
|
|
7
|
+
import { NgvBaseControlValueAccessorComponent } from '@sebgroup/green-angular/src/v-angular/base-control-value-accessor';
|
|
8
|
+
import * as i2 from '@sebgroup/green-angular/src/v-angular/core';
|
|
9
|
+
import { DropdownUtils } from '@sebgroup/green-angular/src/v-angular/core';
|
|
10
|
+
import * as i1 from '@angular/common';
|
|
11
|
+
import { CommonModule } from '@angular/common';
|
|
12
|
+
import scrollIntoView from 'scroll-into-view-if-needed';
|
|
13
|
+
import * as i3 from '@sebgroup/green-angular/src/v-angular/tooltip';
|
|
14
|
+
import { NgvTooltipModule } from '@sebgroup/green-angular/src/v-angular/tooltip';
|
|
15
|
+
import { NgvInputComponent } from '@sebgroup/green-angular/src/v-angular/input';
|
|
16
|
+
import { NgvI18nModule } from '@sebgroup/green-angular/src/v-angular/i18n';
|
|
17
|
+
|
|
18
|
+
class NgvTypeaheadHighlightComponent {
|
|
19
|
+
constructor() {
|
|
20
|
+
this.text = '';
|
|
21
|
+
this.input = '';
|
|
22
|
+
/**
|
|
23
|
+
* Regexp of characters that are allowed in textContent without being found in textToHighlight
|
|
24
|
+
* Allow whitespaces.
|
|
25
|
+
* */
|
|
26
|
+
this.allowedNonMatchingChars = new RegExp(/\s/);
|
|
27
|
+
}
|
|
28
|
+
ngOnChanges(changes) {
|
|
29
|
+
const { textContent, textToHighlight } = changes;
|
|
30
|
+
if (textContent?.currentValue != null)
|
|
31
|
+
this.text = `${textContent.currentValue}`;
|
|
32
|
+
if (textToHighlight?.currentValue != null)
|
|
33
|
+
this.input = `${textToHighlight.currentValue}`;
|
|
34
|
+
this.updateValues();
|
|
35
|
+
}
|
|
36
|
+
updateValues() {
|
|
37
|
+
const splittedText = this.text.toLocaleLowerCase().split('');
|
|
38
|
+
const splittedInput = this.input.toLocaleLowerCase().split('');
|
|
39
|
+
const { start, end } = this.getHighlightedPart(splittedText, splittedInput);
|
|
40
|
+
// If user input is not found within the textcontent, reset options and return.
|
|
41
|
+
if (start === -1 || end === -1) {
|
|
42
|
+
this.prefix = this.match = this.suffix = '';
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
this.prefix = this.text.substring(0, start);
|
|
46
|
+
this.match = this.text.substring(start, end);
|
|
47
|
+
this.suffix = this.text.substring(end);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Function that finds the start and end index of where the input is located within the text to display.
|
|
51
|
+
* First occurence is returned. Allows for spaces to occur despite input not matching space.
|
|
52
|
+
* Loops through each character in splittedText and when a char in splittedText equlas the first character of
|
|
53
|
+
* splittedInput, evaluate wether it's match on the entire input.
|
|
54
|
+
* - If it's => return indexes.
|
|
55
|
+
* - If it's not => break out and check next char in outer loop.
|
|
56
|
+
* @param splittedText the text content splitted in an array
|
|
57
|
+
* @param splittedInput the input splitted in an array
|
|
58
|
+
* @returns { start: number, end: number } Indexes of where the match starts and ends in the text displatyed
|
|
59
|
+
*/
|
|
60
|
+
getHighlightedPart(splittedText, splittedInput) {
|
|
61
|
+
let start = -1;
|
|
62
|
+
let end = -1;
|
|
63
|
+
for (let i = 0; i < splittedText.length; i++) {
|
|
64
|
+
// If start and end have been set, break and return
|
|
65
|
+
if (start > -1 || end > -1)
|
|
66
|
+
break;
|
|
67
|
+
// If current char match first in input, try see if whole input match from that index
|
|
68
|
+
if (splittedText[i] === splittedInput[0]) {
|
|
69
|
+
let matches = 1;
|
|
70
|
+
for (let t = 1; t <= splittedText.length; t++) {
|
|
71
|
+
// If match on last character of input, we're finished.
|
|
72
|
+
if (matches === splittedInput.length) {
|
|
73
|
+
start = i;
|
|
74
|
+
end = start + t;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
if (splittedText[t + i] === splittedInput[matches])
|
|
78
|
+
matches++;
|
|
79
|
+
else if (this.allowedNonMatchingChars.test(splittedText[t + i]))
|
|
80
|
+
continue; // Ignore whitespace, continue
|
|
81
|
+
else
|
|
82
|
+
break; // No match, break out of inner loop to check next char in text
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return { start, end };
|
|
87
|
+
}
|
|
88
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgvTypeaheadHighlightComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
89
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgvTypeaheadHighlightComponent, selector: "nggv-typeahead-highlight", inputs: { textContent: "textContent", textToHighlight: "textToHighlight" }, usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"!this.match\">{{ textContent }}</ng-container>\n<!-- Note that this is sensitive to line breaks producing extra spacing between the different parts -->\n<ng-container *ngIf=\"!!this.match\">\n {{ prefix || '' }}<span class=\"match\">{{ match }}</span>{{ suffix ||''}}\n</ng-container>", styles: [":host .match{font-weight:500}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
|
|
90
|
+
}
|
|
91
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgvTypeaheadHighlightComponent, decorators: [{
|
|
92
|
+
type: Component,
|
|
93
|
+
args: [{ selector: 'nggv-typeahead-highlight', template: "<ng-container *ngIf=\"!this.match\">{{ textContent }}</ng-container>\n<!-- Note that this is sensitive to line breaks producing extra spacing between the different parts -->\n<ng-container *ngIf=\"!!this.match\">\n {{ prefix || '' }}<span class=\"match\">{{ match }}</span>{{ suffix ||''}}\n</ng-container>", styles: [":host .match{font-weight:500}\n"] }]
|
|
94
|
+
}], propDecorators: { textContent: [{
|
|
95
|
+
type: Input
|
|
96
|
+
}], textToHighlight: [{
|
|
97
|
+
type: Input
|
|
98
|
+
}] } });
|
|
99
|
+
|
|
100
|
+
class NgvDropdownListComponent {
|
|
101
|
+
set expanded(state) {
|
|
102
|
+
this.setExpanded(state);
|
|
103
|
+
}
|
|
104
|
+
get expanded() {
|
|
105
|
+
return this._expanded;
|
|
106
|
+
}
|
|
107
|
+
constructor(translocoScope) {
|
|
108
|
+
this.translocoScope = translocoScope;
|
|
109
|
+
/** The additional amount to show when option is scrolled into view. */
|
|
110
|
+
this.scrollOffset = 24;
|
|
111
|
+
/** Id of the host element and is accessible by the children, automatically generated if not provided. */
|
|
112
|
+
this.id = window.ngv?.nextId();
|
|
113
|
+
/** Special property used for selecting DOM elements during automated UI testing. */
|
|
114
|
+
this.thook = 'dropdown';
|
|
115
|
+
this.selectedValueChanged = new EventEmitter();
|
|
116
|
+
this.closed = new EventEmitter();
|
|
117
|
+
/** The current active option based on numeric index. */
|
|
118
|
+
this.activeIndex = -1;
|
|
119
|
+
this.dropdownUtils = new DropdownUtils();
|
|
120
|
+
this._expanded = false;
|
|
121
|
+
this.closed$ = new Subject();
|
|
122
|
+
if (this.translocoScope)
|
|
123
|
+
this.scope = this.translocoScope.toString();
|
|
124
|
+
}
|
|
125
|
+
ngOnInit() {
|
|
126
|
+
if (this.state)
|
|
127
|
+
this.activeIndex = this.options.findIndex((option) => option.key === this.state.key);
|
|
128
|
+
}
|
|
129
|
+
ngOnChanges(changes) {
|
|
130
|
+
if (!!changes.state && !changes.state.firstChange)
|
|
131
|
+
this.selectedValue = changes.state.currentValue;
|
|
132
|
+
if (!!changes.options?.currentValue?.length && this.expanded)
|
|
133
|
+
this.refreshSelectedOption();
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Returns true if argument is an {@link OptionGroup}.
|
|
137
|
+
* @param option the object to check.
|
|
138
|
+
*/
|
|
139
|
+
isGroup(option) {
|
|
140
|
+
return 'options' in option;
|
|
141
|
+
}
|
|
142
|
+
/** @internal */
|
|
143
|
+
updateState(option, event) {
|
|
144
|
+
if (option.disabled)
|
|
145
|
+
return;
|
|
146
|
+
this.selectedValue = option;
|
|
147
|
+
this.state = option;
|
|
148
|
+
this.selectedValueChanged.emit(option);
|
|
149
|
+
this.setExpanded(false);
|
|
150
|
+
event.stopPropagation();
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* @internal
|
|
154
|
+
*/
|
|
155
|
+
setExpanded(expanded = true) {
|
|
156
|
+
// update expanded state
|
|
157
|
+
this._expanded = expanded;
|
|
158
|
+
if (expanded)
|
|
159
|
+
this.refreshSelectedOption();
|
|
160
|
+
else {
|
|
161
|
+
this.closed$.next(true);
|
|
162
|
+
this.onClickSubscription?.unsubscribe();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* @internal
|
|
167
|
+
*/
|
|
168
|
+
refreshSelectedOption() {
|
|
169
|
+
const options = this.dropdownUtils.flattenOptions(this.options, !this.optionContentTpl);
|
|
170
|
+
this.activeIndex = this.getActiveIndex();
|
|
171
|
+
this.state = options[this.activeIndex];
|
|
172
|
+
this.scrollToResult(this.state);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* @internal
|
|
176
|
+
* @returns The active index (number) if option is found, -1 otherwise.
|
|
177
|
+
* - If a selectedValue exists that's not nullish and that options is found, return that index
|
|
178
|
+
* - Else, return first non nullish index
|
|
179
|
+
* - If none of the above criterias are met, -1 are returned
|
|
180
|
+
*/
|
|
181
|
+
getActiveIndex() {
|
|
182
|
+
if (!!this.selectedValue && this.selectedValue?.key != null) {
|
|
183
|
+
const selectedIndex = this.dropdownUtils
|
|
184
|
+
.flattenOptions(this.options, !this.optionContentTpl)
|
|
185
|
+
.findIndex((option) => option.key != null && option.key === this.selectedValue?.key);
|
|
186
|
+
if (selectedIndex > -1)
|
|
187
|
+
return selectedIndex;
|
|
188
|
+
}
|
|
189
|
+
return this.dropdownUtils
|
|
190
|
+
.flattenOptions(this.options, !this.optionContentTpl)
|
|
191
|
+
.findIndex((option) => option.key != null);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* @internal
|
|
195
|
+
* evaluates wether the HTML element overflows
|
|
196
|
+
* @param elem The HTMLElement to evaluate
|
|
197
|
+
* */
|
|
198
|
+
isOverflow(elem) {
|
|
199
|
+
return elem.offsetWidth < elem.scrollWidth;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Typecast anything to an {@link OptionGroup}.
|
|
203
|
+
* @param group the object to typecast.
|
|
204
|
+
*/
|
|
205
|
+
castGroup(group) {
|
|
206
|
+
return group;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* @internal
|
|
210
|
+
* Disables default events.
|
|
211
|
+
* @param event fired containing which key was pressed.
|
|
212
|
+
*/
|
|
213
|
+
onKeyDown(event) {
|
|
214
|
+
switch (event.key) {
|
|
215
|
+
case 'Enter': // Disable form submission
|
|
216
|
+
case 'ArrowUp': // Disable scrolling up
|
|
217
|
+
case 'ArrowDown': // Disable scrolling down
|
|
218
|
+
event.preventDefault();
|
|
219
|
+
event.stopPropagation();
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* @internal
|
|
226
|
+
* Enter toggles the dropdown, home, end, and, arrows change the index.
|
|
227
|
+
* @param event fired containing which key was released.
|
|
228
|
+
*/
|
|
229
|
+
onKeyUp(event) {
|
|
230
|
+
if (!this.expanded)
|
|
231
|
+
return;
|
|
232
|
+
const options = this.dropdownUtils.flattenOptions(this.options, !this.optionContentTpl);
|
|
233
|
+
let option;
|
|
234
|
+
switch (event.key) {
|
|
235
|
+
case 'Escape':
|
|
236
|
+
this.setExpanded(false);
|
|
237
|
+
this.closed.emit();
|
|
238
|
+
break;
|
|
239
|
+
case 'Enter': // Select the currently chosen value
|
|
240
|
+
option = options[this.activeIndex];
|
|
241
|
+
this.updateState(option, event);
|
|
242
|
+
break;
|
|
243
|
+
case 'Home': // Move to the first option
|
|
244
|
+
this.activeIndex = 0;
|
|
245
|
+
option = options[this.activeIndex];
|
|
246
|
+
this.state = option;
|
|
247
|
+
this.scrollToResult(option);
|
|
248
|
+
break;
|
|
249
|
+
case 'ArrowUp': // Move up one step to the previous option
|
|
250
|
+
if (this.activeIndex > 0)
|
|
251
|
+
this.activeIndex--;
|
|
252
|
+
else if (this.activeIndex === 0)
|
|
253
|
+
this.activeIndex = options.length - 1;
|
|
254
|
+
option = options[this.activeIndex];
|
|
255
|
+
this.state = option;
|
|
256
|
+
this.scrollToResult(option);
|
|
257
|
+
break;
|
|
258
|
+
case 'ArrowDown': // Move down one step to the next option
|
|
259
|
+
if (options.length > this.activeIndex + 1)
|
|
260
|
+
this.activeIndex++;
|
|
261
|
+
else if (this.activeIndex === options.length - 1)
|
|
262
|
+
this.activeIndex = 0;
|
|
263
|
+
option = options[this.activeIndex];
|
|
264
|
+
this.state = option;
|
|
265
|
+
this.scrollToResult(option);
|
|
266
|
+
break;
|
|
267
|
+
case 'End': // Move to the last options
|
|
268
|
+
this.activeIndex = options.length - 1;
|
|
269
|
+
option = options[this.activeIndex];
|
|
270
|
+
this.state = option;
|
|
271
|
+
this.scrollToResult(option);
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Scrolls focused result into view with a specified offset.
|
|
277
|
+
* @param key the result index which to scroll to.
|
|
278
|
+
*/
|
|
279
|
+
scrollToResult(option) {
|
|
280
|
+
if (!this.optionRefs || !option)
|
|
281
|
+
return;
|
|
282
|
+
const optionRef = this.optionRefs.find((li) => li.nativeElement.id === this.id + '-option-' + option.key);
|
|
283
|
+
const offset = this.scrollOffset;
|
|
284
|
+
if (optionRef) {
|
|
285
|
+
let delta = window.scrollY || document.documentElement.scrollTop;
|
|
286
|
+
// The list seems not to be visible at the time of scrolling, but this setTimeout "hack" makes it work...
|
|
287
|
+
setTimeout(() => {
|
|
288
|
+
scrollIntoView(optionRef.nativeElement, {
|
|
289
|
+
scrollMode: 'if-needed',
|
|
290
|
+
block: 'nearest',
|
|
291
|
+
});
|
|
292
|
+
delta -= window.scrollY || document.documentElement.scrollTop;
|
|
293
|
+
if (delta)
|
|
294
|
+
window.scrollBy(0, delta > 0 ? -offset : offset);
|
|
295
|
+
}, 0);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgvDropdownListComponent, deps: [{ token: TRANSLOCO_SCOPE, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
299
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgvDropdownListComponent, selector: "nggv-dropdown-list", inputs: { expanded: "expanded", state: "state", scrollOffset: "scrollOffset", optionContentTpl: "optionContentTpl", id: "id", thook: "thook", options: "options", textToHighlight: "textToHighlight" }, outputs: { selectedValueChanged: "selectedValueChanged", closed: "closed" }, host: { listeners: { "document:keydown": "onKeyDown($event)", "document:keyup": "onKeyUp($event)" }, properties: { "attr.id": "this.id", "attr.data-thook": "this.thook" } }, viewQueries: [{ propertyName: "optionRefs", predicate: ["optionRefs"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-container *transloco=\"let t; read: scope\">\n <ul\n class=\"gds-dropdown__options card options gds-reset\"\n [class.gds-dropdown__options-expanded]=\"expanded\"\n role=\"listbox\"\n tabindex=\"-1\"\n [attr.data-thook]=\"thook + '-options'\"\n [attr.aria-labelledby]=\"id + '-label'\"\n [attr.aria-activedescendant]=\"\n state ? id + '-option-' + state?.key : undefined\n \"\n >\n <ng-container *ngFor=\"let item of options\">\n <!-- OPTION -->\n <ng-container *ngIf=\"!isGroup(item)\">\n <ng-template\n *ngTemplateOutlet=\"listItemTemplate; context: { $implicit: item }\"\n ></ng-template>\n </ng-container>\n\n <!-- OPTION GROUP -->\n <li\n class=\"gds-dropdown__options__label group\"\n [attr.data-thook]=\"thook + '-option-group'\"\n *ngIf=\"isGroup(item)\"\n >\n <div class=\"sdv-list__label\">{{ t(item.label) }}</div>\n <ul [attr.aria-disabled]=\"item.disabled\">\n <ng-container *ngFor=\"let option of castGroup(item).options\">\n <ng-template\n *ngTemplateOutlet=\"\n listItemTemplate;\n context: { $implicit: option }\n \"\n ></ng-template>\n </ng-container>\n </ul>\n </li>\n </ng-container>\n </ul>\n\n <!-- TEMPLATE -->\n <ng-template #listItemTemplate let-option>\n <li\n #optionRefs\n *ngIf=\"!optionContentTpl\"\n tabindex=\"-1\"\n [id]=\"id + '-option-' + option.key\"\n class=\"gds-dropdown__options__label option\"\n role=\"option\"\n #liElem\n [attr.data-thook]=\"thook + '-option-' + option.key\"\n [attr.aria-disabled]=\"option.disabled\"\n [attr.aria-selected]=\"\n option.key === selectedValue?.key && !!selectedValue?.key\n \"\n [attr.aria-focus]=\"option.key === state?.key && !option.disabled\"\n [ngvTooltip]=\"isOverflow(liElem) ? t(option.label) : undefined\"\n (click)=\"updateState(option, $event)\"\n >\n <ng-template\n *ngTemplateOutlet=\"\n basicOptionContentTpl;\n context: { $implicit: option }\n \"\n >\n </ng-template>\n </li>\n <!-- Checking overflow on custom templates do not work skip adding ngvToolTip if custom template is provided -->\n <li\n #optionRefs\n *ngIf=\"!!optionContentTpl\"\n tabindex=\"-1\"\n [id]=\"id + '-option-' + option.key\"\n class=\"gds-dropdown__options__label option\"\n role=\"option\"\n #liElem\n [attr.data-thook]=\"thook + '-option-' + option.key\"\n [attr.aria-disabled]=\"option.disabled\"\n [attr.aria-selected]=\"\n option.key === selectedValue?.key && !!selectedValue?.key\n \"\n [attr.aria-focus]=\"option.key === state?.key && !option.disabled\"\n (click)=\"updateState(option, $event)\"\n >\n <ng-template\n *ngTemplateOutlet=\"optionContentTpl; context: { $implicit: option }\"\n >\n </ng-template>\n </li>\n </ng-template>\n\n <ng-template #basicOptionContentTpl let-option>\n <nggv-typeahead-highlight\n *ngIf=\"!!textToHighlight\"\n [textToHighlight]=\"textToHighlight\"\n [textContent]=\"t(option.label)\"\n >\n </nggv-typeahead-highlight>\n <ng-container *ngIf=\"!textToHighlight\">\n {{ t(option.label) }}\n </ng-container>\n </ng-template>\n</ng-container>\n", styles: [":host{position:absolute;bottom:0;transform:translateY(calc(100% + .5rem));--z-index: var(--sg-z-index-dropdown)}:host .hidden{visibility:hidden;display:none}:host ul[role=menu] [role=menuitem]{padding:.75rem;cursor:pointer}:host ul[role=menu] [role=menuitem]:hover,:host ul[role=menu] [role=menuitem]:focus-visible{background-color:var(--gds-ref-pallet-base200)}:host ul[role=menu] [role=menuitem]:active{background-color:var(--gds-ref-pallet-base300)}:host ul[role=menu] [role=menuitem]:focus{outline-color:#000;outline-offset:-.25rem}:host ul[role=listbox]{--z-index: var(--sg-z-index-popover);background-color:var(--sg-popover-background);flex-direction:column;justify-content:flex-end;inset:auto;z-index:var(--z-index);box-shadow:var(--sg-popover-box-shadow);color:var(--text-primary-color);padding:0;border:solid var(--sg-border-width) var(--sg-border-color);--border-color: var(--text-primary-color);--sg-border-color: var(--text-primary-color);border-radius:var(--sg-border-radius)}:host ul[role=listbox] [role=option]{padding:.75rem 1rem;line-height:1.25;cursor:pointer}:host ul[role=listbox] [role=option]:hover,:host ul[role=listbox] [role=option]:focus-visible{background-color:var(--grey-400)}:host ul[role=listbox] [role=option]:active{background-color:var(--grey-400)}:host ul[role=listbox] [role=option]:focus{outline-color:#000;outline-offset:-.25rem}:host ul[role=listbox] [role=option].active.sg-highlighted,:host ul[role=listbox] [role=option][aria-selected=true]{background:var(--grey-1000);color:#fff}:host .sg-fieldset-container{overflow-y:auto}:host .sg-fieldset-container fieldset[role=listbox][aria-multiselectable=true] [role=option]{display:flex;width:100%}:host .sg-fieldset-container fieldset[role=listbox][aria-multiselectable=true] [role=option].active.sg-highlighted input[type=checkbox]~i{border-color:#007ac7!important;box-shadow:0 0 .25em .0625em #41b0ee;outline-color:transparent;outline-style:solid}:host .gds-dropdown__options{padding-left:0;margin-bottom:0;margin-top:0;display:flex;flex-direction:column;list-style:none;display:none}:host .gds-dropdown__options>li{padding-bottom:.5rem;padding-top:.5rem;border:0;display:block;position:relative}:host .gds-dropdown__options>li:before{font-weight:500;display:inline-block;left:0;position:absolute;text-align:center}:host .gds-dropdown__options-expanded{display:block}:host .gds-dropdown__options__label:hover,:host .gds-dropdown__options__label:focus-visible{background-color:var(--grey-400)}:host .gds-dropdown__options__label:active{background-color:var(--grey-500)}:host .gds-dropdown__options__label:focus-visible{outline-color:#000;outline-offset:-.25rem}:host .gds-dropdown__options__label[aria-hidden=true]{display:none}:host .gds-dropdown__options__label[highlighted]{color:#fff}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NgvTypeaheadHighlightComponent, selector: "nggv-typeahead-highlight", inputs: ["textContent", "textToHighlight"] }, { kind: "directive", type: i3.NgvTooltipDirective, selector: "[ngvTooltip]", inputs: ["ngvTooltip", "thook", "placement", "shown", "offset", "resizeThrottle", "maxWidth"], outputs: ["ngvShow", "ngvHide"] }, { kind: "directive", type: i4.TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoLang", "translocoLoadingTpl"] }] }); }
|
|
300
|
+
}
|
|
301
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgvDropdownListComponent, decorators: [{
|
|
302
|
+
type: Component,
|
|
303
|
+
args: [{ selector: 'nggv-dropdown-list', template: "<ng-container *transloco=\"let t; read: scope\">\n <ul\n class=\"gds-dropdown__options card options gds-reset\"\n [class.gds-dropdown__options-expanded]=\"expanded\"\n role=\"listbox\"\n tabindex=\"-1\"\n [attr.data-thook]=\"thook + '-options'\"\n [attr.aria-labelledby]=\"id + '-label'\"\n [attr.aria-activedescendant]=\"\n state ? id + '-option-' + state?.key : undefined\n \"\n >\n <ng-container *ngFor=\"let item of options\">\n <!-- OPTION -->\n <ng-container *ngIf=\"!isGroup(item)\">\n <ng-template\n *ngTemplateOutlet=\"listItemTemplate; context: { $implicit: item }\"\n ></ng-template>\n </ng-container>\n\n <!-- OPTION GROUP -->\n <li\n class=\"gds-dropdown__options__label group\"\n [attr.data-thook]=\"thook + '-option-group'\"\n *ngIf=\"isGroup(item)\"\n >\n <div class=\"sdv-list__label\">{{ t(item.label) }}</div>\n <ul [attr.aria-disabled]=\"item.disabled\">\n <ng-container *ngFor=\"let option of castGroup(item).options\">\n <ng-template\n *ngTemplateOutlet=\"\n listItemTemplate;\n context: { $implicit: option }\n \"\n ></ng-template>\n </ng-container>\n </ul>\n </li>\n </ng-container>\n </ul>\n\n <!-- TEMPLATE -->\n <ng-template #listItemTemplate let-option>\n <li\n #optionRefs\n *ngIf=\"!optionContentTpl\"\n tabindex=\"-1\"\n [id]=\"id + '-option-' + option.key\"\n class=\"gds-dropdown__options__label option\"\n role=\"option\"\n #liElem\n [attr.data-thook]=\"thook + '-option-' + option.key\"\n [attr.aria-disabled]=\"option.disabled\"\n [attr.aria-selected]=\"\n option.key === selectedValue?.key && !!selectedValue?.key\n \"\n [attr.aria-focus]=\"option.key === state?.key && !option.disabled\"\n [ngvTooltip]=\"isOverflow(liElem) ? t(option.label) : undefined\"\n (click)=\"updateState(option, $event)\"\n >\n <ng-template\n *ngTemplateOutlet=\"\n basicOptionContentTpl;\n context: { $implicit: option }\n \"\n >\n </ng-template>\n </li>\n <!-- Checking overflow on custom templates do not work skip adding ngvToolTip if custom template is provided -->\n <li\n #optionRefs\n *ngIf=\"!!optionContentTpl\"\n tabindex=\"-1\"\n [id]=\"id + '-option-' + option.key\"\n class=\"gds-dropdown__options__label option\"\n role=\"option\"\n #liElem\n [attr.data-thook]=\"thook + '-option-' + option.key\"\n [attr.aria-disabled]=\"option.disabled\"\n [attr.aria-selected]=\"\n option.key === selectedValue?.key && !!selectedValue?.key\n \"\n [attr.aria-focus]=\"option.key === state?.key && !option.disabled\"\n (click)=\"updateState(option, $event)\"\n >\n <ng-template\n *ngTemplateOutlet=\"optionContentTpl; context: { $implicit: option }\"\n >\n </ng-template>\n </li>\n </ng-template>\n\n <ng-template #basicOptionContentTpl let-option>\n <nggv-typeahead-highlight\n *ngIf=\"!!textToHighlight\"\n [textToHighlight]=\"textToHighlight\"\n [textContent]=\"t(option.label)\"\n >\n </nggv-typeahead-highlight>\n <ng-container *ngIf=\"!textToHighlight\">\n {{ t(option.label) }}\n </ng-container>\n </ng-template>\n</ng-container>\n", styles: [":host{position:absolute;bottom:0;transform:translateY(calc(100% + .5rem));--z-index: var(--sg-z-index-dropdown)}:host .hidden{visibility:hidden;display:none}:host ul[role=menu] [role=menuitem]{padding:.75rem;cursor:pointer}:host ul[role=menu] [role=menuitem]:hover,:host ul[role=menu] [role=menuitem]:focus-visible{background-color:var(--gds-ref-pallet-base200)}:host ul[role=menu] [role=menuitem]:active{background-color:var(--gds-ref-pallet-base300)}:host ul[role=menu] [role=menuitem]:focus{outline-color:#000;outline-offset:-.25rem}:host ul[role=listbox]{--z-index: var(--sg-z-index-popover);background-color:var(--sg-popover-background);flex-direction:column;justify-content:flex-end;inset:auto;z-index:var(--z-index);box-shadow:var(--sg-popover-box-shadow);color:var(--text-primary-color);padding:0;border:solid var(--sg-border-width) var(--sg-border-color);--border-color: var(--text-primary-color);--sg-border-color: var(--text-primary-color);border-radius:var(--sg-border-radius)}:host ul[role=listbox] [role=option]{padding:.75rem 1rem;line-height:1.25;cursor:pointer}:host ul[role=listbox] [role=option]:hover,:host ul[role=listbox] [role=option]:focus-visible{background-color:var(--grey-400)}:host ul[role=listbox] [role=option]:active{background-color:var(--grey-400)}:host ul[role=listbox] [role=option]:focus{outline-color:#000;outline-offset:-.25rem}:host ul[role=listbox] [role=option].active.sg-highlighted,:host ul[role=listbox] [role=option][aria-selected=true]{background:var(--grey-1000);color:#fff}:host .sg-fieldset-container{overflow-y:auto}:host .sg-fieldset-container fieldset[role=listbox][aria-multiselectable=true] [role=option]{display:flex;width:100%}:host .sg-fieldset-container fieldset[role=listbox][aria-multiselectable=true] [role=option].active.sg-highlighted input[type=checkbox]~i{border-color:#007ac7!important;box-shadow:0 0 .25em .0625em #41b0ee;outline-color:transparent;outline-style:solid}:host .gds-dropdown__options{padding-left:0;margin-bottom:0;margin-top:0;display:flex;flex-direction:column;list-style:none;display:none}:host .gds-dropdown__options>li{padding-bottom:.5rem;padding-top:.5rem;border:0;display:block;position:relative}:host .gds-dropdown__options>li:before{font-weight:500;display:inline-block;left:0;position:absolute;text-align:center}:host .gds-dropdown__options-expanded{display:block}:host .gds-dropdown__options__label:hover,:host .gds-dropdown__options__label:focus-visible{background-color:var(--grey-400)}:host .gds-dropdown__options__label:active{background-color:var(--grey-500)}:host .gds-dropdown__options__label:focus-visible{outline-color:#000;outline-offset:-.25rem}:host .gds-dropdown__options__label[aria-hidden=true]{display:none}:host .gds-dropdown__options__label[highlighted]{color:#fff}\n"] }]
|
|
304
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
305
|
+
type: Optional
|
|
306
|
+
}, {
|
|
307
|
+
type: Inject,
|
|
308
|
+
args: [TRANSLOCO_SCOPE]
|
|
309
|
+
}] }]; }, propDecorators: { expanded: [{
|
|
310
|
+
type: Input
|
|
311
|
+
}], state: [{
|
|
312
|
+
type: Input
|
|
313
|
+
}], scrollOffset: [{
|
|
314
|
+
type: Input
|
|
315
|
+
}], optionContentTpl: [{
|
|
316
|
+
type: Input
|
|
317
|
+
}], optionRefs: [{
|
|
318
|
+
type: ViewChildren,
|
|
319
|
+
args: ['optionRefs']
|
|
320
|
+
}], id: [{
|
|
321
|
+
type: HostBinding,
|
|
322
|
+
args: ['attr.id']
|
|
323
|
+
}, {
|
|
324
|
+
type: Input
|
|
325
|
+
}], thook: [{
|
|
326
|
+
type: HostBinding,
|
|
327
|
+
args: ['attr.data-thook']
|
|
328
|
+
}, {
|
|
329
|
+
type: Input
|
|
330
|
+
}], options: [{
|
|
331
|
+
type: Input
|
|
332
|
+
}], textToHighlight: [{
|
|
333
|
+
type: Input
|
|
334
|
+
}], selectedValueChanged: [{
|
|
335
|
+
type: Output
|
|
336
|
+
}], closed: [{
|
|
337
|
+
type: Output
|
|
338
|
+
}], onKeyDown: [{
|
|
339
|
+
type: HostListener,
|
|
340
|
+
args: ['document:keydown', ['$event']]
|
|
341
|
+
}], onKeyUp: [{
|
|
342
|
+
type: HostListener,
|
|
343
|
+
args: ['document:keyup', ['$event']]
|
|
344
|
+
}] } });
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* A dropdown allows the user to select an option from a list.
|
|
348
|
+
* Dropdowns enables users to make a quick selection of the available options for a specific entry.
|
|
349
|
+
* https://designlibrary.sebgroup.com/components/component-dropdown
|
|
350
|
+
*/
|
|
351
|
+
class NgvDropdownComponent extends NgvBaseControlValueAccessorComponent {
|
|
352
|
+
/** List of {@link Option} and {@link OptionGroup} listed when dropdown is expanded. */
|
|
353
|
+
set options(value) {
|
|
354
|
+
// update options
|
|
355
|
+
this._options = value;
|
|
356
|
+
// already has a null/undefined key
|
|
357
|
+
const nullishOption = this.dropdownUtils
|
|
358
|
+
.flattenOptions(value, false)
|
|
359
|
+
.find((option) => option.key == null);
|
|
360
|
+
// if the dropdown is optional, add a null value to deselect option
|
|
361
|
+
if (!this.required && !nullishOption && this.allowControlNullishOption) {
|
|
362
|
+
this._options = [this.defaultNullishOption].concat(this._options);
|
|
363
|
+
}
|
|
364
|
+
// set default value and emit if there is only one option
|
|
365
|
+
if (value.length === 1 && this.required && this.selectOnSingleOption) {
|
|
366
|
+
const onlyOption = this.dropdownUtils.flattenOptions(value, false)[0];
|
|
367
|
+
this.updateModel(onlyOption);
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
// don't update local state if we shouldn't control nullish value and we cant find the selected value amongst the options
|
|
371
|
+
const matchingOption = this.dropdownUtils
|
|
372
|
+
.flattenOptions(value, false)
|
|
373
|
+
.find((option) => option.key == this.ngControl?.value);
|
|
374
|
+
if (!this.allowControlNullishOption && !matchingOption)
|
|
375
|
+
return;
|
|
376
|
+
// Update local state
|
|
377
|
+
this.writeValue(this.ngControl?.value);
|
|
378
|
+
}
|
|
379
|
+
get options() {
|
|
380
|
+
return this._options;
|
|
381
|
+
}
|
|
382
|
+
/** @internal nullish option. */
|
|
383
|
+
get defaultNullishOption() {
|
|
384
|
+
return { key: null, label: this.placeholder ?? '\u00A0' };
|
|
385
|
+
}
|
|
386
|
+
constructor(ngControl, translocoScope, cdr, dropdownUtils) {
|
|
387
|
+
super(ngControl, translocoScope, cdr);
|
|
388
|
+
this.ngControl = ngControl;
|
|
389
|
+
this.translocoScope = translocoScope;
|
|
390
|
+
this.cdr = cdr;
|
|
391
|
+
this.dropdownUtils = dropdownUtils;
|
|
392
|
+
/** Special property used for selecting DOM elements during automated UI testing. */
|
|
393
|
+
this.thook = 'dropdown';
|
|
394
|
+
/** The additional amount to show when option is scrolled into view. */
|
|
395
|
+
this.scrollOffset = 24;
|
|
396
|
+
/**
|
|
397
|
+
* Allow this component to add/ remove nullish options based on wether the control is required or not
|
|
398
|
+
* Defaults to true.
|
|
399
|
+
*/
|
|
400
|
+
this.allowControlNullishOption = true;
|
|
401
|
+
/**
|
|
402
|
+
* If only one option exists in options[], default is to select it.
|
|
403
|
+
* This input can be used to alter that behaviour so it doesn't automatically
|
|
404
|
+
* select a value if it's the only one.
|
|
405
|
+
* Defaults to true.
|
|
406
|
+
*/
|
|
407
|
+
this.selectOnSingleOption = true;
|
|
408
|
+
/**
|
|
409
|
+
* Emits changes of the expanded state of the dropdown
|
|
410
|
+
*/
|
|
411
|
+
this.expandedChange = new EventEmitter();
|
|
412
|
+
/** The current expanded state of the dropdown options. */
|
|
413
|
+
this.expanded = false;
|
|
414
|
+
/** The current option selected based on numeric index. */
|
|
415
|
+
this.activeIndex = -1;
|
|
416
|
+
this.keyEvent = {};
|
|
417
|
+
this._options = [];
|
|
418
|
+
}
|
|
419
|
+
ngOnChanges(changes) {
|
|
420
|
+
if (changes.required?.currentValue !== undefined) {
|
|
421
|
+
const isRequired = changes.required.currentValue;
|
|
422
|
+
// remove nullish option
|
|
423
|
+
const hasNullishOption = this.dropdownUtils.flattenOptions(this._options, false)[0]?.key == null;
|
|
424
|
+
// if required, remove nullish option
|
|
425
|
+
if (isRequired && hasNullishOption && this.allowControlNullishOption) {
|
|
426
|
+
this._options = this._options.slice(1);
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
// if not required, add nullish option
|
|
430
|
+
if (!isRequired && !hasNullishOption && this.allowControlNullishOption) {
|
|
431
|
+
this._options = [this.defaultNullishOption].concat(this._options);
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
ngOnDestroy() {
|
|
437
|
+
this.onClickSubscription?.unsubscribe();
|
|
438
|
+
}
|
|
439
|
+
/** @internal override to correctly set state from form value */
|
|
440
|
+
writeValue(value) {
|
|
441
|
+
const options = this.dropdownUtils.flattenOptions(this._options, false);
|
|
442
|
+
this.state = options.find((option) => option.key === value);
|
|
443
|
+
}
|
|
444
|
+
// ----------------------------------------------------------------------------
|
|
445
|
+
// EVENTS
|
|
446
|
+
// ----------------------------------------------------------------------------
|
|
447
|
+
/** @internal */
|
|
448
|
+
onSelectChange(option) {
|
|
449
|
+
if (option.disabled)
|
|
450
|
+
return;
|
|
451
|
+
this.updateModel(option);
|
|
452
|
+
this.setExpanded(false);
|
|
453
|
+
}
|
|
454
|
+
// /**
|
|
455
|
+
// * @internal
|
|
456
|
+
// * Enter toggles the dropdown, home, end, and, arrows change the index.
|
|
457
|
+
// * @param event fired containing which key was released.
|
|
458
|
+
// */
|
|
459
|
+
onKeyUp(event) {
|
|
460
|
+
this.keyEvent = event;
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Closes the dropdown on click outside.
|
|
464
|
+
*/
|
|
465
|
+
subscribeToOutsideClickEvent() {
|
|
466
|
+
this.onClickSubscription = fromEvent(document, 'click').subscribe({
|
|
467
|
+
next: (event) => {
|
|
468
|
+
if (this.expanded &&
|
|
469
|
+
!this.inputRef?.nativeElement.contains(event.target)) {
|
|
470
|
+
this.toggleDropdown();
|
|
471
|
+
this.onClickSubscription?.unsubscribe();
|
|
472
|
+
}
|
|
473
|
+
},
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
// ----------------------------------------------------------------------------
|
|
477
|
+
// HELPERS
|
|
478
|
+
// ----------------------------------------------------------------------------
|
|
479
|
+
/**
|
|
480
|
+
* Set the dropdown value to given option.
|
|
481
|
+
* @param value the dropdown option to select.
|
|
482
|
+
*/
|
|
483
|
+
updateModel(value) {
|
|
484
|
+
this.state = value;
|
|
485
|
+
this.onChange(value.key);
|
|
486
|
+
}
|
|
487
|
+
/** Toggle the expanded state of the dropdown options. */
|
|
488
|
+
toggleDropdown() {
|
|
489
|
+
this.setExpanded(!this.expanded);
|
|
490
|
+
this.cdr.detectChanges();
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Set the expanded state of the dropdown options. If true the options are shown below the field.
|
|
494
|
+
* Activate on click event to be able to close dropdown on click outside.
|
|
495
|
+
* @param state the expanded state which to set.
|
|
496
|
+
*/
|
|
497
|
+
setExpanded(state = true) {
|
|
498
|
+
this.expanded = state;
|
|
499
|
+
this.expandedChange.emit(this.expanded);
|
|
500
|
+
if (this.expanded)
|
|
501
|
+
this.subscribeToOutsideClickEvent();
|
|
502
|
+
if (!this.expanded)
|
|
503
|
+
this.onTouched();
|
|
504
|
+
}
|
|
505
|
+
/* TYPE CASTS */
|
|
506
|
+
/**
|
|
507
|
+
* Typecast anything to an {@link Option}.
|
|
508
|
+
* @param option the object to typecast.
|
|
509
|
+
*/
|
|
510
|
+
castOption(option) {
|
|
511
|
+
return option;
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Typecast anything to an {@link OptionGroup}.
|
|
515
|
+
* @param group the object to typecast.
|
|
516
|
+
*/
|
|
517
|
+
castGroup(group) {
|
|
518
|
+
return group;
|
|
519
|
+
}
|
|
520
|
+
/* TYPE CHECKS */
|
|
521
|
+
/**
|
|
522
|
+
* Returns true if argument is an {@link Option}.
|
|
523
|
+
* @param option the object to check.
|
|
524
|
+
*/
|
|
525
|
+
isOption(option) {
|
|
526
|
+
return !('options' in option);
|
|
527
|
+
}
|
|
528
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgvDropdownComponent, deps: [{ token: i1$1.NgControl, optional: true, self: true }, { token: TRANSLOCO_SCOPE, optional: true }, { token: i0.ChangeDetectorRef }, { token: i2.DropdownUtils }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
529
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgvDropdownComponent, selector: "nggv-dropdown", inputs: { thook: "thook", placeholder: "placeholder", options: "options", scrollOffset: "scrollOffset", allowControlNullishOption: "allowControlNullishOption", textToHighlight: "textToHighlight", selectOnSingleOption: "selectOnSingleOption" }, outputs: { expandedChange: "expandedChange" }, host: { listeners: { "keyup": "onKeyUp($event)" }, properties: { "attr.data-thook": "this.thook" } }, queries: [{ propertyName: "selectedContentTpl", first: true, predicate: ["selectedTpl"], descendants: true, read: TemplateRef }, { propertyName: "optionContentTpl", first: true, predicate: ["optionTpl"], descendants: true, read: TemplateRef }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<!-- LABEL -->\n<ng-container *transloco=\"let t; read: scope\">\n <label [id]=\"id + '-label'\" class=\"hide-if-empty\" [attr.for]=\"id + '-toggle'\">\n <ng-template\n *ngTemplateOutlet=\"labelContentTpl || basicLabelContentTpl\"\n ></ng-template>\n <ng-template #basicLabelContentTpl>\n <!-- to trigger css:empty if no label was added -->\n <ng-container *ngIf=\"label\">\n {{ label }}\n <span\n *ngIf=\"optional === true || (required !== true && optional !== false)\"\n class=\"sdv-field-label--optional\"\n >\n ({{ t('label.optional') }})\n </span>\n </ng-container>\n </ng-template>\n </label>\n\n <!-- DESCRIPTION -->\n <div class=\"description\">{{ description }}</div>\n\n <!-- LOCKED INPUT -->\n <ng-container *ngIf=\"locked\">\n <div\n [id]=\"id + '-input'\"\n class=\"nggv-field--locked\"\n [attr.name]=\"name\"\n [attr.value]=\"state\"\n [attr.role]=\"role\"\n [attr.aria-labelledby]=\"id + '-label ' + id + '-input'\"\n >\n <span *ngIf=\"!state\" class=\"unset-state\">-</span>\n <ng-container *ngIf=\"state\">\n <ng-template\n *ngTemplateOutlet=\"\n selectedContentTpl || defaultSelectedContentTpl;\n context: { $implicit: state }\n \"\n >\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- INPUT -->\n <ng-container *ngIf=\"!locked\">\n <div #input [id]=\"id + '-input'\" class=\"dropdown\">\n <button\n [id]=\"id + '-toggle'\"\n [disabled]=\"disabled\"\n type=\"button\"\n class=\"nggv-field-dropdown__label toggle\"\n [class.nggv-field--error]=\"invalid\"\n aria-haspopup=\"listbox\"\n [attr.data-thook]=\"thook + '-toggle'\"\n [attr.aria-expanded]=\"expanded\"\n [attr.aria-labelledby]=\"id + '-label ' + id + '-toggle'\"\n (click)=\"toggleDropdown()\"\n >\n <ng-template\n *ngTemplateOutlet=\"\n selectedContentTpl || defaultSelectedContentTpl;\n context: { $implicit: state }\n \"\n >\n </ng-template>\n </button>\n\n <nggv-dropdown-list\n #dropDownList\n [options]=\"options\"\n [scrollOffset]=\"scrollOffset\"\n [state]=\"state\"\n [expanded]=\"expanded\"\n [optionContentTpl]=\"optionContentTpl\"\n [textToHighlight]=\"textToHighlight\"\n (selectedValueChanged)=\"onSelectChange($event)\"\n >\n </nggv-dropdown-list>\n </div>\n <!-- ERRORS -->\n <label\n class=\"sdv-field-notice sdv-field-notice--error\"\n [attr.for]=\"id + '-input'\"\n *ngIf=\"invalid && (error || ngControl?.invalid)\"\n >\n <span *ngIf=\"error; else errorsRef\">{{ error }}</span>\n <ng-template #errorsRef>\n <span *ngIf=\"firstError as error\">\n {{ t('error.field' + error?.code, error?.params) }}\n </span>\n </ng-template>\n </label>\n\n <!-- CHILDREN -->\n <ng-content></ng-content>\n </ng-container>\n\n <ng-template #defaultSelectedContentTpl let-state>\n <!-- eslint-disable-next-line @angular-eslint/template/eqeqeq -->\n {{ state?.key != null && state?.label ? t(state.label) : placeholder }}\n </ng-template>\n</ng-container>\n", styles: [":host label{display:block;font-weight:500;line-height:1.25rem;margin-bottom:.5rem;width:100%}:host .description{margin-bottom:.5rem;line-height:1.25rem;width:100%}:host button{font-weight:500;display:inline-flex;justify-content:center;transition:all .3s cubic-bezier(.23,1,.32,1),outline-offset 0s,outline-width 0s;background:transparent;border-color:#007ac7;color:#007ac7;--color: rgb(0, 122, 199);background-color:transparent;border:0;cursor:pointer;font-family:inherit;padding:0;padding:.75rem 1rem;border-radius:var(--sg-border-radius);border:solid var(--sg-border-width) var(--sg-border-color);--border-color: var(--grey-800);--sg-border-color: var(--grey-800);background:var(--sg-form-control-bg);color:var(--text-primary-color);min-height:2.75rem;display:flex;flex-wrap:nowrap;justify-content:space-between;align-items:center;max-width:100%;font-size:inherit;font-weight:400;line-height:1.125;margin-bottom:.5rem;margin-top:.5rem;width:100%}@media screen and (-ms-high-contrast: active){:host button{border:2px solid currentcolor}}:host button.small{min-height:2rem;padding:.4375rem .75rem;line-height:1rem}:host button.large{min-height:4rem;padding:1rem 1.5rem;font-size:1.5rem;line-height:2rem}:host button:focus:not(:focus-visible){box-shadow:none;outline:0}:host button:focus,:host button:focus-visible{outline-color:var(--gds-sys-color-focus-outline);outline-style:solid;outline-width:.125rem;outline-offset:.125rem}:host button:not(:disabled,.disabled,[aria-disabled]):hover{background-color:#199be3;color:#fff;--background: #199be3;--color: rgb(255, 255, 255);border-color:#199be3}:host button[aria-selected=true],:host button:active,:host button.active,:host button.active:hover,:host button:active:hover{background-color:#007ac7;color:#fff;--background: rgb(0, 122, 199);--color: rgb(255, 255, 255);border-color:#007ac7}:host button:disabled,:host button.disabled,:host button[aria-disabled=true]{background:var(--sg-form-control-bg-disabled)!important;color:var(--text-disabled-color)!important;border-color:var(--border-disabled-color)!important;cursor:not-allowed}:host button:disabled::placeholder,:host button.disabled::placeholder,:host button[aria-disabled=true]::placeholder{color:var(--text-disabled-color)}:host button:focus{outline-color:var(--gds-sys-color-focus-outline);outline-style:solid;outline-width:.125rem;outline-offset:.125rem}@media (max-width: 35.98em){:host button{min-width:100%}}:host button:not(:disabled,.disabled,[aria-disabled]):hover{--background: var(--grey-400);--color: var(--grey-1000);background-color:var(--grey-400);color:var(--grey-1000);border-color:var(--grey-1000)}:host button>span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host button:after{margin-left:.5rem;margin-right:.5rem;border-bottom:solid 2px var(--text-primary-color);border-left:solid 2px var(--text-primary-color);content:\"\";display:block;height:.5rem;width:.5rem;position:relative;top:-.15rem;transform:translate(75%) rotate3d(0,0,1,-45deg) scaleZ(-1);transition:transform .3s ease-in;flex-shrink:0}:host button[aria-expanded=true]:after{transform:translate(75%,6px) rotate3d(0,0,1,-45deg) scale3d(-1,-1,1)}:host button:hover:after{border-color:currentColor}:host button.small{font-size:.875rem}:host button:hover{background:var(--grey-400)}:host .dropdown{position:relative}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i4.TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: NgvDropdownListComponent, selector: "nggv-dropdown-list", inputs: ["expanded", "state", "scrollOffset", "optionContentTpl", "id", "thook", "options", "textToHighlight"], outputs: ["selectedValueChanged", "closed"] }] }); }
|
|
530
|
+
}
|
|
531
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgvDropdownComponent, decorators: [{
|
|
532
|
+
type: Component,
|
|
533
|
+
args: [{ selector: 'nggv-dropdown', template: "<!-- LABEL -->\n<ng-container *transloco=\"let t; read: scope\">\n <label [id]=\"id + '-label'\" class=\"hide-if-empty\" [attr.for]=\"id + '-toggle'\">\n <ng-template\n *ngTemplateOutlet=\"labelContentTpl || basicLabelContentTpl\"\n ></ng-template>\n <ng-template #basicLabelContentTpl>\n <!-- to trigger css:empty if no label was added -->\n <ng-container *ngIf=\"label\">\n {{ label }}\n <span\n *ngIf=\"optional === true || (required !== true && optional !== false)\"\n class=\"sdv-field-label--optional\"\n >\n ({{ t('label.optional') }})\n </span>\n </ng-container>\n </ng-template>\n </label>\n\n <!-- DESCRIPTION -->\n <div class=\"description\">{{ description }}</div>\n\n <!-- LOCKED INPUT -->\n <ng-container *ngIf=\"locked\">\n <div\n [id]=\"id + '-input'\"\n class=\"nggv-field--locked\"\n [attr.name]=\"name\"\n [attr.value]=\"state\"\n [attr.role]=\"role\"\n [attr.aria-labelledby]=\"id + '-label ' + id + '-input'\"\n >\n <span *ngIf=\"!state\" class=\"unset-state\">-</span>\n <ng-container *ngIf=\"state\">\n <ng-template\n *ngTemplateOutlet=\"\n selectedContentTpl || defaultSelectedContentTpl;\n context: { $implicit: state }\n \"\n >\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- INPUT -->\n <ng-container *ngIf=\"!locked\">\n <div #input [id]=\"id + '-input'\" class=\"dropdown\">\n <button\n [id]=\"id + '-toggle'\"\n [disabled]=\"disabled\"\n type=\"button\"\n class=\"nggv-field-dropdown__label toggle\"\n [class.nggv-field--error]=\"invalid\"\n aria-haspopup=\"listbox\"\n [attr.data-thook]=\"thook + '-toggle'\"\n [attr.aria-expanded]=\"expanded\"\n [attr.aria-labelledby]=\"id + '-label ' + id + '-toggle'\"\n (click)=\"toggleDropdown()\"\n >\n <ng-template\n *ngTemplateOutlet=\"\n selectedContentTpl || defaultSelectedContentTpl;\n context: { $implicit: state }\n \"\n >\n </ng-template>\n </button>\n\n <nggv-dropdown-list\n #dropDownList\n [options]=\"options\"\n [scrollOffset]=\"scrollOffset\"\n [state]=\"state\"\n [expanded]=\"expanded\"\n [optionContentTpl]=\"optionContentTpl\"\n [textToHighlight]=\"textToHighlight\"\n (selectedValueChanged)=\"onSelectChange($event)\"\n >\n </nggv-dropdown-list>\n </div>\n <!-- ERRORS -->\n <label\n class=\"sdv-field-notice sdv-field-notice--error\"\n [attr.for]=\"id + '-input'\"\n *ngIf=\"invalid && (error || ngControl?.invalid)\"\n >\n <span *ngIf=\"error; else errorsRef\">{{ error }}</span>\n <ng-template #errorsRef>\n <span *ngIf=\"firstError as error\">\n {{ t('error.field' + error?.code, error?.params) }}\n </span>\n </ng-template>\n </label>\n\n <!-- CHILDREN -->\n <ng-content></ng-content>\n </ng-container>\n\n <ng-template #defaultSelectedContentTpl let-state>\n <!-- eslint-disable-next-line @angular-eslint/template/eqeqeq -->\n {{ state?.key != null && state?.label ? t(state.label) : placeholder }}\n </ng-template>\n</ng-container>\n", styles: [":host label{display:block;font-weight:500;line-height:1.25rem;margin-bottom:.5rem;width:100%}:host .description{margin-bottom:.5rem;line-height:1.25rem;width:100%}:host button{font-weight:500;display:inline-flex;justify-content:center;transition:all .3s cubic-bezier(.23,1,.32,1),outline-offset 0s,outline-width 0s;background:transparent;border-color:#007ac7;color:#007ac7;--color: rgb(0, 122, 199);background-color:transparent;border:0;cursor:pointer;font-family:inherit;padding:0;padding:.75rem 1rem;border-radius:var(--sg-border-radius);border:solid var(--sg-border-width) var(--sg-border-color);--border-color: var(--grey-800);--sg-border-color: var(--grey-800);background:var(--sg-form-control-bg);color:var(--text-primary-color);min-height:2.75rem;display:flex;flex-wrap:nowrap;justify-content:space-between;align-items:center;max-width:100%;font-size:inherit;font-weight:400;line-height:1.125;margin-bottom:.5rem;margin-top:.5rem;width:100%}@media screen and (-ms-high-contrast: active){:host button{border:2px solid currentcolor}}:host button.small{min-height:2rem;padding:.4375rem .75rem;line-height:1rem}:host button.large{min-height:4rem;padding:1rem 1.5rem;font-size:1.5rem;line-height:2rem}:host button:focus:not(:focus-visible){box-shadow:none;outline:0}:host button:focus,:host button:focus-visible{outline-color:var(--gds-sys-color-focus-outline);outline-style:solid;outline-width:.125rem;outline-offset:.125rem}:host button:not(:disabled,.disabled,[aria-disabled]):hover{background-color:#199be3;color:#fff;--background: #199be3;--color: rgb(255, 255, 255);border-color:#199be3}:host button[aria-selected=true],:host button:active,:host button.active,:host button.active:hover,:host button:active:hover{background-color:#007ac7;color:#fff;--background: rgb(0, 122, 199);--color: rgb(255, 255, 255);border-color:#007ac7}:host button:disabled,:host button.disabled,:host button[aria-disabled=true]{background:var(--sg-form-control-bg-disabled)!important;color:var(--text-disabled-color)!important;border-color:var(--border-disabled-color)!important;cursor:not-allowed}:host button:disabled::placeholder,:host button.disabled::placeholder,:host button[aria-disabled=true]::placeholder{color:var(--text-disabled-color)}:host button:focus{outline-color:var(--gds-sys-color-focus-outline);outline-style:solid;outline-width:.125rem;outline-offset:.125rem}@media (max-width: 35.98em){:host button{min-width:100%}}:host button:not(:disabled,.disabled,[aria-disabled]):hover{--background: var(--grey-400);--color: var(--grey-1000);background-color:var(--grey-400);color:var(--grey-1000);border-color:var(--grey-1000)}:host button>span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host button:after{margin-left:.5rem;margin-right:.5rem;border-bottom:solid 2px var(--text-primary-color);border-left:solid 2px var(--text-primary-color);content:\"\";display:block;height:.5rem;width:.5rem;position:relative;top:-.15rem;transform:translate(75%) rotate3d(0,0,1,-45deg) scaleZ(-1);transition:transform .3s ease-in;flex-shrink:0}:host button[aria-expanded=true]:after{transform:translate(75%,6px) rotate3d(0,0,1,-45deg) scale3d(-1,-1,1)}:host button:hover:after{border-color:currentColor}:host button.small{font-size:.875rem}:host button:hover{background:var(--grey-400)}:host .dropdown{position:relative}\n"] }]
|
|
534
|
+
}], ctorParameters: function () { return [{ type: i1$1.NgControl, decorators: [{
|
|
535
|
+
type: Self
|
|
536
|
+
}, {
|
|
537
|
+
type: Optional
|
|
538
|
+
}] }, { type: undefined, decorators: [{
|
|
539
|
+
type: Optional
|
|
540
|
+
}, {
|
|
541
|
+
type: Inject,
|
|
542
|
+
args: [TRANSLOCO_SCOPE]
|
|
543
|
+
}] }, { type: i0.ChangeDetectorRef }, { type: i2.DropdownUtils }]; }, propDecorators: { selectedContentTpl: [{
|
|
544
|
+
type: ContentChild,
|
|
545
|
+
args: ['selectedTpl', { read: TemplateRef }]
|
|
546
|
+
}], optionContentTpl: [{
|
|
547
|
+
type: ContentChild,
|
|
548
|
+
args: ['optionTpl', { read: TemplateRef }]
|
|
549
|
+
}], thook: [{
|
|
550
|
+
type: HostBinding,
|
|
551
|
+
args: ['attr.data-thook']
|
|
552
|
+
}, {
|
|
553
|
+
type: Input
|
|
554
|
+
}], placeholder: [{
|
|
555
|
+
type: Input
|
|
556
|
+
}], options: [{
|
|
557
|
+
type: Input
|
|
558
|
+
}], scrollOffset: [{
|
|
559
|
+
type: Input
|
|
560
|
+
}], allowControlNullishOption: [{
|
|
561
|
+
type: Input
|
|
562
|
+
}], textToHighlight: [{
|
|
563
|
+
type: Input
|
|
564
|
+
}], selectOnSingleOption: [{
|
|
565
|
+
type: Input
|
|
566
|
+
}], expandedChange: [{
|
|
567
|
+
type: Output
|
|
568
|
+
}], onKeyUp: [{
|
|
569
|
+
type: HostListener,
|
|
570
|
+
args: ['keyup', ['$event']]
|
|
571
|
+
}] } });
|
|
572
|
+
|
|
573
|
+
class NgvTypeaheadInputComponent extends NgvInputComponent {
|
|
574
|
+
get dropdownButton() {
|
|
575
|
+
return this.hostComponent.inputRef?.nativeElement;
|
|
576
|
+
}
|
|
577
|
+
constructor(element, renderer2, ngControl, translocoScope, cdr) {
|
|
578
|
+
super(ngControl, translocoScope, cdr);
|
|
579
|
+
this.element = element;
|
|
580
|
+
this.renderer2 = renderer2;
|
|
581
|
+
this.ngControl = ngControl;
|
|
582
|
+
this.translocoScope = translocoScope;
|
|
583
|
+
this.cdr = cdr;
|
|
584
|
+
/** Boolean to indicate wether the dropdown is expanded or not, to apply appropriate styling */
|
|
585
|
+
this.expanded = false;
|
|
586
|
+
super.ngOnInit();
|
|
587
|
+
}
|
|
588
|
+
ngOnInit() {
|
|
589
|
+
this.autocomplete = 'off';
|
|
590
|
+
this.debounceTime = 0;
|
|
591
|
+
this.hostComponent.selectOnSingleOption = false;
|
|
592
|
+
this.moveInput();
|
|
593
|
+
this.handleExpandedChange();
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* @internal
|
|
597
|
+
* Allow space to be inputted as text
|
|
598
|
+
* @param event fired containing which key was released.
|
|
599
|
+
*/
|
|
600
|
+
onKeyUp(event) {
|
|
601
|
+
if (event.code === 'Space') {
|
|
602
|
+
event.preventDefault();
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* @internal
|
|
607
|
+
* First time the dropdown is expanded, move the input sp it becomes a child of the dropdown button
|
|
608
|
+
* to better reflect semantics and styling.
|
|
609
|
+
*/
|
|
610
|
+
moveInput() {
|
|
611
|
+
// Workaround to execute code in setTimeout due to hooks management etc.
|
|
612
|
+
setTimeout(() => {
|
|
613
|
+
// Only move if parent dropdown is found
|
|
614
|
+
if (this.dropdownButton) {
|
|
615
|
+
this.renderer2.appendChild(this.dropdownButton.querySelector('button'), this.element.nativeElement);
|
|
616
|
+
// Get the height of the parent button so the input can be explicitly set to the same height since it's absolutely positioned
|
|
617
|
+
this.buttonHeight =
|
|
618
|
+
this.dropdownButton.getBoundingClientRect().height || 32; // Default to 2em;
|
|
619
|
+
}
|
|
620
|
+
}, 0);
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* @internal
|
|
624
|
+
* When dropdown is expanded, focus on the input. If a value is selected, set it in the input.
|
|
625
|
+
* When the dropdown is collapsed, empty the input from text.
|
|
626
|
+
*/
|
|
627
|
+
handleExpandedChange() {
|
|
628
|
+
this.hostComponent.expandedChange
|
|
629
|
+
.pipe(takeUntil(this._destroy$))
|
|
630
|
+
.subscribe((state) => {
|
|
631
|
+
this.expanded = state;
|
|
632
|
+
if (this.expanded) {
|
|
633
|
+
// Weird workaround for setting focus. Didn't set focus, but wrapping in setTimeout solved it.
|
|
634
|
+
// See suggestion here: https://github.com/ionic-team/stencil/issues/3772#issuecomment-1292599609
|
|
635
|
+
setTimeout(() => this.setFocus());
|
|
636
|
+
// Format and interpolate result since return type can be other than string from the formatter
|
|
637
|
+
const formattedValue = `${this.formatSelected(this.hostComponent.state)}`;
|
|
638
|
+
this.setInput(formattedValue, false);
|
|
639
|
+
}
|
|
640
|
+
else
|
|
641
|
+
this.setInput('', true);
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* @internal Formats the selected option to display in the input. Interpolate the returned value
|
|
646
|
+
* since we don't know the return type or label type.
|
|
647
|
+
* @param value The selected value
|
|
648
|
+
* @returns The formatted value
|
|
649
|
+
*/
|
|
650
|
+
formatSelected(value) {
|
|
651
|
+
if (value?.key == null)
|
|
652
|
+
return '';
|
|
653
|
+
// If no formatter exists, return the label or empty string
|
|
654
|
+
if (!this.selectedFormatter)
|
|
655
|
+
return value.label ?? '';
|
|
656
|
+
// If a formatter exists, use it
|
|
657
|
+
return this.selectedFormatter(value) ?? '';
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Sets the input programmatically instead of native HTML input event.
|
|
661
|
+
* @param input
|
|
662
|
+
*/
|
|
663
|
+
setInput(input, triggerFilter) {
|
|
664
|
+
this.state = input;
|
|
665
|
+
if (triggerFilter) {
|
|
666
|
+
this.onChange(this.state);
|
|
667
|
+
this.inputChange$.next(this.state);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgvTypeaheadInputComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1$1.NgControl, optional: true, self: true }, { token: TRANSLOCO_SCOPE, optional: true }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
671
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgvTypeaheadInputComponent, selector: "nggv-typeahead-input", inputs: { hostComponent: "hostComponent", resultFormatter: "resultFormatter", selectedFormatter: "selectedFormatter" }, host: { listeners: { "document:keyup": "onKeyUp($event)" } }, usesInheritance: true, ngImport: i0, template: "<ng-container>\n <div class=\"input-wrapper\"\n [ngClass]=\"{ 'expanded': expanded, 'collapsed': !expanded }\"\n [ngStyle]=\"{ 'height.px': buttonHeight }\"\n (click)=\"$event.stopPropagation();\">\n <!-- INPUT FIELD -->\n <div class=\"input-group\">\n <input #input\n [id]=\"id + '-input'\"\n class=\"sdv-field\"\n [attr.type]=\"type\"\n [attr.name]=\"name\"\n [attr.required]=\"required\"\n [attr.email]=\"email\"\n [min]=\"min\"\n [max]=\"max\"\n [step]=\"step\"\n [attr.maxlength]=\"maxlength\"\n [attr.minlength]=\"minlength\"\n [pattern]=\"pattern\"\n [disabled]=\"disabled\"\n [autocomplete]=\"autocomplete\"\n [autofocus]=\"autofocus\"\n [readOnly]=\"readonly\"\n [attr.role]=\"role\"\n [attr.placeholder]=\"placeholder\"\n [attr.aria-label]=\"description\"\n [value]=\"state\"\n (input)=\"onInput($event)\"\n (focus)=\"onFocus($event)\"\n (blur)=\"onBlur($event)\" />\n </div>\n </div>\n</ng-container>", styles: [":host{position:absolute;top:0;left:0;width:calc(100% - 2.625em)}:host .input-wrapper{border:none;box-shadow:none}:host .input-wrapper.expanded{display:flex}:host .input-wrapper.expanded .input-group input.sdv-field{height:100%;width:100%;min-height:unset;margin-left:1px;border:none;box-shadow:none}:host .input-wrapper.collapsed{display:none}:host .input-wrapper .input-group{width:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
|
|
672
|
+
}
|
|
673
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgvTypeaheadInputComponent, decorators: [{
|
|
674
|
+
type: Component,
|
|
675
|
+
args: [{ selector: 'nggv-typeahead-input', template: "<ng-container>\n <div class=\"input-wrapper\"\n [ngClass]=\"{ 'expanded': expanded, 'collapsed': !expanded }\"\n [ngStyle]=\"{ 'height.px': buttonHeight }\"\n (click)=\"$event.stopPropagation();\">\n <!-- INPUT FIELD -->\n <div class=\"input-group\">\n <input #input\n [id]=\"id + '-input'\"\n class=\"sdv-field\"\n [attr.type]=\"type\"\n [attr.name]=\"name\"\n [attr.required]=\"required\"\n [attr.email]=\"email\"\n [min]=\"min\"\n [max]=\"max\"\n [step]=\"step\"\n [attr.maxlength]=\"maxlength\"\n [attr.minlength]=\"minlength\"\n [pattern]=\"pattern\"\n [disabled]=\"disabled\"\n [autocomplete]=\"autocomplete\"\n [autofocus]=\"autofocus\"\n [readOnly]=\"readonly\"\n [attr.role]=\"role\"\n [attr.placeholder]=\"placeholder\"\n [attr.aria-label]=\"description\"\n [value]=\"state\"\n (input)=\"onInput($event)\"\n (focus)=\"onFocus($event)\"\n (blur)=\"onBlur($event)\" />\n </div>\n </div>\n</ng-container>", styles: [":host{position:absolute;top:0;left:0;width:calc(100% - 2.625em)}:host .input-wrapper{border:none;box-shadow:none}:host .input-wrapper.expanded{display:flex}:host .input-wrapper.expanded .input-group input.sdv-field{height:100%;width:100%;min-height:unset;margin-left:1px;border:none;box-shadow:none}:host .input-wrapper.collapsed{display:none}:host .input-wrapper .input-group{width:100%}\n"] }]
|
|
676
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1$1.NgControl, decorators: [{
|
|
677
|
+
type: Self
|
|
678
|
+
}, {
|
|
679
|
+
type: Optional
|
|
680
|
+
}] }, { type: undefined, decorators: [{
|
|
681
|
+
type: Optional
|
|
682
|
+
}, {
|
|
683
|
+
type: Inject,
|
|
684
|
+
args: [TRANSLOCO_SCOPE]
|
|
685
|
+
}] }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { hostComponent: [{
|
|
686
|
+
type: Input
|
|
687
|
+
}], resultFormatter: [{
|
|
688
|
+
type: Input
|
|
689
|
+
}], selectedFormatter: [{
|
|
690
|
+
type: Input
|
|
691
|
+
}], onKeyUp: [{
|
|
692
|
+
type: HostListener,
|
|
693
|
+
args: ['document:keyup', ['$event']]
|
|
694
|
+
}] } });
|
|
695
|
+
|
|
696
|
+
// Use dropdownList template and combine stylesheets
|
|
697
|
+
class NgvTypeaheadDropdownListComponent extends NgvDropdownListComponent {
|
|
698
|
+
constructor(translocoScope, element) {
|
|
699
|
+
super(translocoScope);
|
|
700
|
+
this.translocoScope = translocoScope;
|
|
701
|
+
this.element = element;
|
|
702
|
+
this._destroy$ = new Subject();
|
|
703
|
+
}
|
|
704
|
+
ngOnInit() {
|
|
705
|
+
this.handleSelectedValueChanges();
|
|
706
|
+
this.handleFocusChanges();
|
|
707
|
+
}
|
|
708
|
+
ngOnDestroy() {
|
|
709
|
+
this._destroy$.next(true);
|
|
710
|
+
this._destroy$.complete();
|
|
711
|
+
}
|
|
712
|
+
/** @Internal Subscribe to click outside dropdownList and input to close dropdownList */
|
|
713
|
+
subscribeToOutsideClickEvent() {
|
|
714
|
+
this.onClickSubscription = fromEvent(document, 'click')
|
|
715
|
+
.pipe(takeUntil(this._destroy$))
|
|
716
|
+
.subscribe({
|
|
717
|
+
next: (event) => {
|
|
718
|
+
if (this.expanded &&
|
|
719
|
+
!this.element.nativeElement.contains(event.target) &&
|
|
720
|
+
!this.hostComponent.inputRef?.nativeElement.contains(event.target)) {
|
|
721
|
+
this.setExpanded(false);
|
|
722
|
+
this.onClickSubscription?.unsubscribe();
|
|
723
|
+
}
|
|
724
|
+
},
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
/** @Internal Update state of the host-input to reflect the selected value */
|
|
728
|
+
handleSelectedValueChanges() {
|
|
729
|
+
this.selectedValueChanged
|
|
730
|
+
.pipe(takeUntil(this._destroy$))
|
|
731
|
+
.subscribe((selected) => {
|
|
732
|
+
if (this.hostComponent.inputRef) {
|
|
733
|
+
this.hostComponent.state = `${this.formatSelected(selected)}`;
|
|
734
|
+
}
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
/** @Internal Expand the dropdown when input receives focus. If no state, set empty string in input */
|
|
738
|
+
handleFocusChanges() {
|
|
739
|
+
this.hostComponent.ngvFocus
|
|
740
|
+
.asObservable()
|
|
741
|
+
.pipe(takeUntil(this._destroy$))
|
|
742
|
+
.subscribe(() => {
|
|
743
|
+
if (!this.state)
|
|
744
|
+
this.hostComponent.ngvInput.emit('');
|
|
745
|
+
this.setExpanded(true);
|
|
746
|
+
this.subscribeToOutsideClickEvent();
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* @internal Formats the selected option to display in the input. Interpolate the returned value
|
|
751
|
+
* since we don't know the return type or label type.
|
|
752
|
+
* @param value The selected value
|
|
753
|
+
* @returns The formatted value
|
|
754
|
+
*/
|
|
755
|
+
formatSelected(value) {
|
|
756
|
+
if (value?.key == null)
|
|
757
|
+
return '';
|
|
758
|
+
//If no formatter exists, return the label or empty string
|
|
759
|
+
if (!this.selectedFormatter)
|
|
760
|
+
return value.label ?? '';
|
|
761
|
+
// If a formatter exists, use it
|
|
762
|
+
return this.selectedFormatter(value) ?? '';
|
|
763
|
+
}
|
|
764
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgvTypeaheadDropdownListComponent, deps: [{ token: TRANSLOCO_SCOPE, optional: true, skipSelf: true }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
765
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgvTypeaheadDropdownListComponent, selector: "nggv-typeahead-dropdown-list", inputs: { hostComponent: "hostComponent", resultFormatter: "resultFormatter", selectedFormatter: "selectedFormatter" }, usesInheritance: true, ngImport: i0, template: "<ng-container *transloco=\"let t; read: scope\">\n <ul\n class=\"gds-dropdown__options card options gds-reset\"\n [class.gds-dropdown__options-expanded]=\"expanded\"\n role=\"listbox\"\n tabindex=\"-1\"\n [attr.data-thook]=\"thook + '-options'\"\n [attr.aria-labelledby]=\"id + '-label'\"\n [attr.aria-activedescendant]=\"\n state ? id + '-option-' + state?.key : undefined\n \"\n >\n <ng-container *ngFor=\"let item of options\">\n <!-- OPTION -->\n <ng-container *ngIf=\"!isGroup(item)\">\n <ng-template\n *ngTemplateOutlet=\"listItemTemplate; context: { $implicit: item }\"\n ></ng-template>\n </ng-container>\n\n <!-- OPTION GROUP -->\n <li\n class=\"gds-dropdown__options__label group\"\n [attr.data-thook]=\"thook + '-option-group'\"\n *ngIf=\"isGroup(item)\"\n >\n <div class=\"sdv-list__label\">{{ t(item.label) }}</div>\n <ul [attr.aria-disabled]=\"item.disabled\">\n <ng-container *ngFor=\"let option of castGroup(item).options\">\n <ng-template\n *ngTemplateOutlet=\"\n listItemTemplate;\n context: { $implicit: option }\n \"\n ></ng-template>\n </ng-container>\n </ul>\n </li>\n </ng-container>\n </ul>\n\n <!-- TEMPLATE -->\n <ng-template #listItemTemplate let-option>\n <li\n #optionRefs\n *ngIf=\"!optionContentTpl\"\n tabindex=\"-1\"\n [id]=\"id + '-option-' + option.key\"\n class=\"gds-dropdown__options__label option\"\n role=\"option\"\n #liElem\n [attr.data-thook]=\"thook + '-option-' + option.key\"\n [attr.aria-disabled]=\"option.disabled\"\n [attr.aria-selected]=\"\n option.key === selectedValue?.key && !!selectedValue?.key\n \"\n [attr.aria-focus]=\"option.key === state?.key && !option.disabled\"\n [ngvTooltip]=\"isOverflow(liElem) ? t(option.label) : undefined\"\n (click)=\"updateState(option, $event)\"\n >\n <ng-template\n *ngTemplateOutlet=\"\n basicOptionContentTpl;\n context: { $implicit: option }\n \"\n >\n </ng-template>\n </li>\n <!-- Checking overflow on custom templates do not work skip adding ngvToolTip if custom template is provided -->\n <li\n #optionRefs\n *ngIf=\"!!optionContentTpl\"\n tabindex=\"-1\"\n [id]=\"id + '-option-' + option.key\"\n class=\"gds-dropdown__options__label option\"\n role=\"option\"\n #liElem\n [attr.data-thook]=\"thook + '-option-' + option.key\"\n [attr.aria-disabled]=\"option.disabled\"\n [attr.aria-selected]=\"\n option.key === selectedValue?.key && !!selectedValue?.key\n \"\n [attr.aria-focus]=\"option.key === state?.key && !option.disabled\"\n (click)=\"updateState(option, $event)\"\n >\n <ng-template\n *ngTemplateOutlet=\"optionContentTpl; context: { $implicit: option }\"\n >\n </ng-template>\n </li>\n </ng-template>\n\n <ng-template #basicOptionContentTpl let-option>\n <nggv-typeahead-highlight\n *ngIf=\"!!textToHighlight\"\n [textToHighlight]=\"textToHighlight\"\n [textContent]=\"t(option.label)\"\n >\n </nggv-typeahead-highlight>\n <ng-container *ngIf=\"!textToHighlight\">\n {{ t(option.label) }}\n </ng-container>\n </ng-template>\n</ng-container>\n", styles: [":host{display:flex;width:100%;position:relative}\n", ":host{position:absolute;bottom:0;transform:translateY(calc(100% + .5rem));--z-index: var(--sg-z-index-dropdown)}:host .hidden{visibility:hidden;display:none}:host ul[role=menu] [role=menuitem]{padding:.75rem;cursor:pointer}:host ul[role=menu] [role=menuitem]:hover,:host ul[role=menu] [role=menuitem]:focus-visible{background-color:var(--gds-ref-pallet-base200)}:host ul[role=menu] [role=menuitem]:active{background-color:var(--gds-ref-pallet-base300)}:host ul[role=menu] [role=menuitem]:focus{outline-color:#000;outline-offset:-.25rem}:host ul[role=listbox]{--z-index: var(--sg-z-index-popover);background-color:var(--sg-popover-background);flex-direction:column;justify-content:flex-end;inset:auto;z-index:var(--z-index);box-shadow:var(--sg-popover-box-shadow);color:var(--text-primary-color);padding:0;border:solid var(--sg-border-width) var(--sg-border-color);--border-color: var(--text-primary-color);--sg-border-color: var(--text-primary-color);border-radius:var(--sg-border-radius)}:host ul[role=listbox] [role=option]{padding:.75rem 1rem;line-height:1.25;cursor:pointer}:host ul[role=listbox] [role=option]:hover,:host ul[role=listbox] [role=option]:focus-visible{background-color:var(--grey-400)}:host ul[role=listbox] [role=option]:active{background-color:var(--grey-400)}:host ul[role=listbox] [role=option]:focus{outline-color:#000;outline-offset:-.25rem}:host ul[role=listbox] [role=option].active.sg-highlighted,:host ul[role=listbox] [role=option][aria-selected=true]{background:var(--grey-1000);color:#fff}:host .sg-fieldset-container{overflow-y:auto}:host .sg-fieldset-container fieldset[role=listbox][aria-multiselectable=true] [role=option]{display:flex;width:100%}:host .sg-fieldset-container fieldset[role=listbox][aria-multiselectable=true] [role=option].active.sg-highlighted input[type=checkbox]~i{border-color:#007ac7!important;box-shadow:0 0 .25em .0625em #41b0ee;outline-color:transparent;outline-style:solid}:host .gds-dropdown__options{padding-left:0;margin-bottom:0;margin-top:0;display:flex;flex-direction:column;list-style:none;display:none}:host .gds-dropdown__options>li{padding-bottom:.5rem;padding-top:.5rem;border:0;display:block;position:relative}:host .gds-dropdown__options>li:before{font-weight:500;display:inline-block;left:0;position:absolute;text-align:center}:host .gds-dropdown__options-expanded{display:block}:host .gds-dropdown__options__label:hover,:host .gds-dropdown__options__label:focus-visible{background-color:var(--grey-400)}:host .gds-dropdown__options__label:active{background-color:var(--grey-500)}:host .gds-dropdown__options__label:focus-visible{outline-color:#000;outline-offset:-.25rem}:host .gds-dropdown__options__label[aria-hidden=true]{display:none}:host .gds-dropdown__options__label[highlighted]{color:#fff}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.NgvTooltipDirective, selector: "[ngvTooltip]", inputs: ["ngvTooltip", "thook", "placement", "shown", "offset", "resizeThrottle", "maxWidth"], outputs: ["ngvShow", "ngvHide"] }, { kind: "component", type: NgvTypeaheadHighlightComponent, selector: "nggv-typeahead-highlight", inputs: ["textContent", "textToHighlight"] }] }); }
|
|
766
|
+
}
|
|
767
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgvTypeaheadDropdownListComponent, decorators: [{
|
|
768
|
+
type: Component,
|
|
769
|
+
args: [{ selector: 'nggv-typeahead-dropdown-list', template: "<ng-container *transloco=\"let t; read: scope\">\n <ul\n class=\"gds-dropdown__options card options gds-reset\"\n [class.gds-dropdown__options-expanded]=\"expanded\"\n role=\"listbox\"\n tabindex=\"-1\"\n [attr.data-thook]=\"thook + '-options'\"\n [attr.aria-labelledby]=\"id + '-label'\"\n [attr.aria-activedescendant]=\"\n state ? id + '-option-' + state?.key : undefined\n \"\n >\n <ng-container *ngFor=\"let item of options\">\n <!-- OPTION -->\n <ng-container *ngIf=\"!isGroup(item)\">\n <ng-template\n *ngTemplateOutlet=\"listItemTemplate; context: { $implicit: item }\"\n ></ng-template>\n </ng-container>\n\n <!-- OPTION GROUP -->\n <li\n class=\"gds-dropdown__options__label group\"\n [attr.data-thook]=\"thook + '-option-group'\"\n *ngIf=\"isGroup(item)\"\n >\n <div class=\"sdv-list__label\">{{ t(item.label) }}</div>\n <ul [attr.aria-disabled]=\"item.disabled\">\n <ng-container *ngFor=\"let option of castGroup(item).options\">\n <ng-template\n *ngTemplateOutlet=\"\n listItemTemplate;\n context: { $implicit: option }\n \"\n ></ng-template>\n </ng-container>\n </ul>\n </li>\n </ng-container>\n </ul>\n\n <!-- TEMPLATE -->\n <ng-template #listItemTemplate let-option>\n <li\n #optionRefs\n *ngIf=\"!optionContentTpl\"\n tabindex=\"-1\"\n [id]=\"id + '-option-' + option.key\"\n class=\"gds-dropdown__options__label option\"\n role=\"option\"\n #liElem\n [attr.data-thook]=\"thook + '-option-' + option.key\"\n [attr.aria-disabled]=\"option.disabled\"\n [attr.aria-selected]=\"\n option.key === selectedValue?.key && !!selectedValue?.key\n \"\n [attr.aria-focus]=\"option.key === state?.key && !option.disabled\"\n [ngvTooltip]=\"isOverflow(liElem) ? t(option.label) : undefined\"\n (click)=\"updateState(option, $event)\"\n >\n <ng-template\n *ngTemplateOutlet=\"\n basicOptionContentTpl;\n context: { $implicit: option }\n \"\n >\n </ng-template>\n </li>\n <!-- Checking overflow on custom templates do not work skip adding ngvToolTip if custom template is provided -->\n <li\n #optionRefs\n *ngIf=\"!!optionContentTpl\"\n tabindex=\"-1\"\n [id]=\"id + '-option-' + option.key\"\n class=\"gds-dropdown__options__label option\"\n role=\"option\"\n #liElem\n [attr.data-thook]=\"thook + '-option-' + option.key\"\n [attr.aria-disabled]=\"option.disabled\"\n [attr.aria-selected]=\"\n option.key === selectedValue?.key && !!selectedValue?.key\n \"\n [attr.aria-focus]=\"option.key === state?.key && !option.disabled\"\n (click)=\"updateState(option, $event)\"\n >\n <ng-template\n *ngTemplateOutlet=\"optionContentTpl; context: { $implicit: option }\"\n >\n </ng-template>\n </li>\n </ng-template>\n\n <ng-template #basicOptionContentTpl let-option>\n <nggv-typeahead-highlight\n *ngIf=\"!!textToHighlight\"\n [textToHighlight]=\"textToHighlight\"\n [textContent]=\"t(option.label)\"\n >\n </nggv-typeahead-highlight>\n <ng-container *ngIf=\"!textToHighlight\">\n {{ t(option.label) }}\n </ng-container>\n </ng-template>\n</ng-container>\n", styles: [":host{display:flex;width:100%;position:relative}\n", ":host{position:absolute;bottom:0;transform:translateY(calc(100% + .5rem));--z-index: var(--sg-z-index-dropdown)}:host .hidden{visibility:hidden;display:none}:host ul[role=menu] [role=menuitem]{padding:.75rem;cursor:pointer}:host ul[role=menu] [role=menuitem]:hover,:host ul[role=menu] [role=menuitem]:focus-visible{background-color:var(--gds-ref-pallet-base200)}:host ul[role=menu] [role=menuitem]:active{background-color:var(--gds-ref-pallet-base300)}:host ul[role=menu] [role=menuitem]:focus{outline-color:#000;outline-offset:-.25rem}:host ul[role=listbox]{--z-index: var(--sg-z-index-popover);background-color:var(--sg-popover-background);flex-direction:column;justify-content:flex-end;inset:auto;z-index:var(--z-index);box-shadow:var(--sg-popover-box-shadow);color:var(--text-primary-color);padding:0;border:solid var(--sg-border-width) var(--sg-border-color);--border-color: var(--text-primary-color);--sg-border-color: var(--text-primary-color);border-radius:var(--sg-border-radius)}:host ul[role=listbox] [role=option]{padding:.75rem 1rem;line-height:1.25;cursor:pointer}:host ul[role=listbox] [role=option]:hover,:host ul[role=listbox] [role=option]:focus-visible{background-color:var(--grey-400)}:host ul[role=listbox] [role=option]:active{background-color:var(--grey-400)}:host ul[role=listbox] [role=option]:focus{outline-color:#000;outline-offset:-.25rem}:host ul[role=listbox] [role=option].active.sg-highlighted,:host ul[role=listbox] [role=option][aria-selected=true]{background:var(--grey-1000);color:#fff}:host .sg-fieldset-container{overflow-y:auto}:host .sg-fieldset-container fieldset[role=listbox][aria-multiselectable=true] [role=option]{display:flex;width:100%}:host .sg-fieldset-container fieldset[role=listbox][aria-multiselectable=true] [role=option].active.sg-highlighted input[type=checkbox]~i{border-color:#007ac7!important;box-shadow:0 0 .25em .0625em #41b0ee;outline-color:transparent;outline-style:solid}:host .gds-dropdown__options{padding-left:0;margin-bottom:0;margin-top:0;display:flex;flex-direction:column;list-style:none;display:none}:host .gds-dropdown__options>li{padding-bottom:.5rem;padding-top:.5rem;border:0;display:block;position:relative}:host .gds-dropdown__options>li:before{font-weight:500;display:inline-block;left:0;position:absolute;text-align:center}:host .gds-dropdown__options-expanded{display:block}:host .gds-dropdown__options__label:hover,:host .gds-dropdown__options__label:focus-visible{background-color:var(--grey-400)}:host .gds-dropdown__options__label:active{background-color:var(--grey-500)}:host .gds-dropdown__options__label:focus-visible{outline-color:#000;outline-offset:-.25rem}:host .gds-dropdown__options__label[aria-hidden=true]{display:none}:host .gds-dropdown__options__label[highlighted]{color:#fff}\n"] }]
|
|
770
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
771
|
+
type: SkipSelf
|
|
772
|
+
}, {
|
|
773
|
+
type: Optional
|
|
774
|
+
}, {
|
|
775
|
+
type: Inject,
|
|
776
|
+
args: [TRANSLOCO_SCOPE]
|
|
777
|
+
}] }, { type: i0.ElementRef }]; }, propDecorators: { hostComponent: [{
|
|
778
|
+
type: Input
|
|
779
|
+
}], resultFormatter: [{
|
|
780
|
+
type: Input
|
|
781
|
+
}], selectedFormatter: [{
|
|
782
|
+
type: Input
|
|
783
|
+
}] } });
|
|
784
|
+
|
|
785
|
+
class NgvTypeaheadModule {
|
|
786
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgvTypeaheadModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
787
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: NgvTypeaheadModule, declarations: [NgvTypeaheadHighlightComponent,
|
|
788
|
+
NgvTypeaheadInputComponent,
|
|
789
|
+
NgvTypeaheadDropdownListComponent], imports: [CommonModule, NgvTooltipModule], exports: [NgvTypeaheadHighlightComponent,
|
|
790
|
+
NgvTypeaheadInputComponent,
|
|
791
|
+
NgvTypeaheadDropdownListComponent] }); }
|
|
792
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgvTypeaheadModule, imports: [CommonModule, NgvTooltipModule] }); }
|
|
793
|
+
}
|
|
794
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgvTypeaheadModule, decorators: [{
|
|
795
|
+
type: NgModule,
|
|
796
|
+
args: [{
|
|
797
|
+
declarations: [
|
|
798
|
+
NgvTypeaheadHighlightComponent,
|
|
799
|
+
NgvTypeaheadInputComponent,
|
|
800
|
+
NgvTypeaheadDropdownListComponent,
|
|
801
|
+
],
|
|
802
|
+
imports: [CommonModule, NgvTooltipModule],
|
|
803
|
+
exports: [
|
|
804
|
+
NgvTypeaheadHighlightComponent,
|
|
805
|
+
NgvTypeaheadInputComponent,
|
|
806
|
+
NgvTypeaheadDropdownListComponent,
|
|
807
|
+
],
|
|
808
|
+
}]
|
|
809
|
+
}] });
|
|
810
|
+
|
|
811
|
+
class NgvDropdownModule {
|
|
812
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgvDropdownModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
813
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: NgvDropdownModule, declarations: [NgvDropdownComponent, NgvDropdownListComponent], imports: [CommonModule, NgvTypeaheadModule, NgvTooltipModule, NgvI18nModule], exports: [NgvDropdownComponent, NgvDropdownListComponent] }); }
|
|
814
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgvDropdownModule, imports: [CommonModule, NgvTypeaheadModule, NgvTooltipModule, NgvI18nModule] }); }
|
|
815
|
+
}
|
|
816
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgvDropdownModule, decorators: [{
|
|
817
|
+
type: NgModule,
|
|
818
|
+
args: [{
|
|
819
|
+
declarations: [NgvDropdownComponent, NgvDropdownListComponent],
|
|
820
|
+
imports: [CommonModule, NgvTypeaheadModule, NgvTooltipModule, NgvI18nModule],
|
|
821
|
+
exports: [NgvDropdownComponent, NgvDropdownListComponent],
|
|
822
|
+
}]
|
|
823
|
+
}] });
|
|
824
|
+
|
|
825
|
+
/**
|
|
826
|
+
* Generated bundle index. Do not edit.
|
|
827
|
+
*/
|
|
828
|
+
|
|
829
|
+
export { NgvDropdownComponent, NgvDropdownListComponent, NgvDropdownModule, NgvTypeaheadHighlightComponent, NgvTypeaheadInputComponent };
|
|
830
|
+
//# sourceMappingURL=sebgroup-green-angular-src-v-angular-dropdown.mjs.map
|