@eui/ecl 22.0.0-alpha.4 → 22.0.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8457,13 +8457,13 @@
8457
8457
  },
8458
8458
  {
8459
8459
  "name": "EclSocialMediaFollowItemClickEvent",
8460
- "id": "class-EclSocialMediaFollowItemClickEvent-a5a386ce91d38e0d4ebb07c2085b8c669354f1a816b2677b7dde9628c9a14908687d7a7d0f9f6e66e8172233d257ac2a1145254275a03f9216caa201b32c6018",
8460
+ "id": "class-EclSocialMediaFollowItemClickEvent-be2bc74a52d7b183206e23fa9c6edd0706816decad401fed2ccd0e2788dead5b1d6dbb066556634b97683220c7111e50c45fd911c2cccbe1ec6738847a5e6fdf",
8461
8461
  "file": "packages/ecl/components/ecl-social-media-follow/ecl-social-media-follow-item.component.ts",
8462
8462
  "coverageIgnore": false,
8463
8463
  "deprecated": false,
8464
8464
  "deprecationMessage": "",
8465
8465
  "type": "class",
8466
- "sourceCode": "import { booleanAttribute, Component, inject, input, output } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { EUI_ECL_ICON } from '@eui/ecl/components/ecl-icon';\nimport { EclBaseEvent } from '@eui/ecl/core';\nimport { ECLBaseDirective } from '@eui/ecl/core';\nimport { EUI_ECL_LINK } from '@eui/ecl/components/ecl-link';\nimport { RouterLink, RouterLinkWithHref } from '@angular/router';\nimport { EclSocialMediaFollowComponent } from './ecl-social-media-follow.component';\n\nexport class EclSocialMediaFollowItemClickEvent extends EclBaseEvent {}\n\n@Component({\n selector: 'ecl-social-media-follow-item',\n templateUrl: './ecl-social-media-follow-item.component.html',\n imports: [...EUI_ECL_ICON, ...EUI_ECL_LINK, NgTemplateOutlet, RouterLink, RouterLinkWithHref],\n host: {\n 'role': 'listitem',\n '[class]': 'cssClasses',\n },\n})\nexport class EclSocialMediaFollowItemComponent extends ECLBaseDirective {\n readonly isInverted = input<false, unknown>(undefined, { transform: (booleanAttribute) as any });\n icon = input<string>();\n iconSet = input<string>('social-media');\n readonly href = input('');\n readonly routerLink = input('');\n readonly target = input<string>(undefined);\n readonly size = input('m');\n readonly extraAttributes = input<{\n name: string;\n value?: string | null;\n }[]>(undefined);\n\n private parent = inject(EclSocialMediaFollowComponent);\n\n get isIconOnly(): boolean {\n return this.parent?.isIconOnly() ?? false;\n }\n\n get cssClasses(): string {\n return [super.getCssClasses('ecl-social-media-follow__item')].join(' ').trim();\n }\n\n readonly itemClick = output<EclSocialMediaFollowItemClickEvent>();\n\n onItemClick(evt): void {\n this.itemClick.emit(new EclSocialMediaFollowItemClickEvent());\n if (!this.href() && !this.routerLink()) {\n evt.preventDefault();\n }\n }\n}\n",
8466
+ "sourceCode": "import { booleanAttribute, Component, inject, input, output } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { EUI_ECL_ICON } from '@eui/ecl/components/ecl-icon';\nimport { EclBaseEvent } from '@eui/ecl/core';\nimport { ECLBaseDirective } from '@eui/ecl/core';\nimport { EUI_ECL_LINK } from '@eui/ecl/components/ecl-link';\nimport { RouterLink, RouterLinkWithHref } from '@angular/router';\nimport { EclSocialMediaFollowComponent } from './ecl-social-media-follow.component';\n\nexport class EclSocialMediaFollowItemClickEvent extends EclBaseEvent {}\n\n@Component({\n selector: 'ecl-social-media-follow-item',\n templateUrl: './ecl-social-media-follow-item.component.html',\n imports: [...EUI_ECL_ICON, ...EUI_ECL_LINK, NgTemplateOutlet, RouterLink, RouterLinkWithHref],\n host: {\n role: 'listitem',\n '[class]': 'cssClasses',\n },\n})\nexport class EclSocialMediaFollowItemComponent extends ECLBaseDirective {\n readonly isInverted = input<false, unknown>(undefined, { transform: (booleanAttribute) as any });\n icon = input<string>();\n iconSet = input<string>('social-media');\n readonly href = input('');\n readonly routerLink = input('');\n readonly target = input<string>(undefined);\n readonly size = input('m');\n readonly extraAttributes = input<{\n name: string;\n value?: string | null;\n }[]>(undefined);\n\n get cssClasses(): string {\n return [super.getCssClasses('ecl-social-media-follow__item')].join(' ').trim();\n }\n\n readonly itemClick = output<EclSocialMediaFollowItemClickEvent>();\n\n private parent = inject(EclSocialMediaFollowComponent);\n\n get isIconOnly(): boolean {\n return this.parent?.isIconOnly() ?? false;\n }\n\n onItemClick(evt: Event): void {\n this.itemClick.emit(new EclSocialMediaFollowItemClickEvent());\n if (!this.href() && !this.routerLink()) {\n evt.preventDefault();\n }\n }\n}\n",
8467
8467
  "displayName": "EclSocialMediaFollowItemClickEvent",
8468
8468
  "inputsClass": [],
8469
8469
  "outputsClass": [],
@@ -22604,12 +22604,12 @@
22604
22604
  },
22605
22605
  {
22606
22606
  "name": "EclLinkDirective",
22607
- "id": "directive-EclLinkDirective-739a62b701c6c8fceceac1560ad0dbc240f3b0b4168c9009ce68f360a71af9549945dc5181e5e24dd52baf85cc6540f26d5614d44ffa294316e0d4d71e65874f",
22607
+ "id": "directive-EclLinkDirective-fb6b45fe7d77a582abd56929a240d6a1418c1ca58d979b7d3c29ff7989887b38145c46f3cd3c8055fcab7abe78119fa333c24d646e16e636785744a886b96932",
22608
22608
  "file": "packages/ecl/components/ecl-link/ecl-link.directive.ts",
22609
22609
  "type": "directive",
22610
22610
  "description": "<p>&#39;eclLink&#39; directive is used to add some styling to the defalt HTML anchor component. In order to comply with ECL standards.</p>\n",
22611
22611
  "rawdescription": "\n\n'eclLink' directive is used to add some styling to the defalt HTML anchor component. In order to comply with ECL standards.\n",
22612
- "sourceCode": "import { AfterContentInit, booleanAttribute, ChangeDetectorRef, contentChildren, Directive, ElementRef, HostBinding, inject, input, Renderer2, effect, computed, forwardRef } from '@angular/core';\nimport { EclIconComponent } from '@eui/ecl/components/ecl-icon';\nimport { ECLBaseDirective } from '@eui/ecl/core';\n\n/**\n * 'eclLink' directive is used to add some styling to the defalt HTML anchor component. In order to comply with ECL standards.\n */\n@Directive({\n selector: '[eclLink]',\n})\nexport class EclLinkDirective extends ECLBaseDirective implements AfterContentInit {\n el = inject(ElementRef);\n renderer = inject(Renderer2);\n cd = inject(ChangeDetectorRef);\n\n /**\n * Additional HTML attributes to be set on the link element.\n * Used e.g. by social-media-follow for passing extra_attributes.\n */\n extraAttributes = input<{ name: string; value?: string | null }[] | undefined>();\n\n /**\n * Property to style the component as 'inverted' (with dark background). Can be used alone or with 'standalone' variant.\n */\n isInverted = input(false, { transform: booleanAttribute });\n\n /**\n * Property to style the component if it consist only of an icon.\n */\n isIconOnly = input(false, { transform: booleanAttribute });\n\n /** Adds class for hightlighted link (works only with 'primary' variant)\n * @deprecated - to be removed in v23. Use variant='primary-highlight', as only primary variant can be highlighted.\n */\n isHighlight = input(false, { transform: booleanAttribute });\n\n /**\n * @deprecated - will be removed in v21. Deprecated on ECL side.\n */\n isNoVisited = input(false, { transform: booleanAttribute });\n\n isBranded = input(false, { transform: booleanAttribute });\n\n /**\n * With 'variant' property user can add some more specific styling to the <a> component.\n */\n variant = input<'standalone' | 'primary' | 'secondary' | 'secondary-neutral' | 'primary-neutral' | 'primary-highlight'>();\n\n eclIconComponents = contentChildren(forwardRef(() => EclIconComponent), { descendants: true });\n\n constructor() {\n super();\n effect(() => {\n const attrs = this.extraAttributes();\n if (attrs && attrs.length) {\n attrs.forEach((attr) => {\n if (attr?.name) {\n this.el.nativeElement.setAttribute(attr.name, attr.value ?? '');\n }\n });\n }\n });\n }\n\n @HostBinding('class.ecl-link--inverted')\n get hostIsInverted(): boolean {\n return (!this.variant() || this.variant() === 'standalone') && this.isInverted();\n }\n\n @HostBinding('class.ecl-link--brand')\n get hostIsBranded(): boolean {\n return (!this.variant() || this.variant() === 'standalone') && this.isBranded();\n }\n\n @HostBinding('class.ecl-link--icon-only')\n get hostIsIconOnly(): boolean {\n return this.isIconOnly();\n }\n\n @HostBinding('class.ecl-link--icon')\n get hasIcon(): boolean {\n return this._hasIcon();\n }\n\n private _hasIcon = computed(() => {\n return this.eclIconComponents()?.length > 0;\n });\n\n /**\n * Adds speific ECL classes to the <a> component.\n */\n @HostBinding('class')\n get cssClasses(): string {\n const variantClass = this.variant()\n ? (this.variant() === 'secondary' && this.isInverted()\n ? 'ecl-link--secondary-inverted'\n : `ecl-link--${this.variant()}`)\n : '';\n\n return [super.getCssClasses('ecl-link'),\n variantClass,\n (this.variant() === 'primary' && this.isHighlight()) ? 'ecl-link--primary-highlight' : '',\n ].join(' ').trim();\n }\n\n ngAfterContentInit(): void {\n // Add additional class to the child icon, if any.\n if (this.eclIconComponents()?.length > 0 ) {\n setTimeout(() => {\n this.eclIconComponents().forEach((icn) => {\n icn.addExtraClass('ecl-link__icon');\n });\n this.cd.markForCheck();\n });\n }\n }\n\n /**\n * Calls the native focus() method of the default HTML element.\n */\n onFocus(): void {\n this.el.nativeElement.focus();\n }\n\n /**\n * Calls the native click() method of the default HTML element.\n */\n onClick(): void {\n this.el.nativeElement.click();\n }\n\n /**\n * Calls the native blur() method of the default HTML element.\n */\n onBlur(): void {\n this.el.nativeElement.blur();\n }\n}\n",
22612
+ "sourceCode": "import { booleanAttribute, contentChildren, Directive, ElementRef, HostBinding, inject, input, Renderer2, effect, computed, forwardRef } from '@angular/core';\nimport { EclIconComponent } from '@eui/ecl/components/ecl-icon';\nimport { ECLBaseDirective } from '@eui/ecl/core';\n\n/**\n * 'eclLink' directive is used to add some styling to the defalt HTML anchor component. In order to comply with ECL standards.\n */\n@Directive({\n selector: '[eclLink]',\n})\nexport class EclLinkDirective extends ECLBaseDirective {\n el = inject(ElementRef);\n renderer = inject(Renderer2);\n\n /**\n * Additional HTML attributes to be set on the link element.\n * Used e.g. by social-media-follow for passing extra_attributes.\n */\n extraAttributes = input<{ name: string; value?: string | null }[] | undefined>();\n\n /**\n * Property to style the component as 'inverted' (with dark background). Can be used alone or with 'standalone' variant.\n */\n isInverted = input(false, { transform: booleanAttribute });\n\n /**\n * Property to style the component if it consist only of an icon.\n */\n isIconOnly = input(false, { transform: booleanAttribute });\n\n /** Adds class for hightlighted link (works only with 'primary' variant)\n * @deprecated - to be removed in v23. Use variant='primary-highlight', as only primary variant can be highlighted.\n */\n isHighlight = input(false, { transform: booleanAttribute });\n\n /**\n * @deprecated - will be removed in v21. Deprecated on ECL side.\n */\n isNoVisited = input(false, { transform: booleanAttribute });\n\n isBranded = input(false, { transform: booleanAttribute });\n\n /**\n * With 'variant' property user can add some more specific styling to the <a> component.\n */\n variant = input<'standalone' | 'primary' | 'secondary' | 'secondary-neutral' | 'primary-neutral' | 'primary-highlight'>();\n\n eclIconComponents = contentChildren(forwardRef(() => EclIconComponent), { descendants: true });\n\n constructor() {\n super();\n effect(() => {\n const attrs = this.extraAttributes();\n if (attrs && attrs.length) {\n attrs.forEach((attr) => {\n if (attr?.name) {\n this.el.nativeElement.setAttribute(attr.name, attr.value ?? '');\n }\n });\n }\n });\n\n // Add 'ecl-link__icon' class to child icons reactively.\n effect(() => {\n const icons = this.eclIconComponents();\n if (icons?.length > 0) {\n icons.forEach((icn) => {\n icn.addExtraClass('ecl-link__icon');\n });\n }\n });\n }\n\n @HostBinding('class.ecl-link--inverted')\n get hostIsInverted(): boolean {\n return (!this.variant() || this.variant() === 'standalone') && this.isInverted();\n }\n\n @HostBinding('class.ecl-link--brand')\n get hostIsBranded(): boolean {\n return (!this.variant() || this.variant() === 'standalone') && this.isBranded();\n }\n\n @HostBinding('class.ecl-link--icon-only')\n get hostIsIconOnly(): boolean {\n return this.isIconOnly();\n }\n\n @HostBinding('class.ecl-link--icon')\n get hasIcon(): boolean {\n return this._hasIcon();\n }\n\n private _hasIcon = computed(() => {\n return this.eclIconComponents()?.length > 0;\n });\n\n /**\n * Adds speific ECL classes to the <a> component.\n */\n @HostBinding('class')\n get cssClasses(): string {\n const variantClass = this.variant()\n ? (this.variant() === 'secondary' && this.isInverted()\n ? 'ecl-link--secondary-inverted'\n : `ecl-link--${this.variant()}`)\n : '';\n\n return [super.getCssClasses('ecl-link'),\n variantClass,\n (this.variant() === 'primary' && this.isHighlight()) ? 'ecl-link--primary-highlight' : '',\n ].join(' ').trim();\n }\n\n /**\n * Calls the native focus() method of the default HTML element.\n */\n onFocus(): void {\n this.el.nativeElement.focus();\n }\n\n /**\n * Calls the native click() method of the default HTML element.\n */\n onClick(): void {\n this.el.nativeElement.click();\n }\n\n /**\n * Calls the native blur() method of the default HTML element.\n */\n onBlur(): void {\n this.el.nativeElement.blur();\n }\n}\n",
22613
22613
  "selector": "[eclLink]",
22614
22614
  "providers": [],
22615
22615
  "hostDirectives": [],
@@ -22624,7 +22624,7 @@
22624
22624
  "indexKey": "",
22625
22625
  "optional": false,
22626
22626
  "description": "<p>Additional HTML attributes to be set on the link element.\nUsed e.g. by social-media-follow for passing extra_attributes.</p>\n",
22627
- "line": 20,
22627
+ "line": 19,
22628
22628
  "rawdescription": "\n\nAdditional HTML attributes to be set on the link element.\nUsed e.g. by social-media-follow for passing extra_attributes.\n",
22629
22629
  "required": false
22630
22630
  },
@@ -22638,7 +22638,7 @@
22638
22638
  "indexKey": "",
22639
22639
  "optional": false,
22640
22640
  "description": "",
22641
- "line": 42,
22641
+ "line": 41,
22642
22642
  "rawdescription": "\n",
22643
22643
  "required": false
22644
22644
  },
@@ -22652,20 +22652,20 @@
22652
22652
  "indexKey": "",
22653
22653
  "optional": false,
22654
22654
  "description": "<p>Adds class for hightlighted link (works only with &#39;primary&#39; variant)</p>\n",
22655
- "line": 35,
22655
+ "line": 34,
22656
22656
  "rawdescription": "\nAdds class for hightlighted link (works only with 'primary' variant)\n",
22657
22657
  "jsdoctags": [
22658
22658
  {
22659
- "pos": 1354,
22660
- "end": 1471,
22659
+ "pos": 1253,
22660
+ "end": 1370,
22661
22661
  "kind": 332,
22662
22662
  "id": 0,
22663
22663
  "flags": 16842752,
22664
22664
  "modifierFlagsCache": 0,
22665
22665
  "transformFlags": 0,
22666
22666
  "tagName": {
22667
- "pos": 1355,
22668
- "end": 1365,
22667
+ "pos": 1254,
22668
+ "end": 1264,
22669
22669
  "kind": 80,
22670
22670
  "id": 0,
22671
22671
  "flags": 16842752,
@@ -22687,7 +22687,7 @@
22687
22687
  "indexKey": "",
22688
22688
  "optional": false,
22689
22689
  "description": "<p>Property to style the component if it consist only of an icon.</p>\n",
22690
- "line": 30,
22690
+ "line": 29,
22691
22691
  "rawdescription": "\n\nProperty to style the component if it consist only of an icon.\n",
22692
22692
  "required": false
22693
22693
  },
@@ -22701,7 +22701,7 @@
22701
22701
  "indexKey": "",
22702
22702
  "optional": false,
22703
22703
  "description": "<p>Property to style the component as &#39;inverted&#39; (with dark background). Can be used alone or with &#39;standalone&#39; variant.</p>\n",
22704
- "line": 25,
22704
+ "line": 24,
22705
22705
  "rawdescription": "\n\nProperty to style the component as 'inverted' (with dark background). Can be used alone or with 'standalone' variant.\n",
22706
22706
  "required": false
22707
22707
  },
@@ -22715,20 +22715,20 @@
22715
22715
  "indexKey": "",
22716
22716
  "optional": false,
22717
22717
  "description": "",
22718
- "line": 40,
22718
+ "line": 39,
22719
22719
  "rawdescription": "\n\n",
22720
22720
  "jsdoctags": [
22721
22721
  {
22722
- "pos": 1555,
22723
- "end": 1622,
22722
+ "pos": 1454,
22723
+ "end": 1521,
22724
22724
  "kind": 332,
22725
22725
  "id": 0,
22726
22726
  "flags": 16842752,
22727
22727
  "modifierFlagsCache": 0,
22728
22728
  "transformFlags": 0,
22729
22729
  "tagName": {
22730
- "pos": 1556,
22731
- "end": 1566,
22730
+ "pos": 1455,
22731
+ "end": 1465,
22732
22732
  "kind": 80,
22733
22733
  "id": 0,
22734
22734
  "flags": 16842752,
@@ -22749,7 +22749,7 @@
22749
22749
  "indexKey": "",
22750
22750
  "optional": false,
22751
22751
  "description": "<p>With &#39;variant&#39; property user can add some more specific styling to the <a> component.</p>\n",
22752
- "line": 47,
22752
+ "line": 46,
22753
22753
  "rawdescription": "\n\nWith 'variant' property user can add some more specific styling to the <a> component.\n",
22754
22754
  "required": false
22755
22755
  },
@@ -22809,7 +22809,7 @@
22809
22809
  "deprecationMessage": "",
22810
22810
  "rawdescription": "\n\nAdds speific ECL classes to the <a> component.\n",
22811
22811
  "description": "<p>Adds speific ECL classes to the <a> component.</p>\n",
22812
- "line": 93,
22812
+ "line": 102,
22813
22813
  "type": "string",
22814
22814
  "decorators": []
22815
22815
  },
@@ -22821,7 +22821,7 @@
22821
22821
  "deprecationMessage": "",
22822
22822
  "rawdescription": "\n",
22823
22823
  "description": "",
22824
- "line": 71,
22824
+ "line": 80,
22825
22825
  "type": "boolean",
22826
22826
  "decorators": []
22827
22827
  },
@@ -22833,7 +22833,7 @@
22833
22833
  "deprecationMessage": "",
22834
22834
  "rawdescription": "\n",
22835
22835
  "description": "",
22836
- "line": 81,
22836
+ "line": 90,
22837
22837
  "type": "boolean",
22838
22838
  "decorators": []
22839
22839
  },
@@ -22845,7 +22845,7 @@
22845
22845
  "deprecationMessage": "",
22846
22846
  "rawdescription": "\n",
22847
22847
  "description": "",
22848
- "line": 76,
22848
+ "line": 85,
22849
22849
  "type": "boolean",
22850
22850
  "decorators": []
22851
22851
  },
@@ -22857,26 +22857,13 @@
22857
22857
  "deprecationMessage": "",
22858
22858
  "rawdescription": "\n",
22859
22859
  "description": "",
22860
- "line": 66,
22860
+ "line": 75,
22861
22861
  "type": "boolean",
22862
22862
  "decorators": []
22863
22863
  }
22864
22864
  ],
22865
22865
  "hostListeners": [],
22866
22866
  "propertiesClass": [
22867
- {
22868
- "name": "cd",
22869
- "coverageIgnore": false,
22870
- "defaultValue": "inject(ChangeDetectorRef)",
22871
- "deprecated": false,
22872
- "deprecationMessage": "",
22873
- "type": "unknown",
22874
- "indexKey": "",
22875
- "optional": false,
22876
- "description": "",
22877
- "line": 14,
22878
- "rawdescription": "\n"
22879
- },
22880
22867
  {
22881
22868
  "name": "eclIconComponents",
22882
22869
  "coverageIgnore": false,
@@ -22887,7 +22874,7 @@
22887
22874
  "indexKey": "",
22888
22875
  "optional": false,
22889
22876
  "description": "",
22890
- "line": 49,
22877
+ "line": 48,
22891
22878
  "rawdescription": "\n"
22892
22879
  },
22893
22880
  {
@@ -22918,19 +22905,6 @@
22918
22905
  }
22919
22906
  ],
22920
22907
  "methodsClass": [
22921
- {
22922
- "name": "ngAfterContentInit",
22923
- "coverageIgnore": false,
22924
- "args": [],
22925
- "optional": false,
22926
- "returnType": "void",
22927
- "typeParameters": [],
22928
- "line": 106,
22929
- "deprecated": false,
22930
- "deprecationMessage": "",
22931
- "rawdescription": "\n",
22932
- "description": ""
22933
- },
22934
22908
  {
22935
22909
  "name": "onBlur",
22936
22910
  "coverageIgnore": false,
@@ -22938,7 +22912,7 @@
22938
22912
  "optional": false,
22939
22913
  "returnType": "void",
22940
22914
  "typeParameters": [],
22941
- "line": 135,
22915
+ "line": 132,
22942
22916
  "deprecated": false,
22943
22917
  "deprecationMessage": "",
22944
22918
  "rawdescription": "\n\nCalls the native blur() method of the default HTML element.\n",
@@ -22951,7 +22925,7 @@
22951
22925
  "optional": false,
22952
22926
  "returnType": "void",
22953
22927
  "typeParameters": [],
22954
- "line": 128,
22928
+ "line": 125,
22955
22929
  "deprecated": false,
22956
22930
  "deprecationMessage": "",
22957
22931
  "rawdescription": "\n\nCalls the native click() method of the default HTML element.\n",
@@ -22964,7 +22938,7 @@
22964
22938
  "optional": false,
22965
22939
  "returnType": "void",
22966
22940
  "typeParameters": [],
22967
- "line": 121,
22941
+ "line": 118,
22968
22942
  "deprecated": false,
22969
22943
  "deprecationMessage": "",
22970
22944
  "rawdescription": "\n\nCalls the native focus() method of the default HTML element.\n",
@@ -23012,8 +22986,8 @@
23012
22986
  "coverageIgnore": false,
23013
22987
  "jsdoctags": [
23014
22988
  {
23015
- "pos": 312,
23016
- "end": 446,
22989
+ "pos": 275,
22990
+ "end": 409,
23017
22991
  "kind": 321,
23018
22992
  "id": 0,
23019
22993
  "flags": 16777216,
@@ -23025,16 +22999,13 @@
23025
22999
  "extends": [
23026
23000
  "ECLBaseDirective"
23027
23001
  ],
23028
- "implements": [
23029
- "AfterContentInit"
23030
- ],
23031
23002
  "constructorObj": {
23032
23003
  "name": "constructor",
23033
23004
  "description": "",
23034
23005
  "deprecated": false,
23035
23006
  "deprecationMessage": "",
23036
23007
  "args": [],
23037
- "line": 49,
23008
+ "line": 48,
23038
23009
  "rawdescription": "\n"
23039
23010
  },
23040
23011
  "accessors": {
@@ -23044,7 +23015,7 @@
23044
23015
  "name": "hostIsInverted",
23045
23016
  "type": "boolean",
23046
23017
  "returnType": "boolean",
23047
- "line": 66,
23018
+ "line": 75,
23048
23019
  "rawdescription": "\n",
23049
23020
  "description": ""
23050
23021
  }
@@ -23055,7 +23026,7 @@
23055
23026
  "name": "hostIsBranded",
23056
23027
  "type": "boolean",
23057
23028
  "returnType": "boolean",
23058
- "line": 71,
23029
+ "line": 80,
23059
23030
  "rawdescription": "\n",
23060
23031
  "description": ""
23061
23032
  }
@@ -23066,7 +23037,7 @@
23066
23037
  "name": "hostIsIconOnly",
23067
23038
  "type": "boolean",
23068
23039
  "returnType": "boolean",
23069
- "line": 76,
23040
+ "line": 85,
23070
23041
  "rawdescription": "\n",
23071
23042
  "description": ""
23072
23043
  }
@@ -23077,7 +23048,7 @@
23077
23048
  "name": "hasIcon",
23078
23049
  "type": "boolean",
23079
23050
  "returnType": "boolean",
23080
- "line": 81,
23051
+ "line": 90,
23081
23052
  "rawdescription": "\n",
23082
23053
  "description": ""
23083
23054
  }
@@ -23088,7 +23059,7 @@
23088
23059
  "name": "cssClasses",
23089
23060
  "type": "string",
23090
23061
  "returnType": "string",
23091
- "line": 93,
23062
+ "line": 102,
23092
23063
  "rawdescription": "\n\nAdds speific ECL classes to the <a> component.\n",
23093
23064
  "description": "<p>Adds speific ECL classes to the <a> component.</p>\n"
23094
23065
  }
@@ -23100,10 +23071,6 @@
23100
23071
  {
23101
23072
  "name": "ECLBaseDirective",
23102
23073
  "type": "directive"
23103
- },
23104
- {
23105
- "name": "AfterContentInit",
23106
- "type": "interface"
23107
23074
  }
23108
23075
  ]
23109
23076
  }
@@ -57095,7 +57062,7 @@
57095
57062
  },
57096
57063
  {
57097
57064
  "name": "EclIconComponent",
57098
- "id": "component-EclIconComponent-b815ca32f7e41bc74b5baa46b6d6a2147c83194ed861e5024ab8bf5cbf1aa0486c078ea66bdea8ad2cf93dd99889c8245886ada3238564160531c7978e632b73",
57065
+ "id": "component-EclIconComponent-098102385dea8ae19585b13531343588c38d879186ee8a691fc0aeb0f6cef41ef570f2be629b561695d0c3f13ebb52e8869d91e74ca8d7e05471f478e7ad412b",
57099
57066
  "file": "packages/ecl/components/ecl-icon/ecl-icon.component.ts",
57100
57067
  "encapsulation": [],
57101
57068
  "entryComponents": [],
@@ -57208,7 +57175,7 @@
57208
57175
  "defaultValue": "'default'",
57209
57176
  "deprecated": false,
57210
57177
  "deprecationMessage": "",
57211
- "type": "'default' | 'social' | 'social-media' | 'social-media-color' | 'flag' | 'flag-non-members' | 'phosphor' | string",
57178
+ "type": "'default' | 'social' | 'social-media' | 'social-media-color' | 'flag' | 'flag-non-members' | 'phosphor' | 'phosphor-fill' | string",
57212
57179
  "indexKey": "",
57213
57180
  "optional": false,
57214
57181
  "description": "<p>Defines the icon set to use.\nAvailable sets: <code>default</code>, <code>social</code>, <code>social-media</code>, <code>flag</code>, or a custom URL prefix.\nDefaults to <code>&#39;default&#39;</code>.</p>\n",
@@ -57628,7 +57595,7 @@
57628
57595
  "description": "<p>ECL icon component – renders SVG icons from various sets depending on current theme.\nIntegrates with ECL theming and supports accessibility options.</p>\n",
57629
57596
  "rawdescription": "\n\nECL icon component – renders SVG icons from various sets depending on current theme.\nIntegrates with ECL theming and supports accessibility options.\n",
57630
57597
  "type": "component",
57631
- "sourceCode": "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",
57598
+ "sourceCode": "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",
57632
57599
  "assetsDirs": [],
57633
57600
  "styleUrlsData": "",
57634
57601
  "stylesData": "",
@@ -64716,7 +64683,7 @@
64716
64683
  },
64717
64684
  {
64718
64685
  "name": "EclMenuItemComponent",
64719
- "id": "component-EclMenuItemComponent-34f452bf97feb65169901e0c06a1fb0de14d012edd6ec1567c23c2a3ff5f8da70e3e579ec2af4034ca2d8cca1fa411c32b4c899c2b8dfc1e89d67142e51d0cb8",
64686
+ "id": "component-EclMenuItemComponent-2e828b9fa40b69437b34ee8534c8041d5f0329c62e7f0de43e9f6bb1b0fc888748f0edb953a4cbcde823fcc0192e5393d366ce1c2ad78727e2b78670410f86bc",
64720
64687
  "file": "packages/ecl/components/ecl-menu/ecl-menu/ecl-menu-item.component.ts",
64721
64688
  "encapsulation": [
64722
64689
  "ViewEncapsulation.None"
@@ -65654,7 +65621,7 @@
65654
65621
  "description": "<p>This component represents a root menu item. Adds styling and functionality to menu item.</p>\n",
65655
65622
  "rawdescription": "\n\nThis component represents a root menu item. Adds styling and functionality to menu item.\n",
65656
65623
  "type": "component",
65657
- "sourceCode": "import { NgTemplateOutlet } from '@angular/common';\nimport {\n AfterContentInit,\n afterNextRender,\n Component,\n ElementRef,\n EventEmitter,\n forwardRef,\n inject,\n Input,\n OnDestroy,\n Output,\n Renderer2,\n ViewEncapsulation,\n DOCUMENT,\n input,\n contentChild,\n viewChild,\n booleanAttribute,\n} from '@angular/core';\nimport { Params, QueryParamsHandling, RouterLink, RouterLinkWithHref } from '@angular/router';\nimport { EuiAppShellService } from '@eui/core';\nimport { EclButtonComponent, EUI_ECL_BUTTON } from '@eui/ecl/components/ecl-button';\nimport { EUI_ECL_ICON } from '@eui/ecl/components/ecl-icon';\nimport { EUI_ECL_LINK } from '@eui/ecl/components/ecl-link';\nimport { ECLBaseDirective, KeyCode } from '@eui/ecl/core';\nimport { Subject } from 'rxjs';\nimport { distinctUntilChanged, map, takeUntil } from 'rxjs/operators';\nimport { EclMenuMegaComponent } from '../ecl-menu-mega';\nimport {\n EclMenuItemCaretEvent,\n EclMenuItemFocusEvent,\n EclMenuItemHoverEvent,\n EclMenuItemHoverOutEvent,\n EclMenuItemKeydownEvent,\n EclMenuItemParentFocusEvent,\n EclMenuItemSelectEvent,\n} from '../events';\nimport { EclMenuItem } from '../models/ecl-menu-item.model';\n\nconst enum ColTrigger {\n COL1_TRIGGER = 5,\n COL2_TRIGGER = 9,\n COL3_TRIGGER = 13,\n}\n\n/**\n * This component represents a root menu item. Adds styling and functionality to menu item.\n */\n@Component({\n selector: 'ecl-menu-item',\n templateUrl: './ecl-menu-item.component.html',\n imports: [NgTemplateOutlet, RouterLink, RouterLinkWithHref, ...EUI_ECL_BUTTON, ...EUI_ECL_ICON, ...EUI_ECL_LINK],\n encapsulation: ViewEncapsulation.None,\n host: {\n role: 'listitem',\n '[class]': 'cssClasses',\n '[class.ecl-menu__item--has-children]': 'hasEclChildrenDataAttribute',\n '[attr.aria-haspopup]': 'hasEclChildrenDataAttribute',\n '[attr.data-expanded]': 'isDataExpanded',\n '(mouseenter)': 'onItemMouseEnter($event)',\n '(mouseleave)': 'onItemMouseLeave($event)',\n },\n})\nexport class EclMenuItemComponent extends ECLBaseDirective implements EclMenuItem, AfterContentInit, OnDestroy {\n el = inject(ElementRef);\n\n @Input() id: string;\n @Input() label: string;\n /**\n * When in mobile view, use this property to set aria-label for the toggle items button (to expand item's children).\n */\n readonly toggleAriaLabel = input<string>(undefined);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly routerLink = input<string | any[]>(null);\n readonly queryParams = input<Params | null>(null);\n readonly queryParamsHandling = input<QueryParamsHandling>(null);\n @Input() href = '';\n readonly target = input('');\n @Input({ transform: booleanAttribute }) isCurrent = false;\n /**\n * Custom attributes, to be added to the <a> tag of the menu item.\n */\n readonly linkExtraAttributes = input<Record<string, string>>(undefined);\n\n isExpanded: boolean;\n /**\n * Set to 'true', when item has more than 13 chidren and the overlay needs to use the full available space.\n */\n isFull = false;\n isHovered = false;\n isMobileBreakpoint = false;\n /**\n * Used when menu has overlay, to show if the item is currently displayed.\n */\n isVisible = true;\n\n private readonly doc = inject(DOCUMENT);\n private readonly window = this.doc.defaultView; // Window | null\n\n /**\n * The default role of the item is 'listitem' and should not be changed.\n */\n get cssClasses(): string {\n return [\n super.getCssClasses('ecl-menu__item'),\n this.isCurrent ? 'ecl-menu__item--current' : '',\n this.isExpanded ? 'ecl-menu__item--expanded' : '',\n this.getClassDependingChildrenCnt(),\n ]\n .join(' ')\n .trim();\n }\n\n readonly submenu = contentChild(forwardRef(() => EclMenuMegaComponent));\n /**\n * The <a> element of the menu item, when there are no children.\n */\n readonly menuLink = viewChild<ElementRef<HTMLAnchorElement>>('menuLink');\n /**\n * The <button> element of the menu item, when item has children.\n */\n readonly menuButton = viewChild(EclButtonComponent);\n\n @Output() menuItemSelect = new EventEmitter<EclMenuItemSelectEvent>();\n @Output() menuItemCaret = new EventEmitter<EclMenuItemCaretEvent>();\n /**\n * Event that is emited on clicking the caret button to expand item's children in mobile mode.\n */\n @Output() menuItemHover = new EventEmitter<EclMenuItemHoverEvent>();\n @Output() menuItemHoverOut = new EventEmitter<EclMenuItemHoverOutEvent>();\n @Output() menuMegaItemSelect = new EventEmitter<EclMenuItemSelectEvent>();\n @Output() menuItemFocus = new EventEmitter<EclMenuItemFocusEvent>();\n @Output() menuItemKeydown = new EventEmitter<EclMenuItemKeydownEvent>();\n /**\n * This event is emited when the keyboard nav reaches the last item in mobile view.\n * Then the next focused element should be the 'close' btn.\n */\n @Output() menuMegaLastItemTab = new EventEmitter<void>();\n\n get hasEclChildrenDataAttribute(): boolean {\n return this.hasChildren || undefined;\n }\n\n get isDataExpanded(): boolean {\n return this.hasChildren ? this.isHovered : null;\n }\n\n /**\n * 'aria-current' is set to 'page' only when this item itself is the current page, and not when it is\n * marked current merely because one of its children is the active item (in that case the child link\n * carries 'aria-current=\"page\"'). Derived from live state so it stays correct whether 'isCurrent' is set\n * at render time or updated on selection.\n */\n get ariaCurrent(): string | null {\n return this.isCurrent && !this.hasCurrentChild ? 'page' : null;\n }\n\n /**\n * Whether any child (sub-item) is the current item.\n */\n get hasCurrentChild(): boolean {\n return this.children.some((child) => child.isCurrent);\n }\n\n get hasChildren(): boolean {\n return !!this.submenu();\n }\n\n get children(): EclMenuItem[] {\n return this.hasChildren ? this.submenu().eclMenuMegaItems.toArray() : [];\n }\n\n private destroy$: Subject<boolean> = new Subject<boolean>();\n private renderer = inject(Renderer2);\n private appShell = inject(EuiAppShellService);\n\n constructor() {\n super();\n afterNextRender(() => {\n this.observeBreakpointChanges();\n this.setExtraAttributesForLink(this.menuLink()?.nativeElement, this.linkExtraAttributes());\n });\n }\n\n onItemMouseEnter(evt: MouseEvent): void {\n if (this.isMobileBreakpoint) return;\n this.menuItemHover.next(new EclMenuItemHoverEvent(this, evt));\n }\n\n onItemMouseLeave(evt: MouseEvent): void {\n if (this.isMobileBreakpoint) return;\n this.menuItemHoverOut.next(new EclMenuItemHoverOutEvent(this, evt));\n }\n\n ngAfterContentInit(): void {\n // Subscibe to submenu component events.\n const submenu = this.submenu();\n if (submenu) {\n submenu.menuItemSelect.pipe(takeUntil(this.destroy$)).subscribe((it: EclMenuItemSelectEvent) => {\n this.menuMegaItemSelect.next(new EclMenuItemSelectEvent(it.menuItem, it.domEvent));\n });\n submenu.menuMegaItemParentFocus.pipe(takeUntil(this.destroy$)).subscribe((it: EclMenuItemParentFocusEvent) => {\n if (!this.isMobileBreakpoint) {\n this.onFocusFromSubmenu();\n }\n });\n submenu.menuMegaLastItemTab.pipe(takeUntil(this.destroy$)).subscribe(() => {\n if (this.isMobileBreakpoint) {\n this.menuMegaLastItemTab.next();\n }\n });\n\n if (this.hasSubmenuAnySelections()) {\n this.isCurrent = true;\n }\n }\n\n // this.tabindex = this.routerLink || this.href ? 0 : -1;\n }\n\n ngOnDestroy(): void {\n this.destroy$.next(true);\n this.destroy$.unsubscribe();\n }\n\n onItemFocus(evt: FocusEvent): void {\n this.menuItemFocus.next(new EclMenuItemFocusEvent(this, evt));\n }\n\n onItemClick(evt: Event): void {\n this.menuItemSelect.next(new EclMenuItemSelectEvent(this, evt));\n\n if (!this.href) {\n evt.stopPropagation();\n }\n }\n\n /**\n * When clicking the caret button, to expand item's children. Used in mobile view.\n * @param evt\n */\n onItemCaretClick(evt: MouseEvent): void {\n this.menuItemCaret.next(new EclMenuItemCaretEvent(this, evt));\n }\n\n /**\n * Manages the state when the item is focused, when navigating with keyboard and the navigation is coming from the submenu.\n */\n onFocusFromSubmenu(): void {\n this.onButtonFocus();\n this.isHovered = false;\n this.isExpanded = false;\n }\n\n /**\n * Manages the state when the item is focused, when navigating with keyboard and the navigation is coming from\n * the next root menu item.\n */\n onFocusFromNext(): void {\n if (this.menuButton()) {\n this.onButtonFocus();\n } else {\n this.onLinkFocus();\n }\n }\n\n /**\n * Manages the state when the item is focused, when navigating with keyboard and the navigation is coming from\n * the previous root menu item.\n */\n onFocusFromPrev(): void {\n this.onLinkFocus();\n }\n\n /**\n * Manages the keyboard navigation when the current element is the button of the menu item.\n * @param evt\n */\n onButtonKeydown(evt: Event): void {\n switch ((evt as KeyboardEvent).key) {\n case KeyCode.ARROW_DOWN: {\n evt.preventDefault();\n if (this.isHovered) {\n this.selectFirstMegaMenuItem();\n } else {\n this.menuItemKeydown.next(new EclMenuItemKeydownEvent(this, evt as KeyboardEvent));\n }\n break;\n }\n case KeyCode.ARROW_UP: {\n evt.preventDefault();\n this.onLinkFocus();\n break;\n }\n case KeyCode.ARROW_RIGHT: {\n evt.preventDefault();\n this.menuItemKeydown.next(new EclMenuItemKeydownEvent(this, evt as KeyboardEvent));\n break;\n }\n case KeyCode.ARROW_LEFT: {\n evt.preventDefault();\n this.onLinkFocus();\n break;\n }\n case KeyCode.TAB: {\n this.menuItemKeydown.next(new EclMenuItemKeydownEvent(this, evt as KeyboardEvent));\n break;\n }\n case KeyCode.ENTER: {\n evt.preventDefault();\n this.menuItemKeydown.next(new EclMenuItemKeydownEvent(this, evt as KeyboardEvent));\n break;\n }\n case KeyCode.ESCAPE: {\n evt.preventDefault();\n this.menuItemKeydown.next(new EclMenuItemKeydownEvent(this, evt as KeyboardEvent));\n break;\n }\n default: {\n break;\n }\n }\n }\n\n /**\n * Manages the keyboard navigation when the current element is the <a> tag of the menu item.\n * @param evt\n */\n onLinkKeydown(evt: Event): void {\n switch ((evt as KeyboardEvent).key) {\n case KeyCode.ARROW_DOWN: {\n evt.preventDefault();\n this.onLinkNextFocus(evt);\n break;\n }\n case KeyCode.ARROW_UP: {\n evt.preventDefault();\n this.menuItemKeydown.next(new EclMenuItemKeydownEvent(this, evt as KeyboardEvent));\n break;\n }\n case KeyCode.ARROW_RIGHT: {\n evt.preventDefault();\n this.onLinkNextFocus(evt);\n break;\n }\n case KeyCode.ARROW_LEFT: {\n evt.preventDefault();\n this.menuItemKeydown.next(new EclMenuItemKeydownEvent(this, evt as KeyboardEvent));\n break;\n }\n case KeyCode.ENTER: {\n this.onItemClick(evt);\n break;\n }\n case KeyCode.ESCAPE: {\n evt.preventDefault();\n this.onLinkEscape(evt);\n break;\n }\n default: {\n break;\n }\n }\n }\n\n /**\n * This method calculates height and width of an item, depending the maximum of lines(rows) allowed.\n * Depends on the 'maxLines' property of the parent menu component.\n * @param maxLines - property that sets the maximum possible lines in a menu item.\n * @param isMobileBreakpoint\n * @returns\n */\n checkMenuItem(maxLines: number, isMobileBreakpoint: boolean): void {\n if (maxLines < 1) return;\n\n const currentItem = this.el.nativeElement;\n const currentLink = this.menuLink().nativeElement;\n if (isMobileBreakpoint) {\n this.renderer.setStyle(currentLink, 'width', '100%');\n return;\n }\n this.renderer.setStyle(currentItem, 'alignItems', 'flex-start');\n const linkStyle = this.window.getComputedStyle(currentLink);\n\n const maxHeight = this.getMenuItemLinkMaxHeight(linkStyle, maxLines);\n\n if (currentLink.offsetHeight > maxHeight) {\n this.changeMenuItemLinkWidth(currentLink, maxLines, linkStyle);\n }\n this.renderer.removeStyle(currentItem, 'alignItems');\n }\n\n private onLinkEscape(evt: Event): void {\n const menuButton = this.menuButton();\n if (menuButton) {\n menuButton.el.nativeElement.focus();\n evt.stopPropagation();\n } else {\n this.menuLink().nativeElement.blur();\n }\n }\n\n private selectFirstMegaMenuItem(): void {\n this.submenu().selectFirstSubItem();\n }\n\n private onLinkFocus(): void {\n this.menuLink().nativeElement.focus();\n }\n\n private onLinkNextFocus(evt: Event): void {\n if (this.menuButton()) {\n this.onButtonFocus();\n } else {\n this.menuItemKeydown.next(new EclMenuItemKeydownEvent(this, evt as KeyboardEvent));\n }\n }\n\n private onButtonFocus(): void {\n this.menuButton().el.nativeElement.focus();\n }\n\n private getMenuItemLinkMaxHeight(linkStyle: CSSStyleDeclaration, maxLines: number): number {\n return parseInt(linkStyle.lineHeight, 10) * maxLines + parseInt(linkStyle.paddingTop, 10) + parseInt(linkStyle.paddingBottom, 10);\n }\n\n /**\n * Calculates width of a menu item, depending on maximum lines of text allowed.\n * @param currentLink\n * @param maxLines\n * @param linkStyle\n * @returns\n */\n private changeMenuItemLinkWidth(currentLink: HTMLAnchorElement, maxLines: number, linkStyle: CSSStyleDeclaration): void {\n this.renderer.setStyle(currentLink, 'white-space', 'nowrap');\n const linkWidth = currentLink.offsetWidth;\n if (maxLines === 1) {\n this.renderer.setStyle(currentLink, 'width', `${linkWidth + parseInt(linkStyle.paddingLeft, 10) + parseInt(linkStyle.paddingRight, 10)}px`);\n this.renderer.removeStyle(currentLink, 'white-space');\n return;\n }\n const textSize = currentLink.text.length;\n const letterWidth = Math.ceil(linkWidth / textSize);\n const wordsArray = currentLink.text.trim().split(' ');\n const goalWidth = Math.ceil(linkWidth / maxLines);\n const firstWord = wordsArray[0];\n let cnt = 1;\n let wordWidth = Math.ceil((firstWord.length + 1) * letterWidth);\n while (wordWidth < goalWidth) {\n wordWidth += Math.ceil((wordsArray[cnt].length + 1) * letterWidth);\n cnt++;\n }\n this.renderer.setStyle(currentLink, 'width', `${wordWidth + parseInt(linkStyle.paddingLeft, 10) + parseInt(linkStyle.paddingRight, 10)}px`);\n this.renderer.removeStyle(currentLink, 'white-space');\n }\n\n private getClassDependingChildrenCnt(): string {\n if (this.hasChildren) {\n if (this.submenu().eclMenuMegaItems.length < ColTrigger.COL1_TRIGGER) {\n return 'ecl-menu__item--col1';\n } else if (this.submenu().eclMenuMegaItems.length < ColTrigger.COL2_TRIGGER) {\n return 'ecl-menu__item--col2';\n } else if (this.submenu().eclMenuMegaItems.length < ColTrigger.COL3_TRIGGER) {\n return 'ecl-menu__item--col3';\n } else {\n this.isFull = true;\n return 'ecl-menu__item--full';\n }\n }\n return '';\n }\n\n private hasSubmenuAnySelections(): boolean {\n const submenu = this.submenu();\n return submenu && !!submenu.eclMenuMegaItems.find((it) => it.isCurrent);\n }\n\n private setExtraAttributesForLink(link: HTMLElement, linkExtraAttributes: Record<string, string>): void {\n if (linkExtraAttributes) {\n Object.keys(linkExtraAttributes).forEach((key) => {\n if (key !== 'href' && key !== 'routerLink') {\n this.renderer.setAttribute(link, key, linkExtraAttributes[key]);\n }\n });\n }\n }\n\n private observeBreakpointChanges(): void {\n this.appShell.getState<any>('breakpoints')\n .pipe(\n map(bp => !!(bp?.isMobile || bp?.isTablet || bp?.isLtLargeTablet)), // xs/sm/md/lg (< 1140px)\n distinctUntilChanged(),\n takeUntil(this.destroy$),\n )\n .subscribe((isMobile) => {\n this.isMobileBreakpoint = isMobile;\n });\n }\n}\n",
65624
+ "sourceCode": "import { NgTemplateOutlet } from '@angular/common';\nimport {\n AfterContentInit,\n afterNextRender,\n Component,\n ElementRef,\n EventEmitter,\n forwardRef,\n inject,\n Input,\n OnDestroy,\n Output,\n Renderer2,\n ViewEncapsulation,\n DOCUMENT,\n booleanAttribute,\n input,\n contentChild,\n viewChild,\n} from '@angular/core';\nimport { Params, QueryParamsHandling, RouterLink, RouterLinkWithHref } from '@angular/router';\nimport { EuiAppShellService } from '@eui/core';\nimport { EclButtonComponent, EUI_ECL_BUTTON } from '@eui/ecl/components/ecl-button';\nimport { EUI_ECL_ICON } from '@eui/ecl/components/ecl-icon';\nimport { EUI_ECL_LINK } from '@eui/ecl/components/ecl-link';\nimport { ECLBaseDirective, KeyCode } from '@eui/ecl/core';\nimport { Subject } from 'rxjs';\nimport { distinctUntilChanged, map, takeUntil } from 'rxjs/operators';\nimport { EclMenuMegaComponent } from '../ecl-menu-mega';\nimport {\n EclMenuItemCaretEvent,\n EclMenuItemFocusEvent,\n EclMenuItemHoverEvent,\n EclMenuItemHoverOutEvent,\n EclMenuItemKeydownEvent,\n EclMenuItemParentFocusEvent,\n EclMenuItemSelectEvent,\n} from '../events';\nimport { EclMenuItem } from '../models/ecl-menu-item.model';\n\nconst enum ColTrigger {\n COL1_TRIGGER = 5,\n COL2_TRIGGER = 9,\n COL3_TRIGGER = 13,\n}\n\n/**\n * This component represents a root menu item. Adds styling and functionality to menu item.\n */\n@Component({\n selector: 'ecl-menu-item',\n templateUrl: './ecl-menu-item.component.html',\n imports: [NgTemplateOutlet, RouterLink, RouterLinkWithHref, ...EUI_ECL_BUTTON, ...EUI_ECL_ICON, ...EUI_ECL_LINK],\n encapsulation: ViewEncapsulation.None,\n host: {\n role: 'listitem',\n '[class]': 'cssClasses',\n '[class.ecl-menu__item--has-children]': 'hasEclChildrenDataAttribute',\n '[attr.aria-haspopup]': 'hasEclChildrenDataAttribute',\n '[attr.data-expanded]': 'isDataExpanded',\n '(mouseenter)': 'onItemMouseEnter($event)',\n '(mouseleave)': 'onItemMouseLeave($event)',\n },\n})\nexport class EclMenuItemComponent extends ECLBaseDirective implements EclMenuItem, AfterContentInit, OnDestroy {\n el = inject(ElementRef);\n\n @Input() id: string;\n @Input() label: string;\n /**\n * When in mobile view, use this property to set aria-label for the toggle items button (to expand item's children).\n */\n readonly toggleAriaLabel = input<string>(undefined);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly routerLink = input<string | any[]>(null);\n readonly queryParams = input<Params | null>(null);\n readonly queryParamsHandling = input<QueryParamsHandling>(null);\n @Input() href = '';\n readonly target = input('');\n @Input({ transform: booleanAttribute }) isCurrent = false;\n /**\n * Custom attributes, to be added to the <a> tag of the menu item.\n */\n readonly linkExtraAttributes = input<Record<string, string>>(undefined);\n\n isExpanded: boolean;\n /**\n * Set to 'true', when item has more than 13 chidren and the overlay needs to use the full available space.\n */\n isFull = false;\n isHovered = false;\n isMobileBreakpoint = false;\n /**\n * Used when menu has overlay, to show if the item is currently displayed.\n */\n isVisible = true;\n\n private readonly doc = inject(DOCUMENT);\n private readonly window = this.doc.defaultView; // Window | null\n\n /**\n * The default role of the item is 'listitem' and should not be changed.\n */\n get cssClasses(): string {\n return [\n super.getCssClasses('ecl-menu__item'),\n this.isCurrent ? 'ecl-menu__item--current' : '',\n this.isExpanded ? 'ecl-menu__item--expanded' : '',\n this.getClassDependingChildrenCnt(),\n ]\n .join(' ')\n .trim();\n }\n\n readonly submenu = contentChild(forwardRef(() => EclMenuMegaComponent));\n /**\n * The <a> element of the menu item, when there are no children.\n */\n readonly menuLink = viewChild<ElementRef<HTMLAnchorElement>>('menuLink');\n /**\n * The <button> element of the menu item, when item has children.\n */\n readonly menuButton = viewChild(EclButtonComponent);\n\n @Output() menuItemSelect = new EventEmitter<EclMenuItemSelectEvent>();\n @Output() menuItemCaret = new EventEmitter<EclMenuItemCaretEvent>();\n /**\n * Event that is emited on clicking the caret button to expand item's children in mobile mode.\n */\n @Output() menuItemHover = new EventEmitter<EclMenuItemHoverEvent>();\n @Output() menuItemHoverOut = new EventEmitter<EclMenuItemHoverOutEvent>();\n @Output() menuMegaItemSelect = new EventEmitter<EclMenuItemSelectEvent>();\n @Output() menuItemFocus = new EventEmitter<EclMenuItemFocusEvent>();\n @Output() menuItemKeydown = new EventEmitter<EclMenuItemKeydownEvent>();\n /**\n * This event is emited when the keyboard nav reaches the last item in mobile view.\n * Then the next focused element should be the 'close' btn.\n */\n @Output() menuMegaLastItemTab = new EventEmitter<void>();\n\n get hasEclChildrenDataAttribute(): boolean {\n return this.hasChildren || undefined;\n }\n\n get isDataExpanded(): boolean {\n return this.hasChildren ? this.isHovered : null;\n }\n\n /**\n * 'aria-current' is set to 'page' only when this item itself is the current page, and not when it is\n * marked current merely because one of its children is the active item (in that case the child link\n * carries 'aria-current=\"page\"'). Derived from live state so it stays correct whether 'isCurrent' is set\n * at render time or updated on selection.\n */\n get ariaCurrent(): string | null {\n return this.isCurrent && !this.hasCurrentChild ? 'page' : null;\n }\n\n /**\n * Whether any child (sub-item) is the current item.\n */\n get hasCurrentChild(): boolean {\n return this.children.some((child) => child.isCurrent);\n }\n\n get hasChildren(): boolean {\n return !!this.submenu();\n }\n\n get children(): EclMenuItem[] {\n return this.hasChildren ? this.submenu().eclMenuMegaItems.toArray() : [];\n }\n\n private destroy$: Subject<boolean> = new Subject<boolean>();\n private renderer = inject(Renderer2);\n private appShell = inject(EuiAppShellService);\n\n constructor() {\n super();\n afterNextRender(() => {\n this.observeBreakpointChanges();\n this.setExtraAttributesForLink(this.menuLink()?.nativeElement, this.linkExtraAttributes());\n });\n }\n\n onItemMouseEnter(evt: MouseEvent): void {\n if (this.isMobileBreakpoint) return;\n this.menuItemHover.next(new EclMenuItemHoverEvent(this, evt));\n }\n\n onItemMouseLeave(evt: MouseEvent): void {\n if (this.isMobileBreakpoint) return;\n this.menuItemHoverOut.next(new EclMenuItemHoverOutEvent(this, evt));\n }\n\n ngAfterContentInit(): void {\n // Subscibe to submenu component events.\n const submenu = this.submenu();\n if (submenu) {\n submenu.menuItemSelect.pipe(takeUntil(this.destroy$)).subscribe((it: EclMenuItemSelectEvent) => {\n this.menuMegaItemSelect.next(new EclMenuItemSelectEvent(it.menuItem, it.domEvent));\n });\n submenu.menuMegaItemParentFocus.pipe(takeUntil(this.destroy$)).subscribe((it: EclMenuItemParentFocusEvent) => {\n if (!this.isMobileBreakpoint) {\n this.onFocusFromSubmenu();\n }\n });\n submenu.menuMegaLastItemTab.pipe(takeUntil(this.destroy$)).subscribe(() => {\n if (this.isMobileBreakpoint) {\n this.menuMegaLastItemTab.next();\n }\n });\n\n if (this.hasSubmenuAnySelections()) {\n this.isCurrent = true;\n }\n }\n\n // this.tabindex = this.routerLink || this.href ? 0 : -1;\n }\n\n ngOnDestroy(): void {\n this.destroy$.next(true);\n this.destroy$.unsubscribe();\n }\n\n onItemFocus(evt: FocusEvent): void {\n this.menuItemFocus.next(new EclMenuItemFocusEvent(this, evt));\n }\n\n onItemClick(evt: Event): void {\n this.menuItemSelect.next(new EclMenuItemSelectEvent(this, evt));\n\n if (!this.href) {\n evt.stopPropagation();\n }\n }\n\n /**\n * When clicking the caret button, to expand item's children. Used in mobile view.\n * @param evt\n */\n onItemCaretClick(evt: MouseEvent): void {\n this.menuItemCaret.next(new EclMenuItemCaretEvent(this, evt));\n }\n\n /**\n * Manages the state when the item is focused, when navigating with keyboard and the navigation is coming from the submenu.\n */\n onFocusFromSubmenu(): void {\n this.onButtonFocus();\n this.isHovered = false;\n this.isExpanded = false;\n }\n\n /**\n * Manages the state when the item is focused, when navigating with keyboard and the navigation is coming from\n * the next root menu item.\n */\n onFocusFromNext(): void {\n if (this.menuButton()) {\n this.onButtonFocus();\n } else {\n this.onLinkFocus();\n }\n }\n\n /**\n * Manages the state when the item is focused, when navigating with keyboard and the navigation is coming from\n * the previous root menu item.\n */\n onFocusFromPrev(): void {\n this.onLinkFocus();\n }\n\n /**\n * Manages the keyboard navigation when the current element is the button of the menu item.\n * @param evt\n */\n onButtonKeydown(evt: Event): void {\n switch ((evt as KeyboardEvent).key) {\n case KeyCode.ARROW_DOWN: {\n evt.preventDefault();\n if (this.isHovered) {\n this.selectFirstMegaMenuItem();\n } else {\n this.menuItemKeydown.next(new EclMenuItemKeydownEvent(this, evt as KeyboardEvent));\n }\n break;\n }\n case KeyCode.ARROW_UP: {\n evt.preventDefault();\n this.onLinkFocus();\n break;\n }\n case KeyCode.ARROW_RIGHT: {\n evt.preventDefault();\n this.menuItemKeydown.next(new EclMenuItemKeydownEvent(this, evt as KeyboardEvent));\n break;\n }\n case KeyCode.ARROW_LEFT: {\n evt.preventDefault();\n this.onLinkFocus();\n break;\n }\n case KeyCode.TAB: {\n this.menuItemKeydown.next(new EclMenuItemKeydownEvent(this, evt as KeyboardEvent));\n break;\n }\n case KeyCode.ENTER: {\n evt.preventDefault();\n this.menuItemKeydown.next(new EclMenuItemKeydownEvent(this, evt as KeyboardEvent));\n break;\n }\n case KeyCode.ESCAPE: {\n evt.preventDefault();\n this.menuItemKeydown.next(new EclMenuItemKeydownEvent(this, evt as KeyboardEvent));\n break;\n }\n default: {\n break;\n }\n }\n }\n\n /**\n * Manages the keyboard navigation when the current element is the <a> tag of the menu item.\n * @param evt\n */\n onLinkKeydown(evt: Event): void {\n switch ((evt as KeyboardEvent).key) {\n case KeyCode.ARROW_DOWN: {\n evt.preventDefault();\n this.onLinkNextFocus(evt);\n break;\n }\n case KeyCode.ARROW_UP: {\n evt.preventDefault();\n this.menuItemKeydown.next(new EclMenuItemKeydownEvent(this, evt as KeyboardEvent));\n break;\n }\n case KeyCode.ARROW_RIGHT: {\n evt.preventDefault();\n this.onLinkNextFocus(evt);\n break;\n }\n case KeyCode.ARROW_LEFT: {\n evt.preventDefault();\n this.menuItemKeydown.next(new EclMenuItemKeydownEvent(this, evt as KeyboardEvent));\n break;\n }\n case KeyCode.ENTER: {\n this.onItemClick(evt);\n break;\n }\n case KeyCode.ESCAPE: {\n evt.preventDefault();\n this.onLinkEscape(evt);\n break;\n }\n default: {\n break;\n }\n }\n }\n\n /**\n * This method calculates height and width of an item, depending the maximum of lines(rows) allowed.\n * Depends on the 'maxLines' property of the parent menu component.\n * @param maxLines - property that sets the maximum possible lines in a menu item.\n * @param isMobileBreakpoint\n * @returns\n */\n checkMenuItem(maxLines: number, isMobileBreakpoint: boolean): void {\n if (maxLines < 1) return;\n\n const currentItem = this.el.nativeElement;\n const currentLink = this.menuLink().nativeElement;\n if (isMobileBreakpoint) {\n this.renderer.setStyle(currentLink, 'width', '100%');\n return;\n }\n this.renderer.setStyle(currentItem, 'alignItems', 'flex-start');\n const linkStyle = this.window.getComputedStyle(currentLink);\n\n const maxHeight = this.getMenuItemLinkMaxHeight(linkStyle, maxLines);\n\n if (currentLink.offsetHeight > maxHeight) {\n this.changeMenuItemLinkWidth(currentLink, maxLines, linkStyle);\n }\n this.renderer.removeStyle(currentItem, 'alignItems');\n }\n\n private onLinkEscape(evt: Event): void {\n const menuButton = this.menuButton();\n if (menuButton) {\n menuButton.el.nativeElement.focus();\n evt.stopPropagation();\n } else {\n this.menuLink().nativeElement.blur();\n }\n }\n\n private selectFirstMegaMenuItem(): void {\n this.submenu().selectFirstSubItem();\n }\n\n private onLinkFocus(): void {\n this.menuLink().nativeElement.focus();\n }\n\n private onLinkNextFocus(evt: Event): void {\n if (this.menuButton()) {\n this.onButtonFocus();\n } else {\n this.menuItemKeydown.next(new EclMenuItemKeydownEvent(this, evt as KeyboardEvent));\n }\n }\n\n private onButtonFocus(): void {\n this.menuButton().el.nativeElement.focus();\n }\n\n private getMenuItemLinkMaxHeight(linkStyle: CSSStyleDeclaration, maxLines: number): number {\n return parseInt(linkStyle.lineHeight, 10) * maxLines + parseInt(linkStyle.paddingTop, 10) + parseInt(linkStyle.paddingBottom, 10);\n }\n\n /**\n * Calculates width of a menu item, depending on maximum lines of text allowed.\n * @param currentLink\n * @param maxLines\n * @param linkStyle\n * @returns\n */\n private changeMenuItemLinkWidth(currentLink: HTMLAnchorElement, maxLines: number, linkStyle: CSSStyleDeclaration): void {\n this.renderer.setStyle(currentLink, 'white-space', 'nowrap');\n const linkWidth = currentLink.offsetWidth;\n if (maxLines === 1) {\n this.renderer.setStyle(currentLink, 'width', `${linkWidth + parseInt(linkStyle.paddingLeft, 10) + parseInt(linkStyle.paddingRight, 10)}px`);\n this.renderer.removeStyle(currentLink, 'white-space');\n return;\n }\n const textSize = currentLink.text.length;\n const letterWidth = Math.ceil(linkWidth / textSize);\n const wordsArray = currentLink.text.trim().split(' ');\n const goalWidth = Math.ceil(linkWidth / maxLines);\n const firstWord = wordsArray[0];\n let cnt = 1;\n let wordWidth = Math.ceil((firstWord.length + 1) * letterWidth);\n while (wordWidth < goalWidth) {\n wordWidth += Math.ceil((wordsArray[cnt].length + 1) * letterWidth);\n cnt++;\n }\n this.renderer.setStyle(currentLink, 'width', `${wordWidth + parseInt(linkStyle.paddingLeft, 10) + parseInt(linkStyle.paddingRight, 10)}px`);\n this.renderer.removeStyle(currentLink, 'white-space');\n }\n\n private getClassDependingChildrenCnt(): string {\n if (this.hasChildren) {\n if (this.submenu().eclMenuMegaItems.length < ColTrigger.COL1_TRIGGER) {\n return 'ecl-menu__item--col1';\n } else if (this.submenu().eclMenuMegaItems.length < ColTrigger.COL2_TRIGGER) {\n return 'ecl-menu__item--col2';\n } else if (this.submenu().eclMenuMegaItems.length < ColTrigger.COL3_TRIGGER) {\n return 'ecl-menu__item--col3';\n } else {\n this.isFull = true;\n return 'ecl-menu__item--full';\n }\n }\n return '';\n }\n\n private hasSubmenuAnySelections(): boolean {\n const submenu = this.submenu();\n return submenu && !!submenu.eclMenuMegaItems.find((it) => it.isCurrent);\n }\n\n private setExtraAttributesForLink(link: HTMLElement, linkExtraAttributes: Record<string, string>): void {\n if (linkExtraAttributes) {\n Object.keys(linkExtraAttributes).forEach((key) => {\n if (key !== 'href' && key !== 'routerLink') {\n this.renderer.setAttribute(link, key, linkExtraAttributes[key]);\n }\n });\n }\n }\n\n private observeBreakpointChanges(): void {\n this.appShell.getState<any>('breakpoints')\n .pipe(\n map(bp => !!(bp?.isMobile || bp?.isTablet || bp?.isLtLargeTablet)), // xs/sm/md/lg (< 1140px)\n distinctUntilChanged(),\n takeUntil(this.destroy$),\n )\n .subscribe((isMobile) => {\n this.isMobileBreakpoint = isMobile;\n });\n }\n}\n",
65658
65625
  "assetsDirs": [],
65659
65626
  "styleUrlsData": "",
65660
65627
  "stylesData": "",
@@ -82552,7 +82519,7 @@
82552
82519
  }
82553
82520
  ]
82554
82521
  },
82555
- "templateData": "<div class=\"ecl-site-footer__section ecl-site-footer__section--common\">\n @if (!isCore()) {\n <a href=\"https://commission.europa.eu/index_{{languageCode()}}\"\n class=\"ecl-link ecl-link--standalone ecl-link--inverted ecl-site-footer__logo-link\">\n <picture class=\"ecl-picture ecl-site-footer__picture\"><img class=\"ecl-site-footer__logo-image\"\n src=\"assets/images/ecl/logo/ec/negative/logo-ec--{{logoLanguageCode}}.svg\" alt=\"European Commission\">\n </picture>\n </a>\n <div class=\"ecl-site-footer__extra-links-container\">\n <ecl-social-media-follow isIconOnly description=\"{{'ecl.footer.FOLLOW-EUROPEAN-COMMISSION' | translate}}\"\n class=\"ecl-social-media-follow--description_inline ecl-site-footer__social-media\">\n <ecl-social-media-follow-item icon=\"mastodon\" href=\"https://ec.social-network.europa.eu/@EUCommission\"\n isInverted>Mastodon</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"linkedin\" href=\"https://www.linkedin.com/company/european-commission\"\n isInverted>LinkedIn</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"bluesky\" href=\"https://bsky.app/profile/ec.europa.eu\"\n isInverted>Bluesky</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"facebook\" href=\"https://www.facebook.com/EuropeanCommission\"\n isInverted>Facebook</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"youtube\" href=\"https://www.youtube.com/user/eutube\"\n isInverted>YouTube</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"chain\"\n href=\"https://european-union.europa.eu/contact-eu/social-media-channels_{{languageCode()}}\"\n isInverted>Other</ecl-social-media-follow-item>\n </ecl-social-media-follow>\n <ul eclSiteFooterList isInline>\n <li eclSiteFooterListItem><a\n href=\"https://commission.europa.eu/about-european-commission/contact_{{languageCode()}}\"\n class=\"ecl-link ecl-link--standalone ecl-link--inverted ecl-site-footer__link\">{{ 'ecl.footer.CONTACT' | translate }}</a></li>\n </ul>\n </div>\n } @else {\n <ecl-social-media-follow isIconOnly description=\"{{'ecl.footer.FOLLOW-US' | translate}}\"\n class=\"ecl-social-media-follow--description_inline ecl-site-footer__social-media\">\n <ecl-social-media-follow-item icon=\"mastodon\" href=\"https://ec.social-network.europa.eu/@EUCommission\"\n isInverted>Mastodon</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"linkedin\" href=\"https://www.linkedin.com/company/european-commission\"\n isInverted>LinkedIn</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"bluesky\" href=\"https://bsky.app/profile/ec.europa.eu\"\n isInverted>Bluesky</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"facebook\" href=\"https://www.facebook.com/EuropeanCommission\"\n isInverted>Facebook</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"youtube\" href=\"https://www.youtube.com/user/eutube\"\n isInverted>YouTube</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"chain\"\n href=\"https://european-union.europa.eu/contact-eu/social-media-channels_{{languageCode()}}\"\n isInverted>Other</ecl-social-media-follow-item>\n </ecl-social-media-follow>\n }\n <ul eclSiteFooterList isInline>\n <li eclSiteFooterListItem><a\n href=\"https://commission.europa.eu/legal-notice/vulnerability-disclosure-policy_{{languageCode()}}\"\n eclLink isInverted variant=\"standalone\" eclSiteFooterLink>{{ 'ecl.footer.REPORT-IT-VULNERABILITY' | translate }}</a></li>\n <li eclSiteFooterListItem><a href=\"https://commission.europa.eu/languages-our-websites_{{languageCode()}}\" eclLink\n isInverted variant=\"standalone\" eclSiteFooterLink>{{ 'ecl.footer.LANGUAGES' | translate }}</a></li>\n <li eclSiteFooterListItem><a href=\"https://commission.europa.eu/cookies_{{languageCode()}}\" eclLink isInverted\n variant=\"standalone\" eclSiteFooterLink>{{ 'ecl.footer.COOKIES' | translate }}</a></li>\n <li eclSiteFooterListItem><a href=\"https://commission.europa.eu/privacy-policy_{{languageCode()}}\" eclLink\n isInverted variant=\"standalone\" eclSiteFooterLink>{{ 'ecl.footer.PRIVACY-POLICY' | translate }}</a></li>\n <li eclSiteFooterListItem><a href=\"https://commission.europa.eu/legal-notice_{{languageCode()}}\" eclLink\n isInverted variant=\"standalone\" eclSiteFooterLink>{{ 'ecl.footer.LEGAL-NOTICE' | translate }}</a></li>\n <li eclSiteFooterListItem><a href=\"{{ a11yStatementRef() }}\"\n eclLink isInverted variant=\"standalone\" eclSiteFooterLink>{{ 'ecl.footer.ACCESSIBILITY' | translate }}</a></li>\n </ul>\n</div>"
82522
+ "templateData": "<div class=\"ecl-site-footer__section ecl-site-footer__section--common\">\n @if (!isCore()) {\n <a href=\"https://commission.europa.eu/index_{{languageCode()}}\"\n class=\"ecl-link ecl-link--standalone ecl-link--inverted ecl-site-footer__logo-link\">\n <picture class=\"ecl-picture ecl-site-footer__picture\"><img class=\"ecl-site-footer__logo-image\"\n src=\"assets/images/ecl/logo/ec/negative/logo-ec--{{logoLanguageCode}}.svg\" alt=\"European Commission\">\n </picture>\n </a>\n <div class=\"ecl-site-footer__extra-links-container\">\n <ecl-social-media-follow isIconOnly description=\"{{'ecl.footer.FOLLOW-EUROPEAN-COMMISSION' | translate}}\"\n class=\"ecl-social-media-follow--description_inline ecl-site-footer__social-media\">\n <ecl-social-media-follow-item icon=\"mastodon\" href=\"https://ec.social-network.europa.eu/@EUCommission\"\n isInverted>Mastodon</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"linkedin\" href=\"https://www.linkedin.com/company/european-commission\"\n isInverted>LinkedIn</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"bluesky\" href=\"https://bsky.app/profile/ec.europa.eu\"\n isInverted>Bluesky</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"facebook\" href=\"https://www.facebook.com/EuropeanCommission\"\n isInverted>Facebook</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"youtube\" href=\"https://www.youtube.com/user/eutube\"\n isInverted>YouTube</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"chain\"\n href=\"https://european-union.europa.eu/contact-eu/social-media-channels_{{languageCode()}}\"\n isInverted>Other</ecl-social-media-follow-item>\n </ecl-social-media-follow>\n <ul eclSiteFooterList isInline>\n <li eclSiteFooterListItem><a\n href=\"https://commission.europa.eu/about-european-commission/contact_{{languageCode()}}\"\n class=\"ecl-link ecl-link--standalone ecl-link--inverted ecl-site-footer__link\">{{ 'ecl.footer.CONTACT' | translate }}</a></li>\n </ul>\n </div>\n } @else {\n <ecl-social-media-follow isIconOnly description=\"{{'ecl.footer.FOLLOW-US' | translate}}\"\n class=\"ecl-social-media-follow--description_inline ecl-site-footer__social-media\">\n <ecl-social-media-follow-item icon=\"mastodon\" href=\"https://ec.social-network.europa.eu/@EUCommission\"\n isInverted>Mastodon</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"linkedin\" href=\"https://www.linkedin.com/company/european-commission\"\n isInverted>LinkedIn</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"bluesky\" href=\"https://bsky.app/profile/ec.europa.eu\"\n isInverted>Bluesky</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"facebook\" href=\"https://www.facebook.com/EuropeanCommission\"\n isInverted>Facebook</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"youtube\" href=\"https://www.youtube.com/user/eutube\"\n isInverted>YouTube</ecl-social-media-follow-item>\n <ecl-social-media-follow-item icon=\"chain\"\n href=\"https://european-union.europa.eu/contact-eu/social-media-channels_{{languageCode()}}\"\n isInverted>Other</ecl-social-media-follow-item>\n </ecl-social-media-follow>\n }\n <ul eclSiteFooterList isInline>\n <li eclSiteFooterListItem><a\n href=\"https://commission.europa.eu/legal-notice/vulnerability-disclosure-policy_{{languageCode()}}\"\n eclLink isInverted variant=\"standalone\" eclSiteFooterLink>{{ 'ecl.footer.REPORT-IT-VULNERABILITY' | translate }}</a></li>\n <li eclSiteFooterListItem><a href=\"https://commission.europa.eu/languages-our-websites_{{languageCode()}}\" eclLink\n isInverted variant=\"standalone\" eclSiteFooterLink>{{ 'ecl.footer.LANGUAGES' | translate }}</a></li>\n <li eclSiteFooterListItem><a href=\"https://commission.europa.eu/cookies_{{languageCode()}}\" eclLink isInverted\n variant=\"standalone\" eclSiteFooterLink>{{ 'ecl.footer.COOKIES' | translate }}</a></li>\n <li eclSiteFooterListItem><a href=\"https://commission.europa.eu/privacy-policy_{{languageCode()}}\" eclLink\n isInverted variant=\"standalone\" eclSiteFooterLink>{{ 'ecl.footer.PRIVACY-POLICY' | translate }}</a></li>\n <li eclSiteFooterListItem><a href=\"https://commission.europa.eu/legal-notice_{{languageCode()}}\" eclLink\n isInverted variant=\"standalone\" eclSiteFooterLink>{{ 'ecl.footer.LEGAL-NOTICE' | translate }}</a></li>\n <li eclSiteFooterListItem><a href=\"{{ a11yStatementRef() }}\"\n eclLink isInverted variant=\"standalone\" eclSiteFooterLink>{{ 'ecl.footer.ACCESSIBILITY' | translate }}</a></li>\n </ul>\n</div>\n"
82556
82523
  },
82557
82524
  {
82558
82525
  "name": "EclSiteHeaderActionComponent",
@@ -87531,7 +87498,7 @@
87531
87498
  },
87532
87499
  {
87533
87500
  "name": "EclSocialMediaFollowItemComponent",
87534
- "id": "component-EclSocialMediaFollowItemComponent-a5a386ce91d38e0d4ebb07c2085b8c669354f1a816b2677b7dde9628c9a14908687d7a7d0f9f6e66e8172233d257ac2a1145254275a03f9216caa201b32c6018",
87501
+ "id": "component-EclSocialMediaFollowItemComponent-be2bc74a52d7b183206e23fa9c6edd0706816decad401fed2ccd0e2788dead5b1d6dbb066556634b97683220c7111e50c45fd911c2cccbe1ec6738847a5e6fdf",
87535
87502
  "file": "packages/ecl/components/ecl-social-media-follow/ecl-social-media-follow-item.component.ts",
87536
87503
  "encapsulation": [],
87537
87504
  "entryComponents": [],
@@ -87732,7 +87699,7 @@
87732
87699
  "indexKey": "",
87733
87700
  "optional": false,
87734
87701
  "description": "",
87735
- "line": 44,
87702
+ "line": 38,
87736
87703
  "rawdescription": "\n",
87737
87704
  "modifierKind": [
87738
87705
  148
@@ -87748,7 +87715,7 @@
87748
87715
  "args": [
87749
87716
  {
87750
87717
  "name": "evt",
87751
- "type": "unknown",
87718
+ "type": "Event",
87752
87719
  "optional": false,
87753
87720
  "dotDotDotToken": false,
87754
87721
  "deprecated": false,
@@ -87766,7 +87733,7 @@
87766
87733
  "jsdoctags": [
87767
87734
  {
87768
87735
  "name": "evt",
87769
- "type": "unknown",
87736
+ "type": "Event",
87770
87737
  "optional": false,
87771
87738
  "dotDotDotToken": false,
87772
87739
  "deprecated": false,
@@ -87842,7 +87809,7 @@
87842
87809
  "description": "",
87843
87810
  "rawdescription": "\n",
87844
87811
  "type": "component",
87845
- "sourceCode": "import { booleanAttribute, Component, inject, input, output } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { EUI_ECL_ICON } from '@eui/ecl/components/ecl-icon';\nimport { EclBaseEvent } from '@eui/ecl/core';\nimport { ECLBaseDirective } from '@eui/ecl/core';\nimport { EUI_ECL_LINK } from '@eui/ecl/components/ecl-link';\nimport { RouterLink, RouterLinkWithHref } from '@angular/router';\nimport { EclSocialMediaFollowComponent } from './ecl-social-media-follow.component';\n\nexport class EclSocialMediaFollowItemClickEvent extends EclBaseEvent {}\n\n@Component({\n selector: 'ecl-social-media-follow-item',\n templateUrl: './ecl-social-media-follow-item.component.html',\n imports: [...EUI_ECL_ICON, ...EUI_ECL_LINK, NgTemplateOutlet, RouterLink, RouterLinkWithHref],\n host: {\n 'role': 'listitem',\n '[class]': 'cssClasses',\n },\n})\nexport class EclSocialMediaFollowItemComponent extends ECLBaseDirective {\n readonly isInverted = input<false, unknown>(undefined, { transform: (booleanAttribute) as any });\n icon = input<string>();\n iconSet = input<string>('social-media');\n readonly href = input('');\n readonly routerLink = input('');\n readonly target = input<string>(undefined);\n readonly size = input('m');\n readonly extraAttributes = input<{\n name: string;\n value?: string | null;\n }[]>(undefined);\n\n private parent = inject(EclSocialMediaFollowComponent);\n\n get isIconOnly(): boolean {\n return this.parent?.isIconOnly() ?? false;\n }\n\n get cssClasses(): string {\n return [super.getCssClasses('ecl-social-media-follow__item')].join(' ').trim();\n }\n\n readonly itemClick = output<EclSocialMediaFollowItemClickEvent>();\n\n onItemClick(evt): void {\n this.itemClick.emit(new EclSocialMediaFollowItemClickEvent());\n if (!this.href() && !this.routerLink()) {\n evt.preventDefault();\n }\n }\n}\n",
87812
+ "sourceCode": "import { booleanAttribute, Component, inject, input, output } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { EUI_ECL_ICON } from '@eui/ecl/components/ecl-icon';\nimport { EclBaseEvent } from '@eui/ecl/core';\nimport { ECLBaseDirective } from '@eui/ecl/core';\nimport { EUI_ECL_LINK } from '@eui/ecl/components/ecl-link';\nimport { RouterLink, RouterLinkWithHref } from '@angular/router';\nimport { EclSocialMediaFollowComponent } from './ecl-social-media-follow.component';\n\nexport class EclSocialMediaFollowItemClickEvent extends EclBaseEvent {}\n\n@Component({\n selector: 'ecl-social-media-follow-item',\n templateUrl: './ecl-social-media-follow-item.component.html',\n imports: [...EUI_ECL_ICON, ...EUI_ECL_LINK, NgTemplateOutlet, RouterLink, RouterLinkWithHref],\n host: {\n role: 'listitem',\n '[class]': 'cssClasses',\n },\n})\nexport class EclSocialMediaFollowItemComponent extends ECLBaseDirective {\n readonly isInverted = input<false, unknown>(undefined, { transform: (booleanAttribute) as any });\n icon = input<string>();\n iconSet = input<string>('social-media');\n readonly href = input('');\n readonly routerLink = input('');\n readonly target = input<string>(undefined);\n readonly size = input('m');\n readonly extraAttributes = input<{\n name: string;\n value?: string | null;\n }[]>(undefined);\n\n get cssClasses(): string {\n return [super.getCssClasses('ecl-social-media-follow__item')].join(' ').trim();\n }\n\n readonly itemClick = output<EclSocialMediaFollowItemClickEvent>();\n\n private parent = inject(EclSocialMediaFollowComponent);\n\n get isIconOnly(): boolean {\n return this.parent?.isIconOnly() ?? false;\n }\n\n onItemClick(evt: Event): void {\n this.itemClick.emit(new EclSocialMediaFollowItemClickEvent());\n if (!this.href() && !this.routerLink()) {\n evt.preventDefault();\n }\n }\n}\n",
87846
87813
  "assetsDirs": [],
87847
87814
  "styleUrlsData": "",
87848
87815
  "stylesData": "",
@@ -87850,24 +87817,24 @@
87850
87817
  "ECLBaseDirective"
87851
87818
  ],
87852
87819
  "accessors": {
87853
- "isIconOnly": {
87854
- "name": "isIconOnly",
87855
- "getSignature": {
87856
- "name": "isIconOnly",
87857
- "type": "boolean",
87858
- "returnType": "boolean",
87859
- "line": 36,
87860
- "rawdescription": "\n",
87861
- "description": ""
87862
- }
87863
- },
87864
87820
  "cssClasses": {
87865
87821
  "name": "cssClasses",
87866
87822
  "getSignature": {
87867
87823
  "name": "cssClasses",
87868
87824
  "type": "string",
87869
87825
  "returnType": "string",
87870
- "line": 40,
87826
+ "line": 34,
87827
+ "rawdescription": "\n",
87828
+ "description": ""
87829
+ }
87830
+ },
87831
+ "isIconOnly": {
87832
+ "name": "isIconOnly",
87833
+ "getSignature": {
87834
+ "name": "isIconOnly",
87835
+ "type": "boolean",
87836
+ "returnType": "boolean",
87837
+ "line": 42,
87871
87838
  "rawdescription": "\n",
87872
87839
  "description": ""
87873
87840
  }
@@ -90224,7 +90191,7 @@
90224
90191
  }
90225
90192
  ]
90226
90193
  },
90227
- "templateData": "@if (eclTitle() || eclDescription()) {\n<div class=\"ecl-story-card__header\">\n @if (eclTitle()) {\n <div class=\"ecl-story-card__title\" [attr.id]=\"titleId()\">{{ eclTitle() }}</div>\n }\n @if (eclDescription()) {\n <div class=\"ecl-story-card__description\">{{ eclDescription() }}</div>\n }\n</div>\n}\n\n<!-- Mobile: Embla Carousel (auto-generated from items + details) -->\n<div class=\"ecl-story-card__carousel\">\n <div class=\"ecl-story-card__carousel-viewport\"\n role=\"region\"\n [attr.aria-label]=\"'ecl.story-card.SLIDER-LABEL' | translate\"\n emblaCarousel\n [options]=\"emblaOptions\"\n [subscribeToEvents]=\"subscribeToEvents\"\n (emblaChange)=\"onEmblaChange($event)\">\n <ul class=\"ecl-story-card__carousel-container\">\n @for (item of items(); track i; let i = $index) {\n <li class=\"ecl-story-card__carousel-slide\"\n [attr.aria-hidden]=\"i !== activeSlideIndex() ? true : null\">\n <article class=\"ecl-story-card__card\">\n <div class=\"ecl-story-card__image-wrapper\" #carouselImageWrapper>\n </div>\n <div class=\"ecl-story-card__content\" #carouselContentWrapper>\n @if (detailsPanels()[i]; as panel) {\n @if (panel.eclTitle()) {\n <div class=\"ecl-story-card__card-title\">{{ panel.eclTitle() }}</div>\n }\n @if (panel.description()) {\n <div class=\"ecl-story-card__card-description\">{{ panel.description() }}</div>\n }\n }\n </div>\n </article>\n </li>\n }\n </ul>\n </div>\n\n <!-- Carousel Controls -->\n @if (totalSlides() > 1) {\n <div class=\"ecl-story-card__pager\">\n <button class=\"ecl-story-card__prev\"\n [disabled]=\"prevDisabled()\"\n (click)=\"onCarouselPrevClick()\"\n [attr.aria-label]=\"'ecl.story-card.SHOW-PREV-SLIDE' | translate\">\n <ecl-icon icon=\"corner-arrow\" size=\"s\" transform=\"rotate-270\"></ecl-icon>\n <span class=\"ecl-story-card__prev-label\">\n {{ 'ecl.story-card.PREVIOUS' | translate }}\n </span>\n </button>\n\n <div class=\"ecl-story-card__dots\">\n @for (dotIndex of getDotIndices(); track dotIndex) {\n <button\n #dotButton\n class=\"ecl-story-card__dot\"\n [class.ecl-story-card__dot--active]=\"dotIndex === activeSlideIndex()\"\n [class.is-prev]=\"dotIndex === activeSlideIndex() - 1\"\n [attr.aria-label]=\"'ecl.story-card.GO-TO-SLIDE' | translate: { current: dotIndex + 1, total: totalSlides() }\"\n (click)=\"goToSlide(dotIndex)\">\n </button>\n }\n </div>\n\n <button class=\"ecl-story-card__next\"\n [disabled]=\"nextDisabled()\"\n (click)=\"onCarouselNextClick()\"\n [attr.aria-label]=\"'ecl.story-card.SHOW-NEXT-SLIDE' | translate\">\n <span class=\"ecl-story-card__next-label\">\n {{ 'ecl.story-card.NEXT' | translate }}\n </span>\n <ecl-icon icon=\"corner-arrow\" size=\"s\" transform=\"rotate-90\"></ecl-icon>\n </button>\n </div>\n }\n</div>\n\n<!-- Desktop: Grid with Accordion (user-authored content projected here) -->\n<div class=\"ecl-story-card__grid\">\n <ng-content select=\"ul[eclStoryCardList]\"></ng-content>\n <ng-content select=\"[eclStoryCardGridDetails]\"></ng-content>\n\n <!-- Grid Controls -->\n @if (totalSlides() > 1) {\n <div class=\"ecl-story-card__grid-controls\">\n <button class=\"ecl-button ecl-button--tertiary ecl-button--neutral ecl-story-card__grid-prev ecl-button--icon-only\"\n type=\"button\"\n (click)=\"onGridPrevClick()\"\n [attr.aria-label]=\"'ecl.story-card.PREVIOUS' | translate\">\n <span class=\"ecl-button__container\">\n <span class=\"ecl-button__label\" data-ecl-label=\"true\">\n {{ 'ecl.story-card.PREVIOUS' | translate }}\n </span>\n <ecl-icon iconSet=\"phosphor\" icon=\"caret-left\" size=\"l\"></ecl-icon>\n </span>\n </button>\n\n <button class=\"ecl-button ecl-button--secondary ecl-button--neutral ecl-story-card__grid-play ecl-button--icon-only\"\n type=\"button\"\n [style.display]=\"isAutoPlaying() ? 'none' : 'flex'\"\n (click)=\"onPlayClick()\"\n [attr.aria-label]=\"'ecl.story-card.PLAY' | translate\">\n <span class=\"ecl-button__container\">\n <span class=\"ecl-button__label\" data-ecl-label=\"true\">\n {{ 'ecl.story-card.PLAY' | translate }}\n </span>\n <ecl-icon iconSet=\"phosphor-fill\" icon=\"play\" size=\"l\"></ecl-icon>\n </span>\n </button>\n\n <button class=\"ecl-button ecl-button--secondary ecl-button--neutral ecl-story-card__grid-pause ecl-button--icon-only\"\n type=\"button\"\n [style.display]=\"isAutoPlaying() ? 'flex' : 'none'\"\n (click)=\"onPauseClick()\"\n [attr.aria-label]=\"'ecl.story-card.PAUSE' | translate\">\n <span class=\"ecl-button__container\">\n <span class=\"ecl-button__label\" data-ecl-label=\"true\">\n {{ 'ecl.story-card.PAUSE' | translate }}\n </span>\n <ecl-icon iconSet=\"phosphor-fill\" icon=\"pause\" size=\"l\"></ecl-icon>\n </span>\n </button>\n\n <button class=\"ecl-button ecl-button--tertiary ecl-button--neutral ecl-story-card__grid-next ecl-button--icon-only\"\n type=\"button\"\n (click)=\"onGridNextClick()\"\n [attr.aria-label]=\"'ecl.story-card.NEXT' | translate\">\n <span class=\"ecl-button__container\">\n <span class=\"ecl-button__label\" data-ecl-label=\"true\">\n {{ 'ecl.story-card.NEXT' | translate }}\n </span>\n <ecl-icon iconSet=\"phosphor\" icon=\"caret-right\" size=\"l\"></ecl-icon>\n </span>\n </button>\n </div>\n }\n</div>\n"
90194
+ "templateData": "@if (eclTitle() || eclDescription()) {\n<div class=\"ecl-story-card__header\">\n @if (eclTitle()) {\n <div class=\"ecl-story-card__title\" [attr.id]=\"titleId()\">{{ eclTitle() }}</div>\n }\n @if (eclDescription()) {\n <div class=\"ecl-story-card__description\">{{ eclDescription() }}</div>\n }\n</div>\n}\n\n<!-- Mobile: Embla Carousel (auto-generated from items + details) -->\n<div class=\"ecl-story-card__carousel\">\n <div class=\"ecl-story-card__carousel-viewport\"\n role=\"region\"\n [attr.aria-label]=\"'ecl.story-card.SLIDER-LABEL' | translate\"\n emblaCarousel\n [options]=\"emblaOptions\"\n [subscribeToEvents]=\"subscribeToEvents\"\n (emblaChange)=\"onEmblaChange($event)\">\n <ul class=\"ecl-story-card__carousel-container\">\n @for (item of items(); track i; let i = $index) {\n <li class=\"ecl-story-card__carousel-slide\"\n [attr.aria-hidden]=\"i !== activeSlideIndex() ? true : null\">\n <article class=\"ecl-story-card__card\">\n <div class=\"ecl-story-card__image-wrapper\" #carouselImageWrapper>\n </div>\n <div class=\"ecl-story-card__content\" #carouselContentWrapper>\n @if (detailsPanels()[i]; as panel) {\n @if (panel.eclTitle()) {\n <div class=\"ecl-story-card__card-title\">{{ panel.eclTitle() }}</div>\n }\n @if (panel.description()) {\n <div class=\"ecl-story-card__card-description\">{{ panel.description() }}</div>\n }\n }\n </div>\n </article>\n </li>\n }\n </ul>\n </div>\n\n <!-- Carousel Controls -->\n @if (totalSlides() > 1) {\n <div class=\"ecl-story-card__pager\">\n <button class=\"ecl-story-card__prev\"\n [disabled]=\"prevDisabled()\"\n (click)=\"onCarouselPrevClick()\"\n [attr.aria-label]=\"'ecl.story-card.SHOW-PREV-SLIDE' | translate\">\n <ecl-icon icon=\"corner-arrow\" size=\"s\" transform=\"rotate-270\"></ecl-icon>\n <span class=\"ecl-story-card__prev-label\">\n {{ 'ecl.story-card.PREVIOUS' | translate }}\n </span>\n </button>\n\n <div class=\"ecl-story-card__dots\">\n @for (dotIndex of getDotIndices(); track dotIndex) {\n <button\n #dotButton\n class=\"ecl-story-card__dot\"\n [class.ecl-story-card__dot--active]=\"dotIndex === activeSlideIndex()\"\n [class.is-prev]=\"dotIndex === activeSlideIndex() - 1\"\n [attr.aria-label]=\"'ecl.story-card.GO-TO-SLIDE' | translate: { current: dotIndex + 1, total: totalSlides() }\"\n (click)=\"goToSlide(dotIndex)\">\n </button>\n }\n </div>\n\n <button class=\"ecl-story-card__next\"\n [disabled]=\"nextDisabled()\"\n (click)=\"onCarouselNextClick()\"\n [attr.aria-label]=\"'ecl.story-card.SHOW-NEXT-SLIDE' | translate\">\n <span class=\"ecl-story-card__next-label\">\n {{ 'ecl.story-card.NEXT' | translate }}\n </span>\n <ecl-icon icon=\"corner-arrow\" size=\"s\" transform=\"rotate-90\"></ecl-icon>\n </button>\n </div>\n }\n</div>\n\n<!-- Desktop: Grid with Accordion (user-authored content projected here) -->\n<div class=\"ecl-story-card__grid\">\n <ng-content select=\"ul[eclStoryCardList]\"></ng-content>\n <ng-content select=\"[eclStoryCardGridDetails]\"></ng-content>\n\n <!-- Grid Controls -->\n @if (totalSlides() > 1) {\n <div class=\"ecl-story-card__grid-controls\">\n <button class=\"ecl-button ecl-button--tertiary ecl-button--neutral ecl-story-card__grid-prev ecl-button--icon-only\"\n type=\"button\"\n (click)=\"onGridPrevClick()\"\n [attr.aria-label]=\"'ecl.story-card.PREVIOUS' | translate\">\n <span class=\"ecl-button__container\">\n <span class=\"ecl-button__label\">\n {{ 'ecl.story-card.PREVIOUS' | translate }}\n </span>\n <ecl-icon iconSet=\"phosphor\" icon=\"caret-left\" size=\"l\"></ecl-icon>\n </span>\n </button>\n\n <button class=\"ecl-button ecl-button--secondary ecl-button--neutral ecl-story-card__grid-play ecl-button--icon-only\"\n type=\"button\"\n [style.display]=\"isAutoPlaying() ? 'none' : 'flex'\"\n (click)=\"onPlayClick()\"\n [attr.aria-label]=\"'ecl.story-card.PLAY' | translate\">\n <span class=\"ecl-button__container\">\n <span class=\"ecl-button__label\">\n {{ 'ecl.story-card.PLAY' | translate }}\n </span>\n <ecl-icon iconSet=\"phosphor-fill\" icon=\"play\" size=\"l\"></ecl-icon>\n </span>\n </button>\n\n <button class=\"ecl-button ecl-button--secondary ecl-button--neutral ecl-story-card__grid-pause ecl-button--icon-only\"\n type=\"button\"\n [style.display]=\"isAutoPlaying() ? 'flex' : 'none'\"\n (click)=\"onPauseClick()\"\n [attr.aria-label]=\"'ecl.story-card.PAUSE' | translate\">\n <span class=\"ecl-button__container\">\n <span class=\"ecl-button__label\">\n {{ 'ecl.story-card.PAUSE' | translate }}\n </span>\n <ecl-icon iconSet=\"phosphor-fill\" icon=\"pause\" size=\"l\"></ecl-icon>\n </span>\n </button>\n\n <button class=\"ecl-button ecl-button--tertiary ecl-button--neutral ecl-story-card__grid-next ecl-button--icon-only\"\n type=\"button\"\n (click)=\"onGridNextClick()\"\n [attr.aria-label]=\"'ecl.story-card.NEXT' | translate\">\n <span class=\"ecl-button__container\">\n <span class=\"ecl-button__label\">\n {{ 'ecl.story-card.NEXT' | translate }}\n </span>\n <ecl-icon iconSet=\"phosphor\" icon=\"caret-right\" size=\"l\"></ecl-icon>\n </span>\n </button>\n </div>\n }\n</div>\n"
90228
90195
  },
90229
90196
  {
90230
90197
  "name": "EclStoryCardGridDetailsComponent",