@filip.mazev/blocks 1.4.3 → 1.4.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.
Files changed (52) hide show
  1. package/README.md +1 -1
  2. package/_index.scss +1 -1
  3. package/core/styles/_field-state.scss +16 -4
  4. package/core/styles/_index.scss +0 -1
  5. package/core/styles/_mixins.scss +2 -2
  6. package/core/styles/_motion.scss +1 -1
  7. package/core/styles/_palettes.scss +127 -132
  8. package/core/styles/_slider.scss +158 -40
  9. package/core/styles/_theme-engine.scss +43 -63
  10. package/core/styles/_utilities.scss +3 -4
  11. package/core/styles/_validation.scss +6 -1
  12. package/core/styles/_variables.scss +24 -14
  13. package/core/styles/themes/_cyberpunk-theme.scss +1 -1
  14. package/core/styles/themes/_green-theme.scss +1 -1
  15. package/core/styles/themes/_high-contrast-theme.scss +152 -133
  16. package/core/styles/themes/_orange-theme.scss +1 -1
  17. package/core/styles/themes/_purple-theme.scss +1 -1
  18. package/core/styles/themes/_red-theme.scss +1 -1
  19. package/core/styles/themes/_white-theme.scss +26 -20
  20. package/effects/README.md +5 -9
  21. package/effects/effects.css +200 -121
  22. package/effects/runtime/README.md +19 -11
  23. package/fesm2022/filip.mazev-blocks-core.mjs +27 -22
  24. package/fesm2022/filip.mazev-blocks-core.mjs.map +1 -1
  25. package/fesm2022/filip.mazev-blocks-effects-runtime.mjs +887 -67
  26. package/fesm2022/filip.mazev-blocks-effects-runtime.mjs.map +1 -1
  27. package/fesm2022/filip.mazev-blocks-effects.mjs +8 -48
  28. package/fesm2022/filip.mazev-blocks-effects.mjs.map +1 -1
  29. package/fesm2022/filip.mazev-blocks-forms.mjs +65 -61
  30. package/fesm2022/filip.mazev-blocks-forms.mjs.map +1 -1
  31. package/fesm2022/filip.mazev-blocks-modal.mjs +29 -32
  32. package/fesm2022/filip.mazev-blocks-modal.mjs.map +1 -1
  33. package/fesm2022/filip.mazev-blocks-navigation.mjs +35 -1
  34. package/fesm2022/filip.mazev-blocks-navigation.mjs.map +1 -1
  35. package/fesm2022/filip.mazev-blocks-primitives.mjs +106 -32
  36. package/fesm2022/filip.mazev-blocks-primitives.mjs.map +1 -1
  37. package/fesm2022/filip.mazev-blocks-toastr.mjs +5 -7
  38. package/fesm2022/filip.mazev-blocks-toastr.mjs.map +1 -1
  39. package/fesm2022/filip.mazev-blocks.mjs +1 -1
  40. package/fesm2022/filip.mazev-blocks.mjs.map +1 -1
  41. package/navigation/README.md +44 -0
  42. package/package.json +1 -1
  43. package/schematics/ng-add/index.js +4 -1
  44. package/types/filip.mazev-blocks-core.d.ts +3 -4
  45. package/types/filip.mazev-blocks-effects-runtime.d.ts +10 -8
  46. package/types/filip.mazev-blocks-effects.d.ts +5 -17
  47. package/types/filip.mazev-blocks-forms.d.ts +13 -11
  48. package/types/filip.mazev-blocks-modal.d.ts +1 -0
  49. package/types/filip.mazev-blocks-navigation.d.ts +20 -4
  50. package/types/filip.mazev-blocks-primitives.d.ts +12 -2
  51. package/types/filip.mazev-blocks-toastr.d.ts +4 -4
  52. package/types/filip.mazev-blocks.d.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"filip.mazev-blocks-navigation.mjs","names":[],"sources":["../../../projects/blocks/navigation/tokens/navigation-config.token.ts","../../../projects/blocks/navigation/tokens/navigation-access-adapter.token.ts","../../../projects/blocks/navigation/services/navigation.service.ts","../../../projects/blocks/navigation/components/breadcrumbs/breadcrumbs.ts","../../../projects/blocks/navigation/components/breadcrumbs/breadcrumbs.html","../../../projects/blocks/navigation/helpers/navigation-functions.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { INavigationConfig } from '../interfaces/inavigation-config.interface';\n\nexport const NAVIGATION_CONFIG = new InjectionToken<INavigationConfig>('NAVIGATION_CONFIG');\n","import { InjectionToken } from '@angular/core';\nimport { INavigationAccessAdapter } from '../interfaces/inavigation-access-adapter.interface';\n\nexport const NAVIGATION_ACCESS_ADAPTER = new InjectionToken<INavigationAccessAdapter>('NAVIGATION_ACCESS_ADAPTER');\n","import { computed, inject, Injectable, Signal } from '@angular/core';\nimport { ActivatedRouteSnapshot, NavigationEnd, Router, Routes } from '@angular/router';\nimport { NAVIGATION_CONFIG } from '../tokens/navigation-config.token';\nimport { IResolvedNavigation } from '../interfaces/iresolved-navigation.interface';\nimport { filter } from 'rxjs';\nimport { IBreadcrumbItem } from '../interfaces/ibreadcrumb-item.interface';\nimport { INavMeta } from '../interfaces/inav-meta.interface';\nimport { INavigationItem } from '../interfaces/inavigation-item.interface';\nimport { NAVIGATION_ACCESS_ADAPTER } from '../tokens/navigation-access-adapter.token';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { INavContext } from '../interfaces/inav-context.interface';\nimport { BX_I18N, isTextWithKey, ResolvableText } from '@filip.mazev/blocks/core';\nimport { NavText } from '../types/navigation.types';\n\n@Injectable({ providedIn: 'root' })\nexport class NavigationService {\n private readonly router = inject(Router);\n private readonly config = inject(NAVIGATION_CONFIG, { optional: true });\n private readonly i18n = inject(BX_I18N, { optional: true });\n private readonly accessAdapter = inject(NAVIGATION_ACCESS_ADAPTER, { optional: true });\n\n private readonly navEnd = toSignal(this.router.events.pipe(filter((e): e is NavigationEnd => e instanceof NavigationEnd)));\n\n public readonly current = computed<IResolvedNavigation>(() => {\n this.navEnd();\n this.i18n?.version?.();\n return this.resolveCurrent(this.router.routerState.snapshot.root);\n });\n\n public readonly routeBase = computed<string | undefined>(() => {\n return this.accessAdapter?.resolveBaseRoute();\n });\n\n public readonly routes: Signal<INavigationItem[]> = computed(() => {\n this.i18n?.version?.();\n return this.extractRoutes(this.router.config);\n });\n\n public readonly baseRoute = computed<string | undefined>(() => {\n const viewableRoutes = this.routes();\n\n const primaryPrefix = this.routeBase();\n\n let firstFoundRoot: string | undefined;\n\n const findRootRoute = (items: INavigationItem[]): string | undefined => {\n for (const item of items) {\n if (item.data?.root) {\n if (!firstFoundRoot) {\n firstFoundRoot = item.route;\n }\n\n if (primaryPrefix && item.route.startsWith(primaryPrefix)) {\n return item.route;\n }\n }\n\n if (item.children?.length) {\n const childRoot = findRootRoute(item.children);\n if (childRoot) return childRoot;\n }\n }\n return undefined;\n };\n\n const perfectMatch = findRootRoute(viewableRoutes);\n\n return perfectMatch ?? firstFoundRoot ?? primaryPrefix;\n });\n\n public readonly menu = computed(() => this.buildMenu(this.routes()));\n\n public navigateBack(): void {\n const breadcrumbs = this.current().breadcrumbs;\n\n if (breadcrumbs.length > 1) {\n const previousBreadcrumb = breadcrumbs[breadcrumbs.length - 2];\n this.router.navigateByUrl(previousBreadcrumb.route);\n } else {\n this.router.navigateByUrl(this.routeBase() ?? '/');\n }\n }\n\n //#region Helpers\n\n private extractRoutes(routes: Routes, parentSegment: string[] = []): INavigationItem[] {\n const items: INavigationItem[] = [];\n\n for (const route of routes) {\n if (route.redirectTo) continue;\n\n if (this.accessAdapter && !this.accessAdapter.canAccessMenu(route.data ?? {})) {\n continue;\n }\n\n const ownPath = route.path ?? '';\n\n const fullSegments = ownPath ? [...parentSegment, ownPath] : [...parentSegment];\n\n const fullRoute = '/' + fullSegments.filter(Boolean).join('/');\n\n const children = route.children?.length ? this.extractRoutes(route.children, fullSegments) : [];\n\n const nav = route.data?.['nav'] as INavMeta | undefined;\n\n if (!nav) {\n items.push(...children);\n continue;\n }\n\n const item = {\n id: fullRoute,\n route: fullRoute,\n label: this.resolveNavText(nav.label, { snapshot: undefined }) ?? '',\n icon: nav.icon,\n section: nav.section,\n visible: nav.visible ? nav.visible() : true,\n data: nav,\n children\n };\n\n items.push(item);\n }\n\n return this.sortNavigationItems(items);\n }\n\n private resolveCurrent(root: ActivatedRouteSnapshot): IResolvedNavigation {\n let currentNode: ActivatedRouteSnapshot | null = root;\n let finalSnapshot: ActivatedRouteSnapshot | undefined;\n\n while (currentNode) {\n const next: ActivatedRouteSnapshot | null = currentNode.children.find((child) => child.outlet === 'primary') ?? null;\n if (!next) {\n finalSnapshot = currentNode;\n break;\n }\n currentNode = next;\n }\n\n if (!finalSnapshot) return { breadcrumbs: [] };\n\n const urlSegments = finalSnapshot.pathFromRoot.flatMap((s) => s.url.map((u) => u.path)).filter(Boolean);\n\n const breadcrumbs: IBreadcrumbItem[] = [];\n const allItems = this.flattenRoutes(this.routes());\n let currentUrl = '';\n\n for (const segment of urlSegments) {\n currentUrl += '/' + segment;\n\n const matchingItem = this.matchRouteToUrl(allItems, currentUrl);\n\n if (matchingItem && matchingItem.data && !matchingItem.data.hidden) {\n const ctx: INavContext = { snapshot: finalSnapshot };\n\n const label = this.resolveNavText(matchingItem.data.breadcrumb, ctx) ?? this.resolveNavText(matchingItem.data.label, ctx);\n\n if (label && breadcrumbs[breadcrumbs.length - 1]?.label !== label) {\n breadcrumbs.push({ label, route: currentUrl });\n }\n }\n }\n\n const leafNav = finalSnapshot.routeConfig?.data?.['nav'] as INavMeta | undefined;\n const fullUrl = '/' + urlSegments.join('/');\n\n let current: INavigationItem | undefined;\n\n if (leafNav && !leafNav.hidden) {\n current = {\n id: fullUrl,\n route: fullUrl,\n label: this.resolveNavText(leafNav.label, { snapshot: finalSnapshot }) ?? '',\n icon: leafNav.icon,\n section: leafNav.section,\n visible: leafNav.visible ? leafNav.visible() : true,\n data: leafNav\n };\n }\n\n return { current, breadcrumbs };\n }\n\n private buildMenu(items: INavigationItem[]): INavigationItem[] {\n return items\n .map((item): INavigationItem | null => {\n const children = this.buildMenu(item.children ?? []);\n const includeSelf = item.visible && item.data?.menu !== false;\n\n if (!includeSelf && !children.length) {\n return null;\n }\n\n return {\n ...item,\n children\n };\n })\n .filter((item): item is INavigationItem => item !== null);\n }\n\n private sortNavigationItems(items: INavigationItem[]): INavigationItem[] {\n const customSort = this.config?.sortItems;\n\n return [...items].sort((a, b) => {\n if (customSort) {\n return customSort(a, b);\n }\n\n const orderA = a.data?.order ?? Number.POSITIVE_INFINITY;\n const orderB = b.data?.order ?? Number.POSITIVE_INFINITY;\n\n if (orderA !== orderB) return orderA - orderB;\n return a.label.localeCompare(b.label);\n });\n }\n\n private matchRouteToUrl(items: INavigationItem[], url: string): INavigationItem | undefined {\n const exactMatch = items.find((i) => i.route === url);\n if (exactMatch) return exactMatch;\n\n return items.find((i) => {\n if (!i.route.includes(':')) return false;\n const routeRegex = new RegExp('^' + i.route.replace(/:[^\\s/]+/g, '([^/]+)') + '$');\n return routeRegex.test(url);\n });\n }\n\n private flattenRoutes(items: INavigationItem[]): INavigationItem[] {\n return items.reduce((acc, item) => {\n acc.push(item);\n if (item.children) acc.push(...this.flattenRoutes(item.children));\n return acc;\n }, [] as INavigationItem[]);\n }\n\n private resolveNavText(textDef: NavText | undefined, ctx: INavContext): string | undefined {\n if (!textDef) return undefined;\n\n const text: ResolvableText = typeof textDef === 'function' ? textDef(ctx) : textDef;\n\n if (isTextWithKey(text)) {\n return this.i18n?.translate(text.key, { route: ctx.snapshot });\n }\n\n return text;\n }\n\n //#endregion\n}\n","import { Component, computed, inject, input, ChangeDetectionStrategy } from '@angular/core';\nimport { RouterLink } from '@angular/router';\nimport { NavigationService } from '../../services/navigation.service';\nimport { Icon, IconName } from '@filip.mazev/blocks/icons';\nimport { BxA11yService } from '@filip.mazev/blocks/core';\n\n@Component({\n selector: 'bx-breadcrumbs',\n imports: [RouterLink, Icon],\n templateUrl: './breadcrumbs.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n styleUrl: './breadcrumbs.scss'\n})\nexport class Breadcrumbs {\n private readonly navigationService = inject(NavigationService);\n private readonly a11y = inject(BxA11yService);\n\n protected readonly isAnimated = computed(() => {\n return !this.a11y.isReducedMotion();\n });\n\n public readonly minimumBreadcrumbs = input<number>(2);\n public readonly divider = input<IconName>('chevron-right');\n\n protected showBreadcumbs = computed(() => {\n const minimum = Math.max(1, this.minimumBreadcrumbs());\n return this.current().breadcrumbs.length >= minimum;\n });\n\n protected ariaLabel = computed(() => {\n const labels = this.current()\n .breadcrumbs.map((crumb) => crumb.label)\n .join(' > ');\n return `Breadcrumbs: ${labels}`;\n });\n\n protected current = this.navigationService.current;\n}\n","@if(showBreadcumbs()) {\n<nav class=\"breadcrumbs\" [attr.aria-label]=\"ariaLabel()\">\n @for (crumb of current().breadcrumbs; track crumb.route; let last = $last) {\n @if (last) {\n <span class=\"crumb last\" aria-current=\"page\">{{ crumb.label }}</span>\n } @else {\n <a class=\"crumb\" [routerLink]=\"crumb.route\">{{ crumb.label }}</a>\n <bx-icon [name]=\"divider()\" size=\"16\" class=\"breadcrumb-separator\" />\n }\n }\n</nav>\n}\n","import { Strict } from '@filip.mazev/blocks/core';\nimport { INavMeta } from '../interfaces/inav-meta.interface';\nimport { INavigationConfig } from '../interfaces/inavigation-config.interface';\nimport { NAVIGATION_CONFIG } from '../tokens/navigation-config.token';\nimport { Route } from '@angular/router';\n\n/**\n *\n * @param config\n * This function is a helper to provide the navigation configuration in your Angular application.\n * It takes an `INavigationConfig` object as an argument and returns an array of providers that can be used in the `providers` array of your Angular module.\n * By using this function, you can easily set up the navigation configuration for your application without having to manually create the provider object each time.\n */\nexport function provideNavigation(config: INavigationConfig) {\n return [\n {\n provide: NAVIGATION_CONFIG,\n useValue: config\n }\n ];\n}\n\n/**\n *\n * @param route\n * @param nav\n * This function is a helper to attach navigation metadata to Angular routes. It takes an Angular `Route` object and a navigation metadata object of type `Strict<T, INavMeta>`, where `T`\n * is a generic type that can be used to enforce specific properties on the navigation metadata.\n * The function returns a new `Route` object with the provided navigation metadata merged into the existing route data under the 'nav' property.\n * This allows you to easily associate navigation information with your routes, which can then be used by navigation components to generate menus, breadcrumbs, etc.\n */\nexport function withNav<T>(route: Route, nav: Strict<T, INavMeta>): Route {\n const existingNav = (route.data?.['nav'] as INavMeta | undefined) ?? {};\n\n return {\n ...route,\n data: {\n ...(route.data ?? {}),\n nav: {\n ...existingNav,\n ...nav\n }\n }\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"filip.mazev-blocks-navigation.mjs","names":[],"sources":["../../../projects/blocks/navigation/tokens/navigation-config.token.ts","../../../projects/blocks/navigation/tokens/navigation-access-adapter.token.ts","../../../projects/blocks/navigation/services/navigation.service.ts","../../../projects/blocks/navigation/components/breadcrumbs/breadcrumbs.ts","../../../projects/blocks/navigation/components/breadcrumbs/breadcrumbs.html","../../../projects/blocks/navigation/helpers/navigation-functions.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { INavigationConfig } from '../interfaces/inavigation-config.interface';\n\nexport const NAVIGATION_CONFIG = new InjectionToken<INavigationConfig>('NAVIGATION_CONFIG');\n","import { InjectionToken } from '@angular/core';\nimport { INavigationAccessAdapter } from '../interfaces/inavigation-access-adapter.interface';\n\nexport const NAVIGATION_ACCESS_ADAPTER = new InjectionToken<INavigationAccessAdapter>('NAVIGATION_ACCESS_ADAPTER');\n","import { computed, inject, Injectable, Signal } from '@angular/core';\nimport { ActivatedRouteSnapshot, NavigationEnd, Router, Routes } from '@angular/router';\nimport { NAVIGATION_CONFIG } from '../tokens/navigation-config.token';\nimport { IResolvedNavigation } from '../interfaces/iresolved-navigation.interface';\nimport { filter } from 'rxjs';\nimport { IBreadcrumbItem } from '../interfaces/ibreadcrumb-item.interface';\nimport { INavMeta } from '../interfaces/inav-meta.interface';\nimport { INavigationItem } from '../interfaces/inavigation-item.interface';\nimport { NAVIGATION_ACCESS_ADAPTER } from '../tokens/navigation-access-adapter.token';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { INavContext } from '../interfaces/inav-context.interface';\nimport { BX_I18N, isTextWithKey, ResolvableText } from '@filip.mazev/blocks/core';\nimport { NavText } from '../types/navigation.types';\nimport { INavigationGroup } from '../interfaces/inavigation-group.interface';\n\n@Injectable({ providedIn: 'root' })\nexport class NavigationService {\n private readonly router = inject(Router);\n private readonly config = inject(NAVIGATION_CONFIG, { optional: true });\n private readonly i18n = inject(BX_I18N, { optional: true });\n private readonly accessAdapter = inject(NAVIGATION_ACCESS_ADAPTER, { optional: true });\n\n private readonly navEnd = toSignal(this.router.events.pipe(filter((e): e is NavigationEnd => e instanceof NavigationEnd)));\n\n public readonly current = computed<IResolvedNavigation>(() => {\n this.navEnd();\n this.i18n?.version?.();\n return this.resolveCurrent(this.router.routerState.snapshot.root);\n });\n\n public readonly routeBase = computed<string | undefined>(() => {\n return this.accessAdapter?.resolveBaseRoute();\n });\n\n public readonly routes: Signal<INavigationItem[]> = computed(() => {\n this.i18n?.version?.();\n return this.extractRoutes(this.router.config);\n });\n\n public readonly baseRoute = computed<string | undefined>(() => {\n const viewableRoutes = this.routes();\n\n const primaryPrefix = this.routeBase();\n\n let firstFoundRoot: string | undefined;\n\n const findRootRoute = (items: INavigationItem[]): string | undefined => {\n for (const item of items) {\n if (item.data?.root) {\n if (!firstFoundRoot) {\n firstFoundRoot = item.route;\n }\n\n if (primaryPrefix && item.route.startsWith(primaryPrefix)) {\n return item.route;\n }\n }\n\n if (item.children?.length) {\n const childRoot = findRootRoute(item.children);\n if (childRoot) return childRoot;\n }\n }\n return undefined;\n };\n\n const perfectMatch = findRootRoute(viewableRoutes);\n\n return perfectMatch ?? firstFoundRoot ?? primaryPrefix;\n });\n\n public readonly menu = computed(() => this.buildMenu(this.routes()));\n\n public readonly menuGroups = computed<INavigationGroup[]>(() => {\n const sections = [...(this.config?.sections ?? [])].sort((a, b) => (a.order ?? Number.POSITIVE_INFINITY) - (b.order ?? Number.POSITIVE_INFINITY));\n const groups = new Map<string, INavigationGroup>(\n sections.map((section) => [section.id, { id: section.id, title: section.title ?? section.id, items: [] }])\n );\n\n for (const item of this.flattenRoutes(this.menu())) {\n if (!item.visible || item.data?.menu === false) continue;\n\n const id = item.section ?? '';\n let group = groups.get(id);\n if (!group) {\n group = { id, title: id, items: [] };\n groups.set(id, group);\n }\n group.items.push({ ...item, children: undefined });\n }\n\n return [...groups.values()].filter((group) => group.items.length > 0);\n });\n\n public navigateBack(): void {\n const breadcrumbs = this.current().breadcrumbs;\n\n if (breadcrumbs.length > 1) {\n const previousBreadcrumb = breadcrumbs[breadcrumbs.length - 2];\n this.router.navigateByUrl(previousBreadcrumb.route);\n } else {\n this.router.navigateByUrl(this.routeBase() ?? '/');\n }\n }\n\n //#region Helpers\n\n private extractRoutes(routes: Routes, parentSegment: string[] = []): INavigationItem[] {\n const items: INavigationItem[] = [];\n\n for (const route of routes) {\n if (route.redirectTo) continue;\n\n if (this.accessAdapter && !this.accessAdapter.canAccessMenu(route.data ?? {})) {\n continue;\n }\n\n const ownPath = route.path ?? '';\n\n const fullSegments = ownPath ? [...parentSegment, ownPath] : [...parentSegment];\n\n const fullRoute = '/' + fullSegments.filter(Boolean).join('/');\n\n const children = route.children?.length ? this.extractRoutes(route.children, fullSegments) : [];\n\n const nav = route.data?.['nav'] as INavMeta | undefined;\n\n if (!nav) {\n items.push(...children);\n continue;\n }\n\n const item = {\n id: fullRoute,\n route: fullRoute,\n label: this.resolveNavText(nav.label, { snapshot: undefined }) ?? '',\n icon: nav.icon,\n section: nav.section,\n visible: nav.visible ? nav.visible() : true,\n data: nav,\n children\n };\n\n items.push(item);\n }\n\n return this.sortNavigationItems(items);\n }\n\n private resolveCurrent(root: ActivatedRouteSnapshot): IResolvedNavigation {\n let currentNode: ActivatedRouteSnapshot | null = root;\n let finalSnapshot: ActivatedRouteSnapshot | undefined;\n\n while (currentNode) {\n const next: ActivatedRouteSnapshot | null = currentNode.children.find((child) => child.outlet === 'primary') ?? null;\n if (!next) {\n finalSnapshot = currentNode;\n break;\n }\n currentNode = next;\n }\n\n if (!finalSnapshot) return { breadcrumbs: [] };\n\n const urlSegments = finalSnapshot.pathFromRoot.flatMap((s) => s.url.map((u) => u.path)).filter(Boolean);\n\n const breadcrumbs: IBreadcrumbItem[] = [];\n const allItems = this.flattenRoutes(this.routes());\n let currentUrl = '';\n\n for (const segment of urlSegments) {\n currentUrl += '/' + segment;\n\n const matchingItem = this.matchRouteToUrl(allItems, currentUrl);\n\n if (matchingItem && matchingItem.data && !matchingItem.data.hidden) {\n const ctx: INavContext = { snapshot: finalSnapshot };\n\n const label = this.resolveNavText(matchingItem.data.breadcrumb, ctx) ?? this.resolveNavText(matchingItem.data.label, ctx);\n\n if (label && breadcrumbs[breadcrumbs.length - 1]?.label !== label) {\n breadcrumbs.push({ label, route: currentUrl });\n }\n }\n }\n\n const leafNav = finalSnapshot.routeConfig?.data?.['nav'] as INavMeta | undefined;\n const fullUrl = '/' + urlSegments.join('/');\n\n let current: INavigationItem | undefined;\n\n if (leafNav && !leafNav.hidden) {\n current = {\n id: fullUrl,\n route: fullUrl,\n label: this.resolveNavText(leafNav.label, { snapshot: finalSnapshot }) ?? '',\n icon: leafNav.icon,\n section: leafNav.section,\n visible: leafNav.visible ? leafNav.visible() : true,\n data: leafNav\n };\n }\n\n return { current, breadcrumbs };\n }\n\n private buildMenu(items: INavigationItem[]): INavigationItem[] {\n return items\n .map((item): INavigationItem | null => {\n const children = this.buildMenu(item.children ?? []);\n const includeSelf = item.visible && item.data?.menu !== false;\n\n if (!includeSelf && !children.length) {\n return null;\n }\n\n return {\n ...item,\n children\n };\n })\n .filter((item): item is INavigationItem => item !== null);\n }\n\n private sortNavigationItems(items: INavigationItem[]): INavigationItem[] {\n const customSort = this.config?.sortItems;\n\n return [...items].sort((a, b) => {\n if (customSort) {\n return customSort(a, b);\n }\n\n const orderA = a.data?.order ?? Number.POSITIVE_INFINITY;\n const orderB = b.data?.order ?? Number.POSITIVE_INFINITY;\n\n if (orderA !== orderB) return orderA - orderB;\n return a.label.localeCompare(b.label);\n });\n }\n\n private matchRouteToUrl(items: INavigationItem[], url: string): INavigationItem | undefined {\n const exactMatch = items.find((i) => i.route === url);\n if (exactMatch) return exactMatch;\n\n return items.find((i) => {\n if (!i.route.includes(':')) return false;\n const routeRegex = new RegExp('^' + i.route.replace(/:[^\\s/]+/g, '([^/]+)') + '$');\n return routeRegex.test(url);\n });\n }\n\n private flattenRoutes(items: INavigationItem[]): INavigationItem[] {\n return items.reduce((acc, item) => {\n acc.push(item);\n if (item.children) acc.push(...this.flattenRoutes(item.children));\n return acc;\n }, [] as INavigationItem[]);\n }\n\n private resolveNavText(textDef: NavText | undefined, ctx: INavContext): string | undefined {\n if (!textDef) return undefined;\n\n const text: ResolvableText = typeof textDef === 'function' ? textDef(ctx) : textDef;\n\n if (isTextWithKey(text)) {\n return this.i18n?.translate(text.key, { route: ctx.snapshot });\n }\n\n return text;\n }\n\n //#endregion\n}\n","import { Component, computed, inject, input, ChangeDetectionStrategy } from '@angular/core';\nimport { RouterLink } from '@angular/router';\nimport { NavigationService } from '../../services/navigation.service';\nimport { Icon, IconName } from '@filip.mazev/blocks/icons';\nimport { BxA11yService } from '@filip.mazev/blocks/core';\n\n@Component({\n selector: 'bx-breadcrumbs',\n imports: [RouterLink, Icon],\n templateUrl: './breadcrumbs.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n styleUrl: './breadcrumbs.scss'\n})\nexport class Breadcrumbs {\n private readonly navigationService = inject(NavigationService);\n private readonly a11y = inject(BxA11yService);\n\n protected readonly isAnimated = computed(() => {\n return !this.a11y.isReducedMotion();\n });\n\n public readonly minimumBreadcrumbs = input<number>(2);\n public readonly divider = input<IconName>('chevron-right');\n\n protected showBreadcumbs = computed(() => {\n const minimum = Math.max(1, this.minimumBreadcrumbs());\n return this.current().breadcrumbs.length >= minimum;\n });\n\n protected ariaLabel = computed(() => {\n const labels = this.current()\n .breadcrumbs.map((crumb) => crumb.label)\n .join(' > ');\n return `Breadcrumbs: ${labels}`;\n });\n\n protected current = this.navigationService.current;\n}\n","@if(showBreadcumbs()) {\n<nav class=\"breadcrumbs\" [attr.aria-label]=\"ariaLabel()\">\n @for (crumb of current().breadcrumbs; track crumb.route; let last = $last) {\n @if (last) {\n <span class=\"crumb last\" aria-current=\"page\">{{ crumb.label }}</span>\n } @else {\n <a class=\"crumb\" [routerLink]=\"crumb.route\">{{ crumb.label }}</a>\n <bx-icon [name]=\"divider()\" size=\"16\" class=\"breadcrumb-separator\" />\n }\n }\n</nav>\n}\n","import { Strict } from '@filip.mazev/blocks/core';\nimport { INavMeta } from '../interfaces/inav-meta.interface';\nimport { INavigationConfig } from '../interfaces/inavigation-config.interface';\nimport { NAVIGATION_CONFIG } from '../tokens/navigation-config.token';\nimport { Route } from '@angular/router';\nimport { INavigationSectionConfig } from '../interfaces/inavigation-section-config.interface';\n\n/** Declares UI sections and binds route metadata to their literal IDs. */\nexport function defineNavigation<const TSections extends readonly INavigationSectionConfig[]>(\n config: Omit<INavigationConfig, 'sections'> & { sections: TSections }\n) {\n return {\n config,\n withNav<T extends INavMeta<TSections[number]['id']>>(route: Route, nav: Strict<T, INavMeta<TSections[number]['id']>>): Route {\n return withNav(route, nav);\n }\n };\n}\n\n/**\n *\n * @param config\n * This function is a helper to provide the navigation configuration in your Angular application.\n * It takes an `INavigationConfig` object as an argument and returns an array of providers that can be used in the `providers` array of your Angular module.\n * By using this function, you can easily set up the navigation configuration for your application without having to manually create the provider object each time.\n */\nexport function provideNavigation(config: INavigationConfig) {\n return [\n {\n provide: NAVIGATION_CONFIG,\n useValue: config\n }\n ];\n}\n\n/**\n *\n * @param route\n * @param nav\n * This function is a helper to attach navigation metadata to Angular routes. It takes an Angular `Route` object and a navigation metadata object of type `Strict<T, INavMeta>`, where `T`\n * is a generic type that can be used to enforce specific properties on the navigation metadata.\n * The function returns a new `Route` object with the provided navigation metadata merged into the existing route data under the 'nav' property.\n * This allows you to easily associate navigation information with your routes, which can then be used by navigation components to generate menus, breadcrumbs, etc.\n */\nexport function withNav<T extends INavMeta>(route: Route, nav: Strict<T, INavMeta>): Route {\n const existingNav = (route.data?.['nav'] as INavMeta | undefined) ?? {};\n\n return {\n ...route,\n data: {\n ...(route.data ?? {}),\n nav: {\n ...existingNav,\n ...nav\n }\n }\n };\n}\n"],"mappings":"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"}
@@ -5,7 +5,7 @@ import { BX_I18N, BxA11yService, BxOverlayPositionService, BxShortcutService, in
5
5
  import { Icon } from "@filip.mazev/blocks/icons";
6
6
  import { Overlay } from "@angular/cdk/overlay";
7
7
  import { ComponentPortal, TemplatePortal } from "@angular/cdk/portal";
8
- import { createGlassTransition } from "@filip.mazev/blocks/effects/runtime";
8
+ import { createGlassTransition, inheritGlassLighting } from "@filip.mazev/blocks/effects/runtime";
9
9
  import { isPlatformBrowser } from "@angular/common";
10
10
  import { Subscription } from "rxjs";
11
11
  var Tooltip = class Tooltip {
@@ -43,16 +43,14 @@ var Tooltip = class Tooltip {
43
43
  } },
44
44
  ngImport: i0,
45
45
  template: "<div class=\"bx-tooltip-surface\" bxSurface [class.bx-tooltip-animated]=\"isAnimated()\">\n @if (resolvedText()) {\n {{ resolvedText() }}\n }\n</div>",
46
- styles: [":host{display:block;pointer-events:none;z-index:600}.bx-tooltip-surface[data-bx-surface]{position:relative;padding:.25rem .5rem;border:1px solid var(--bx-border-default);border-radius:.25rem;font-size:.75rem;font-family:inherit;max-width:min(22rem,100vw - 1.5rem);white-space:normal;overflow-wrap:anywhere;--bx-glass-surface: var(--bx-bg-surface);--bx-glass-text: var(--bx-text-primary);--bx-glass-shadow: 0 2px 4px 0 rgba(0, 0, 0, .1), 0 1px 2px -1px rgba(0, 0, 0, .1);--bx-glass-min-opacity: 1;--bx-glass-decoration-opacity: 0;-webkit-backdrop-filter:none;backdrop-filter:none}.bx-tooltip-surface[data-bx-surface]:after{content:\"\";position:absolute;z-index:2;width:.5rem;height:.5rem;box-sizing:border-box;border-radius:0;background:var(--bx-glass-surface);border:0 solid var(--bx-border-default);transform:translate(-50%,-50%) rotate(45deg);pointer-events:none}:host-context(.bx-overlay-pos-bottom) .bx-tooltip-surface:after{top:-1px;left:clamp(.75rem,var(--bx-tooltip-arrow-x, 50%),100% - .75rem);border-top-width:1px;border-left-width:1px}:host-context(.bx-overlay-pos-top) .bx-tooltip-surface:after{top:calc(100% + 1px);left:clamp(.75rem,var(--bx-tooltip-arrow-x, 50%),100% - .75rem);border-right-width:1px;border-bottom-width:1px}:host-context(.bx-overlay-pos-left) .bx-tooltip-surface:after{left:calc(100% + 1px);top:clamp(.5rem,var(--bx-tooltip-arrow-y, 50%),100% - .5rem);border-top-width:1px;border-right-width:1px}:host-context(.bx-overlay-pos-right) .bx-tooltip-surface:after{left:-1px;top:clamp(.5rem,var(--bx-tooltip-arrow-y, 50%),100% - .5rem);border-bottom-width:1px;border-left-width:1px}@media(forced-colors:active){.bx-tooltip-surface[data-bx-surface]:after{background:Canvas;border-color:CanvasText}}\n"],
46
+ styles: [":host{display:block;pointer-events:none;z-index:600}.bx-tooltip-surface[data-bx-surface]{position:relative;padding:.25rem .5rem;border:1px solid var(--bx-glass-edge);border-radius:var(--bx-glass-radius, var(--bx-rounded-sm, .25rem));font-size:.75rem;font-family:inherit;max-width:min(22rem,100vw - 1.5rem);white-space:normal;overflow-wrap:anywhere;--bx-glass-unified-lighting: 1;--bx-glass-surface: var(--bx-bg-neutral);--bx-glass-edge: var(--bx-border-default);--bx-glass-text: var(--bx-text-primary);--bx-glass-shadow: 0 2px 4px 0 rgba(0, 0, 0, .1), 0 1px 2px -1px rgba(0, 0, 0, .1);--bx-glass-min-opacity: 1;--bx-glass-decoration-opacity: 0;--bx-glass-rim-visibility: .35;-webkit-backdrop-filter:none;backdrop-filter:none}.bx-tooltip-surface[data-bx-surface]:after{content:\"\";position:absolute;z-index:2;width:.5rem;height:.5rem;box-sizing:border-box;border-radius:0;background:var(--bx-glass-surface);border:0 solid var(--bx-tooltip-arrow-edge, var(--bx-glass-edge));transform:translate(-50%,-50%) rotate(45deg);pointer-events:none}@media(prefers-contrast:more){.bx-tooltip-surface[data-bx-surface]{--bx-glass-surface: var(--bx-bg-surface);--bx-glass-edge: currentcolor}.bx-tooltip-surface[data-bx-surface]:after{border-color:currentcolor}}:host-context(.bx-overlay-pos-bottom) .bx-tooltip-surface{--bx-tooltip-arrow-edge: var(--bx-glass-lit-edge-top, var(--bx-glass-edge))}:host-context(.bx-overlay-pos-bottom) .bx-tooltip-surface:after{top:-1px;left:clamp(.75rem,var(--bx-tooltip-arrow-x, 50%),100% - .75rem);border-top-width:1px;border-left-width:1px}:host-context(.bx-overlay-pos-top) .bx-tooltip-surface{--bx-tooltip-arrow-edge: var(--bx-glass-lit-edge-bottom, var(--bx-glass-edge))}:host-context(.bx-overlay-pos-top) .bx-tooltip-surface:after{top:calc(100% + 1px);left:clamp(.75rem,var(--bx-tooltip-arrow-x, 50%),100% - .75rem);border-right-width:1px;border-bottom-width:1px}:host-context(.bx-overlay-pos-left) .bx-tooltip-surface{--bx-tooltip-arrow-edge: var(--bx-glass-lit-edge-right, var(--bx-glass-edge))}:host-context(.bx-overlay-pos-left) .bx-tooltip-surface:after{left:calc(100% + 1px);top:clamp(.5rem,var(--bx-tooltip-arrow-y, 50%),100% - .5rem);border-top-width:1px;border-right-width:1px}:host-context(.bx-overlay-pos-right) .bx-tooltip-surface{--bx-tooltip-arrow-edge: var(--bx-glass-lit-edge-left, var(--bx-glass-edge))}:host-context(.bx-overlay-pos-right) .bx-tooltip-surface:after{left:-1px;top:clamp(.5rem,var(--bx-tooltip-arrow-y, 50%),100% - .5rem);border-bottom-width:1px;border-left-width:1px}@media(forced-colors:active){.bx-tooltip-surface[data-bx-surface]:after{background:Canvas;border-color:CanvasText}}\n"],
47
47
  dependencies: [{
48
48
  kind: "directive",
49
49
  type: BxSurfaceDirective,
50
50
  selector: "[bxSurface]",
51
51
  inputs: [
52
- "bxSurface",
53
52
  "bxSurfaceInteractive",
54
- "bxSurfaceBlur",
55
- "bxSurfaceTint",
53
+ "bxSurfaceGlassiness",
56
54
  "bxSurfaceEmission",
57
55
  "bxSurfaceFocusEmission",
58
56
  "bxReducedTransparency"
@@ -74,7 +72,7 @@ i0.ɵɵngDeclareClassMetadata({
74
72
  imports: [BxSurfaceDirective],
75
73
  changeDetection: ChangeDetectionStrategy.OnPush,
76
74
  template: "<div class=\"bx-tooltip-surface\" bxSurface [class.bx-tooltip-animated]=\"isAnimated()\">\n @if (resolvedText()) {\n {{ resolvedText() }}\n }\n</div>",
77
- styles: [":host{display:block;pointer-events:none;z-index:600}.bx-tooltip-surface[data-bx-surface]{position:relative;padding:.25rem .5rem;border:1px solid var(--bx-border-default);border-radius:.25rem;font-size:.75rem;font-family:inherit;max-width:min(22rem,100vw - 1.5rem);white-space:normal;overflow-wrap:anywhere;--bx-glass-surface: var(--bx-bg-surface);--bx-glass-text: var(--bx-text-primary);--bx-glass-shadow: 0 2px 4px 0 rgba(0, 0, 0, .1), 0 1px 2px -1px rgba(0, 0, 0, .1);--bx-glass-min-opacity: 1;--bx-glass-decoration-opacity: 0;-webkit-backdrop-filter:none;backdrop-filter:none}.bx-tooltip-surface[data-bx-surface]:after{content:\"\";position:absolute;z-index:2;width:.5rem;height:.5rem;box-sizing:border-box;border-radius:0;background:var(--bx-glass-surface);border:0 solid var(--bx-border-default);transform:translate(-50%,-50%) rotate(45deg);pointer-events:none}:host-context(.bx-overlay-pos-bottom) .bx-tooltip-surface:after{top:-1px;left:clamp(.75rem,var(--bx-tooltip-arrow-x, 50%),100% - .75rem);border-top-width:1px;border-left-width:1px}:host-context(.bx-overlay-pos-top) .bx-tooltip-surface:after{top:calc(100% + 1px);left:clamp(.75rem,var(--bx-tooltip-arrow-x, 50%),100% - .75rem);border-right-width:1px;border-bottom-width:1px}:host-context(.bx-overlay-pos-left) .bx-tooltip-surface:after{left:calc(100% + 1px);top:clamp(.5rem,var(--bx-tooltip-arrow-y, 50%),100% - .5rem);border-top-width:1px;border-right-width:1px}:host-context(.bx-overlay-pos-right) .bx-tooltip-surface:after{left:-1px;top:clamp(.5rem,var(--bx-tooltip-arrow-y, 50%),100% - .5rem);border-bottom-width:1px;border-left-width:1px}@media(forced-colors:active){.bx-tooltip-surface[data-bx-surface]:after{background:Canvas;border-color:CanvasText}}\n"]
75
+ styles: [":host{display:block;pointer-events:none;z-index:600}.bx-tooltip-surface[data-bx-surface]{position:relative;padding:.25rem .5rem;border:1px solid var(--bx-glass-edge);border-radius:var(--bx-glass-radius, var(--bx-rounded-sm, .25rem));font-size:.75rem;font-family:inherit;max-width:min(22rem,100vw - 1.5rem);white-space:normal;overflow-wrap:anywhere;--bx-glass-unified-lighting: 1;--bx-glass-surface: var(--bx-bg-neutral);--bx-glass-edge: var(--bx-border-default);--bx-glass-text: var(--bx-text-primary);--bx-glass-shadow: 0 2px 4px 0 rgba(0, 0, 0, .1), 0 1px 2px -1px rgba(0, 0, 0, .1);--bx-glass-min-opacity: 1;--bx-glass-decoration-opacity: 0;--bx-glass-rim-visibility: .35;-webkit-backdrop-filter:none;backdrop-filter:none}.bx-tooltip-surface[data-bx-surface]:after{content:\"\";position:absolute;z-index:2;width:.5rem;height:.5rem;box-sizing:border-box;border-radius:0;background:var(--bx-glass-surface);border:0 solid var(--bx-tooltip-arrow-edge, var(--bx-glass-edge));transform:translate(-50%,-50%) rotate(45deg);pointer-events:none}@media(prefers-contrast:more){.bx-tooltip-surface[data-bx-surface]{--bx-glass-surface: var(--bx-bg-surface);--bx-glass-edge: currentcolor}.bx-tooltip-surface[data-bx-surface]:after{border-color:currentcolor}}:host-context(.bx-overlay-pos-bottom) .bx-tooltip-surface{--bx-tooltip-arrow-edge: var(--bx-glass-lit-edge-top, var(--bx-glass-edge))}:host-context(.bx-overlay-pos-bottom) .bx-tooltip-surface:after{top:-1px;left:clamp(.75rem,var(--bx-tooltip-arrow-x, 50%),100% - .75rem);border-top-width:1px;border-left-width:1px}:host-context(.bx-overlay-pos-top) .bx-tooltip-surface{--bx-tooltip-arrow-edge: var(--bx-glass-lit-edge-bottom, var(--bx-glass-edge))}:host-context(.bx-overlay-pos-top) .bx-tooltip-surface:after{top:calc(100% + 1px);left:clamp(.75rem,var(--bx-tooltip-arrow-x, 50%),100% - .75rem);border-right-width:1px;border-bottom-width:1px}:host-context(.bx-overlay-pos-left) .bx-tooltip-surface{--bx-tooltip-arrow-edge: var(--bx-glass-lit-edge-right, var(--bx-glass-edge))}:host-context(.bx-overlay-pos-left) .bx-tooltip-surface:after{left:calc(100% + 1px);top:clamp(.5rem,var(--bx-tooltip-arrow-y, 50%),100% - .5rem);border-top-width:1px;border-right-width:1px}:host-context(.bx-overlay-pos-right) .bx-tooltip-surface{--bx-tooltip-arrow-edge: var(--bx-glass-lit-edge-left, var(--bx-glass-edge))}:host-context(.bx-overlay-pos-right) .bx-tooltip-surface:after{left:-1px;top:clamp(.5rem,var(--bx-tooltip-arrow-y, 50%),100% - .5rem);border-bottom-width:1px;border-left-width:1px}@media(forced-colors:active){.bx-tooltip-surface[data-bx-surface]:after{background:Canvas;border-color:CanvasText}}\n"]
78
76
  }]
79
77
  }],
80
78
  propDecorators: { text: [{
@@ -106,17 +104,15 @@ var Menu = class Menu {
106
104
  isStandalone: true,
107
105
  selector: "bx-menu",
108
106
  ngImport: i0,
109
- template: "<div bxSurface class=\"bx-menu-wrapper\" [class.bx-menu-animated]=\"isAnimated()\">\n <ng-content></ng-content>\n</div>",
110
- styles: [":host{display:block}.bx-menu-wrapper{background-color:var(--bx-bg-surface);border:1px solid var(--bx-border-subtle);border-radius:.25rem;box-shadow:0 2px 4px #0000001a,0 1px 2px -1px #0000001a;padding:.25rem;display:flex;flex-direction:column;min-width:12rem}.bx-menu-wrapper.bx-menu-animated{transition:opacity .2s cubic-bezier(.25,.8,.25,1),transform .2s cubic-bezier(.25,.8,.25,1)}.bx-menu-wrapper{transform-origin:top}.bx-menu-wrapper.is-hidden{opacity:0;transform:scaleY(.95);pointer-events:none}:host([data-bx-surface]){border-radius:var(--bx-glass-radius, .25rem);--bx-glass-shadow: 0 2px 4px 0 rgba(0, 0, 0, .1), 0 1px 2px -1px rgba(0, 0, 0, .1);color:var(--bx-glass-text, var(--bx-text-primary))}:host([data-bx-surface]) .bx-menu-wrapper{background:transparent;border-color:transparent;border-radius:inherit;box-shadow:none}[data-bx-surface]{--bx-glass-min-opacity: .8}\n"],
107
+ template: "<div bxSurface role=\"menu\" class=\"bx-menu-wrapper\" [class.bx-menu-animated]=\"isAnimated()\">\n <ng-content></ng-content>\n</div>\n",
108
+ styles: [":host{display:block}.bx-menu-wrapper{--bx-glass-surface: var(--bx-bg-surface);--bx-glass-text: var(--bx-text-primary);--bx-glass-edge: var(--bx-border-default);--bx-glass-min-opacity: 0;--bx-glass-decoration-opacity: 1;--bx-glass-rim-visibility: 1;--bx-glass-unified-lighting: 0;--bx-glass-shadow: 0 2px 4px 0 rgba(0, 0, 0, .1), 0 1px 2px -1px rgba(0, 0, 0, .1);background-color:var(--bx-glass-surface);border:1px solid var(--bx-glass-edge);border-radius:var(--bx-glass-radius, var(--bx-rounded-lg, .75rem));box-shadow:0 2px 4px #0000001a,0 1px 2px -1px #0000001a;padding:.25rem;display:flex;flex-direction:column;min-width:12rem}.bx-menu-wrapper.bx-menu-animated{transition:transform .2s cubic-bezier(.25,.8,.25,1)}.bx-menu-wrapper{transform-origin:top}.bx-menu-wrapper.is-hidden{opacity:0;transform:scaleY(.95);pointer-events:none}:host([data-bx-surface]){border-radius:var(--bx-glass-radius, var(--bx-rounded-lg, .75rem));--bx-glass-shadow: 0 2px 4px 0 rgba(0, 0, 0, .1), 0 1px 2px -1px rgba(0, 0, 0, .1);color:var(--bx-glass-text, var(--bx-text-primary))}:host([data-bx-surface]) .bx-menu-wrapper{background:transparent;border-color:transparent;border-radius:inherit;box-shadow:none}\n"],
111
109
  dependencies: [{
112
110
  kind: "directive",
113
111
  type: BxSurfaceDirective,
114
112
  selector: "[bxSurface]",
115
113
  inputs: [
116
- "bxSurface",
117
114
  "bxSurfaceInteractive",
118
- "bxSurfaceBlur",
119
- "bxSurfaceTint",
115
+ "bxSurfaceGlassiness",
120
116
  "bxSurfaceEmission",
121
117
  "bxSurfaceFocusEmission",
122
118
  "bxReducedTransparency"
@@ -137,8 +133,8 @@ i0.ɵɵngDeclareClassMetadata({
137
133
  selector: "bx-menu",
138
134
  imports: [BxSurfaceDirective],
139
135
  changeDetection: ChangeDetectionStrategy.OnPush,
140
- template: "<div bxSurface class=\"bx-menu-wrapper\" [class.bx-menu-animated]=\"isAnimated()\">\n <ng-content></ng-content>\n</div>",
141
- styles: [":host{display:block}.bx-menu-wrapper{background-color:var(--bx-bg-surface);border:1px solid var(--bx-border-subtle);border-radius:.25rem;box-shadow:0 2px 4px #0000001a,0 1px 2px -1px #0000001a;padding:.25rem;display:flex;flex-direction:column;min-width:12rem}.bx-menu-wrapper.bx-menu-animated{transition:opacity .2s cubic-bezier(.25,.8,.25,1),transform .2s cubic-bezier(.25,.8,.25,1)}.bx-menu-wrapper{transform-origin:top}.bx-menu-wrapper.is-hidden{opacity:0;transform:scaleY(.95);pointer-events:none}:host([data-bx-surface]){border-radius:var(--bx-glass-radius, .25rem);--bx-glass-shadow: 0 2px 4px 0 rgba(0, 0, 0, .1), 0 1px 2px -1px rgba(0, 0, 0, .1);color:var(--bx-glass-text, var(--bx-text-primary))}:host([data-bx-surface]) .bx-menu-wrapper{background:transparent;border-color:transparent;border-radius:inherit;box-shadow:none}[data-bx-surface]{--bx-glass-min-opacity: .8}\n"]
136
+ template: "<div bxSurface role=\"menu\" class=\"bx-menu-wrapper\" [class.bx-menu-animated]=\"isAnimated()\">\n <ng-content></ng-content>\n</div>\n",
137
+ styles: [":host{display:block}.bx-menu-wrapper{--bx-glass-surface: var(--bx-bg-surface);--bx-glass-text: var(--bx-text-primary);--bx-glass-edge: var(--bx-border-default);--bx-glass-min-opacity: 0;--bx-glass-decoration-opacity: 1;--bx-glass-rim-visibility: 1;--bx-glass-unified-lighting: 0;--bx-glass-shadow: 0 2px 4px 0 rgba(0, 0, 0, .1), 0 1px 2px -1px rgba(0, 0, 0, .1);background-color:var(--bx-glass-surface);border:1px solid var(--bx-glass-edge);border-radius:var(--bx-glass-radius, var(--bx-rounded-lg, .75rem));box-shadow:0 2px 4px #0000001a,0 1px 2px -1px #0000001a;padding:.25rem;display:flex;flex-direction:column;min-width:12rem}.bx-menu-wrapper.bx-menu-animated{transition:transform .2s cubic-bezier(.25,.8,.25,1)}.bx-menu-wrapper{transform-origin:top}.bx-menu-wrapper.is-hidden{opacity:0;transform:scaleY(.95);pointer-events:none}:host([data-bx-surface]){border-radius:var(--bx-glass-radius, var(--bx-rounded-lg, .75rem));--bx-glass-shadow: 0 2px 4px 0 rgba(0, 0, 0, .1), 0 1px 2px -1px rgba(0, 0, 0, .1);color:var(--bx-glass-text, var(--bx-text-primary))}:host([data-bx-surface]) .bx-menu-wrapper{background:transparent;border-color:transparent;border-radius:inherit;box-shadow:none}\n"]
142
138
  }]
143
139
  }]
144
140
  });
@@ -160,6 +156,7 @@ var MenuItem = class MenuItem {
160
156
  icon = input(void 0, ...ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []);
161
157
  endIcon = input(void 0, ...ngDevMode ? [{ debugName: "endIcon" }] : /* istanbul ignore next */ []);
162
158
  label = input(void 0, ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
159
+ wrapLabel = input(false, ...ngDevMode ? [{ debugName: "wrapLabel" }] : /* istanbul ignore next */ []);
163
160
  disabled = input(false, ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
164
161
  danger = input(false, ...ngDevMode ? [{ debugName: "danger" }] : /* istanbul ignore next */ []);
165
162
  shortcut = input(void 0, ...ngDevMode ? [{ debugName: "shortcut" }] : /* istanbul ignore next */ []);
@@ -208,6 +205,13 @@ var MenuItem = class MenuItem {
208
205
  isRequired: false,
209
206
  transformFunction: null
210
207
  },
208
+ wrapLabel: {
209
+ classPropertyName: "wrapLabel",
210
+ publicName: "wrapLabel",
211
+ isSignal: true,
212
+ isRequired: false,
213
+ transformFunction: null
214
+ },
211
215
  disabled: {
212
216
  classPropertyName: "disabled",
213
217
  publicName: "disabled",
@@ -232,8 +236,8 @@ var MenuItem = class MenuItem {
232
236
  },
233
237
  outputs: { action: "action" },
234
238
  ngImport: i0,
235
- template: "<button type=\"button\" [disabled]=\"disabled()\" class=\"bx-menu-item-btn\" [class.is-disabled]=\"disabled()\" [class.is-danger]=\"danger()\"\n [class.bx-menu-item-animated]=\"isAnimated()\" (click)=\"onClick($event)\">\n\n @if (icon()) {\n <bx-icon class=\"bx-icon-pos-start\" [name]=\"icon()!\" size=\"20\" />\n }\n\n <span class=\"bx-menu-item-content\">\n @if (resolvedLabel()) {\n {{ resolvedLabel() }}\n } @else {\n <ng-content></ng-content>\n }\n </span>\n\n @if (resolvedShortcut()) {\n <span class=\"bx-menu-item-shortcut\">\n @for (key of resolvedShortcut(); track $index) {\n <kbd>{{ key }}</kbd>\n }\n </span>\n }\n\n @if (endIcon()) {\n <bx-icon class=\"bx-icon-pos-end\" [name]=\"endIcon()!\" size=\"20\" />\n }\n</button>",
236
- styles: [":host{display:block;width:100%}.bx-menu-item-btn{width:100%;display:flex;align-items:center;background:transparent;border:none;padding:.5rem .75rem;cursor:pointer;font-family:inherit;font-size:.875rem;text-align:left;border-radius:.25rem;color:var(--bx-text-primary)}.bx-menu-item-btn:focus-visible{outline:2px solid var(--bx-border-brand);outline-offset:-2px}.bx-menu-item-btn.bx-menu-item-animated{transition:background-color .1s ease-in-out,color .1s ease-in-out}.bx-menu-item-btn.bx-menu-item-animated .bx-menu-item-shortcut{transition:color .1s ease-in-out}.bx-menu-item-btn:hover:not(.is-disabled){background-color:var(--bx-bg-element-hover)}.bx-menu-item-btn:hover:not(.is-disabled) .bx-menu-item-shortcut{color:inherit;opacity:1}.bx-menu-item-btn:active:not(.is-disabled){background-color:var(--bx-bg-element-active)}.bx-menu-item-btn:active:not(.is-disabled) .bx-menu-item-shortcut{color:inherit;opacity:1}.bx-menu-item-btn.is-danger{color:var(--bx-text-danger)}.bx-menu-item-btn.is-danger .bx-menu-item-shortcut{color:var(--bx-text-danger);opacity:.7}.bx-menu-item-btn.is-danger:hover:not(.is-disabled){background-color:var(--bx-bg-danger-hover)}.bx-menu-item-btn.is-danger:active:not(.is-disabled){background-color:var(--bx-bg-danger-active)}.bx-menu-item-btn.is-disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.bx-menu-item-content{flex:1 1 auto;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.4;text-align:left}.bx-menu-item-shortcut{display:flex;align-items:center;gap:.15rem;margin-left:1.5rem;color:var(--bx-text-secondary);font-size:.875rem}.bx-menu-item-shortcut kbd{font-family:inherit;background:transparent;border:none;box-shadow:none;padding:0;margin:0;color:inherit}\n"],
239
+ template: "<button bxSurface [bxSurfaceEmission]=\"danger() ? 'var(--bx-text-danger)' : 'var(--bx-primary)'\" type=\"button\" role=\"menuitem\" [disabled]=\"disabled()\" class=\"bx-menu-item-btn\" [class.is-disabled]=\"disabled()\" [class.is-danger]=\"danger()\"\n [class.bx-menu-item-animated]=\"isAnimated()\" (click)=\"onClick($event)\">\n\n @if (icon()) {\n <bx-icon class=\"bx-icon-pos-start\" [name]=\"icon()!\" size=\"20\" />\n }\n\n <span class=\"bx-menu-item-content\" [class.bx-menu-item-content-wrapped]=\"wrapLabel()\">\n @if (resolvedLabel()) {\n {{ resolvedLabel() }}\n } @else {\n <ng-content></ng-content>\n }\n </span>\n\n @if (resolvedShortcut()) {\n <span class=\"bx-menu-item-shortcut\">\n @for (key of resolvedShortcut(); track $index) {\n <kbd>{{ key }}</kbd>\n }\n </span>\n }\n\n @if (endIcon()) {\n <bx-icon class=\"bx-icon-pos-end\" [name]=\"endIcon()!\" size=\"20\" />\n }\n</button>\n",
240
+ styles: [":host{display:block;width:100%}.bx-menu-item-btn{width:100%;display:flex;align-items:center;background:transparent!important;border:none;padding:.5rem .75rem;cursor:pointer;font-family:inherit;font-size:.875rem;text-align:left;border-radius:max(0px,var(--bx-glass-radius, var(--bx-rounded-lg, .75rem)) - .25rem);color:var(--bx-text-primary);--bx-glass-decoration-opacity: 0;--bx-glass-rim-visibility: 0;-webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:none}.bx-menu-item-btn:focus-visible{outline:2px solid var(--bx-border-brand);outline-offset:-2px}.bx-menu-item-btn.bx-menu-item-animated{transition:background-color .1s ease-in-out,color .1s ease-in-out}.bx-menu-item-btn.bx-menu-item-animated .bx-menu-item-shortcut{transition:color .1s ease-in-out}.bx-menu-item-btn:hover:not(.is-disabled){background:var(--bx-bg-element-hover)!important}.bx-menu-item-btn:hover:not(.is-disabled) .bx-menu-item-shortcut{color:inherit;opacity:1}.bx-menu-item-btn:active:not(.is-disabled){background:var(--bx-bg-element-active)!important}.bx-menu-item-btn:active:not(.is-disabled) .bx-menu-item-shortcut{color:inherit;opacity:1}.bx-menu-item-btn.is-danger{color:var(--bx-text-danger)}.bx-menu-item-btn.is-danger .bx-menu-item-shortcut{color:var(--bx-text-danger);opacity:.7}.bx-menu-item-btn.is-danger:hover:not(.is-disabled){background:var(--bx-bg-danger-hover)!important}.bx-menu-item-btn.is-danger:active:not(.is-disabled){background:var(--bx-bg-danger-active)!important}.bx-menu-item-btn.is-disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.bx-menu-item-content{flex:1 1 auto;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.4;text-align:left}.bx-menu-item-content-wrapped{white-space:normal;overflow:visible;text-overflow:clip;overflow-wrap:anywhere}.bx-menu-item-shortcut{display:flex;align-items:center;gap:.15rem;margin-left:1.5rem;color:var(--bx-text-secondary);font-size:.875rem}.bx-menu-item-shortcut kbd{font-family:inherit;background:transparent;border:none;box-shadow:none;padding:0;margin:0;color:inherit}\n"],
237
241
  dependencies: [{
238
242
  kind: "component",
239
243
  type: Icon,
@@ -247,6 +251,18 @@ var MenuItem = class MenuItem {
247
251
  "decorative",
248
252
  "ariaLabel"
249
253
  ]
254
+ }, {
255
+ kind: "directive",
256
+ type: BxSurfaceDirective,
257
+ selector: "[bxSurface]",
258
+ inputs: [
259
+ "bxSurfaceInteractive",
260
+ "bxSurfaceGlassiness",
261
+ "bxSurfaceEmission",
262
+ "bxSurfaceFocusEmission",
263
+ "bxReducedTransparency"
264
+ ],
265
+ exportAs: ["bxSurface"]
250
266
  }],
251
267
  changeDetection: i0.ChangeDetectionStrategy.OnPush
252
268
  });
@@ -260,10 +276,10 @@ i0.ɵɵngDeclareClassMetadata({
260
276
  type: Component,
261
277
  args: [{
262
278
  selector: "bx-menu-item",
263
- imports: [Icon],
279
+ imports: [Icon, BxSurfaceDirective],
264
280
  changeDetection: ChangeDetectionStrategy.OnPush,
265
- template: "<button type=\"button\" [disabled]=\"disabled()\" class=\"bx-menu-item-btn\" [class.is-disabled]=\"disabled()\" [class.is-danger]=\"danger()\"\n [class.bx-menu-item-animated]=\"isAnimated()\" (click)=\"onClick($event)\">\n\n @if (icon()) {\n <bx-icon class=\"bx-icon-pos-start\" [name]=\"icon()!\" size=\"20\" />\n }\n\n <span class=\"bx-menu-item-content\">\n @if (resolvedLabel()) {\n {{ resolvedLabel() }}\n } @else {\n <ng-content></ng-content>\n }\n </span>\n\n @if (resolvedShortcut()) {\n <span class=\"bx-menu-item-shortcut\">\n @for (key of resolvedShortcut(); track $index) {\n <kbd>{{ key }}</kbd>\n }\n </span>\n }\n\n @if (endIcon()) {\n <bx-icon class=\"bx-icon-pos-end\" [name]=\"endIcon()!\" size=\"20\" />\n }\n</button>",
266
- styles: [":host{display:block;width:100%}.bx-menu-item-btn{width:100%;display:flex;align-items:center;background:transparent;border:none;padding:.5rem .75rem;cursor:pointer;font-family:inherit;font-size:.875rem;text-align:left;border-radius:.25rem;color:var(--bx-text-primary)}.bx-menu-item-btn:focus-visible{outline:2px solid var(--bx-border-brand);outline-offset:-2px}.bx-menu-item-btn.bx-menu-item-animated{transition:background-color .1s ease-in-out,color .1s ease-in-out}.bx-menu-item-btn.bx-menu-item-animated .bx-menu-item-shortcut{transition:color .1s ease-in-out}.bx-menu-item-btn:hover:not(.is-disabled){background-color:var(--bx-bg-element-hover)}.bx-menu-item-btn:hover:not(.is-disabled) .bx-menu-item-shortcut{color:inherit;opacity:1}.bx-menu-item-btn:active:not(.is-disabled){background-color:var(--bx-bg-element-active)}.bx-menu-item-btn:active:not(.is-disabled) .bx-menu-item-shortcut{color:inherit;opacity:1}.bx-menu-item-btn.is-danger{color:var(--bx-text-danger)}.bx-menu-item-btn.is-danger .bx-menu-item-shortcut{color:var(--bx-text-danger);opacity:.7}.bx-menu-item-btn.is-danger:hover:not(.is-disabled){background-color:var(--bx-bg-danger-hover)}.bx-menu-item-btn.is-danger:active:not(.is-disabled){background-color:var(--bx-bg-danger-active)}.bx-menu-item-btn.is-disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.bx-menu-item-content{flex:1 1 auto;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.4;text-align:left}.bx-menu-item-shortcut{display:flex;align-items:center;gap:.15rem;margin-left:1.5rem;color:var(--bx-text-secondary);font-size:.875rem}.bx-menu-item-shortcut kbd{font-family:inherit;background:transparent;border:none;box-shadow:none;padding:0;margin:0;color:inherit}\n"]
281
+ template: "<button bxSurface [bxSurfaceEmission]=\"danger() ? 'var(--bx-text-danger)' : 'var(--bx-primary)'\" type=\"button\" role=\"menuitem\" [disabled]=\"disabled()\" class=\"bx-menu-item-btn\" [class.is-disabled]=\"disabled()\" [class.is-danger]=\"danger()\"\n [class.bx-menu-item-animated]=\"isAnimated()\" (click)=\"onClick($event)\">\n\n @if (icon()) {\n <bx-icon class=\"bx-icon-pos-start\" [name]=\"icon()!\" size=\"20\" />\n }\n\n <span class=\"bx-menu-item-content\" [class.bx-menu-item-content-wrapped]=\"wrapLabel()\">\n @if (resolvedLabel()) {\n {{ resolvedLabel() }}\n } @else {\n <ng-content></ng-content>\n }\n </span>\n\n @if (resolvedShortcut()) {\n <span class=\"bx-menu-item-shortcut\">\n @for (key of resolvedShortcut(); track $index) {\n <kbd>{{ key }}</kbd>\n }\n </span>\n }\n\n @if (endIcon()) {\n <bx-icon class=\"bx-icon-pos-end\" [name]=\"endIcon()!\" size=\"20\" />\n }\n</button>\n",
282
+ styles: [":host{display:block;width:100%}.bx-menu-item-btn{width:100%;display:flex;align-items:center;background:transparent!important;border:none;padding:.5rem .75rem;cursor:pointer;font-family:inherit;font-size:.875rem;text-align:left;border-radius:max(0px,var(--bx-glass-radius, var(--bx-rounded-lg, .75rem)) - .25rem);color:var(--bx-text-primary);--bx-glass-decoration-opacity: 0;--bx-glass-rim-visibility: 0;-webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:none}.bx-menu-item-btn:focus-visible{outline:2px solid var(--bx-border-brand);outline-offset:-2px}.bx-menu-item-btn.bx-menu-item-animated{transition:background-color .1s ease-in-out,color .1s ease-in-out}.bx-menu-item-btn.bx-menu-item-animated .bx-menu-item-shortcut{transition:color .1s ease-in-out}.bx-menu-item-btn:hover:not(.is-disabled){background:var(--bx-bg-element-hover)!important}.bx-menu-item-btn:hover:not(.is-disabled) .bx-menu-item-shortcut{color:inherit;opacity:1}.bx-menu-item-btn:active:not(.is-disabled){background:var(--bx-bg-element-active)!important}.bx-menu-item-btn:active:not(.is-disabled) .bx-menu-item-shortcut{color:inherit;opacity:1}.bx-menu-item-btn.is-danger{color:var(--bx-text-danger)}.bx-menu-item-btn.is-danger .bx-menu-item-shortcut{color:var(--bx-text-danger);opacity:.7}.bx-menu-item-btn.is-danger:hover:not(.is-disabled){background:var(--bx-bg-danger-hover)!important}.bx-menu-item-btn.is-danger:active:not(.is-disabled){background:var(--bx-bg-danger-active)!important}.bx-menu-item-btn.is-disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.bx-menu-item-content{flex:1 1 auto;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.4;text-align:left}.bx-menu-item-content-wrapped{white-space:normal;overflow:visible;text-overflow:clip;overflow-wrap:anywhere}.bx-menu-item-shortcut{display:flex;align-items:center;gap:.15rem;margin-left:1.5rem;color:var(--bx-text-secondary);font-size:.875rem}.bx-menu-item-shortcut kbd{font-family:inherit;background:transparent;border:none;box-shadow:none;padding:0;margin:0;color:inherit}\n"]
267
283
  }]
268
284
  }],
269
285
  propDecorators: {
@@ -291,6 +307,14 @@ i0.ɵɵngDeclareClassMetadata({
291
307
  required: false
292
308
  }]
293
309
  }],
310
+ wrapLabel: [{
311
+ type: i0.Input,
312
+ args: [{
313
+ isSignal: true,
314
+ alias: "wrapLabel",
315
+ required: false
316
+ }]
317
+ }],
294
318
  disabled: [{
295
319
  type: i0.Input,
296
320
  args: [{
@@ -333,6 +357,7 @@ var TooltipDirective = class TooltipDirective {
333
357
  overlayRef = null;
334
358
  transition;
335
359
  disconnectTheme;
360
+ disconnectLighting;
336
361
  positionSubscription;
337
362
  keyboardSubscription;
338
363
  revision = 0;
@@ -356,6 +381,7 @@ var TooltipDirective = class TooltipDirective {
356
381
  pane.id = this.id;
357
382
  pane.setAttribute("role", "tooltip");
358
383
  this.disconnectTheme = this.zone.runOutsideAngular(() => inheritOverlayTheme(this.elementRef.nativeElement, pane));
384
+ this.disconnectLighting = inheritGlassLighting(pane, this.elementRef.nativeElement);
359
385
  const component = this.overlayRef.attach(new ComponentPortal(Tooltip));
360
386
  pane.style.pointerEvents = "none";
361
387
  this.keyboardSubscription = this.overlayRef.keydownEvents().subscribe((event) => this.onEscape(event));
@@ -388,7 +414,8 @@ var TooltipDirective = class TooltipDirective {
388
414
  const revision = ++this.revision;
389
415
  this.removeDescription();
390
416
  if (!this.overlayRef) return;
391
- if (this.transition && !this.a11y.isReducedMotion()) this.zone.runOutsideAngular(() => this.transition.exit()).then(() => {
417
+ const transition = this.transition;
418
+ if (transition && !this.a11y.isReducedMotion()) this.zone.runOutsideAngular(() => transition.exit()).then(() => {
392
419
  if (revision === this.revision) this.dispose();
393
420
  }).catch(() => {
394
421
  if (revision === this.revision) this.dispose();
@@ -438,6 +465,8 @@ var TooltipDirective = class TooltipDirective {
438
465
  this.transition = void 0;
439
466
  this.overlayRef?.dispose();
440
467
  this.overlayRef = null;
468
+ this.disconnectLighting?.();
469
+ this.disconnectLighting = void 0;
441
470
  }
442
471
  static ɵfac = i0.ɵɵngDeclareFactory({
443
472
  minVersion: "12.0.0",
@@ -544,6 +573,7 @@ var DropdownDirective = class DropdownDirective {
544
573
  subscriptions = new Subscription();
545
574
  revision = 0;
546
575
  disconnectTheme;
576
+ disconnectLighting;
547
577
  constructor() {
548
578
  inject(DestroyRef).onDestroy(() => {
549
579
  ++this.revision;
@@ -562,7 +592,8 @@ var DropdownDirective = class DropdownDirective {
562
592
  toggle(event) {
563
593
  if (this.isDisabled()) return;
564
594
  event?.stopPropagation();
565
- this.isOpen() ? this.close() : this.open();
595
+ if (this.isOpen()) this.close();
596
+ else this.open();
566
597
  }
567
598
  onTriggerKeydown(event) {
568
599
  if (this.bxTransition() === "none" || this.isDisabled() || this.isEditing(event.target)) return;
@@ -584,8 +615,8 @@ var DropdownDirective = class DropdownDirective {
584
615
  overlay.overlayElement.inert = false;
585
616
  overlay.overlayElement.style.removeProperty("pointer-events");
586
617
  if (this.bxTransition() !== "none" && !this.a11y.isReducedMotion()) {
587
- this.transition ??= this.zone.runOutsideAngular(() => createGlassTransition(this.elementRef.nativeElement, overlay.overlayElement));
588
- this.zone.runOutsideAngular(() => this.transition.enter()).then(() => {
618
+ const transition = this.transition ??= this.zone.runOutsideAngular(() => createGlassTransition(this.elementRef.nativeElement, overlay.overlayElement));
619
+ this.zone.runOutsideAngular(() => transition.enter()).then(() => {
589
620
  if (revision === this.revision && this.isOpen()) this.zone.run(() => this._state.set("open"));
590
621
  }).catch(() => {
591
622
  if (revision === this.revision && this.isOpen()) {
@@ -606,7 +637,8 @@ var DropdownDirective = class DropdownDirective {
606
637
  if (restoreFocus || overlay.overlayElement.contains(source.ownerDocument.activeElement)) source.focus({ preventScroll: true });
607
638
  overlay.overlayElement.inert = true;
608
639
  overlay.overlayElement.style.pointerEvents = "none";
609
- if (this.transition && !this.a11y.isReducedMotion()) this.zone.runOutsideAngular(() => this.transition.exit()).then(() => {
640
+ const transition = this.transition;
641
+ if (transition && !this.a11y.isReducedMotion()) this.zone.runOutsideAngular(() => transition.exit()).then(() => {
610
642
  if (revision === this.revision && !this.isOpen()) this.zone.run(() => this.dispose());
611
643
  }).catch(() => {
612
644
  if (revision === this.revision && !this.isOpen()) this.dispose();
@@ -623,14 +655,17 @@ var DropdownDirective = class DropdownDirective {
623
655
  const positionStrategy = this.positionBuilder.getElementStrategy(this.elementRef.nativeElement, this.placement(), 4);
624
656
  const overlay = this.overlay.create({
625
657
  positionStrategy,
626
- scrollStrategy: this.overlay.scrollStrategies.reposition(),
658
+ scrollStrategy: this.overlay.scrollStrategies.noop(),
659
+ usePopover: !!this.elementRef.nativeElement.closest("dialog, [role=\"dialog\"], [role=\"alertdialog\"], bx-modal, bx-modal-core, [popover], .app-toolbar"),
627
660
  hasBackdrop: this.bxTransition() === "none",
628
661
  backdropClass: "cdk-overlay-transparent-backdrop"
629
662
  });
630
663
  this.overlayRef = overlay;
631
664
  this.overlayId.set(overlay.overlayElement.id || null);
632
665
  this.disconnectTheme = this.zone.runOutsideAngular(() => inheritOverlayTheme(this.elementRef.nativeElement, overlay.overlayElement));
666
+ this.disconnectLighting = inheritGlassLighting(overlay.overlayElement, this.elementRef.nativeElement);
633
667
  this.subscriptions = new Subscription();
668
+ this.trackScroll(overlay, positionStrategy);
634
669
  this.subscriptions.add(overlay.backdropClick().subscribe(() => this.close()));
635
670
  this.subscriptions.add(overlay.outsidePointerEvents().subscribe((event) => {
636
671
  if (!this.elementRef.nativeElement.contains(event.target)) this.close();
@@ -648,6 +683,22 @@ var DropdownDirective = class DropdownDirective {
648
683
  overlay.attach(new TemplatePortal(this.bxDropdown(), this.vcr)).detectChanges();
649
684
  overlay.updatePosition();
650
685
  }
686
+ trackScroll(overlay, positionStrategy) {
687
+ const source = this.elementRef.nativeElement;
688
+ const view = source.ownerDocument.defaultView;
689
+ if (!view) return;
690
+ this.zone.runOutsideAngular(() => {
691
+ const reposition = (event) => {
692
+ const target = event.target;
693
+ if (overlay.hasAttached() && (target === view || target instanceof Node && target.contains(source))) positionStrategy.reapplyLastPosition();
694
+ };
695
+ view.addEventListener("scroll", reposition, {
696
+ capture: true,
697
+ passive: true
698
+ });
699
+ this.subscriptions.add(() => view.removeEventListener("scroll", reposition, true));
700
+ });
701
+ }
651
702
  isDisabled() {
652
703
  const element = this.elementRef.nativeElement;
653
704
  return element.hasAttribute("disabled") || element.getAttribute("aria-disabled") === "true";
@@ -693,6 +744,8 @@ var DropdownDirective = class DropdownDirective {
693
744
  this.subscriptions.unsubscribe();
694
745
  this.overlayRef?.dispose();
695
746
  this.overlayRef = null;
747
+ this.disconnectLighting?.();
748
+ this.disconnectLighting = void 0;
696
749
  this.overlayId.set(null);
697
750
  this._isOpen.set(false);
698
751
  this._state.set("closed");
@@ -820,6 +873,7 @@ var ContextMenuDirective = class ContextMenuDirective {
820
873
  transition;
821
874
  point;
822
875
  disconnectTheme;
876
+ disconnectLighting;
823
877
  subscriptions = new Subscription();
824
878
  revision = 0;
825
879
  constructor() {
@@ -837,7 +891,8 @@ var ContextMenuDirective = class ContextMenuDirective {
837
891
  const revision = ++this.revision;
838
892
  if (restoreFocus || this.overlayRef.overlayElement.contains(this.elementRef.nativeElement.ownerDocument.activeElement)) this.elementRef.nativeElement.focus({ preventScroll: true });
839
893
  this.overlayRef.overlayElement.inert = true;
840
- if (this.transition && !this.a11y.isReducedMotion()) this.zone.runOutsideAngular(() => this.transition.exit()).then(() => {
894
+ const transition = this.transition;
895
+ if (transition && !this.a11y.isReducedMotion()) this.zone.runOutsideAngular(() => transition.exit()).then(() => {
841
896
  if (revision === this.revision) this.dispose();
842
897
  }).catch(() => {
843
898
  if (revision === this.revision) this.dispose();
@@ -861,22 +916,37 @@ var ContextMenuDirective = class ContextMenuDirective {
861
916
  const source = this.elementRef.nativeElement;
862
917
  this.overlayRef = this.overlay.create({
863
918
  positionStrategy: this.positionBuilder.getCoordinateStrategy(x, y),
864
- scrollStrategy: this.overlay.scrollStrategies.close(),
919
+ scrollStrategy: this.overlay.scrollStrategies.noop(),
920
+ usePopover: !!source.closest("dialog, [role=\"dialog\"], [role=\"alertdialog\"], bx-modal, bx-modal-core, [popover], .app-toolbar"),
865
921
  hasBackdrop: true,
866
922
  backdropClass: "cdk-overlay-transparent-backdrop"
867
923
  });
868
924
  this.subscriptions = new Subscription();
925
+ const win = source.ownerDocument.defaultView;
926
+ if (win) this.zone.runOutsideAngular(() => {
927
+ const closeOnScroll = (event) => {
928
+ const target = event.target;
929
+ if (this.overlayRef?.overlayElement.inert) return;
930
+ if (target === win || target instanceof Node && target.contains(source)) this.zone.run(() => this.close());
931
+ };
932
+ win.addEventListener("scroll", closeOnScroll, {
933
+ capture: true,
934
+ passive: true
935
+ });
936
+ this.subscriptions.add(() => win.removeEventListener("scroll", closeOnScroll, true));
937
+ });
869
938
  this.subscriptions.add(this.overlayRef.backdropClick().subscribe(() => this.close()));
870
939
  this.subscriptions.add(this.overlayRef.detachments().subscribe(() => this.dispose()));
871
940
  this.subscriptions.add(this.overlayRef.keydownEvents().subscribe((event) => this.onMenuKey(event)));
872
941
  const pane = this.overlayRef.overlayElement;
873
942
  this.disconnectTheme = this.zone.runOutsideAngular(() => inheritOverlayTheme(source, pane));
943
+ this.disconnectLighting = inheritGlassLighting(pane, source);
874
944
  this.overlayRef.attach(new TemplatePortal(this.bxContextMenu(), this.vcr)).detectChanges();
875
945
  this.overlayRef.updatePosition();
876
946
  if (!this.a11y.isReducedMotion()) {
877
- this.point = source.ownerDocument.createElement("span");
878
- this.point.setAttribute("aria-hidden", "true");
879
- Object.assign(this.point.style, {
947
+ const point = source.ownerDocument.createElement("span");
948
+ point.setAttribute("aria-hidden", "true");
949
+ Object.assign(point.style, {
880
950
  position: "fixed",
881
951
  left: `${x}px`,
882
952
  top: `${y}px`,
@@ -884,9 +954,11 @@ var ContextMenuDirective = class ContextMenuDirective {
884
954
  height: "1px",
885
955
  pointerEvents: "none"
886
956
  });
887
- source.ownerDocument.body.append(this.point);
888
- this.transition = this.zone.runOutsideAngular(() => createGlassTransition(this.point, pane));
889
- this.zone.runOutsideAngular(() => this.transition.enter()).catch(() => {
957
+ source.ownerDocument.body.append(point);
958
+ this.point = point;
959
+ const transition = this.zone.runOutsideAngular(() => createGlassTransition(point, pane));
960
+ this.transition = transition;
961
+ this.zone.runOutsideAngular(() => transition.enter()).catch(() => {
890
962
  this.transition?.destroy();
891
963
  this.transition = void 0;
892
964
  });
@@ -926,6 +998,8 @@ var ContextMenuDirective = class ContextMenuDirective {
926
998
  const overlay = this.overlayRef;
927
999
  this.overlayRef = null;
928
1000
  overlay?.dispose();
1001
+ this.disconnectLighting?.();
1002
+ this.disconnectLighting = void 0;
929
1003
  }
930
1004
  static ɵfac = i0.ɵɵngDeclareFactory({
931
1005
  minVersion: "12.0.0",