@eui/ecl 22.0.0-alpha.1 → 22.0.0-alpha.10

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.
Files changed (120) hide show
  1. package/docs/changelog.html +527 -0
  2. package/docs/components/EclCategoryFilterComponent.html +23 -187
  3. package/docs/components/EclCategoryFilterItemComponent.html +111 -274
  4. package/docs/components/EclCategoryFilterListComponent.html +9 -225
  5. package/docs/components/EclDateBlockComponent.html +0 -9
  6. package/docs/components/EclDescriptionListDefinitionComponent.html +6 -44
  7. package/docs/components/EclIconComponent.html +1 -1
  8. package/docs/components/EclListIllustrationComponent.html +0 -171
  9. package/docs/components/EclListIllustrationItemComponent.html +77 -83
  10. package/docs/components/EclLoadingIndicatorComponent.html +4 -91
  11. package/docs/components/EclMegaMenuComponent.html +5 -203
  12. package/docs/components/EclMegaMenuFeaturedComponent.html +10 -126
  13. package/docs/components/EclMegaMenuInfoComponent.html +0 -91
  14. package/docs/components/EclMegaMenuItemComponent.html +38 -115
  15. package/docs/components/EclMegaMenuSubitemComponent.html +4 -68
  16. package/docs/components/EclMenuItemComponent.html +46 -0
  17. package/docs/components/EclSiteFooterRowCommonComponent.html +1 -1
  18. package/docs/components/EclSiteHeaderLanguageComponent.html +5 -627
  19. package/docs/components/EclSiteHeaderLanguagePopoverComponent.html +99 -440
  20. package/docs/components/EclSiteHeaderLoginComponent.html +9 -453
  21. package/docs/components/EclSiteHeaderSearchComponent.html +18 -470
  22. package/docs/components/EclSocialMediaFollowComponent.html +28 -39
  23. package/docs/components/EclSocialMediaFollowItemComponent.html +26 -129
  24. package/docs/components/EclStoryCardComponent.html +1 -1
  25. package/docs/directives/ECLClickOutsideDirective.html +3 -0
  26. package/docs/directives/EclDescriptionListDefinitionItemDirective.html +6 -47
  27. package/docs/directives/EclDescriptionListDefinitionListDirective.html +0 -116
  28. package/docs/directives/EclDividerDirective.html +0 -116
  29. package/docs/directives/EclFileUploadDirective.html +2 -390
  30. package/docs/directives/EclLabelDirective.html +0 -46
  31. package/docs/directives/EclLinkDirective.html +0 -39
  32. package/docs/directives/EclLoadingIndicatorLabelDirective.html +0 -61
  33. package/docs/directives/EclLoadingIndicatorOverlayDirective.html +0 -45
  34. package/docs/directives/EclMediaContainerCaptionDirective.html +0 -39
  35. package/docs/directives/EclMediaContainerCreditDirective.html +0 -39
  36. package/docs/directives/EclMediaContainerIframeDirective.html +13 -19
  37. package/docs/directives/EclMediaContainerItemAudioDescriptionDirective.html +0 -39
  38. package/docs/directives/EclMediaContainerItemDirective.html +0 -39
  39. package/docs/directives/EclMediaContainerPictureDirective.html +0 -39
  40. package/docs/directives/EclMegaMenuContainerDirective.html +0 -104
  41. package/docs/directives/EclMegaMenuFeaturedImageDirective.html +0 -104
  42. package/docs/directives/EclMegaMenuFeaturedListDirective.html +0 -104
  43. package/docs/directives/EclMegaMenuFeaturedListItemDescriptionDirective.html +0 -104
  44. package/docs/directives/EclMegaMenuFeaturedListItemDirective.html +0 -104
  45. package/docs/directives/EclMegaMenuFeaturedPictureDirective.html +0 -39
  46. package/docs/directives/EclMegaMenuListDirective.html +0 -104
  47. package/docs/directives/EclMegaMenuSpacerDirective.html +0 -104
  48. package/docs/directives/EclMegaMenuSublistDirective.html +0 -165
  49. package/docs/js/search/search_index.js +2 -2
  50. package/docs/json/EclIconComponent.md +1 -1
  51. package/docs/json/EclMediaContainerIframeDirective.md +0 -1
  52. package/docs/json/EclSiteHeaderLanguagePopoverComponent.md +6 -6
  53. package/docs/json/EclSiteHeaderSearchComponent.md +1 -0
  54. package/docs/json/EclSocialMediaFollowComponent.md +1 -0
  55. package/docs/json/documentation.json +1317 -2896
  56. package/docs/llms.txt +30 -90
  57. package/docs/miscellaneous/variables.html +222 -41
  58. package/docs/properties.html +1 -1
  59. package/fesm2022/eui-ecl-components-ecl-category-filter.mjs +94 -129
  60. package/fesm2022/eui-ecl-components-ecl-category-filter.mjs.map +1 -1
  61. package/fesm2022/eui-ecl-components-ecl-date-block.mjs +2 -2
  62. package/fesm2022/eui-ecl-components-ecl-date-block.mjs.map +1 -1
  63. package/fesm2022/eui-ecl-components-ecl-divider.mjs +6 -13
  64. package/fesm2022/eui-ecl-components-ecl-divider.mjs.map +1 -1
  65. package/fesm2022/eui-ecl-components-ecl-file-upload.mjs +13 -27
  66. package/fesm2022/eui-ecl-components-ecl-file-upload.mjs.map +1 -1
  67. package/fesm2022/eui-ecl-components-ecl-icon.mjs.map +1 -1
  68. package/fesm2022/eui-ecl-components-ecl-inpage-navigation.mjs +55 -9
  69. package/fesm2022/eui-ecl-components-ecl-inpage-navigation.mjs.map +1 -1
  70. package/fesm2022/eui-ecl-components-ecl-label.mjs +6 -6
  71. package/fesm2022/eui-ecl-components-ecl-label.mjs.map +1 -1
  72. package/fesm2022/eui-ecl-components-ecl-link.mjs +10 -13
  73. package/fesm2022/eui-ecl-components-ecl-link.mjs.map +1 -1
  74. package/fesm2022/eui-ecl-components-ecl-list-illustration.mjs +19 -30
  75. package/fesm2022/eui-ecl-components-ecl-list-illustration.mjs.map +1 -1
  76. package/fesm2022/eui-ecl-components-ecl-list.mjs +44 -41
  77. package/fesm2022/eui-ecl-components-ecl-list.mjs.map +1 -1
  78. package/fesm2022/eui-ecl-components-ecl-loading-indicator.mjs +17 -20
  79. package/fesm2022/eui-ecl-components-ecl-loading-indicator.mjs.map +1 -1
  80. package/fesm2022/eui-ecl-components-ecl-media-container.mjs +36 -33
  81. package/fesm2022/eui-ecl-components-ecl-media-container.mjs.map +1 -1
  82. package/fesm2022/eui-ecl-components-ecl-mega-menu.mjs +100 -159
  83. package/fesm2022/eui-ecl-components-ecl-mega-menu.mjs.map +1 -1
  84. package/fesm2022/eui-ecl-components-ecl-menu.mjs +16 -3
  85. package/fesm2022/eui-ecl-components-ecl-menu.mjs.map +1 -1
  86. package/fesm2022/eui-ecl-components-ecl-site-footer.mjs +2 -2
  87. package/fesm2022/eui-ecl-components-ecl-site-footer.mjs.map +1 -1
  88. package/fesm2022/eui-ecl-components-ecl-site-header.mjs +326 -261
  89. package/fesm2022/eui-ecl-components-ecl-site-header.mjs.map +1 -1
  90. package/fesm2022/eui-ecl-components-ecl-social-media-follow.mjs +17 -17
  91. package/fesm2022/eui-ecl-components-ecl-social-media-follow.mjs.map +1 -1
  92. package/fesm2022/eui-ecl-components-ecl-story-card.mjs +2 -2
  93. package/fesm2022/eui-ecl-components-ecl-story-card.mjs.map +1 -1
  94. package/package.json +1 -1
  95. package/types/eui-ecl-components-ecl-category-filter.d.ts +32 -56
  96. package/types/eui-ecl-components-ecl-category-filter.d.ts.map +1 -1
  97. package/types/eui-ecl-components-ecl-date-block.d.ts.map +1 -1
  98. package/types/eui-ecl-components-ecl-divider.d.ts +0 -4
  99. package/types/eui-ecl-components-ecl-divider.d.ts.map +1 -1
  100. package/types/eui-ecl-components-ecl-file-upload.d.ts.map +1 -1
  101. package/types/eui-ecl-components-ecl-inpage-navigation.d.ts +25 -0
  102. package/types/eui-ecl-components-ecl-inpage-navigation.d.ts.map +1 -1
  103. package/types/eui-ecl-components-ecl-label.d.ts.map +1 -1
  104. package/types/eui-ecl-components-ecl-link.d.ts +2 -4
  105. package/types/eui-ecl-components-ecl-link.d.ts.map +1 -1
  106. package/types/eui-ecl-components-ecl-list-illustration.d.ts +3 -3
  107. package/types/eui-ecl-components-ecl-list-illustration.d.ts.map +1 -1
  108. package/types/eui-ecl-components-ecl-list.d.ts +9 -12
  109. package/types/eui-ecl-components-ecl-list.d.ts.map +1 -1
  110. package/types/eui-ecl-components-ecl-loading-indicator.d.ts.map +1 -1
  111. package/types/eui-ecl-components-ecl-media-container.d.ts +7 -2
  112. package/types/eui-ecl-components-ecl-media-container.d.ts.map +1 -1
  113. package/types/eui-ecl-components-ecl-mega-menu.d.ts +12 -22
  114. package/types/eui-ecl-components-ecl-mega-menu.d.ts.map +1 -1
  115. package/types/eui-ecl-components-ecl-menu.d.ts +12 -1
  116. package/types/eui-ecl-components-ecl-menu.d.ts.map +1 -1
  117. package/types/eui-ecl-components-ecl-site-header.d.ts +240 -216
  118. package/types/eui-ecl-components-ecl-site-header.d.ts.map +1 -1
  119. package/types/eui-ecl-components-ecl-social-media-follow.d.ts +5 -3
  120. package/types/eui-ecl-components-ecl-social-media-follow.d.ts.map +1 -1
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { HostBinding, Directive } from '@angular/core';
2
+ import { Directive } from '@angular/core';
3
3
  import { ECLBaseDirective } from '@eui/ecl/core';
4
4
 
5
5
  /**
@@ -7,25 +7,18 @@ import { ECLBaseDirective } from '@eui/ecl/core';
7
7
  * Adds the `ecl-separator` CSS class to the host element.
8
8
  */
9
9
  class EclDividerDirective extends ECLBaseDirective {
10
- constructor() {
11
- super(...arguments);
12
- /**
13
- * Binds the `ecl-separator` CSS class to the host `<hr>` element.
14
- */
15
- this.hasClass = true;
16
- }
17
10
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EclDividerDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
18
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.2", type: EclDividerDirective, isStandalone: true, selector: "hr[eclDivider]", host: { properties: { "class.ecl-separator": "this.hasClass" } }, usesInheritance: true, ngImport: i0 }); }
11
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.2", type: EclDividerDirective, isStandalone: true, selector: "hr[eclDivider]", host: { classAttribute: "ecl-separator" }, usesInheritance: true, ngImport: i0 }); }
19
12
  }
20
13
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EclDividerDirective, decorators: [{
21
14
  type: Directive,
22
15
  args: [{
23
16
  selector: 'hr[eclDivider]',
17
+ host: {
18
+ 'class': 'ecl-separator',
19
+ },
24
20
  }]
25
- }], propDecorators: { hasClass: [{
26
- type: HostBinding,
27
- args: ['class.ecl-separator']
28
- }] } });
21
+ }] });
29
22
 
30
23
  const EUI_ECL_DIVIDER = [
31
24
  EclDividerDirective,
@@ -1 +1 @@
1
- {"version":3,"file":"eui-ecl-components-ecl-divider.mjs","sources":["../../components/ecl-divider/ecl-divider.directive.ts","../../components/ecl-divider/index.ts","../../components/ecl-divider/eui-ecl-components-ecl-divider.ts"],"sourcesContent":["import { Directive, HostBinding } from '@angular/core';\nimport { ECLBaseDirective } from '@eui/ecl/core';\n\n/**\n * Directive that applies ECL styling for horizontal separators (`<hr>` elements).\n * Adds the `ecl-separator` CSS class to the host element.\n */\n@Directive({\n selector: 'hr[eclDivider]',\n})\nexport class EclDividerDirective extends ECLBaseDirective {\n /**\n * Binds the `ecl-separator` CSS class to the host `<hr>` element.\n */\n @HostBinding('class.ecl-separator') hasClass = true;\n}\n","import { EclDividerDirective } from './ecl-divider.directive';\n\nexport * from './ecl-divider.directive';\n\nexport const EUI_ECL_DIVIDER = [\n EclDividerDirective,\n] as const;","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAGA;;;AAGG;AAIG,MAAO,mBAAoB,SAAQ,gBAAgB,CAAA;AAHzD,IAAA,WAAA,GAAA;;AAII;;AAEG;QACiC,IAAA,CAAA,QAAQ,GAAG,IAAI;AACtD,IAAA;8GALY,mBAAmB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAAnB,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,qBAAA,EAAA,eAAA,EAAA,EAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA,CAAA;;2FAAnB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAH/B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACP,oBAAA,QAAQ,EAAE,gBAAgB;AAC7B,iBAAA;;sBAKI,WAAW;uBAAC,qBAAqB;;;ACV/B,MAAM,eAAe,GAAG;IAC3B,mBAAmB;;;ACLvB;;AAEG;;;;"}
1
+ {"version":3,"file":"eui-ecl-components-ecl-divider.mjs","sources":["../../components/ecl-divider/ecl-divider.directive.ts","../../components/ecl-divider/index.ts","../../components/ecl-divider/eui-ecl-components-ecl-divider.ts"],"sourcesContent":["import { Directive } from '@angular/core';\nimport { ECLBaseDirective } from '@eui/ecl/core';\n\n/**\n * Directive that applies ECL styling for horizontal separators (`<hr>` elements).\n * Adds the `ecl-separator` CSS class to the host element.\n */\n@Directive({\n selector: 'hr[eclDivider]',\n host: {\n 'class': 'ecl-separator',\n },\n})\nexport class EclDividerDirective extends ECLBaseDirective {}\n","import { EclDividerDirective } from './ecl-divider.directive';\n\nexport * from './ecl-divider.directive';\n\nexport const EUI_ECL_DIVIDER = [\n EclDividerDirective,\n] as const;","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAGA;;;AAGG;AAOG,MAAO,mBAAoB,SAAQ,gBAAgB,CAAA;8GAA5C,mBAAmB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAAnB,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,eAAA,EAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA,CAAA;;2FAAnB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAN/B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACP,oBAAA,QAAQ,EAAE,gBAAgB;AAC1B,oBAAA,IAAI,EAAE;AACF,wBAAA,OAAO,EAAE,eAAe;AAC3B,qBAAA;AACJ,iBAAA;;;ACRM,MAAM,eAAe,GAAG;IAC3B,mBAAmB;;;ACLvB;;AAEG;;;;"}
@@ -1,6 +1,6 @@
1
1
  import { isPlatformBrowser } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { inject, input, booleanAttribute, output, ElementRef, Renderer2, PLATFORM_ID, HostListener, HostBinding, Directive } from '@angular/core';
3
+ import { inject, input, booleanAttribute, output, ElementRef, Renderer2, PLATFORM_ID, Directive } from '@angular/core';
4
4
  import { NgControl } from '@angular/forms';
5
5
  import { TranslateService } from '@ngx-translate/core';
6
6
  import { Subject } from 'rxjs';
@@ -240,38 +240,24 @@ class EclFileUploadDirective extends ECLBaseDirective {
240
240
  return `${parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`;
241
241
  }
242
242
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EclFileUploadDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
243
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.2", type: EclFileUploadDirective, isStandalone: true, selector: "[eclFileUpload]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, isInvalid: { classPropertyName: "isInvalid", publicName: "isInvalid", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filesSelected: "filesSelected" }, host: { listeners: { "click": "onClick($event)", "change": "onFilesSelected($event)" }, properties: { "attr.id": "this.id", "attr.disabled": "this.disabled", "attr.multiple": "this.multiple", "attr.type": "this.type", "class": "this.cssClasses", "class.ecl-file-upload--invalid": "this.invalidState" } }, usesInheritance: true, ngImport: i0 }); }
243
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.2", type: EclFileUploadDirective, isStandalone: true, selector: "[eclFileUpload]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, isInvalid: { classPropertyName: "isInvalid", publicName: "isInvalid", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filesSelected: "filesSelected" }, host: { listeners: { "click": "onClick($event)", "change": "onFilesSelected($event)" }, properties: { "attr.type": "type", "attr.id": "id()", "attr.disabled": "disabled() ? \"\" : null", "attr.multiple": "multiple() ? \"\" : null", "class": "cssClasses", "class.ecl-file-upload--invalid": "invalidState" } }, usesInheritance: true, ngImport: i0 }); }
244
244
  }
245
245
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: EclFileUploadDirective, decorators: [{
246
246
  type: Directive,
247
247
  args: [{
248
248
  selector: '[eclFileUpload]',
249
+ host: {
250
+ '[attr.type]': 'type',
251
+ '[attr.id]': 'id()',
252
+ '[attr.disabled]': 'disabled() ? "" : null',
253
+ '[attr.multiple]': 'multiple() ? "" : null',
254
+ '[class]': 'cssClasses',
255
+ '[class.ecl-file-upload--invalid]': 'invalidState',
256
+ '(click)': 'onClick($event)',
257
+ '(change)': 'onFilesSelected($event)',
258
+ },
249
259
  }]
250
- }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], isInvalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "isInvalid", required: false }] }], id: [{
251
- type: HostBinding,
252
- args: ['attr.id']
253
- }], disabled: [{
254
- type: HostBinding,
255
- args: ['attr.disabled']
256
- }], multiple: [{
257
- type: HostBinding,
258
- args: ['attr.multiple']
259
- }], filesSelected: [{ type: i0.Output, args: ["filesSelected"] }], type: [{
260
- type: HostBinding,
261
- args: ['attr.type']
262
- }], cssClasses: [{
263
- type: HostBinding,
264
- args: ['class']
265
- }], invalidState: [{
266
- type: HostBinding,
267
- args: ['class.ecl-file-upload--invalid']
268
- }], onClick: [{
269
- type: HostListener,
270
- args: ['click', ['$event']]
271
- }], onFilesSelected: [{
272
- type: HostListener,
273
- args: ['change', ['$event']]
274
- }] } });
260
+ }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], isInvalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "isInvalid", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], filesSelected: [{ type: i0.Output, args: ["filesSelected"] }] } });
275
261
 
276
262
  const EUI_ECL_FILE_UPLOAD = [
277
263
  EclFileUploadDirective,
@@ -1 +1 @@
1
- {"version":3,"file":"eui-ecl-components-ecl-file-upload.mjs","sources":["../../components/ecl-file-upload/events/ecl-file-upload-file-selected.event.ts","../../components/ecl-file-upload/ecl-file-upload.directive.ts","../../components/ecl-file-upload/index.ts","../../components/ecl-file-upload/eui-ecl-components-ecl-file-upload.ts"],"sourcesContent":["import { EclBaseEvent } from '@eui/ecl/core';\nimport { EclFileUpload } from '../models/ecl-file-upload.model';\n\n/**\n * Custom event emitted by the ECL file upload directive\n * when one or more files are selected.\n */\nexport class EclFileUploadFileSelectedEvent extends EclBaseEvent {\n /**\n * List of selected files.\n * Each file includes its name, extension, and formatted size.\n */\n constructor(public files: Array<EclFileUpload>) {\n super();\n }\n}\n","import { isPlatformBrowser } from '@angular/common';\nimport {\n Directive,\n DoCheck,\n ElementRef,\n HostBinding,\n HostListener,\n inject,\n OnDestroy,\n OnInit,\n PLATFORM_ID,\n Renderer2,\n booleanAttribute,\n output,\n input,\n} from '@angular/core';\nimport { NgControl } from '@angular/forms';\nimport { TranslateService } from '@ngx-translate/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { ECLBaseDirective } from '@eui/ecl/core';\nimport { EclFileUpload } from './models/ecl-file-upload.model';\nimport { EclFileUploadFileSelectedEvent } from './events/ecl-file-upload-file-selected.event';\n\n/**\n * Directive that enhances a native input[type=file] with ECL-compliant styling and behavior.\n * Supports multiple file selection, dynamic file list rendering, translations and validation state.\n */\n@Directive({\n selector: '[eclFileUpload]',\n})\nexport class EclFileUploadDirective extends ECLBaseDirective implements OnInit, OnDestroy, DoCheck {\n protected ngControl = inject(NgControl, { optional: true, self: true });\n\n /**\n * Variant of the component's appearance. Currently unused. Default: `'default'`.\n */\n readonly variant = input('default');\n\n /**\n * Marks the component as invalid (if not using Angular form validation).\n */\n readonly isInvalid = input(false, { transform: booleanAttribute });\n\n /**\n * ID attribute applied to the native file input.\n */\n @HostBinding('attr.id')\n readonly id = input<string>(undefined);\n\n /**\n * Whether the component is disabled.\n */\n @HostBinding('attr.disabled')\n readonly disabled = input<boolean, unknown>(undefined, { transform: booleanAttribute });\n\n /**\n * Allows selecting multiple files.\n */\n @HostBinding('attr.multiple')\n readonly multiple = input<boolean, unknown>(undefined, { transform: booleanAttribute });\n\n /**\n * Event emitted when files are selected.\n */\n readonly filesSelected = output<EclFileUploadFileSelectedEvent>();\n\n /**\n * Host binding to define input type as 'file'.\n */\n @HostBinding('attr.type') type = 'file';\n\n private fileListEl: HTMLElement;\n\n private files: EclFileUpload[] = [];\n private buttonEl: HTMLElement;\n private labelEl: HTMLElement;\n private destroy$: Subject<boolean> = new Subject<boolean>();\n private readonly SPAN_BUTTON_CONVERSION_CLASSES = ['ecl-button', 'ecl-button--primary', 'ecl-file-upload__button'];\n private el = inject(ElementRef);\n private translate = inject(TranslateService);\n private renderer = inject(Renderer2);\n private platformId = inject(PLATFORM_ID);\n\n /**\n * Applies the base `ecl-file-upload` class to the host element.\n */\n @HostBinding('class')\n get cssClasses(): string {\n return [super.getCssClasses('ecl-file-upload')].join(' ').trim();\n }\n\n /**\n * Returns `true` if component should be displayed as invalid.\n * Prioritizes Angular form control status over `isInvalid` input.\n */\n @HostBinding('class.ecl-file-upload--invalid')\n get invalidState(): boolean {\n if (this.ngControl) {\n return this.ngControl.status === 'INVALID' && this.ngControl.touched;\n } else {\n return this.isInvalid();\n }\n }\n\n /**\n * Initializes component structure and translation subscription (browser-only).\n */\n ngOnInit(): void {\n if (isPlatformBrowser(this.platformId)) {\n this.createDOMStructure();\n this.handleTranslations();\n }\n }\n\n /**\n * Clean up resources and RxJS subscriptions.\n */\n ngOnDestroy(): void {\n this.destroy$.next(true);\n this.destroy$.unsubscribe();\n }\n\n /**\n * Checks component state during change detection to toggle the disabled state of internal elements.\n */\n ngDoCheck(): void {\n if (this.disabled()) {\n this.renderer.setAttribute(this.buttonEl, 'disabled', 'true');\n } else {\n this.renderer.removeAttribute(this.buttonEl, 'disabled');\n }\n }\n\n /**\n * Prevents file dialog from opening when component is disabled.\n * @param evt Click event on the input element.\n */\n @HostListener('click', ['$event']) onClick(evt: Event): void {\n if (this.disabled()) {\n evt.preventDefault();\n }\n }\n\n /**\n * Handles file selection and emits a structured file selection event.\n * @param evt Change event from input.\n */\n @HostListener('change', ['$event']) onFilesSelected(evt: Event): void {\n const inputElement: HTMLInputElement = evt.target as HTMLInputElement;\n const fileList: FileList = inputElement.files;\n this.files = this.getFileModels(fileList);\n\n const fileEvent = new EclFileUploadFileSelectedEvent(this.files);\n this.filesSelected.emit(fileEvent);\n\n if (!fileEvent.defaultPrevented) {\n this.handleTranslations();\n this.updateListItemsDOM(this.files);\n }\n }\n\n private handleTranslations(): void {\n const uploadButtonLabelKey = this.geti18nUploadButtonLabelKey();\n\n this.translate\n .stream(uploadButtonLabelKey)\n .pipe(takeUntil(this.destroy$))\n .subscribe((translation: string) => {\n if (this.buttonEl) {\n this.renderer.setProperty(this.buttonEl, 'textContent', translation);\n }\n });\n }\n\n private geti18nUploadButtonLabelKey(): string {\n let key = '';\n\n if (this.files && this.files.length !== 0) {\n if (this.multiple()) {\n key = 'ecl.file-upload.REPLACE-FILES';\n } else {\n key = 'ecl.file-upload.REPLACE-FILE';\n }\n } else {\n if (this.multiple()) {\n key = 'ecl.file-upload.CHOOSE-FILES';\n } else {\n key = 'ecl.file-upload.CHOOSE-FILE';\n }\n }\n\n return key;\n }\n\n private updateListItemsDOM(files: EclFileUpload[]): void {\n this.renderer.setProperty(this.fileListEl, 'textContent', '');\n files.forEach((file) => {\n const item = this.createFileListItemDOMElement(file);\n this.renderer.appendChild(this.fileListEl, item);\n });\n }\n\n private createDOMStructure(): void {\n const labelEl = this.createLabelDOMElement();\n const hostEl = this.getHostDOMElement();\n const fileListEl = this.createFileListDOMElement();\n\n hostEl.insertAdjacentElement('afterend', fileListEl);\n hostEl.insertAdjacentElement('afterend', labelEl);\n\n this.fileListEl = fileListEl;\n }\n\n private getHostDOMElement(): HTMLInputElement {\n return this.el.nativeElement;\n }\n\n private createLabelDOMElement(): HTMLElement {\n this.buttonEl = this.renderer.createElement('span');\n this.addClasses(this.buttonEl, this.SPAN_BUTTON_CONVERSION_CLASSES);\n\n this.labelEl = this.renderer.createElement('label');\n this.renderer.setAttribute(this.labelEl, 'for', this.id());\n this.renderer.addClass(this.labelEl, 'ecl-file-upload__button-container');\n\n this.renderer.appendChild(this.labelEl, this.buttonEl);\n\n return this.labelEl;\n }\n\n private addClasses(element: HTMLElement, classes: string[] ): void {\n classes.forEach(className=> this.renderer.addClass(element, className) )\n }\n\n private createFileListDOMElement(): HTMLElement {\n const element = this.renderer.createElement('ul');\n this.renderer.addClass(element,'ecl-file-upload__list');\n this.renderer.setAttribute(element,'aria-live','polite');\n\n return element;\n }\n\n private createFileListItemDOMElement(fileUpload: EclFileUpload): HTMLElement {\n const liElement = this.renderer.createElement('li');\n this.renderer.addClass(liElement,'ecl-file-upload__item');\n\n const fileNameElement = this.renderer.createElement('span');\n const fileName = this.renderer.createText(fileUpload.name);\n this.renderer.appendChild(fileNameElement, fileName);\n\n this.renderer.addClass( fileNameElement,'ecl-file-upload__item-name' );\n\n const fileMetaElement = this.renderer.createElement('span');\n\n const fileMetaElementText = this.renderer.createText(`(${fileUpload.size} - ${fileUpload.extension})`);\n this.renderer.appendChild(fileMetaElement, fileMetaElementText);\n this.renderer.addClass(fileMetaElement, 'ecl-file-upload__item-meta');\n\n this.renderer.appendChild(liElement, fileNameElement);\n this.renderer.appendChild(liElement, fileMetaElement);\n\n return liElement;\n }\n\n private getFileModels(fileList: FileList): EclFileUpload[] {\n return Array.from(fileList).map((f) => ({\n name: f.name,\n extension: this.getFilenameExtension(f.name),\n size: this.formatBytes(f.size),\n }));\n }\n\n private getFilenameExtension(filename: string): string {\n return filename.split('.').pop();\n }\n\n private formatBytes(bytes, decimals = 2): string {\n if (bytes === 0) {\n return '0 Bytes';\n }\n\n const k = 1024;\n const dm = decimals < 0 ? 0 : decimals;\n const sizes = ['Bytes', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`;\n }\n}\n","import { EclFileUploadDirective } from './ecl-file-upload.directive';\n\nexport * from './ecl-file-upload.directive';\nexport * from './models/ecl-file-upload.model';\nexport * from './events/ecl-file-upload-file-selected.event';\n\nexport const EUI_ECL_FILE_UPLOAD = [\n EclFileUploadDirective,\n] as const;","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"eui-ecl-components-ecl-file-upload.mjs","sources":["../../components/ecl-file-upload/events/ecl-file-upload-file-selected.event.ts","../../components/ecl-file-upload/ecl-file-upload.directive.ts","../../components/ecl-file-upload/index.ts","../../components/ecl-file-upload/eui-ecl-components-ecl-file-upload.ts"],"sourcesContent":["import { EclBaseEvent } from '@eui/ecl/core';\nimport { EclFileUpload } from '../models/ecl-file-upload.model';\n\n/**\n * Custom event emitted by the ECL file upload directive\n * when one or more files are selected.\n */\nexport class EclFileUploadFileSelectedEvent extends EclBaseEvent {\n /**\n * List of selected files.\n * Each file includes its name, extension, and formatted size.\n */\n constructor(public files: Array<EclFileUpload>) {\n super();\n }\n}\n","import { isPlatformBrowser } from '@angular/common';\nimport {\n Directive,\n DoCheck,\n ElementRef,\n inject,\n OnDestroy,\n OnInit,\n PLATFORM_ID,\n Renderer2,\n booleanAttribute,\n output,\n input,\n} from '@angular/core';\nimport { NgControl } from '@angular/forms';\nimport { TranslateService } from '@ngx-translate/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { ECLBaseDirective } from '@eui/ecl/core';\nimport { EclFileUpload } from './models/ecl-file-upload.model';\nimport { EclFileUploadFileSelectedEvent } from './events/ecl-file-upload-file-selected.event';\n\n/**\n * Directive that enhances a native input[type=file] with ECL-compliant styling and behavior.\n * Supports multiple file selection, dynamic file list rendering, translations and validation state.\n */\n@Directive({\n selector: '[eclFileUpload]',\n host: {\n '[attr.type]': 'type',\n '[attr.id]': 'id()',\n '[attr.disabled]': 'disabled() ? \"\" : null',\n '[attr.multiple]': 'multiple() ? \"\" : null',\n '[class]': 'cssClasses',\n '[class.ecl-file-upload--invalid]': 'invalidState',\n '(click)': 'onClick($event)',\n '(change)': 'onFilesSelected($event)',\n },\n})\nexport class EclFileUploadDirective extends ECLBaseDirective implements OnInit, OnDestroy, DoCheck {\n protected ngControl = inject(NgControl, { optional: true, self: true });\n\n /**\n * Variant of the component's appearance. Currently unused. Default: `'default'`.\n */\n readonly variant = input('default');\n\n /**\n * Marks the component as invalid (if not using Angular form validation).\n */\n readonly isInvalid = input(false, { transform: booleanAttribute });\n\n /**\n * ID attribute applied to the native file input.\n */\n readonly id = input<string>(undefined);\n\n /**\n * Whether the component is disabled.\n */\n readonly disabled = input<boolean, unknown>(undefined, { transform: booleanAttribute });\n\n /**\n * Allows selecting multiple files.\n */\n readonly multiple = input<boolean, unknown>(undefined, { transform: booleanAttribute });\n\n /**\n * Event emitted when files are selected.\n */\n readonly filesSelected = output<EclFileUploadFileSelectedEvent>();\n\n /**\n * Host binding to define input type as 'file'.\n */\n type = 'file';\n\n private fileListEl: HTMLElement;\n\n private files: EclFileUpload[] = [];\n private buttonEl: HTMLElement;\n private labelEl: HTMLElement;\n private destroy$: Subject<boolean> = new Subject<boolean>();\n private readonly SPAN_BUTTON_CONVERSION_CLASSES = ['ecl-button', 'ecl-button--primary', 'ecl-file-upload__button'];\n private el = inject(ElementRef);\n private translate = inject(TranslateService);\n private renderer = inject(Renderer2);\n private platformId = inject(PLATFORM_ID);\n\n /**\n * Applies the base `ecl-file-upload` class to the host element.\n */\n get cssClasses(): string {\n return [super.getCssClasses('ecl-file-upload')].join(' ').trim();\n }\n\n /**\n * Returns `true` if component should be displayed as invalid.\n * Prioritizes Angular form control status over `isInvalid` input.\n */\n get invalidState(): boolean {\n if (this.ngControl) {\n return this.ngControl.status === 'INVALID' && this.ngControl.touched;\n } else {\n return this.isInvalid();\n }\n }\n\n /**\n * Initializes component structure and translation subscription (browser-only).\n */\n ngOnInit(): void {\n if (isPlatformBrowser(this.platformId)) {\n this.createDOMStructure();\n this.handleTranslations();\n }\n }\n\n /**\n * Clean up resources and RxJS subscriptions.\n */\n ngOnDestroy(): void {\n this.destroy$.next(true);\n this.destroy$.unsubscribe();\n }\n\n /**\n * Checks component state during change detection to toggle the disabled state of internal elements.\n */\n ngDoCheck(): void {\n if (this.disabled()) {\n this.renderer.setAttribute(this.buttonEl, 'disabled', 'true');\n } else {\n this.renderer.removeAttribute(this.buttonEl, 'disabled');\n }\n }\n\n /**\n * Prevents file dialog from opening when component is disabled.\n * @param evt Click event on the input element.\n */\n onClick(evt: Event): void {\n if (this.disabled()) {\n evt.preventDefault();\n }\n }\n\n /**\n * Handles file selection and emits a structured file selection event.\n * @param evt Change event from input.\n */\n onFilesSelected(evt: Event): void {\n const inputElement: HTMLInputElement = evt.target as HTMLInputElement;\n const fileList: FileList = inputElement.files;\n this.files = this.getFileModels(fileList);\n\n const fileEvent = new EclFileUploadFileSelectedEvent(this.files);\n this.filesSelected.emit(fileEvent);\n\n if (!fileEvent.defaultPrevented) {\n this.handleTranslations();\n this.updateListItemsDOM(this.files);\n }\n }\n\n private handleTranslations(): void {\n const uploadButtonLabelKey = this.geti18nUploadButtonLabelKey();\n\n this.translate\n .stream(uploadButtonLabelKey)\n .pipe(takeUntil(this.destroy$))\n .subscribe((translation: string) => {\n if (this.buttonEl) {\n this.renderer.setProperty(this.buttonEl, 'textContent', translation);\n }\n });\n }\n\n private geti18nUploadButtonLabelKey(): string {\n let key = '';\n\n if (this.files && this.files.length !== 0) {\n if (this.multiple()) {\n key = 'ecl.file-upload.REPLACE-FILES';\n } else {\n key = 'ecl.file-upload.REPLACE-FILE';\n }\n } else {\n if (this.multiple()) {\n key = 'ecl.file-upload.CHOOSE-FILES';\n } else {\n key = 'ecl.file-upload.CHOOSE-FILE';\n }\n }\n\n return key;\n }\n\n private updateListItemsDOM(files: EclFileUpload[]): void {\n this.renderer.setProperty(this.fileListEl, 'textContent', '');\n files.forEach((file) => {\n const item = this.createFileListItemDOMElement(file);\n this.renderer.appendChild(this.fileListEl, item);\n });\n }\n\n private createDOMStructure(): void {\n const labelEl = this.createLabelDOMElement();\n const hostEl = this.getHostDOMElement();\n const fileListEl = this.createFileListDOMElement();\n\n hostEl.insertAdjacentElement('afterend', fileListEl);\n hostEl.insertAdjacentElement('afterend', labelEl);\n\n this.fileListEl = fileListEl;\n }\n\n private getHostDOMElement(): HTMLInputElement {\n return this.el.nativeElement;\n }\n\n private createLabelDOMElement(): HTMLElement {\n this.buttonEl = this.renderer.createElement('span');\n this.addClasses(this.buttonEl, this.SPAN_BUTTON_CONVERSION_CLASSES);\n\n this.labelEl = this.renderer.createElement('label');\n this.renderer.setAttribute(this.labelEl, 'for', this.id());\n this.renderer.addClass(this.labelEl, 'ecl-file-upload__button-container');\n\n this.renderer.appendChild(this.labelEl, this.buttonEl);\n\n return this.labelEl;\n }\n\n private addClasses(element: HTMLElement, classes: string[] ): void {\n classes.forEach(className=> this.renderer.addClass(element, className) )\n }\n\n private createFileListDOMElement(): HTMLElement {\n const element = this.renderer.createElement('ul');\n this.renderer.addClass(element,'ecl-file-upload__list');\n this.renderer.setAttribute(element,'aria-live','polite');\n\n return element;\n }\n\n private createFileListItemDOMElement(fileUpload: EclFileUpload): HTMLElement {\n const liElement = this.renderer.createElement('li');\n this.renderer.addClass(liElement,'ecl-file-upload__item');\n\n const fileNameElement = this.renderer.createElement('span');\n const fileName = this.renderer.createText(fileUpload.name);\n this.renderer.appendChild(fileNameElement, fileName);\n\n this.renderer.addClass( fileNameElement,'ecl-file-upload__item-name' );\n\n const fileMetaElement = this.renderer.createElement('span');\n\n const fileMetaElementText = this.renderer.createText(`(${fileUpload.size} - ${fileUpload.extension})`);\n this.renderer.appendChild(fileMetaElement, fileMetaElementText);\n this.renderer.addClass(fileMetaElement, 'ecl-file-upload__item-meta');\n\n this.renderer.appendChild(liElement, fileNameElement);\n this.renderer.appendChild(liElement, fileMetaElement);\n\n return liElement;\n }\n\n private getFileModels(fileList: FileList): EclFileUpload[] {\n return Array.from(fileList).map((f) => ({\n name: f.name,\n extension: this.getFilenameExtension(f.name),\n size: this.formatBytes(f.size),\n }));\n }\n\n private getFilenameExtension(filename: string): string {\n return filename.split('.').pop();\n }\n\n private formatBytes(bytes, decimals = 2): string {\n if (bytes === 0) {\n return '0 Bytes';\n }\n\n const k = 1024;\n const dm = decimals < 0 ? 0 : decimals;\n const sizes = ['Bytes', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`;\n }\n}\n","import { EclFileUploadDirective } from './ecl-file-upload.directive';\n\nexport * from './ecl-file-upload.directive';\nexport * from './models/ecl-file-upload.model';\nexport * from './events/ecl-file-upload-file-selected.event';\n\nexport const EUI_ECL_FILE_UPLOAD = [\n EclFileUploadDirective,\n] as const;","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"eui-ecl-components-ecl-icon.mjs","sources":["../../components/ecl-icon/ecl-icon.component.ts","../../components/ecl-icon/ecl-icon.component.html","../../components/ecl-icon/index.ts","../../components/ecl-icon/eui-ecl-components-ecl-icon.ts"],"sourcesContent":["import { isPlatformBrowser, NgClass } from '@angular/common';\nimport {\n afterNextRender,\n booleanAttribute,\n Component,\n computed,\n ElementRef,\n HostBinding,\n inject,\n input,\n OnChanges,\n OnDestroy,\n OnInit,\n PLATFORM_ID,\n Renderer2,\n signal,\n SimpleChanges,\n viewChild,\n} from '@angular/core';\nimport { ECLBaseDirective, EclThemeService } from '@eui/ecl/core';\n\n/**\n * ECL icon component – renders SVG icons from various sets depending on current theme.\n * Integrates with ECL theming and supports accessibility options.\n */\n@Component({\n selector: 'ecl-icon',\n templateUrl: './ecl-icon.component.html',\n hostDirectives: [\n {\n directive: ECLBaseDirective,\n },\n ],\n imports: [NgClass],\n providers: [EclThemeService],\n host: {\n '[class.ecl-icon--flip-horizontal]': 'isFlipHorizontal()',\n },\n})\nexport class EclIconComponent implements OnInit, OnChanges, OnDestroy {\n /**\n * Defines the icon set to use.\n * Available sets: `default`, `social`, `social-media`, `flag`, or a custom URL prefix.\n * Defaults to `'default'`.\n */\n iconSet = input<'default' | 'social' | 'social-media' | 'social-media-color' | 'flag' | 'flag-non-members' |\n 'phosphor' | string>('default');\n\n /**\n * Name of the icon to render from the selected set.\n */\n icon = input<string>();\n\n /**\n * Size of the icon.\n * Supported values: `'2xs'`, `'xs'`, `'s'`, `'m'`, `'l'`, `'xl'`, `'2xl'`, `'fluid'`.\n * Defaults to `'xs'`.\n */\n size = input<'2xs' | 'xs' | 's' | 'm' | 'l' | 'xl' | '2xl' | 'fluid' | string>('xs');\n\n /**\n * Applies color styling to the icon.\n * Use `'inverted'` for icons on dark backgrounds, or `'primary'` for emphasis.\n */\n color = input<'inverted' | 'primary' | null>(null);\n\n /**\n * Adds a transformation modifier to the icon (e.g., rotation).\n */\n transform = input<string>();\n\n /**\n * ID reference for an external element that labels this icon for screen readers.\n */\n readonly ariaLabelledby = input<string>(undefined);\n\n /**\n * ARIA role of the icon. If a `title` is provided and no role is defined, defaults to `'img'`.\n */\n readonly role = input<string>(undefined);\n\n /**\n * Title used for accessibility. Also affects `aria-hidden` and `role`.\n */\n readonly title = input<string>(undefined);\n\n /**\n * Determines whether the icon should be hidden from assistive technologies.\n * Defaults to `true` unless a title is provided.\n */\n readonly ariaHidden = input<boolean, unknown>(undefined, { transform: booleanAttribute });\n\n /**\n * Controls whether the icon is focusable via keyboard.\n * Defaults to `false`.\n */\n readonly focusable = input(false, { transform: booleanAttribute });\n\n /**\n * Resolved role: uses the explicit `role` input if provided,\n * otherwise defaults to `'img'` when a `title` is set.\n */\n readonly effectiveRole = computed<string | undefined>(() => {\n const explicit = this.role();\n if (explicit !== undefined) return explicit;\n return this.title() !== undefined ? 'img' : undefined;\n });\n\n /**\n * Resolved aria-hidden: uses the explicit `ariaHidden` input if provided,\n * otherwise hides the icon unless a `title` is set.\n */\n readonly effectiveAriaHidden = computed<boolean>(() => {\n const explicit = this.ariaHidden();\n if (explicit !== undefined) return explicit;\n return this.title() === undefined;\n });\n\n /**\n * Flips the icon horizontally if set to `true`.\n */\n readonly isFlipHorizontal = input(false, { transform: booleanAttribute });\n\n /**\n * Adds a dark background utility class if the color is set to `'inverted'`.\n */\n @HostBinding('class.ecl-u-bg-grey')\n get isColorInverted(): boolean {\n return this.color() === 'inverted';\n }\n\n readonly svgEl = viewChild<ElementRef>('svg');\n\n iconUrl = signal<string>('');\n baseDirective = inject(ECLBaseDirective);\n el = inject(ElementRef);\n private renderer = inject(Renderer2);\n private platformId = inject(PLATFORM_ID);\n\n /**\n * Extra classes added programmatically by parent components\n * (button, link, etc.)\n */\n readonly extraClasses = signal<string>('');\n\n /**\n * Real classes currently present on <ecl-icon>.\n * To support [class.foo] / [ngClass].\n */\n readonly hostClasses = signal<string>('');\n\n readonly svgClasses = computed<Record<string, boolean>>(() => {\n return {\n [this.baseDirective.getCssClasses('ecl-icon')]: true,\n [`ecl-icon--${this.size()}`]: !!this.size(),\n [`ecl-icon--${this.transform()}`]: !!this.transform(),\n [`ecl-icon--${this.color()}`]: !!this.color(),\n ...this.toClassRecord(this.hostClasses()),\n ...this.toClassRecord(this.extraClasses()),\n };\n });\n\n private classObserver?: MutationObserver;\n\n constructor() {\n afterNextRender(() => {\n this.detachHostAndPromoteSvg();\n this.syncHostClassesFromDom();\n this.observeHostClassChanges();\n });\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['icon']) {\n this.initiateIconUrl();\n }\n }\n\n ngOnInit(): void {\n this.initiateIconUrl();\n }\n\n ngOnDestroy(): void {\n this.classObserver?.disconnect();\n if (!isPlatformBrowser(this.platformId)) return;\n\n try {\n const svgNative = this.svgEl()?.nativeElement as SVGElement | null;\n const parent = svgNative?.parentElement;\n if (svgNative && parent) parent.removeChild(svgNative);\n } catch {\n /* ignore */\n }\n }\n\n addExtraClass(className: string): void {\n const classes = new Set([\n ...this.tokenize(this.extraClasses()),\n ...this.tokenize(className),\n ]);\n this.extraClasses.set(Array.from(classes).join(' '));\n }\n\n removeExtraClass(className: string): void {\n const classes = this.tokenize(this.extraClasses()).filter((c) => c !== className);\n this.extraClasses.set(classes.join(' '));\n }\n\n setExtraClasses(classes: string): void {\n this.extraClasses.set(classes ?? '');\n }\n\n private syncHostClassesFromDom(): void {\n const host = this.el.nativeElement;\n this.hostClasses.set(host.className || '');\n }\n\n private observeHostClassChanges(): void {\n const host = this.el.nativeElement;\n\n this.classObserver = new MutationObserver(() => {\n this.hostClasses.set(host.className || '');\n });\n\n this.classObserver.observe(host, {\n attributes: true,\n attributeFilter: ['class'],\n });\n }\n\n private toClassRecord(classes?: string | null): Record<string, boolean> {\n return Object.fromEntries(\n this.tokenize(classes).map(c => [c, true])\n );\n }\n\n private tokenize(classes: string | null | undefined): string[] {\n return (classes ?? '')\n .split(/\\s+/)\n .filter(Boolean);\n }\n\n private detachHostAndPromoteSvg(): void {\n const hostEl = this.el.nativeElement as HTMLElement | null;\n const svgNative = this.svgEl()?.nativeElement as SVGElement | null;\n if (!hostEl || !svgNative) return;\n\n const hostParentEl = hostEl.parentElement;\n if (!hostParentEl) return;\n\n // add the svg and remove the parent from the DOM\n this.renderer.setStyle(hostEl, 'visibility', 'hidden');\n hostEl.after(svgNative);\n this.renderer.removeChild(hostParentEl, hostEl);\n }\n\n private initiateIconUrl(): void {\n switch (this.iconSet()) {\n case 'default':\n this.iconUrl.set(`assets/images/ecl/icons/sprite.svg#${this.icon()}`);\n break;\n case 'social': // TODO: Remove this in the next version.\n this.iconUrl.set(`assets/images/ecl/networks/sprite.svg#${this.icon()}`);\n break;\n case 'social-media':\n this.iconUrl.set(`assets/images/ecl/networks/sprite.svg#${this.icon()}`);\n break;\n case 'social-media-color':\n this.iconUrl.set(`assets/images/ecl/networks-color/sprite.svg#${this.icon()}`);\n break;\n case 'flag':\n this.iconUrl.set(`assets/images/ecl/icons-flag/sprites/icons-flag.svg#${this.icon()}`);\n break;\n case 'flag-non-members':\n this.iconUrl.set(`assets/images/ecl/icons-flag/sprites/icons-flag-non-members.svg#${this.icon()}`);\n break;\n case 'phosphor':\n this.iconUrl.set(`assets/icons/sprites/regular.svg#${this.icon()}`);\n break;\n case 'phosphor-fill':\n this.iconUrl.set(`assets/icons/sprites/fill.svg#${this.icon()}`);\n break;\n default:\n this.iconUrl.set(`assets/images/ecl/icons/sprite.svg#${this.icon()}`);\n }\n }\n}\n","<svg\n #svg\n [ngClass]=\"svgClasses()\"\n [attr.aria-hidden]=\"effectiveAriaHidden()\"\n [attr.aria-labelledby]=\"ariaLabelledby() || null\"\n [attr.role]=\"effectiveRole() || null\"\n [attr.focusable]=\"focusable()\">\n @if (title()) {\n <title>{{title()}}</title>\n }\n <use [attr.href]=\"iconUrl()\"></use>\n <ng-content></ng-content>\n</svg>\n","import { EclIconComponent } from './ecl-icon.component';\n\nexport * from './ecl-icon.component';\n\nexport const EUI_ECL_ICON = [\n EclIconComponent,\n] as const;","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"eui-ecl-components-ecl-icon.mjs","sources":["../../components/ecl-icon/ecl-icon.component.ts","../../components/ecl-icon/ecl-icon.component.html","../../components/ecl-icon/index.ts","../../components/ecl-icon/eui-ecl-components-ecl-icon.ts"],"sourcesContent":["import { isPlatformBrowser, NgClass } from '@angular/common';\nimport {\n afterNextRender,\n booleanAttribute,\n Component,\n computed,\n ElementRef,\n HostBinding,\n inject,\n input,\n OnChanges,\n OnDestroy,\n OnInit,\n PLATFORM_ID,\n Renderer2,\n signal,\n SimpleChanges,\n viewChild,\n} from '@angular/core';\nimport { ECLBaseDirective, EclThemeService } from '@eui/ecl/core';\n\n/**\n * ECL icon component – renders SVG icons from various sets depending on current theme.\n * Integrates with ECL theming and supports accessibility options.\n */\n@Component({\n selector: 'ecl-icon',\n templateUrl: './ecl-icon.component.html',\n hostDirectives: [\n {\n directive: ECLBaseDirective,\n },\n ],\n imports: [NgClass],\n providers: [EclThemeService],\n host: {\n '[class.ecl-icon--flip-horizontal]': 'isFlipHorizontal()',\n },\n})\nexport class EclIconComponent implements OnInit, OnChanges, OnDestroy {\n /**\n * Defines the icon set to use.\n * Available sets: `default`, `social`, `social-media`, `flag`, or a custom URL prefix.\n * Defaults to `'default'`.\n */\n iconSet = input<'default' | 'social' | 'social-media' | 'social-media-color' | 'flag' | 'flag-non-members' |\n 'phosphor' | 'phosphor-fill' | string>('default');\n\n /**\n * Name of the icon to render from the selected set.\n */\n icon = input<string>();\n\n /**\n * Size of the icon.\n * Supported values: `'2xs'`, `'xs'`, `'s'`, `'m'`, `'l'`, `'xl'`, `'2xl'`, `'fluid'`.\n * Defaults to `'xs'`.\n */\n size = input<'2xs' | 'xs' | 's' | 'm' | 'l' | 'xl' | '2xl' | 'fluid' | string>('xs');\n\n /**\n * Applies color styling to the icon.\n * Use `'inverted'` for icons on dark backgrounds, or `'primary'` for emphasis.\n */\n color = input<'inverted' | 'primary' | null>(null);\n\n /**\n * Adds a transformation modifier to the icon (e.g., rotation).\n */\n transform = input<string>();\n\n /**\n * ID reference for an external element that labels this icon for screen readers.\n */\n readonly ariaLabelledby = input<string>(undefined);\n\n /**\n * ARIA role of the icon. If a `title` is provided and no role is defined, defaults to `'img'`.\n */\n readonly role = input<string>(undefined);\n\n /**\n * Title used for accessibility. Also affects `aria-hidden` and `role`.\n */\n readonly title = input<string>(undefined);\n\n /**\n * Determines whether the icon should be hidden from assistive technologies.\n * Defaults to `true` unless a title is provided.\n */\n readonly ariaHidden = input<boolean, unknown>(undefined, { transform: booleanAttribute });\n\n /**\n * Controls whether the icon is focusable via keyboard.\n * Defaults to `false`.\n */\n readonly focusable = input(false, { transform: booleanAttribute });\n\n /**\n * Resolved role: uses the explicit `role` input if provided,\n * otherwise defaults to `'img'` when a `title` is set.\n */\n readonly effectiveRole = computed<string | undefined>(() => {\n const explicit = this.role();\n if (explicit !== undefined) return explicit;\n return this.title() !== undefined ? 'img' : undefined;\n });\n\n /**\n * Resolved aria-hidden: uses the explicit `ariaHidden` input if provided,\n * otherwise hides the icon unless a `title` is set.\n */\n readonly effectiveAriaHidden = computed<boolean>(() => {\n const explicit = this.ariaHidden();\n if (explicit !== undefined) return explicit;\n return this.title() === undefined;\n });\n\n /**\n * Flips the icon horizontally if set to `true`.\n */\n readonly isFlipHorizontal = input(false, { transform: booleanAttribute });\n\n /**\n * Adds a dark background utility class if the color is set to `'inverted'`.\n */\n @HostBinding('class.ecl-u-bg-grey')\n get isColorInverted(): boolean {\n return this.color() === 'inverted';\n }\n\n readonly svgEl = viewChild<ElementRef>('svg');\n\n iconUrl = signal<string>('');\n baseDirective = inject(ECLBaseDirective);\n el = inject(ElementRef);\n private renderer = inject(Renderer2);\n private platformId = inject(PLATFORM_ID);\n\n /**\n * Extra classes added programmatically by parent components\n * (button, link, etc.)\n */\n readonly extraClasses = signal<string>('');\n\n /**\n * Real classes currently present on <ecl-icon>.\n * To support [class.foo] / [ngClass].\n */\n readonly hostClasses = signal<string>('');\n\n readonly svgClasses = computed<Record<string, boolean>>(() => {\n return {\n [this.baseDirective.getCssClasses('ecl-icon')]: true,\n [`ecl-icon--${this.size()}`]: !!this.size(),\n [`ecl-icon--${this.transform()}`]: !!this.transform(),\n [`ecl-icon--${this.color()}`]: !!this.color(),\n ...this.toClassRecord(this.hostClasses()),\n ...this.toClassRecord(this.extraClasses()),\n };\n });\n\n private classObserver?: MutationObserver;\n\n constructor() {\n afterNextRender(() => {\n this.detachHostAndPromoteSvg();\n this.syncHostClassesFromDom();\n this.observeHostClassChanges();\n });\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['icon']) {\n this.initiateIconUrl();\n }\n }\n\n ngOnInit(): void {\n this.initiateIconUrl();\n }\n\n ngOnDestroy(): void {\n this.classObserver?.disconnect();\n if (!isPlatformBrowser(this.platformId)) return;\n\n try {\n const svgNative = this.svgEl()?.nativeElement as SVGElement | null;\n const parent = svgNative?.parentElement;\n if (svgNative && parent) parent.removeChild(svgNative);\n } catch {\n /* ignore */\n }\n }\n\n addExtraClass(className: string): void {\n const classes = new Set([\n ...this.tokenize(this.extraClasses()),\n ...this.tokenize(className),\n ]);\n this.extraClasses.set(Array.from(classes).join(' '));\n }\n\n removeExtraClass(className: string): void {\n const classes = this.tokenize(this.extraClasses()).filter((c) => c !== className);\n this.extraClasses.set(classes.join(' '));\n }\n\n setExtraClasses(classes: string): void {\n this.extraClasses.set(classes ?? '');\n }\n\n private syncHostClassesFromDom(): void {\n const host = this.el.nativeElement;\n this.hostClasses.set(host.className || '');\n }\n\n private observeHostClassChanges(): void {\n const host = this.el.nativeElement;\n\n this.classObserver = new MutationObserver(() => {\n this.hostClasses.set(host.className || '');\n });\n\n this.classObserver.observe(host, {\n attributes: true,\n attributeFilter: ['class'],\n });\n }\n\n private toClassRecord(classes?: string | null): Record<string, boolean> {\n return Object.fromEntries(\n this.tokenize(classes).map(c => [c, true])\n );\n }\n\n private tokenize(classes: string | null | undefined): string[] {\n return (classes ?? '')\n .split(/\\s+/)\n .filter(Boolean);\n }\n\n private detachHostAndPromoteSvg(): void {\n const hostEl = this.el.nativeElement as HTMLElement | null;\n const svgNative = this.svgEl()?.nativeElement as SVGElement | null;\n if (!hostEl || !svgNative) return;\n\n const hostParentEl = hostEl.parentElement;\n if (!hostParentEl) return;\n\n // add the svg and remove the parent from the DOM\n this.renderer.setStyle(hostEl, 'visibility', 'hidden');\n hostEl.after(svgNative);\n this.renderer.removeChild(hostParentEl, hostEl);\n }\n\n private initiateIconUrl(): void {\n switch (this.iconSet()) {\n case 'default':\n this.iconUrl.set(`assets/images/ecl/icons/sprite.svg#${this.icon()}`);\n break;\n case 'social': // TODO: Remove this in the next version.\n this.iconUrl.set(`assets/images/ecl/networks/sprite.svg#${this.icon()}`);\n break;\n case 'social-media':\n this.iconUrl.set(`assets/images/ecl/networks/sprite.svg#${this.icon()}`);\n break;\n case 'social-media-color':\n this.iconUrl.set(`assets/images/ecl/networks-color/sprite.svg#${this.icon()}`);\n break;\n case 'flag':\n this.iconUrl.set(`assets/images/ecl/icons-flag/sprites/icons-flag.svg#${this.icon()}`);\n break;\n case 'flag-non-members':\n this.iconUrl.set(`assets/images/ecl/icons-flag/sprites/icons-flag-non-members.svg#${this.icon()}`);\n break;\n case 'phosphor':\n this.iconUrl.set(`assets/icons/sprites/regular.svg#${this.icon()}`);\n break;\n case 'phosphor-fill':\n this.iconUrl.set(`assets/icons/sprites/fill.svg#${this.icon()}`);\n break;\n default:\n this.iconUrl.set(`assets/images/ecl/icons/sprite.svg#${this.icon()}`);\n }\n }\n}\n","<svg\n #svg\n [ngClass]=\"svgClasses()\"\n [attr.aria-hidden]=\"effectiveAriaHidden()\"\n [attr.aria-labelledby]=\"ariaLabelledby() || null\"\n [attr.role]=\"effectiveRole() || null\"\n [attr.focusable]=\"focusable()\">\n @if (title()) {\n <title>{{title()}}</title>\n }\n <use [attr.href]=\"iconUrl()\"></use>\n <ng-content></ng-content>\n</svg>\n","import { EclIconComponent } from './ecl-icon.component';\n\nexport * from './ecl-icon.component';\n\nexport const EUI_ECL_ICON = [\n EclIconComponent,\n] as const;","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -243,6 +243,12 @@ class EclInpageNavigationComponent extends ECLBaseDirective {
243
243
  this.destroy$ = new Subject();
244
244
  this.isMobileBreakpoint = false;
245
245
  this.MIN_DISTANCE_TOP = 10;
246
+ /**
247
+ * Extra spacing (px) kept between the sticky toggler and the target heading when scrolling to a section on mobile,
248
+ * so the heading is not flush against the toggler. Mirrors the spacing buffer used by the vanilla ECL
249
+ * `scroll-margin-top` rule (trigger height + spacing).
250
+ */
251
+ this.MOBILE_SCROLL_SPACING = 16;
246
252
  this.ICON_SIZE_EC_THEME = '2xs';
247
253
  this.ICON_SIZE_EU_THEME = 's';
248
254
  this.TABLET_BREAKPOINT = 996;
@@ -321,8 +327,15 @@ class EclInpageNavigationComponent extends ECLBaseDirective {
321
327
  * On mobile view - handle the dropdown toggle.
322
328
  */
323
329
  onExpandButtonClick() {
324
- this.isButtonExpanded = !this.isButtonExpanded;
325
- this.eclInpageNavigationService.eclInpageNavigationToggle(this.isButtonExpanded);
330
+ this.setButtonExpanded(!this.isButtonExpanded);
331
+ }
332
+ /**
333
+ * Single entry point for changing the dropdown expanded state. Keeps the local flag (used for the button's
334
+ * aria-expanded) and the shared service state (that drives the list's visibility class) in sync.
335
+ */
336
+ setButtonExpanded(isExpanded) {
337
+ this.isButtonExpanded = isExpanded;
338
+ this.eclInpageNavigationService.eclInpageNavigationToggle(isExpanded);
326
339
  }
327
340
  /**
328
341
  * Dropdown keyboard navigation on mobile view.
@@ -386,7 +399,7 @@ class EclInpageNavigationComponent extends ECLBaseDirective {
386
399
  }
387
400
  onExpandButtonArrowDown(evt) {
388
401
  evt.preventDefault();
389
- this.isButtonExpanded = true;
402
+ this.setButtonExpanded(true);
390
403
  this.eclNavigationLinkItems().at(0).onFocus();
391
404
  }
392
405
  onExpandButtonTab(evt) {
@@ -411,23 +424,50 @@ class EclInpageNavigationComponent extends ECLBaseDirective {
411
424
  item.itemClick.pipe(takeUntil$1(this.destroy$)).subscribe((evt) => {
412
425
  this.selectNavigationItem(item.sectionElement);
413
426
  if (item.sectionElement) {
414
- item.sectionElement.scrollIntoView();
427
+ this.scrollToSection(item.sectionElement);
415
428
  item.sectionElement.focus();
416
429
  }
417
- this.isButtonExpanded = false;
430
+ this.setButtonExpanded(false);
418
431
  });
419
432
  }
420
433
  onItemEnter(item) {
421
434
  this.selectNavigationItem(item.sectionElement);
422
435
  if (item.sectionElement) {
423
- item.sectionElement.scrollIntoView();
436
+ this.scrollToSection(item.sectionElement);
424
437
  if (item.sectionElement.tabIndex === -1) {
425
438
  item.sectionElement.tabIndex = 0;
426
439
  item.sectionElement.focus();
427
440
  item.sectionElement.tabIndex = -1;
428
441
  }
429
442
  }
430
- this.isButtonExpanded = false;
443
+ this.setButtonExpanded(false);
444
+ }
445
+ /**
446
+ * Scrolls the target section into view. On desktop this is a plain scrollIntoView() (unchanged behaviour). On
447
+ * mobile the in-page navigation toggler is sticky at the top, so a top-aligned scroll would hide the heading
448
+ * underneath it; we therefore set `scroll-margin-top` on the target (sticky toggler height + spacing buffer) and
449
+ * let scrollIntoView() honour it. Using scroll-margin-top instead of a manual window.scrollTo() keeps this working
450
+ * regardless of which element is the actual scroll container (window or a nested scrollable wrapper).
451
+ */
452
+ scrollToSection(sectionElement) {
453
+ if (!this.isBrowser)
454
+ return;
455
+ const offset = this.getMobileScrollOffset();
456
+ sectionElement.style.scrollMarginTop = offset > 0 ? `${offset}px` : '';
457
+ sectionElement.scrollIntoView();
458
+ }
459
+ /**
460
+ * The offset (px) applied on mobile so that a scrolled-to heading clears the sticky toggler: the toggler height
461
+ * plus a spacing buffer. Returns 0 on desktop (no sticky toggler). Shared by the scroll logic and the scroll-spy
462
+ * so the heading lands exactly where the spy expects it, keeping the active item in sync after a click.
463
+ */
464
+ getMobileScrollOffset() {
465
+ if (!this.isMobileBreakpoint)
466
+ return 0;
467
+ const toggleWrapper = this.toggleWrapper()?.nativeElement;
468
+ if (!toggleWrapper)
469
+ return 0;
470
+ return toggleWrapper.getBoundingClientRect().height + this.MOBILE_SCROLL_SPACING;
431
471
  }
432
472
  onItemArrowDown(item) {
433
473
  const index = this.eclNavigationLinkItems().indexOf(item);
@@ -444,7 +484,7 @@ class EclInpageNavigationComponent extends ECLBaseDirective {
444
484
  else {
445
485
  const togglerButton = this.togglerButton();
446
486
  if (this.isMobileBreakpoint && togglerButton) {
447
- this.isButtonExpanded = false;
487
+ this.setButtonExpanded(false);
448
488
  togglerButton.nativeElement.focus();
449
489
  }
450
490
  }
@@ -497,7 +537,13 @@ class EclInpageNavigationComponent extends ECLBaseDirective {
497
537
  if (!this.isBrowser || !this.win)
498
538
  return null;
499
539
  let currentSection = null;
500
- const offset = this.MIN_DISTANCE_TOP + (this.offsetTop() ?? 0);
540
+ // On mobile the heading is scrolled to sit just below the sticky toggler, so the spy must use that same
541
+ // offset; otherwise it would highlight the previous section. The extra MIN_DISTANCE_TOP is a cushion so a
542
+ // heading that lands right on the boundary (sub-pixel rounding) is still treated as "reached". On desktop
543
+ // keep the original threshold.
544
+ const offset = this.isMobileBreakpoint
545
+ ? this.getMobileScrollOffset() + this.MIN_DISTANCE_TOP
546
+ : this.MIN_DISTANCE_TOP + (this.offsetTop() ?? 0);
501
547
  const isNearBottom = this.win.innerHeight + this.win.scrollY >=
502
548
  this.doc.documentElement.scrollHeight - 10;
503
549
  for (const sectionElement of sectionElements) {