@leanix/components 0.4.874 → 0.4.876

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.
@@ -1,10 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
- import { provideAppInitializer, inject, input, effect, untracked, ChangeDetectionStrategy, Component, HostListener, DestroyRef, signal, Injectable, Directive } from '@angular/core';
2
+ import { provideAppInitializer, inject, DOCUMENT, input, effect, untracked, ChangeDetectionStrategy, Component, HostListener, DestroyRef, signal, Injectable, Directive } from '@angular/core';
3
3
  import { setDefaultFontLoading } from '@ui5/webcomponents-base/dist/config/Fonts.js';
4
4
  import { registerIconLoader } from '@ui5/webcomponents-base/dist/asset-registries/Icons.js';
5
5
  export { BusyIndicatorComponent } from '@ui5/webcomponents-ngx/main/busy-indicator';
6
6
  export { IconComponent } from '@ui5/webcomponents-ngx/main/icon';
7
- import { LocationStrategy, DOCUMENT } from '@angular/common';
7
+ import { LocationStrategy, DOCUMENT as DOCUMENT$1 } from '@angular/common';
8
8
  import { Router, RouterLink } from '@angular/router';
9
9
  import { BreadcrumbsItemComponent as BreadcrumbsItemComponent$1 } from '@ui5/webcomponents-ngx/main/breadcrumbs-item';
10
10
  import { BreadcrumbsComponent as BreadcrumbsComponent$1 } from '@ui5/webcomponents-ngx/main/breadcrumbs';
@@ -36,8 +36,11 @@ async function registerIconsWithUi5() {
36
36
  * });
37
37
  * ```
38
38
  */
39
- const provideUi5 = () => provideAppInitializer(async () => {
39
+ const provideUi5 = () => provideAppInitializer(async (document = inject(DOCUMENT)) => {
40
+ // disable default font loading, font needs to be provided by the app
40
41
  setDefaultFontLoading(false);
42
+ // we only support compact density for now
43
+ document.body.classList.add('ui5-content-density-compact');
41
44
  await registerIconsWithUi5();
42
45
  });
43
46
 
@@ -155,15 +158,19 @@ class FioriReskinService {
155
158
  constructor() {
156
159
  this.destroyRef = inject(DestroyRef);
157
160
  this.active = signal(false, ...(ngDevMode ? [{ debugName: "active" }] : []));
158
- const win = (inject(DOCUMENT).defaultView ?? window);
161
+ const doc = inject(DOCUMENT$1);
162
+ const win = (doc.defaultView ?? window);
163
+ this.body = doc.body;
159
164
  if (win[WINDOW_KEY] === undefined) {
160
165
  win[WINDOW_KEY] = new BehaviorSubject(false);
161
166
  }
162
167
  this.subject = win[WINDOW_KEY];
163
168
  this.active.set(this.subject.getValue());
169
+ this.body?.classList.toggle('lxFioriReskin', this.subject.getValue());
164
170
  const sub = this.subject.subscribe((value) => {
165
171
  if (this.active() !== value) {
166
172
  this.active.set(value);
173
+ this.body?.classList.toggle('lxFioriReskin', value);
167
174
  }
168
175
  });
169
176
  this.destroyRef.onDestroy(() => sub.unsubscribe());
@@ -1 +1 @@
1
- {"version":3,"file":"leanix-components-ui5.mjs","sources":["../../../../libs/components/ui5/icons/register-icons.ts","../../../../libs/components/ui5/ui5.provider.ts","../../../../libs/components/ui5/components/breadcrumbs-item.component.ts","../../../../libs/components/ui5/components/breadcrumbs.component.ts","../../../../libs/components/ui5/services/fiori-reskin.service.ts","../../../../libs/components/ui5/directives/fiori-reskin-aware.directive.ts","../../../../libs/components/ui5/utils/get-outer-html-with-shadow-dom.ts","../../../../libs/components/ui5/index.ts","../../../../libs/components/ui5/leanix-components-ui5.ts"],"sourcesContent":["import { registerIconLoader } from '@ui5/webcomponents-base/dist/asset-registries/Icons.js';\n\n/**\n * Registers icon libraries with UI5.\n */\nexport async function registerIconsWithUi5() {\n await Promise.all([\n import('@ui5/webcomponents-icons-business-suite/dist/AllIcons.js'),\n import('@ui5/webcomponents-icons-tnt/dist/AllIcons.js'),\n import('@ui5/webcomponents-icons/dist/AllIcons.js')\n ]);\n\n registerIconLoader('lx-icons', () => import('./lx-icons.json'));\n}\n","import { provideAppInitializer } from '@angular/core';\nimport { setDefaultFontLoading } from '@ui5/webcomponents-base/dist/config/Fonts.js';\nimport { registerIconsWithUi5 } from './icons/register-icons';\n\n/**\n * Sets up providers necessary to use UI5 components in the application.\n *\n * @usageNotes\n *\n * Basic example of how you can add UI5 to your application:\n * ```ts\n * import { provideUi5 } from '@leanix/components/ui5';\n *\n * bootstrapApplication(AppComponent, {\n * providers: [provideUi5()]\n * });\n * ```\n */\nexport const provideUi5 = () =>\n provideAppInitializer(async () => {\n setDefaultFontLoading(false);\n await registerIconsWithUi5();\n });\n","import { LocationStrategy } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, effect, inject, input, untracked } from '@angular/core';\nimport { Router, RouterLink } from '@angular/router';\nimport { BreadcrumbsItemComponent as Ui5BreadcrumbsItemComponent } from '@ui5/webcomponents-ngx/main/breadcrumbs-item';\n\n/**\n * This component extends the `ui5-breadcrumbs-item` component from `@ui5/webcomponents-ngx`.\n * This extension is needed for Angular versions before 20 to sync Angular's `RouterLink` directive\n * with the `href` attribute of the `ui5-breadcrumbs-item`.\n *\n * **Why?** Support for custom elements in the `RouterLink` directive was added in Angular 20.\n * For older versions, this component allows using the `RouterLink` on a `ui5-breadcrumb-item`.\n *\n * @see https://github.com/angular/angular/commit/ff98ccb19391ed4e04528b82771c04ad67067d68\n *\n */\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'ui5-breadcrumbs-item',\n template: '<ng-content />',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class BreadcrumbsItemComponent extends Ui5BreadcrumbsItemComponent {\n private readonly router = inject(Router);\n private readonly routerLinkInstance = inject(RouterLink, { optional: true });\n private readonly locationStrategy = inject(LocationStrategy, { optional: true });\n\n readonly routerLink = input<RouterLink['routerLink']>();\n\n readonly updateBreadcrumbHref = effect(() => {\n const routerLink = this.routerLink();\n\n untracked(() => {\n if (!routerLink || !this.routerLinkInstance) {\n this.href = undefined;\n return;\n }\n const urlTree = this.routerLinkInstance.urlTree;\n\n // See https://github.com/angular/angular/blob/main/packages/router/src/directives/router_link.ts#L430\n if (urlTree !== null && this.locationStrategy) {\n this.href = this.locationStrategy?.prepareExternalUrl(this.router.serializeUrl(urlTree)) ?? '';\n } else {\n this.href = undefined;\n }\n });\n });\n}\n","import { ChangeDetectionStrategy, Component, HostListener } from '@angular/core';\nimport { BreadcrumbsComponent as Ui5BreadcrumbsComponent } from '@ui5/webcomponents-ngx/main/breadcrumbs';\nimport { BreadcrumbsItemClickEventDetail } from '@ui5/webcomponents/dist/Breadcrumbs.js';\n\n/**\n * Enables users to navigate between items by providing a list of links to previous steps in the user's navigation path.\n *\n * It helps the user to be aware of their location within the application and allows faster navigation.\n *\n * This component extends the `ui5-breadcrumbs` component from `@ui5/webcomponents-ngx`.\n * See the [UI5 Breadcrumb documentation](https://ui5.github.io/webcomponents/components/Breadcrumbs) for more info.\n *\n * This extension allows using the `RouterLink` directive on `ui5-breadcrumbs-item` components.\n *\n * @example ```html\n * <ui5-breadcrumbs>\n * <ui5-breadcrumbs-item routerLink=\"/inventory\">Inventory</ui5-breadcrumbs-item>\n * <ui5-breadcrumbs-item routerLink=\"/inventory/agile-tracking\">Agile Tracking</ui5-breadcrumbs-item>\n * <ui5-breadcrumbs-item routerLink=\"/inventory/agile-tracking/settings\">Settings</ui5-breadcrumbs-item>\n * </ui5-breadcrumbs>\n * ```\n */\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'ui5-breadcrumbs',\n template: '<ng-content />',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class BreadcrumbsComponent extends Ui5BreadcrumbsComponent {\n /**\n * @internal\n */\n @HostListener('item-click', ['$event']) onClick(event: CustomEvent<BreadcrumbsItemClickEventDetail>) {\n // When a breadcrumb receives a click event from the nested `ui5-link`, the parent `ui5-breadcrumbs` component\n // emits the custom event `item-click`. However, since the `RouterLink` directive is applied on the individual breadcrumbs,\n // and it only listens to `click` events, the directive would not act on this event.\n // So we're triggering the `click` event on the selected breadcrumb item, to ensure `RouterLink#onClick` is called.\n event.detail.item.click();\n\n // Since the `ui5-breadcrumbs-item` already contains a nested `<a>` element, the `item-click`\n // event needs to be cancelled to prevent a full page reload.\n event.preventDefault();\n }\n}\n","import { DOCUMENT } from '@angular/common';\nimport { DestroyRef, inject, Injectable, signal } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\n\nconst WINDOW_KEY = 'lxFioriReskinActive$';\n\ndeclare global {\n interface Window {\n /**\n * Shared cross-MFE {@link BehaviorSubject} for the Fiori reskin toggle.\n * Defined in {@link FioriReskinService}.\n */\n [WINDOW_KEY]: BehaviorSubject<boolean> | undefined;\n }\n}\n\n/**\n * Global state for the Fiori/UI5 reskin toggle.\n *\n * A {@link BehaviorSubject} on `window.lxFioriReskinActive` is the cross-MFE\n * source of truth. Late-loading MFEs receive the current value on subscribe.\n * Each service keeps a local Angular {@link signal} in sync for template\n * bindings.\n *\n * Components opt in to the reskin by applying\n * {@link FioriReskinAwareDirective}, which reads this service and adds/removes\n * the `lxFioriReskin` host class accordingly.\n */\n@Injectable({ providedIn: 'root' })\nexport class FioriReskinService {\n private readonly destroyRef = inject(DestroyRef);\n private readonly subject: BehaviorSubject<boolean>;\n\n readonly active = signal(false);\n\n constructor() {\n const win = (inject(DOCUMENT).defaultView ?? window) as Window;\n\n if (win[WINDOW_KEY] === undefined) {\n win[WINDOW_KEY] = new BehaviorSubject(false);\n }\n\n this.subject = win[WINDOW_KEY];\n this.active.set(this.subject.getValue());\n\n const sub = this.subject.subscribe((value) => {\n if (this.active() !== value) {\n this.active.set(value);\n }\n });\n\n this.destroyRef.onDestroy(() => sub.unsubscribe());\n }\n\n setActive(value: boolean): void {\n this.subject.next(value);\n }\n}\n","import { Directive, inject } from '@angular/core';\nimport { FioriReskinService } from '../services/fiori-reskin.service';\n\n/**\n * Makes a component aware of the Fiori/UI5 reskin toggle.\n *\n * When the reskin is active (via {@link FioriReskinService}),\n * the directive adds the `lxFioriReskin` CSS class\n * to the host element. Component styles guarded with\n * `:host:where(:not(.lxFioriReskin))` are then skipped, letting Fiori styles\n * take over.\n */\n@Directive({\n selector: '[lxFioriReskinAware]',\n host: { '[class.lxFioriReskin]': 'fioriReskinService?.active()' }\n})\nexport class FioriReskinAwareDirective {\n protected readonly fioriReskinService = inject(FioriReskinService, { optional: true });\n}\n","const TRAVERSED_ELEMENTS_SELECTOR = 'ui5-icon';\nconst WEB_COMPONENT_STYLE_PROPERTIES_WHITELIST = new Set([\n // positioning\n 'width',\n 'height',\n 'display',\n 'margin',\n 'margin-left',\n 'margin-right',\n 'margin-top',\n 'margin-bottom',\n 'padding',\n 'padding-left',\n 'padding-right',\n 'padding-top',\n 'padding-bottom',\n\n // coloring\n 'color',\n 'fill',\n 'outline-color',\n 'background-color'\n]);\n\n/**\n *\n * A replacement for `HTMLElement.outerHTML`, but works with web components shadow DOM.\n * Returns a string of outer HTML of a DOM node, inlining shadow DOM for web components.\n * (@see TRAVERSED_ELEMENTS_SELECTOR for the list of supported web components.)\n *\n *\n * @description\n * Solves the problem of getting the full HTML structure of web components,\n * as `element.outerHTML` does not include shadow DOM.\n * This function inlines shadow DOM into a <template> tag inside the component root.\n * It helps to keep the shadow DOM structure and preserve style encapsulation.\n * Also includes whitelisted styles from computed styles into the component root as inline styles (@see WEB_COMPONENT_STYLE_PROPERTIES_WHITELIST).\n */\nexport function getOuterHtmlWithShadowDom(rootNode: HTMLElement) {\n const lastId = addIdsToWebComponents(rootNode);\n\n return getHTMLWithWebComponents(rootNode, lastId);\n}\n\nfunction addIdsToWebComponents(rootNode: HTMLElement) {\n const components = Array.from(rootNode.querySelectorAll<HTMLElement>(TRAVERSED_ELEMENTS_SELECTOR));\n\n let lastId = 0;\n\n for (const component of components) {\n component.dataset['componentForExportId'] = lastId.toString();\n lastId++;\n }\n\n return lastId;\n}\n\nfunction getNonDefaultStyles(cssStyleDeclaration: CSSStyleDeclaration) {\n const cssText = Array.from(cssStyleDeclaration)\n .filter((property) => {\n const value = cssStyleDeclaration.getPropertyValue(property);\n return value && WEB_COMPONENT_STYLE_PROPERTIES_WHITELIST.has(property);\n })\n .map((property) => `${property}: ${cssStyleDeclaration.getPropertyValue(property)}`)\n .join('; ');\n\n return cssText;\n}\n\nfunction getHTMLWithWebComponents(rootNode: HTMLElement, lastId: number) {\n let htmlString = rootNode.outerHTML.replace(/<!--[\\S\\s]*?-->/g, ''); // clear comments\n\n if (!lastId) {\n return htmlString;\n }\n\n for (let id = 0; id < lastId; id++) {\n const component = rootNode.querySelector(`[data-component-for-export-id=\"${id}\"]`)!;\n const componentClone = component.cloneNode(false) as HTMLElement;\n\n // Preferring defaultView to make getComputedStyle testable in custom jsdom environment\n componentClone.style.cssText = getNonDefaultStyles(component.ownerDocument.defaultView!.getComputedStyle(component));\n\n // Adding shadow root to preserve style encapsulation\n componentClone.innerHTML = `<template shadowrootmode=\"open\">${component.shadowRoot?.innerHTML}</template>`;\n\n // Regex to find the component by its data attribute\n const componentRegex = new RegExp(`<[^>]+? data-component-for-export-id=\"${id}\"[^>]*?>\\\\s*<\\/[^>]+?>`, 'm');\n htmlString = htmlString.replace(componentRegex, componentClone.outerHTML);\n }\n\n return htmlString;\n}\n","/**\n * All UI5-related components / directives supported by the SAP LeanIX Design System.\n */\nexport * from './ui5.provider';\n\n// UI5 Components\nexport { BusyIndicatorComponent } from '@ui5/webcomponents-ngx/main/busy-indicator';\nexport { IconComponent } from '@ui5/webcomponents-ngx/main/icon';\nexport type { BreadcrumbsItemClickEventDetail } from '@ui5/webcomponents/dist/Breadcrumbs.js';\n\n// LX Extensions\nexport { BreadcrumbsItemComponent } from './components/breadcrumbs-item.component';\nexport { BreadcrumbsComponent } from './components/breadcrumbs.component';\n\n// Utils\nexport { FioriReskinAwareDirective } from './directives/fiori-reskin-aware.directive';\nexport { FioriReskinService } from './services/fiori-reskin.service';\nexport { getOuterHtmlWithShadowDom } from './utils/get-outer-html-with-shadow-dom';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["Ui5BreadcrumbsItemComponent","Ui5BreadcrumbsComponent"],"mappings":"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"}
1
+ {"version":3,"file":"leanix-components-ui5.mjs","sources":["../../../../libs/components/ui5/icons/register-icons.ts","../../../../libs/components/ui5/ui5.provider.ts","../../../../libs/components/ui5/components/breadcrumbs-item.component.ts","../../../../libs/components/ui5/components/breadcrumbs.component.ts","../../../../libs/components/ui5/services/fiori-reskin.service.ts","../../../../libs/components/ui5/directives/fiori-reskin-aware.directive.ts","../../../../libs/components/ui5/utils/get-outer-html-with-shadow-dom.ts","../../../../libs/components/ui5/index.ts","../../../../libs/components/ui5/leanix-components-ui5.ts"],"sourcesContent":["import { registerIconLoader } from '@ui5/webcomponents-base/dist/asset-registries/Icons.js';\n\n/**\n * Registers icon libraries with UI5.\n */\nexport async function registerIconsWithUi5() {\n await Promise.all([\n import('@ui5/webcomponents-icons-business-suite/dist/AllIcons.js'),\n import('@ui5/webcomponents-icons-tnt/dist/AllIcons.js'),\n import('@ui5/webcomponents-icons/dist/AllIcons.js')\n ]);\n\n registerIconLoader('lx-icons', () => import('./lx-icons.json'));\n}\n","import { DOCUMENT, inject, provideAppInitializer } from '@angular/core';\nimport { setDefaultFontLoading } from '@ui5/webcomponents-base/dist/config/Fonts.js';\nimport { registerIconsWithUi5 } from './icons/register-icons';\n\n/**\n * Sets up providers necessary to use UI5 components in the application.\n *\n * @usageNotes\n *\n * Basic example of how you can add UI5 to your application:\n * ```ts\n * import { provideUi5 } from '@leanix/components/ui5';\n *\n * bootstrapApplication(AppComponent, {\n * providers: [provideUi5()]\n * });\n * ```\n */\nexport const provideUi5 = () =>\n provideAppInitializer(async (document = inject(DOCUMENT)) => {\n // disable default font loading, font needs to be provided by the app\n setDefaultFontLoading(false);\n\n // we only support compact density for now\n document.body.classList.add('ui5-content-density-compact');\n\n await registerIconsWithUi5();\n });\n","import { LocationStrategy } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, effect, inject, input, untracked } from '@angular/core';\nimport { Router, RouterLink } from '@angular/router';\nimport { BreadcrumbsItemComponent as Ui5BreadcrumbsItemComponent } from '@ui5/webcomponents-ngx/main/breadcrumbs-item';\n\n/**\n * This component extends the `ui5-breadcrumbs-item` component from `@ui5/webcomponents-ngx`.\n * This extension is needed for Angular versions before 20 to sync Angular's `RouterLink` directive\n * with the `href` attribute of the `ui5-breadcrumbs-item`.\n *\n * **Why?** Support for custom elements in the `RouterLink` directive was added in Angular 20.\n * For older versions, this component allows using the `RouterLink` on a `ui5-breadcrumb-item`.\n *\n * @see https://github.com/angular/angular/commit/ff98ccb19391ed4e04528b82771c04ad67067d68\n *\n */\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'ui5-breadcrumbs-item',\n template: '<ng-content />',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class BreadcrumbsItemComponent extends Ui5BreadcrumbsItemComponent {\n private readonly router = inject(Router);\n private readonly routerLinkInstance = inject(RouterLink, { optional: true });\n private readonly locationStrategy = inject(LocationStrategy, { optional: true });\n\n readonly routerLink = input<RouterLink['routerLink']>();\n\n readonly updateBreadcrumbHref = effect(() => {\n const routerLink = this.routerLink();\n\n untracked(() => {\n if (!routerLink || !this.routerLinkInstance) {\n this.href = undefined;\n return;\n }\n const urlTree = this.routerLinkInstance.urlTree;\n\n // See https://github.com/angular/angular/blob/main/packages/router/src/directives/router_link.ts#L430\n if (urlTree !== null && this.locationStrategy) {\n this.href = this.locationStrategy?.prepareExternalUrl(this.router.serializeUrl(urlTree)) ?? '';\n } else {\n this.href = undefined;\n }\n });\n });\n}\n","import { ChangeDetectionStrategy, Component, HostListener } from '@angular/core';\nimport { BreadcrumbsComponent as Ui5BreadcrumbsComponent } from '@ui5/webcomponents-ngx/main/breadcrumbs';\nimport { BreadcrumbsItemClickEventDetail } from '@ui5/webcomponents/dist/Breadcrumbs.js';\n\n/**\n * Enables users to navigate between items by providing a list of links to previous steps in the user's navigation path.\n *\n * It helps the user to be aware of their location within the application and allows faster navigation.\n *\n * This component extends the `ui5-breadcrumbs` component from `@ui5/webcomponents-ngx`.\n * See the [UI5 Breadcrumb documentation](https://ui5.github.io/webcomponents/components/Breadcrumbs) for more info.\n *\n * This extension allows using the `RouterLink` directive on `ui5-breadcrumbs-item` components.\n *\n * @example ```html\n * <ui5-breadcrumbs>\n * <ui5-breadcrumbs-item routerLink=\"/inventory\">Inventory</ui5-breadcrumbs-item>\n * <ui5-breadcrumbs-item routerLink=\"/inventory/agile-tracking\">Agile Tracking</ui5-breadcrumbs-item>\n * <ui5-breadcrumbs-item routerLink=\"/inventory/agile-tracking/settings\">Settings</ui5-breadcrumbs-item>\n * </ui5-breadcrumbs>\n * ```\n */\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'ui5-breadcrumbs',\n template: '<ng-content />',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class BreadcrumbsComponent extends Ui5BreadcrumbsComponent {\n /**\n * @internal\n */\n @HostListener('item-click', ['$event']) onClick(event: CustomEvent<BreadcrumbsItemClickEventDetail>) {\n // When a breadcrumb receives a click event from the nested `ui5-link`, the parent `ui5-breadcrumbs` component\n // emits the custom event `item-click`. However, since the `RouterLink` directive is applied on the individual breadcrumbs,\n // and it only listens to `click` events, the directive would not act on this event.\n // So we're triggering the `click` event on the selected breadcrumb item, to ensure `RouterLink#onClick` is called.\n event.detail.item.click();\n\n // Since the `ui5-breadcrumbs-item` already contains a nested `<a>` element, the `item-click`\n // event needs to be cancelled to prevent a full page reload.\n event.preventDefault();\n }\n}\n","import { DOCUMENT } from '@angular/common';\nimport { DestroyRef, inject, Injectable, signal } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\n\nconst WINDOW_KEY = 'lxFioriReskinActive$';\n\ndeclare global {\n interface Window {\n /**\n * Shared cross-MFE {@link BehaviorSubject} for the Fiori reskin toggle.\n * Defined in {@link FioriReskinService}.\n */\n [WINDOW_KEY]: BehaviorSubject<boolean> | undefined;\n }\n}\n\n/**\n * Global state for the Fiori/UI5 reskin toggle.\n *\n * A {@link BehaviorSubject} on `window.lxFioriReskinActive` is the cross-MFE\n * source of truth. Late-loading MFEs receive the current value on subscribe.\n * Each service keeps a local Angular {@link signal} in sync for template\n * bindings.\n *\n * Components opt in to the reskin by applying\n * {@link FioriReskinAwareDirective}, which reads this service and adds/removes\n * the `lxFioriReskin` host class accordingly.\n */\n@Injectable({ providedIn: 'root' })\nexport class FioriReskinService {\n private readonly destroyRef = inject(DestroyRef);\n private readonly subject: BehaviorSubject<boolean>;\n private readonly body: HTMLElement | null;\n\n readonly active = signal(false);\n\n constructor() {\n const doc = inject(DOCUMENT);\n const win = (doc.defaultView ?? window) as Window;\n this.body = doc.body;\n\n if (win[WINDOW_KEY] === undefined) {\n win[WINDOW_KEY] = new BehaviorSubject(false);\n }\n\n this.subject = win[WINDOW_KEY];\n this.active.set(this.subject.getValue());\n this.body?.classList.toggle('lxFioriReskin', this.subject.getValue());\n\n const sub = this.subject.subscribe((value) => {\n if (this.active() !== value) {\n this.active.set(value);\n this.body?.classList.toggle('lxFioriReskin', value);\n }\n });\n\n this.destroyRef.onDestroy(() => sub.unsubscribe());\n }\n\n setActive(value: boolean): void {\n this.subject.next(value);\n }\n}\n","import { Directive, inject } from '@angular/core';\nimport { FioriReskinService } from '../services/fiori-reskin.service';\n\n/**\n * Makes a component aware of the Fiori/UI5 reskin toggle.\n *\n * When the reskin is active (via {@link FioriReskinService}),\n * the directive adds the `lxFioriReskin` CSS class\n * to the host element. Component styles guarded with\n * `:host:where(:not(.lxFioriReskin))` are then skipped, letting Fiori styles\n * take over.\n */\n@Directive({\n selector: '[lxFioriReskinAware]',\n host: { '[class.lxFioriReskin]': 'fioriReskinService?.active()' }\n})\nexport class FioriReskinAwareDirective {\n protected readonly fioriReskinService = inject(FioriReskinService, { optional: true });\n}\n","const TRAVERSED_ELEMENTS_SELECTOR = 'ui5-icon';\nconst WEB_COMPONENT_STYLE_PROPERTIES_WHITELIST = new Set([\n // positioning\n 'width',\n 'height',\n 'display',\n 'margin',\n 'margin-left',\n 'margin-right',\n 'margin-top',\n 'margin-bottom',\n 'padding',\n 'padding-left',\n 'padding-right',\n 'padding-top',\n 'padding-bottom',\n\n // coloring\n 'color',\n 'fill',\n 'outline-color',\n 'background-color'\n]);\n\n/**\n *\n * A replacement for `HTMLElement.outerHTML`, but works with web components shadow DOM.\n * Returns a string of outer HTML of a DOM node, inlining shadow DOM for web components.\n * (@see TRAVERSED_ELEMENTS_SELECTOR for the list of supported web components.)\n *\n *\n * @description\n * Solves the problem of getting the full HTML structure of web components,\n * as `element.outerHTML` does not include shadow DOM.\n * This function inlines shadow DOM into a <template> tag inside the component root.\n * It helps to keep the shadow DOM structure and preserve style encapsulation.\n * Also includes whitelisted styles from computed styles into the component root as inline styles (@see WEB_COMPONENT_STYLE_PROPERTIES_WHITELIST).\n */\nexport function getOuterHtmlWithShadowDom(rootNode: HTMLElement) {\n const lastId = addIdsToWebComponents(rootNode);\n\n return getHTMLWithWebComponents(rootNode, lastId);\n}\n\nfunction addIdsToWebComponents(rootNode: HTMLElement) {\n const components = Array.from(rootNode.querySelectorAll<HTMLElement>(TRAVERSED_ELEMENTS_SELECTOR));\n\n let lastId = 0;\n\n for (const component of components) {\n component.dataset['componentForExportId'] = lastId.toString();\n lastId++;\n }\n\n return lastId;\n}\n\nfunction getNonDefaultStyles(cssStyleDeclaration: CSSStyleDeclaration) {\n const cssText = Array.from(cssStyleDeclaration)\n .filter((property) => {\n const value = cssStyleDeclaration.getPropertyValue(property);\n return value && WEB_COMPONENT_STYLE_PROPERTIES_WHITELIST.has(property);\n })\n .map((property) => `${property}: ${cssStyleDeclaration.getPropertyValue(property)}`)\n .join('; ');\n\n return cssText;\n}\n\nfunction getHTMLWithWebComponents(rootNode: HTMLElement, lastId: number) {\n let htmlString = rootNode.outerHTML.replace(/<!--[\\S\\s]*?-->/g, ''); // clear comments\n\n if (!lastId) {\n return htmlString;\n }\n\n for (let id = 0; id < lastId; id++) {\n const component = rootNode.querySelector(`[data-component-for-export-id=\"${id}\"]`)!;\n const componentClone = component.cloneNode(false) as HTMLElement;\n\n // Preferring defaultView to make getComputedStyle testable in custom jsdom environment\n componentClone.style.cssText = getNonDefaultStyles(component.ownerDocument.defaultView!.getComputedStyle(component));\n\n // Adding shadow root to preserve style encapsulation\n componentClone.innerHTML = `<template shadowrootmode=\"open\">${component.shadowRoot?.innerHTML}</template>`;\n\n // Regex to find the component by its data attribute\n const componentRegex = new RegExp(`<[^>]+? data-component-for-export-id=\"${id}\"[^>]*?>\\\\s*<\\/[^>]+?>`, 'm');\n htmlString = htmlString.replace(componentRegex, componentClone.outerHTML);\n }\n\n return htmlString;\n}\n","/**\n * All UI5-related components / directives supported by the SAP LeanIX Design System.\n */\nexport * from './ui5.provider';\n\n// UI5 Components\nexport { BusyIndicatorComponent } from '@ui5/webcomponents-ngx/main/busy-indicator';\nexport { IconComponent } from '@ui5/webcomponents-ngx/main/icon';\nexport type { BreadcrumbsItemClickEventDetail } from '@ui5/webcomponents/dist/Breadcrumbs.js';\n\n// LX Extensions\nexport { BreadcrumbsItemComponent } from './components/breadcrumbs-item.component';\nexport { BreadcrumbsComponent } from './components/breadcrumbs.component';\n\n// Utils\nexport { FioriReskinAwareDirective } from './directives/fiori-reskin-aware.directive';\nexport { FioriReskinService } from './services/fiori-reskin.service';\nexport { getOuterHtmlWithShadowDom } from './utils/get-outer-html-with-shadow-dom';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["Ui5BreadcrumbsItemComponent","Ui5BreadcrumbsComponent","DOCUMENT"],"mappings":"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"}
@@ -3789,12 +3789,12 @@ function getCssVariable(cssVariableName) {
3789
3789
  }
3790
3790
  function scrollTop(container, item) {
3791
3791
  if (container && item) {
3792
- const itemClientRect = item.getBoundingClientRect();
3793
- const containerClientRect = container.getBoundingClientRect();
3794
- const scrollDownNeeded = itemClientRect.y > containerClientRect.y;
3795
- const scrollTopNeeded = itemClientRect.y < containerClientRect.y;
3796
- if (scrollDownNeeded || scrollTopNeeded) {
3797
- container.scrollTop = itemClientRect.y - containerClientRect.y + container.scrollTop;
3792
+ const itemRect = item.getBoundingClientRect();
3793
+ const containerRect = container.getBoundingClientRect();
3794
+ const isBelowVisible = itemRect.bottom > containerRect.bottom;
3795
+ const isAboveVisible = itemRect.top < containerRect.top;
3796
+ if (isBelowVisible || isAboveVisible) {
3797
+ item.scrollIntoView({ block: 'nearest' });
3798
3798
  }
3799
3799
  }
3800
3800
  else {
@@ -8327,7 +8327,7 @@ class OptionGroupDropdownComponent extends KeyboardSelectDirective {
8327
8327
  this.isTopDropdown = event.connectionPair.originY === 'top';
8328
8328
  }
8329
8329
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: OptionGroupDropdownComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
8330
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: OptionGroupDropdownComponent, isStandalone: true, selector: "lx-option-group-dropdown", inputs: { optionGroups: "optionGroups", newOptionLabel: "newOptionLabel", highlightTerm: "highlightTerm", showCreateNewOption: "showCreateNewOption", labelKey: "labelKey", loading: "loading", trackByProperty: "trackByProperty", showNoResultsIfGroupIsEmpty: "showNoResultsIfGroupIsEmpty", overlayPositioning: "overlayPositioning" }, outputs: { onItemSelected: "onItemSelected", containerScrolled: "containerScrolled", createNewOption: "createNewOption" }, providers: [{ provide: KeyboardSelectDirective, useExisting: forwardRef(() => OptionGroupDropdownComponent) }], queries: [{ propertyName: "optionTemplateRef", first: true, predicate: ["optionTemplate"], descendants: true }, { propertyName: "noResultsOptionTemplateRef", first: true, predicate: ["noResultsOptionTemplateRef"], descendants: true }], viewQueries: [{ propertyName: "selectOrigin", first: true, predicate: ["selectOrigin"], descendants: true }], usesInheritance: true, ngImport: i0, template: "@if (overlayPositioning) {\n <div class=\"overlayOrigin\" cdkOverlayOrigin #selectOrigin=\"cdkOverlayOrigin\"></div>\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"selectOrigin\"\n [cdkConnectedOverlayOpen]=\"!!(cdkOverlayOpen$ | async)\"\n [cdkConnectedOverlayWidth]=\"selectOrigin.elementRef.nativeElement.offsetWidth\"\n (positionChange)=\"onPositionChange($event)\"\n >\n <div class=\"overlayDropdown\" [ngClass]=\"{ top: isTopDropdown }\">\n <ng-container *ngTemplateOutlet=\"dropdownContent; context: { keyboardSelectContainer: keyboardSelectContainer }\" />\n </div>\n </ng-template>\n} @else {\n <ng-container *ngTemplateOutlet=\"dropdownContent; context: { keyboardSelectContainer: keyboardSelectContainer }\" />\n}\n\n<ng-template #dropdownContent let-keyboardSelectContainer=\"keyboardSelectContainer\">\n <div\n #keyboardSelectContainer\n class=\"scrollingPanel lxThinScrollbar\"\n infinite-scroll\n [scrollWindow]=\"false\"\n [fromRoot]=\"true\"\n (scrolled)=\"containerScrolled.emit()\"\n >\n <ul class=\"options\">\n @if (showCreateNewOption && newOptionLabel && isNewItem) {\n <li\n lxSelectableItem\n [scrollInContainer]=\"keyboardSelectContainer\"\n #item\n (click)=\"onCreateNewOption()\"\n (select)=\"onCreateNewOption()\"\n [class.highlighted]=\"isItemSelected(item, (selectedItem$ | async)?.element)\"\n class=\"option\"\n >\n <span class=\"newEntryContent\">\n {{ newOptionLabel }}\n </span>\n <lx-counter class=\"lx-margin-left\" size=\"small\" [content]=\"'common.new' | translate | uppercase\" />\n </li>\n }\n @for (optionGroup of optionGroups; track trackByLabel($index, optionGroup); let groupIndex = $index) {\n <li>\n @if (optionGroup.label) {\n <div class=\"groupLabel\">\n <span>{{ optionGroup.label | uppercase }}</span>\n </div>\n }\n <ul>\n @if (showNoResultsIfGroupIsEmpty && optionGroup.options.length === 0) {\n <li class=\"noResult\">\n @if (noResultsOptionTemplateRef) {\n <ng-container *ngTemplateOutlet=\"noResultsOptionTemplateRef; context: { group: optionGroup, groupIndex: groupIndex }\" />\n } @else {\n <span>{{ NAME + '.noResults' | translate }}</span>\n }\n </li>\n } @else {\n @for (option of optionGroup.options; track trackByValue($index, option); let index = $index) {\n <li\n lxSelectableItem\n [scrollInContainer]=\"keyboardSelectContainer\"\n #item\n class=\"option\"\n (click)=\"selectOption(option)\"\n (select)=\"selectOption(option)\"\n [class.highlighted]=\"isItemSelected(item, (selectedItem$ | async)?.element)\"\n >\n @if (optionTemplateRef) {\n <ng-container\n *ngTemplateOutlet=\"optionTemplateRef; context: { $implicit: option, index: index, groupIndex: groupIndex }\"\n />\n } @else {\n <lx-basic-dropdown-item [label]=\"option.label\" labelFontWeight=\"normal\" [highlightTerm]=\"highlightTerm\" />\n }\n </li>\n }\n }\n </ul>\n </li>\n }\n @if (loading) {\n <lx-spinner [fadeBackground]=\"true\" />\n }\n </ul>\n </div>\n</ng-template>\n", styles: [":host{display:block}.overlayDropdown{width:100%;background:#fff;border-radius:3px;border-left:solid 1px #e1e5eb;border-right:solid 1px #e1e5eb;margin:0 -1px;width:calc(100% + 2px)}.overlayDropdown:not(.top){box-shadow:0 6px 6px #21252933;border-top:0;border-bottom:solid 1px #e1e5eb;border-top-left-radius:0;border-top-right-radius:0}.overlayDropdown.top{box-shadow:0 -4px 6px #21252933;border-top:solid 1px #e1e5eb;border-bottom:0;border-bottom-left-radius:0;border-bottom-right-radius:0}.scrollingPanel{overflow-y:auto;max-height:400px}.groupLabel{line-height:23px;padding:4px 12px;color:#61779d;letter-spacing:.5px;font-weight:700;text-transform:uppercase;cursor:default}ul{list-style:none;margin:0;padding:0}ul:not(:last-child){border-bottom:solid 1px #eaedf1}.noResult{display:block;padding:4px 12px}.option{cursor:pointer;display:block;padding:4px 12px}.option:hover{background-color:#e1e5eb!important}.option.highlighted{background:#eaedf1}\n"], dependencies: [{ kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: InfiniteScrollModule }, { kind: "directive", type: i1$4.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "directive", type: SelectableItemDirective, selector: "[lxSelectableItem]", inputs: ["scrollInContainer", "lxSelectableItem"], outputs: ["select"] }, { kind: "component", type: CounterComponent, selector: "lx-counter", inputs: ["content", "size", "color"] }, { kind: "component", type: BasicDropdownItemComponent, selector: "lx-basic-dropdown-item", inputs: ["label", "description", "highlightTerm", "labelFontWeight", "descriptionFontStyle", "descriptionStyleOptions"] }, { kind: "component", type: SpinnerComponent, selector: "lx-spinner", inputs: ["fadeBackground"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8330
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: OptionGroupDropdownComponent, isStandalone: true, selector: "lx-option-group-dropdown", inputs: { optionGroups: "optionGroups", newOptionLabel: "newOptionLabel", highlightTerm: "highlightTerm", showCreateNewOption: "showCreateNewOption", labelKey: "labelKey", loading: "loading", trackByProperty: "trackByProperty", showNoResultsIfGroupIsEmpty: "showNoResultsIfGroupIsEmpty", overlayPositioning: "overlayPositioning" }, outputs: { onItemSelected: "onItemSelected", containerScrolled: "containerScrolled", createNewOption: "createNewOption" }, providers: [{ provide: KeyboardSelectDirective, useExisting: forwardRef(() => OptionGroupDropdownComponent) }], queries: [{ propertyName: "optionTemplateRef", first: true, predicate: ["optionTemplate"], descendants: true }, { propertyName: "noResultsOptionTemplateRef", first: true, predicate: ["noResultsOptionTemplateRef"], descendants: true }], viewQueries: [{ propertyName: "selectOrigin", first: true, predicate: ["selectOrigin"], descendants: true }], usesInheritance: true, ngImport: i0, template: "@if (overlayPositioning) {\n <div class=\"overlayOrigin\" cdkOverlayOrigin #selectOrigin=\"cdkOverlayOrigin\"></div>\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"selectOrigin\"\n [cdkConnectedOverlayOpen]=\"!!(cdkOverlayOpen$ | async)\"\n [cdkConnectedOverlayWidth]=\"selectOrigin.elementRef.nativeElement.offsetWidth\"\n (positionChange)=\"onPositionChange($event)\"\n >\n <div class=\"overlayDropdown\" [ngClass]=\"{ top: isTopDropdown }\">\n <ng-container *ngTemplateOutlet=\"dropdownContent\" />\n </div>\n </ng-template>\n} @else {\n <ng-container *ngTemplateOutlet=\"dropdownContent\" />\n}\n\n<ng-template #dropdownContent>\n <div\n #keyboardSelectContainer\n class=\"scrollingPanel lxThinScrollbar\"\n infinite-scroll\n [scrollWindow]=\"false\"\n [fromRoot]=\"true\"\n (scrolled)=\"containerScrolled.emit()\"\n >\n <ul class=\"options\">\n @if (showCreateNewOption && newOptionLabel && isNewItem) {\n <li\n lxSelectableItem\n [scrollInContainer]=\"keyboardSelectContainer\"\n #item\n (click)=\"onCreateNewOption()\"\n (select)=\"onCreateNewOption()\"\n [class.highlighted]=\"isItemSelected(item, (selectedItem$ | async)?.element)\"\n class=\"option\"\n >\n <span class=\"newEntryContent\">\n {{ newOptionLabel }}\n </span>\n <lx-counter class=\"lx-margin-left\" size=\"small\" [content]=\"'common.new' | translate | uppercase\" />\n </li>\n }\n @for (optionGroup of optionGroups; track trackByLabel($index, optionGroup); let groupIndex = $index) {\n <li>\n @if (optionGroup.label) {\n <div class=\"groupLabel\">\n <span>{{ optionGroup.label | uppercase }}</span>\n </div>\n }\n <ul>\n @if (showNoResultsIfGroupIsEmpty && optionGroup.options.length === 0) {\n <li class=\"noResult\">\n @if (noResultsOptionTemplateRef) {\n <ng-container *ngTemplateOutlet=\"noResultsOptionTemplateRef; context: { group: optionGroup, groupIndex: groupIndex }\" />\n } @else {\n <span>{{ NAME + '.noResults' | translate }}</span>\n }\n </li>\n } @else {\n @for (option of optionGroup.options; track trackByValue($index, option); let index = $index) {\n <li\n lxSelectableItem\n [scrollInContainer]=\"keyboardSelectContainer\"\n #item\n class=\"option\"\n (click)=\"selectOption(option)\"\n (select)=\"selectOption(option)\"\n [class.highlighted]=\"isItemSelected(item, (selectedItem$ | async)?.element)\"\n >\n @if (optionTemplateRef) {\n <ng-container\n *ngTemplateOutlet=\"optionTemplateRef; context: { $implicit: option, index: index, groupIndex: groupIndex }\"\n />\n } @else {\n <lx-basic-dropdown-item [label]=\"option.label\" labelFontWeight=\"normal\" [highlightTerm]=\"highlightTerm\" />\n }\n </li>\n }\n }\n </ul>\n </li>\n }\n @if (loading) {\n <lx-spinner [fadeBackground]=\"true\" />\n }\n </ul>\n </div>\n</ng-template>\n", styles: [":host{display:block}.overlayDropdown{width:100%;background:#fff;border-radius:3px;border-left:solid 1px #e1e5eb;border-right:solid 1px #e1e5eb;margin:0 -1px;width:calc(100% + 2px)}.overlayDropdown:not(.top){box-shadow:0 6px 6px #21252933;border-top:0;border-bottom:solid 1px #e1e5eb;border-top-left-radius:0;border-top-right-radius:0}.overlayDropdown.top{box-shadow:0 -4px 6px #21252933;border-top:solid 1px #e1e5eb;border-bottom:0;border-bottom-left-radius:0;border-bottom-right-radius:0}.scrollingPanel{overflow-y:auto;max-height:400px}.groupLabel{line-height:23px;padding:4px 12px;color:#61779d;letter-spacing:.5px;font-weight:700;text-transform:uppercase;cursor:default}ul{list-style:none;margin:0;padding:0}ul:not(:last-child){border-bottom:solid 1px #eaedf1}.noResult{display:block;padding:4px 12px}.option{cursor:pointer;display:block;padding:4px 12px}.option:hover{background-color:#e1e5eb!important}.option.highlighted{background:#eaedf1}\n"], dependencies: [{ kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: InfiniteScrollModule }, { kind: "directive", type: i1$4.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "directive", type: SelectableItemDirective, selector: "[lxSelectableItem]", inputs: ["scrollInContainer", "lxSelectableItem"], outputs: ["select"] }, { kind: "component", type: CounterComponent, selector: "lx-counter", inputs: ["content", "size", "color"] }, { kind: "component", type: BasicDropdownItemComponent, selector: "lx-basic-dropdown-item", inputs: ["label", "description", "highlightTerm", "labelFontWeight", "descriptionFontStyle", "descriptionStyleOptions"] }, { kind: "component", type: SpinnerComponent, selector: "lx-spinner", inputs: ["fadeBackground"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8331
8331
  }
8332
8332
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: OptionGroupDropdownComponent, decorators: [{
8333
8333
  type: Component,
@@ -8344,7 +8344,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
8344
8344
  AsyncPipe,
8345
8345
  UpperCasePipe,
8346
8346
  TranslateModule
8347
- ], template: "@if (overlayPositioning) {\n <div class=\"overlayOrigin\" cdkOverlayOrigin #selectOrigin=\"cdkOverlayOrigin\"></div>\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"selectOrigin\"\n [cdkConnectedOverlayOpen]=\"!!(cdkOverlayOpen$ | async)\"\n [cdkConnectedOverlayWidth]=\"selectOrigin.elementRef.nativeElement.offsetWidth\"\n (positionChange)=\"onPositionChange($event)\"\n >\n <div class=\"overlayDropdown\" [ngClass]=\"{ top: isTopDropdown }\">\n <ng-container *ngTemplateOutlet=\"dropdownContent; context: { keyboardSelectContainer: keyboardSelectContainer }\" />\n </div>\n </ng-template>\n} @else {\n <ng-container *ngTemplateOutlet=\"dropdownContent; context: { keyboardSelectContainer: keyboardSelectContainer }\" />\n}\n\n<ng-template #dropdownContent let-keyboardSelectContainer=\"keyboardSelectContainer\">\n <div\n #keyboardSelectContainer\n class=\"scrollingPanel lxThinScrollbar\"\n infinite-scroll\n [scrollWindow]=\"false\"\n [fromRoot]=\"true\"\n (scrolled)=\"containerScrolled.emit()\"\n >\n <ul class=\"options\">\n @if (showCreateNewOption && newOptionLabel && isNewItem) {\n <li\n lxSelectableItem\n [scrollInContainer]=\"keyboardSelectContainer\"\n #item\n (click)=\"onCreateNewOption()\"\n (select)=\"onCreateNewOption()\"\n [class.highlighted]=\"isItemSelected(item, (selectedItem$ | async)?.element)\"\n class=\"option\"\n >\n <span class=\"newEntryContent\">\n {{ newOptionLabel }}\n </span>\n <lx-counter class=\"lx-margin-left\" size=\"small\" [content]=\"'common.new' | translate | uppercase\" />\n </li>\n }\n @for (optionGroup of optionGroups; track trackByLabel($index, optionGroup); let groupIndex = $index) {\n <li>\n @if (optionGroup.label) {\n <div class=\"groupLabel\">\n <span>{{ optionGroup.label | uppercase }}</span>\n </div>\n }\n <ul>\n @if (showNoResultsIfGroupIsEmpty && optionGroup.options.length === 0) {\n <li class=\"noResult\">\n @if (noResultsOptionTemplateRef) {\n <ng-container *ngTemplateOutlet=\"noResultsOptionTemplateRef; context: { group: optionGroup, groupIndex: groupIndex }\" />\n } @else {\n <span>{{ NAME + '.noResults' | translate }}</span>\n }\n </li>\n } @else {\n @for (option of optionGroup.options; track trackByValue($index, option); let index = $index) {\n <li\n lxSelectableItem\n [scrollInContainer]=\"keyboardSelectContainer\"\n #item\n class=\"option\"\n (click)=\"selectOption(option)\"\n (select)=\"selectOption(option)\"\n [class.highlighted]=\"isItemSelected(item, (selectedItem$ | async)?.element)\"\n >\n @if (optionTemplateRef) {\n <ng-container\n *ngTemplateOutlet=\"optionTemplateRef; context: { $implicit: option, index: index, groupIndex: groupIndex }\"\n />\n } @else {\n <lx-basic-dropdown-item [label]=\"option.label\" labelFontWeight=\"normal\" [highlightTerm]=\"highlightTerm\" />\n }\n </li>\n }\n }\n </ul>\n </li>\n }\n @if (loading) {\n <lx-spinner [fadeBackground]=\"true\" />\n }\n </ul>\n </div>\n</ng-template>\n", styles: [":host{display:block}.overlayDropdown{width:100%;background:#fff;border-radius:3px;border-left:solid 1px #e1e5eb;border-right:solid 1px #e1e5eb;margin:0 -1px;width:calc(100% + 2px)}.overlayDropdown:not(.top){box-shadow:0 6px 6px #21252933;border-top:0;border-bottom:solid 1px #e1e5eb;border-top-left-radius:0;border-top-right-radius:0}.overlayDropdown.top{box-shadow:0 -4px 6px #21252933;border-top:solid 1px #e1e5eb;border-bottom:0;border-bottom-left-radius:0;border-bottom-right-radius:0}.scrollingPanel{overflow-y:auto;max-height:400px}.groupLabel{line-height:23px;padding:4px 12px;color:#61779d;letter-spacing:.5px;font-weight:700;text-transform:uppercase;cursor:default}ul{list-style:none;margin:0;padding:0}ul:not(:last-child){border-bottom:solid 1px #eaedf1}.noResult{display:block;padding:4px 12px}.option{cursor:pointer;display:block;padding:4px 12px}.option:hover{background-color:#e1e5eb!important}.option.highlighted{background:#eaedf1}\n"] }]
8347
+ ], template: "@if (overlayPositioning) {\n <div class=\"overlayOrigin\" cdkOverlayOrigin #selectOrigin=\"cdkOverlayOrigin\"></div>\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"selectOrigin\"\n [cdkConnectedOverlayOpen]=\"!!(cdkOverlayOpen$ | async)\"\n [cdkConnectedOverlayWidth]=\"selectOrigin.elementRef.nativeElement.offsetWidth\"\n (positionChange)=\"onPositionChange($event)\"\n >\n <div class=\"overlayDropdown\" [ngClass]=\"{ top: isTopDropdown }\">\n <ng-container *ngTemplateOutlet=\"dropdownContent\" />\n </div>\n </ng-template>\n} @else {\n <ng-container *ngTemplateOutlet=\"dropdownContent\" />\n}\n\n<ng-template #dropdownContent>\n <div\n #keyboardSelectContainer\n class=\"scrollingPanel lxThinScrollbar\"\n infinite-scroll\n [scrollWindow]=\"false\"\n [fromRoot]=\"true\"\n (scrolled)=\"containerScrolled.emit()\"\n >\n <ul class=\"options\">\n @if (showCreateNewOption && newOptionLabel && isNewItem) {\n <li\n lxSelectableItem\n [scrollInContainer]=\"keyboardSelectContainer\"\n #item\n (click)=\"onCreateNewOption()\"\n (select)=\"onCreateNewOption()\"\n [class.highlighted]=\"isItemSelected(item, (selectedItem$ | async)?.element)\"\n class=\"option\"\n >\n <span class=\"newEntryContent\">\n {{ newOptionLabel }}\n </span>\n <lx-counter class=\"lx-margin-left\" size=\"small\" [content]=\"'common.new' | translate | uppercase\" />\n </li>\n }\n @for (optionGroup of optionGroups; track trackByLabel($index, optionGroup); let groupIndex = $index) {\n <li>\n @if (optionGroup.label) {\n <div class=\"groupLabel\">\n <span>{{ optionGroup.label | uppercase }}</span>\n </div>\n }\n <ul>\n @if (showNoResultsIfGroupIsEmpty && optionGroup.options.length === 0) {\n <li class=\"noResult\">\n @if (noResultsOptionTemplateRef) {\n <ng-container *ngTemplateOutlet=\"noResultsOptionTemplateRef; context: { group: optionGroup, groupIndex: groupIndex }\" />\n } @else {\n <span>{{ NAME + '.noResults' | translate }}</span>\n }\n </li>\n } @else {\n @for (option of optionGroup.options; track trackByValue($index, option); let index = $index) {\n <li\n lxSelectableItem\n [scrollInContainer]=\"keyboardSelectContainer\"\n #item\n class=\"option\"\n (click)=\"selectOption(option)\"\n (select)=\"selectOption(option)\"\n [class.highlighted]=\"isItemSelected(item, (selectedItem$ | async)?.element)\"\n >\n @if (optionTemplateRef) {\n <ng-container\n *ngTemplateOutlet=\"optionTemplateRef; context: { $implicit: option, index: index, groupIndex: groupIndex }\"\n />\n } @else {\n <lx-basic-dropdown-item [label]=\"option.label\" labelFontWeight=\"normal\" [highlightTerm]=\"highlightTerm\" />\n }\n </li>\n }\n }\n </ul>\n </li>\n }\n @if (loading) {\n <lx-spinner [fadeBackground]=\"true\" />\n }\n </ul>\n </div>\n</ng-template>\n", styles: [":host{display:block}.overlayDropdown{width:100%;background:#fff;border-radius:3px;border-left:solid 1px #e1e5eb;border-right:solid 1px #e1e5eb;margin:0 -1px;width:calc(100% + 2px)}.overlayDropdown:not(.top){box-shadow:0 6px 6px #21252933;border-top:0;border-bottom:solid 1px #e1e5eb;border-top-left-radius:0;border-top-right-radius:0}.overlayDropdown.top{box-shadow:0 -4px 6px #21252933;border-top:solid 1px #e1e5eb;border-bottom:0;border-bottom-left-radius:0;border-bottom-right-radius:0}.scrollingPanel{overflow-y:auto;max-height:400px}.groupLabel{line-height:23px;padding:4px 12px;color:#61779d;letter-spacing:.5px;font-weight:700;text-transform:uppercase;cursor:default}ul{list-style:none;margin:0;padding:0}ul:not(:last-child){border-bottom:solid 1px #eaedf1}.noResult{display:block;padding:4px 12px}.option{cursor:pointer;display:block;padding:4px 12px}.option:hover{background-color:#e1e5eb!important}.option.highlighted{background:#eaedf1}\n"] }]
8348
8348
  }], propDecorators: { optionGroups: [{
8349
8349
  type: Input
8350
8350
  }], newOptionLabel: [{