@siemens/element-ng 49.11.0 → 49.12.0

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 (99) hide show
  1. package/carousel/package.json +4 -0
  2. package/fesm2022/siemens-element-ng-ag-grid.mjs +6 -5
  3. package/fesm2022/siemens-element-ng-ag-grid.mjs.map +1 -1
  4. package/fesm2022/siemens-element-ng-application-header.mjs +17 -20
  5. package/fesm2022/siemens-element-ng-application-header.mjs.map +1 -1
  6. package/fesm2022/siemens-element-ng-breadcrumb-router.mjs +3 -3
  7. package/fesm2022/siemens-element-ng-breadcrumb-router.mjs.map +1 -1
  8. package/fesm2022/siemens-element-ng-breadcrumb.mjs +3 -3
  9. package/fesm2022/siemens-element-ng-breadcrumb.mjs.map +1 -1
  10. package/fesm2022/siemens-element-ng-card.mjs +2 -2
  11. package/fesm2022/siemens-element-ng-card.mjs.map +1 -1
  12. package/fesm2022/siemens-element-ng-carousel.mjs +541 -0
  13. package/fesm2022/siemens-element-ng-carousel.mjs.map +1 -0
  14. package/fesm2022/siemens-element-ng-chat-messages.mjs +18 -21
  15. package/fesm2022/siemens-element-ng-chat-messages.mjs.map +1 -1
  16. package/fesm2022/siemens-element-ng-content-action-bar.mjs +2 -2
  17. package/fesm2022/siemens-element-ng-content-action-bar.mjs.map +1 -1
  18. package/fesm2022/siemens-element-ng-dashboard.mjs +34 -35
  19. package/fesm2022/siemens-element-ng-dashboard.mjs.map +1 -1
  20. package/fesm2022/siemens-element-ng-date-range-filter.mjs +10 -8
  21. package/fesm2022/siemens-element-ng-date-range-filter.mjs.map +1 -1
  22. package/fesm2022/siemens-element-ng-datepicker.mjs +10 -9
  23. package/fesm2022/siemens-element-ng-datepicker.mjs.map +1 -1
  24. package/fesm2022/siemens-element-ng-electron-titlebar.mjs +3 -3
  25. package/fesm2022/siemens-element-ng-electron-titlebar.mjs.map +1 -1
  26. package/fesm2022/siemens-element-ng-empty-state.mjs +2 -2
  27. package/fesm2022/siemens-element-ng-empty-state.mjs.map +1 -1
  28. package/fesm2022/siemens-element-ng-file-uploader.mjs +49 -47
  29. package/fesm2022/siemens-element-ng-file-uploader.mjs.map +1 -1
  30. package/fesm2022/siemens-element-ng-filter-bar.mjs +5 -5
  31. package/fesm2022/siemens-element-ng-filter-bar.mjs.map +1 -1
  32. package/fesm2022/siemens-element-ng-filtered-search.mjs +6 -5
  33. package/fesm2022/siemens-element-ng-filtered-search.mjs.map +1 -1
  34. package/fesm2022/siemens-element-ng-footer.mjs +3 -3
  35. package/fesm2022/siemens-element-ng-footer.mjs.map +1 -1
  36. package/fesm2022/siemens-element-ng-form.mjs +5 -4
  37. package/fesm2022/siemens-element-ng-form.mjs.map +1 -1
  38. package/fesm2022/siemens-element-ng-formly.mjs +24 -23
  39. package/fesm2022/siemens-element-ng-formly.mjs.map +1 -1
  40. package/fesm2022/siemens-element-ng-header-dropdown.mjs +26 -17
  41. package/fesm2022/siemens-element-ng-header-dropdown.mjs.map +1 -1
  42. package/fesm2022/siemens-element-ng-help-button.mjs +3 -3
  43. package/fesm2022/siemens-element-ng-help-button.mjs.map +1 -1
  44. package/fesm2022/siemens-element-ng-inline-notification.mjs +3 -3
  45. package/fesm2022/siemens-element-ng-inline-notification.mjs.map +1 -1
  46. package/fesm2022/siemens-element-ng-language-switcher.mjs +3 -3
  47. package/fesm2022/siemens-element-ng-language-switcher.mjs.map +1 -1
  48. package/fesm2022/siemens-element-ng-markdown-renderer.mjs +4 -3
  49. package/fesm2022/siemens-element-ng-markdown-renderer.mjs.map +1 -1
  50. package/fesm2022/siemens-element-ng-menu.mjs +2 -2
  51. package/fesm2022/siemens-element-ng-menu.mjs.map +1 -1
  52. package/fesm2022/siemens-element-ng-navbar-vertical-next.mjs +8 -7
  53. package/fesm2022/siemens-element-ng-navbar-vertical-next.mjs.map +1 -1
  54. package/fesm2022/siemens-element-ng-navbar-vertical.mjs +13 -12
  55. package/fesm2022/siemens-element-ng-navbar-vertical.mjs.map +1 -1
  56. package/fesm2022/siemens-element-ng-navbar.mjs +6 -8
  57. package/fesm2022/siemens-element-ng-navbar.mjs.map +1 -1
  58. package/fesm2022/siemens-element-ng-notification-item.mjs +3 -3
  59. package/fesm2022/siemens-element-ng-notification-item.mjs.map +1 -1
  60. package/fesm2022/siemens-element-ng-pagination.mjs +4 -1
  61. package/fesm2022/siemens-element-ng-pagination.mjs.map +1 -1
  62. package/fesm2022/siemens-element-ng-password-toggle.mjs +3 -3
  63. package/fesm2022/siemens-element-ng-password-toggle.mjs.map +1 -1
  64. package/fesm2022/siemens-element-ng-pills-input.mjs +4 -4
  65. package/fesm2022/siemens-element-ng-pills-input.mjs.map +1 -1
  66. package/fesm2022/siemens-element-ng-popover-legacy.mjs +3 -3
  67. package/fesm2022/siemens-element-ng-popover-legacy.mjs.map +1 -1
  68. package/fesm2022/siemens-element-ng-popover.mjs +3 -3
  69. package/fesm2022/siemens-element-ng-popover.mjs.map +1 -1
  70. package/fesm2022/siemens-element-ng-result-details-list.mjs +3 -3
  71. package/fesm2022/siemens-element-ng-result-details-list.mjs.map +1 -1
  72. package/fesm2022/siemens-element-ng-side-panel.mjs +5 -5
  73. package/fesm2022/siemens-element-ng-side-panel.mjs.map +1 -1
  74. package/fesm2022/siemens-element-ng-sort-bar.mjs +3 -3
  75. package/fesm2022/siemens-element-ng-sort-bar.mjs.map +1 -1
  76. package/fesm2022/siemens-element-ng-split.mjs +3 -3
  77. package/fesm2022/siemens-element-ng-split.mjs.map +1 -1
  78. package/fesm2022/siemens-element-ng-status-bar.mjs +3 -3
  79. package/fesm2022/siemens-element-ng-status-bar.mjs.map +1 -1
  80. package/fesm2022/siemens-element-ng-threshold.mjs +5 -5
  81. package/fesm2022/siemens-element-ng-threshold.mjs.map +1 -1
  82. package/fesm2022/siemens-element-ng-toast-notification.mjs +3 -3
  83. package/fesm2022/siemens-element-ng-toast-notification.mjs.map +1 -1
  84. package/fesm2022/siemens-element-ng-tooltip.mjs +3 -3
  85. package/fesm2022/siemens-element-ng-tooltip.mjs.map +1 -1
  86. package/fesm2022/siemens-element-ng-translate.mjs.map +1 -1
  87. package/fesm2022/siemens-element-ng-tree-view.mjs +5 -5
  88. package/fesm2022/siemens-element-ng-tree-view.mjs.map +1 -1
  89. package/package.json +12 -8
  90. package/template-i18n.json +7 -0
  91. package/types/siemens-element-ng-application-header.d.ts +3 -4
  92. package/types/siemens-element-ng-carousel.d.ts +209 -0
  93. package/types/siemens-element-ng-chat-messages.d.ts +1 -2
  94. package/types/siemens-element-ng-dashboard.d.ts +4 -4
  95. package/types/siemens-element-ng-date-range-filter.d.ts +1 -1
  96. package/types/siemens-element-ng-file-uploader.d.ts +6 -8
  97. package/types/siemens-element-ng-header-dropdown.d.ts +3 -3
  98. package/types/siemens-element-ng-navbar.d.ts +1 -2
  99. package/types/siemens-element-ng-translate.d.ts +7 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"siemens-element-ng-carousel.mjs","sources":["../../../../projects/element-ng/carousel/si-carousel-item.directive.ts","../../../../projects/element-ng/carousel/si-carousel.component.ts","../../../../projects/element-ng/carousel/si-carousel.component.html","../../../../projects/element-ng/carousel/index.ts","../../../../projects/element-ng/carousel/siemens-element-ng-carousel.ts"],"sourcesContent":["/**\n * Copyright (c) Siemens 2016 - 2026\n * SPDX-License-Identifier: MIT\n */\nimport { computed, Directive, ElementRef, inject, signal } from '@angular/core';\n\nimport { SiCarouselComponent } from './si-carousel.component';\n\n@Directive({\n selector: '[siCarouselItem]',\n host: {\n style: 'flex-shrink: 0; flex-basis: 100%; scroll-snap-align: center;',\n '[style.order]': 'order()',\n 'role': 'group',\n '[attr.aria-roledescription]': 'carousel.translatedSlideRoleDescription()',\n '[attr.inert]': 'isVisible() ? null : \"\"',\n '[attr.aria-hidden]': 'isVisible() ? null : \"true\"'\n }\n})\nexport class SiCarouselItemDirective {\n protected readonly carousel = inject(SiCarouselComponent);\n protected readonly isVisible = computed(() => {\n if (this.carousel.currentActiveSlide() === this.elementRef) {\n return true;\n }\n return false;\n });\n /** @internal */\n readonly elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n /** @internal */\n readonly order = signal(0);\n}\n","/**\n * Copyright (c) Siemens 2016 - 2026\n * SPDX-License-Identifier: MIT\n */\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n computed,\n contentChildren,\n DestroyRef,\n effect,\n ElementRef,\n inject,\n input,\n linkedSignal,\n signal,\n viewChild\n} from '@angular/core';\nimport { toObservable, toSignal } from '@angular/core/rxjs-interop';\nimport { elementLeft2, elementRight2, elementPause, elementPlay } from '@siemens/element-icons';\nimport { addIcons, SiIconComponent } from '@siemens/element-ng/icon';\nimport { SiResizeObserverDirective } from '@siemens/element-ng/resize-observer';\nimport {\n injectSiTranslateService,\n SiTranslatePipe,\n t\n} from '@siemens/element-translate-ng/translate';\nimport { switchMap } from 'rxjs';\n\nimport { SiCarouselItemDirective } from './si-carousel-item.directive';\n\n/**\n * Maximum number of pagination dots shown in the pager.\n */\nconst MAX_PAGES = 5;\n\n/**\n * Time constant (in milliseconds) for the exponential-smoothing scroll animation. Smaller values\n * settle faster. The animation is retargetable, so rapid clicks keep adjusting the same animation\n * towards the latest slide instead of starting separate, queued scrolls.\n */\nconst SCROLL_SMOOTHING_TAU = 100;\n\n/**\n * Assumed duration (in milliseconds) of the first animation frame, used before two timestamps are\n * available to measure a real delta. 16ms corresponds to one frame at ~60Hz, a safe default that\n * keeps the first easing step the same size as a normal frame.\n */\nconst FIRST_FRAME_DELTA = 16;\n\n/**\n * Distance (in CSS pixels) below which the viewport is considered to have reached its target. Less\n * than a pixel is imperceptible, so the animation snaps to the target and stops instead of easing\n * across ever-smaller, invisible fractions of a pixel forever.\n */\nconst SCROLL_SETTLE_THRESHOLD = 0.5;\n\n/**\n * Per-frame progress (in CSS pixels) below which the animation is treated as stalled. The browser\n * can cap `scrollLeft` a sub-pixel short of the computed target at the scroll boundary; without\n * this guard the loop would never reach the target and would spin forever. Kept below\n * {@link SCROLL_SETTLE_THRESHOLD} so it only triggers when real movement has effectively stopped.\n */\nconst SCROLL_STALL_THRESHOLD = 0.25;\n\n/**\n * A carousel component for displaying slides with navigation controls and auto-play.\n *\n * Features horizontal scrolling with snap behavior, pagination dots, and ARIA accessibility.\n * Suitable for dashboards, image galleries, and content showcases.\n *\n * @example\n *\n * ```typescript\n * import { SiCarouselComponent, SiCarouselItemDirective } from '@siemens/element-ng/carousel';\n *\n * @Component({\n * imports: [SiCarouselComponent, SiCarouselItemDirective],\n * template: `\n * <si-carousel>\n * <div siCarouselItem><h2>Slide 1</h2></div>\n * <div siCarouselItem><h2>Slide 2</h2></div>\n * <div siCarouselItem><h2>Slide 3</h2></div>\n * </si-carousel>\n * `\n * })\n * export class MyComponent {}\n * ```\n */\n@Component({\n selector: 'si-carousel',\n imports: [SiTranslatePipe, SiResizeObserverDirective, SiIconComponent],\n templateUrl: './si-carousel.component.html',\n styleUrl: './si-carousel.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[attr.role]': 'ariaRole()',\n '[attr.aria-roledescription]': 'translatedCarouselRoleDescription()',\n '[style.min-width.px]': 'pageControlContainerMinWidth()'\n }\n})\nexport class SiCarouselComponent {\n /**\n * Controls whether pagination controls are shown.\n * When `true`, the carousel shows one slide per page and hides pagination controls.\n * @defaultValue false\n * */\n readonly hidePageControls = input(false, { transform: booleanAttribute });\n /**\n * Enables or configures auto-play for the carousel. When set to `true`, the carousel automatically\n * navigates to the next slide every 5000 milliseconds (5 seconds). Pass a positive number to set a\n * custom interval in milliseconds. Pass `false` to disable auto-play.\n * @defaultValue false\n * */\n readonly autoPlay = input<boolean | number>(false);\n /**\n * Aria role of the carousel element. Can be set to 'region' or 'group' depending on the desired accessibility semantics.\n * @defaultValue 'region'\n * */\n readonly ariaRole = input<'region' | 'group'>('region');\n\n /**\n * Aria label for the previous button, used for accessibility purposes.\n * @defaultValue\n * ```\n * t(() => $localize`:@@SI_CAROUSEL.PREVIOUS:Previous slide`)\n * ```\n */\n readonly previousButtonAriaLabel = input(\n t(() => $localize`:@@SI_CAROUSEL.PREVIOUS:Previous slide`)\n );\n /**\n * Aria label for the next button, used for accessibility purposes.\n * @defaultValue\n * ```\n * t(() => $localize`:@@SI_CAROUSEL.NEXT:Next slide`)\n * ```\n */\n readonly nextButtonAriaLabel = input(t(() => $localize`:@@SI_CAROUSEL.NEXT:Next slide`));\n\n /**\n * @defaultValue\n * ```\n * t(() => $localize`:@@SI_CAROUSEL.SLIDE_PAGE:Slide {{page}} of {{total}}`)\n * ```\n */\n readonly slidePageAriaLabel = input(\n t(() => $localize`:@@SI_CAROUSEL.SLIDE_PAGE:Slide {{page}} of {{total}}`)\n );\n\n /**\n * Label for the play button when autoplay is paused.\n * @defaultValue\n * ```\n * t(() => $localize`:@@SI_CAROUSEL.PLAY:Play`)\n * ```\n */\n readonly playButtonLabel = input(t(() => $localize`:@@SI_CAROUSEL.PLAY:Play`));\n\n /**\n * Label for the pause button when autoplay is active.\n * @defaultValue\n * ```\n * t(() => $localize`:@@SI_CAROUSEL.PAUSE:Pause`)\n * ```\n */\n readonly pauseButtonLabel = input(t(() => $localize`:@@SI_CAROUSEL.PAUSE:Pause`));\n\n /**\n * Role description for the carousel container, used for accessibility purposes.\n * @defaultValue\n * ```\n * t(() => $localize`:@@SI_CAROUSEL.ROLE_DESCRIPTION:carousel`)\n * ```\n */\n readonly carouselRoleDescription = input(\n t(() => $localize`:@@SI_CAROUSEL.ROLE_DESCRIPTION:carousel`)\n );\n /**\n * Role description for each slide, used for accessibility purposes.\n * @defaultValue\n * ```\n * t(() => $localize`:@@SI_CAROUSEL.SLIDE_ROLE_DESCRIPTION:Slide`)\n * ```\n */\n readonly slideRoleDescription = input(\n t(() => $localize`:@@SI_CAROUSEL.SLIDE_ROLE_DESCRIPTION:Slide`)\n );\n\n /** @internal */\n readonly translatedSlideRoleDescription = toSignal(\n toObservable(this.slideRoleDescription).pipe(\n switchMap(key => this.translateService.translateAsync(key))\n ),\n { initialValue: '' }\n );\n /** @internal */\n readonly currentActiveSlide = computed(() => {\n const currentPage = this.currentPage();\n if (currentPage !== null && this.items().length) {\n return this.items()[currentPage].elementRef;\n }\n return null;\n });\n\n protected readonly translatedCarouselRoleDescription = toSignal(\n toObservable(this.carouselRoleDescription).pipe(\n switchMap(key => this.translateService.translateAsync(key))\n ),\n { initialValue: '' }\n );\n protected readonly items = contentChildren(SiCarouselItemDirective);\n\n protected readonly currentPage = linkedSignal<number | null>(() =>\n this.items().length ? 0 : null\n );\n protected readonly isPaused = signal(false);\n protected readonly totalPages = computed(() => this.items().length);\n protected readonly edgeLeftIndex = signal(0);\n protected readonly edgeRightIndex = signal(MAX_PAGES - 1);\n protected readonly insufficientSpace = signal(false);\n protected readonly pageControlContainerMinWidth = signal(0);\n protected readonly icons = addIcons({ elementLeft2, elementRight2, elementPlay, elementPause });\n\n private readonly autoPlayDuration = computed(() => {\n const autoPlayValue = this.autoPlay();\n if (typeof autoPlayValue === 'boolean') {\n return autoPlayValue ? 5000 : 0;\n }\n return autoPlayValue > 0 ? autoPlayValue : 0;\n });\n private intervalId: ReturnType<typeof setInterval> | null = null;\n private scrollObserver: IntersectionObserver | null = null;\n /** requestAnimationFrame id of the running scroll animation, or null when idle. */\n private animationFrameId: number | null = null;\n /** Scroll position (`scrollLeft`) the running animation is easing towards. */\n private animationTargetLeft = 0;\n /** Timestamp of the previous animation frame, used to make the easing frame-rate independent. */\n private lastFrameTime = 0;\n /** Whether any slide's CSS order has been changed from its natural (source-index) position. */\n private ordersModified = false;\n private readonly destroyRef = inject(DestroyRef);\n private readonly viewport = viewChild.required<ElementRef<HTMLElement>>('viewport');\n private readonly pageControl = viewChild<ElementRef<HTMLElement>>('pageControl');\n private readonly playPauseBtn = viewChild<ElementRef<HTMLElement>>('playPauseBtn');\n private readonly translateService = injectSiTranslateService();\n private cdRef = inject(ChangeDetectorRef);\n\n constructor() {\n effect(onCleanup => {\n this.scheduleAutoPlay();\n onCleanup(() => clearInterval(this.intervalId!));\n });\n\n effect(() => {\n // Reset to the first page if the current page becomes out of range due to items being added/removed.\n const currentPage = this.currentPage();\n if (currentPage !== null && currentPage >= this.totalPages()) {\n this.cancelAnimation();\n this.items().forEach((_, i) => this.setSlideOrder(i, i));\n this.ordersModified = false;\n this.goToPage(0);\n }\n });\n\n effect(() => {\n this.setupScrollObserver();\n });\n\n effect(() => {\n // Establish the canonical track order (each slide's CSS order equals its source index) so the\n // navigation maths stay consistent. Skipped while an order change is mid-flight, where the\n // orders are intentionally extended and normalized once the animation settles.\n const items = this.items();\n if (this.ordersModified) {\n return;\n }\n items.forEach((_, i) => this.setSlideOrder(i, i));\n });\n\n effect(() => {\n this.updateEdgeIndices();\n });\n\n this.destroyRef.onDestroy(() => {\n if (this.animationFrameId !== null) {\n cancelAnimationFrame(this.animationFrameId);\n }\n this.scrollObserver?.disconnect();\n });\n }\n\n protected goToPage(page: number, forceScroll = true): void {\n this.currentPage.set(page);\n this.scheduleAutoPlay();\n if (forceScroll) {\n this.animateToSlide(page);\n }\n }\n\n protected next(): void {\n this.step(1);\n }\n\n protected previous(): void {\n this.step(-1);\n }\n\n /** Navigates directly to a specific slide, used by the pagination dots. */\n protected goToSlide(index: number): void {\n this.cancelAnimation();\n this.normalizeOrders();\n this.goToPage(index, true);\n }\n\n protected toggleAutoPlay(): void {\n this.isPaused.update(paused => !paused);\n if (this.isPaused()) {\n this.stopAutoPlay();\n } else {\n this.scheduleAutoPlay();\n }\n }\n\n protected onResize(size: { width: number; height: number }): void {\n const pageControl = this.pageControl();\n if (!pageControl) {\n return;\n }\n const pageControlWidth = pageControl.nativeElement.offsetWidth;\n if (this.autoPlay()) {\n const playPauseBtnWidth = this.playPauseBtn()?.nativeElement.offsetWidth ?? 0;\n const minWidth = pageControlWidth + playPauseBtnWidth;\n if (minWidth > size.width - playPauseBtnWidth) {\n this.insufficientSpace.set(true);\n } else {\n this.insufficientSpace.set(false);\n }\n this.pageControlContainerMinWidth.set(minWidth);\n } else {\n this.insufficientSpace.set(false);\n this.pageControlContainerMinWidth.set(pageControlWidth);\n }\n }\n\n /**\n * Navigates a single slide forward (`1`) or backward (`-1`). Rapid clicks are intentionally not\n * queued or throttled: each click advances {@link currentPage} immediately and retargets the\n * running scroll animation (see {@link animateTo}) towards the new slide, so the carousel keeps\n * gliding in the click direction without waiting for the previous scroll to finish.\n *\n * To keep the first/last wrap a continuous one-slide glide instead of a jump across the whole\n * track, the target slide's CSS order is placed exactly one slot away from the current slide in\n * the click direction (so it sits adjacent to it). The viewport scroll is compensated so this\n * reorder is invisible. Orders may extend while the user keeps clicking; they are silently\n * normalized once the animation settles (see {@link normalizeOrders}).\n */\n private step(direction: 1 | -1): void {\n const total = this.totalPages();\n if (total <= 1) {\n return;\n }\n const from = this.currentPage() ?? 0;\n const to = (from + direction + total) % total;\n\n // Ensure the target slide sits one slot away from the current slide in the click direction.\n // For a normal step it already does; for a first/last wrap it does not, so move it there.\n const desiredOrder = this.items()[from].order() + direction;\n if (this.items()[to].order() !== desiredOrder) {\n this.reorderSlide(to, desiredOrder, from);\n }\n\n this.currentPage.set(to);\n this.scheduleAutoPlay();\n this.animateToSlide(to);\n }\n\n /**\n * Changes a slide's CSS order while keeping the picture stable. Reordering shifts slides along\n * the flex track, so the scroll position is adjusted by the exact amount the anchor slide moved,\n * making the relocation invisible and letting any in-flight animation continue seamlessly.\n */\n private reorderSlide(index: number, order: number, anchorIndex: number): void {\n const viewport = this.viewport().nativeElement;\n const anchor = this.items()[anchorIndex].elementRef.nativeElement;\n const before = anchor.getBoundingClientRect().left;\n this.setSlideOrder(index, order);\n // Reading layout after the order change forces a synchronous reflow with the new positions.\n const after = anchor.getBoundingClientRect().left;\n viewport.scrollLeft += after - before;\n this.ordersModified = true;\n }\n\n /**\n * Sets the CSS order of a slide. The value is written to the DOM synchronously in addition to\n * the signal, so a subsequent reflow/scroll uses the new order immediately instead of waiting\n * for the asynchronous, signal-driven change detection update.\n */\n private setSlideOrder(index: number, order: number): void {\n const slide = this.items()[index];\n slide.order.set(order);\n slide.elementRef.nativeElement.style.order = `${order}`;\n }\n\n /**\n * Silently restores the canonical slide order (each slide's CSS order equals its source index).\n * Reordering shifts the track, so it anchors on the current slide and compensates the scroll\n * position to avoid any visible jump. Called once the scroll animation settles.\n */\n private normalizeOrders(): void {\n if (!this.ordersModified) {\n return;\n }\n const items = this.items();\n const viewport = this.viewport().nativeElement;\n const current = this.currentPage();\n const anchor = current !== null ? items[current]?.elementRef.nativeElement : undefined;\n const before = anchor?.getBoundingClientRect().left ?? 0;\n for (let i = 0; i < items.length; i++) {\n if (items[i].order() !== i) {\n this.setSlideOrder(i, i);\n }\n }\n if (anchor) {\n const after = anchor.getBoundingClientRect().left;\n viewport.scrollLeft += after - before;\n }\n this.ordersModified = false;\n }\n\n /** Animates the viewport so the given slide is horizontally centered. */\n private animateToSlide(index: number): void {\n const viewport = this.viewport().nativeElement;\n const slide = this.items()[index].elementRef.nativeElement;\n const viewportRect = viewport.getBoundingClientRect();\n const slideRect = slide.getBoundingClientRect();\n const delta =\n slideRect.left + slideRect.width / 2 - (viewportRect.left + viewportRect.width / 2);\n this.animateTo(viewport.scrollLeft + delta);\n }\n\n /**\n * Eases `scrollLeft` towards `targetLeft` using a frame-rate independent exponential smoothing\n * loop. The target can be updated mid-flight (rapid clicks), so the same animation simply chases\n * the latest slide. Native scroll-snap and smooth scroll-behavior are disabled while animating so\n * they do not fight the manual scrolling, and the scroll observer is paused to avoid feedback.\n */\n private animateTo(targetLeft: number): void {\n this.animationTargetLeft = targetLeft;\n if (this.animationFrameId !== null) {\n return;\n }\n const viewport = this.viewport().nativeElement;\n this.scrollObserver?.disconnect();\n viewport.style.scrollSnapType = 'none';\n viewport.style.scrollBehavior = 'auto';\n this.lastFrameTime = 0;\n this.animationFrameId = requestAnimationFrame(time => this.animationFrame(time));\n }\n\n private animationFrame(now: number): void {\n const viewport = this.viewport().nativeElement;\n const dt = this.lastFrameTime ? now - this.lastFrameTime : FIRST_FRAME_DELTA;\n this.lastFrameTime = now;\n const current = viewport.scrollLeft;\n // Clamp the target to the scrollable range. A wrapped slide can be placed right at the track\n // edge, where the rect-derived target may exceed the maximum by a sub-pixel; without clamping\n // the loop would never reach it and never settle (leaving the order normalization undone).\n const maxScrollLeft = viewport.scrollWidth - viewport.clientWidth;\n const target = Math.max(0, Math.min(this.animationTargetLeft, maxScrollLeft));\n const diff = target - current;\n if (Math.abs(diff) < SCROLL_SETTLE_THRESHOLD) {\n viewport.scrollLeft = target;\n this.animationFrameId = null;\n this.endAnimation();\n return;\n }\n viewport.scrollLeft = current + diff * (1 - Math.exp(-dt / SCROLL_SMOOTHING_TAU));\n // The browser can cap `scrollLeft` a sub-pixel short of the computed target (rounding at the\n // scroll boundary). If a frame makes no real progress, treat the animation as settled instead\n // of spinning forever.\n if (Math.abs(viewport.scrollLeft - current) < SCROLL_STALL_THRESHOLD) {\n this.animationFrameId = null;\n this.endAnimation();\n return;\n }\n this.animationFrameId = requestAnimationFrame(time => this.animationFrame(time));\n }\n\n /** Finalizes the animation: normalizes orders, restores native scrolling and the observer. */\n private endAnimation(): void {\n this.normalizeOrders();\n const viewport = this.viewport().nativeElement;\n viewport.style.scrollSnapType = '';\n viewport.style.scrollBehavior = '';\n this.cdRef.markForCheck();\n this.setupScrollObserver();\n }\n\n /** Stops the running scroll animation and restores native scrolling, without normalizing. */\n private cancelAnimation(): void {\n if (this.animationFrameId !== null) {\n cancelAnimationFrame(this.animationFrameId);\n this.animationFrameId = null;\n }\n const viewport = this.viewport().nativeElement;\n viewport.style.scrollSnapType = '';\n viewport.style.scrollBehavior = '';\n this.cdRef.markForCheck();\n }\n\n private scheduleAutoPlay(): void {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n if (!this.autoPlayDuration() || this.items().length === 0 || this.isPaused()) {\n return;\n }\n this.intervalId = setInterval(() => this.next(), this.autoPlayDuration());\n }\n\n private stopAutoPlay(): void {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n }\n\n private setupScrollObserver(): void {\n if (this.scrollObserver) {\n this.scrollObserver.disconnect();\n }\n\n const items = this.items();\n if (items.length === 0) {\n return;\n }\n\n const viewport = this.viewport().nativeElement;\n this.scrollObserver = new IntersectionObserver(\n (entries: IntersectionObserverEntry[]) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n const target = entry.target as HTMLElement;\n\n const itemIndex = items.findIndex(item => item.elementRef.nativeElement === target);\n if (itemIndex !== -1) {\n this.goToPage(itemIndex, false);\n }\n }\n });\n },\n { root: viewport, threshold: 0.6, rootMargin: '0px' }\n );\n\n for (const item of items) {\n this.scrollObserver.observe(item.elementRef.nativeElement);\n }\n }\n\n private updateEdgeIndices(): void {\n const total = this.totalPages();\n const current = this.currentPage();\n if (current === null) {\n return;\n }\n if (total <= MAX_PAGES) {\n this.edgeLeftIndex.set(0);\n this.edgeRightIndex.set(total - 1);\n return;\n }\n\n if (current < this.edgeLeftIndex()) {\n this.edgeLeftIndex.set(current);\n this.edgeRightIndex.set(current + MAX_PAGES - 1);\n }\n\n if (current > this.edgeRightIndex()) {\n this.edgeRightIndex.set(current);\n this.edgeLeftIndex.set(current - MAX_PAGES + 1);\n }\n }\n}\n","<div class=\"carousel-body d-flex flex-grow-1 align-items-center gap-2 min-h-0\">\n <div #viewport class=\"carousel-viewport flex-grow-1 align-self-stretch\" tabindex=\"0\">\n <div class=\"carousel-track h-100\">\n <ng-content />\n </div>\n </div>\n</div>\n@if ((!hidePageControls() || autoPlay()) && totalPages() > 1) {\n <div\n class=\"position-relative d-flex justify-content-center align-items-center mt-4\"\n (siResizeObserver)=\"onResize($event)\"\n >\n @if (!hidePageControls()) {\n <div #pageControl class=\"d-flex align-items-center gap-2\">\n <button\n type=\"button\"\n class=\"btn btn-icon btn-tertiary-ghost flex-shrink-0\"\n [aria-label]=\"previousButtonAriaLabel() | translate\"\n (click)=\"previous()\"\n >\n <si-icon [icon]=\"icons.elementLeft2\"\n /></button>\n <div class=\"d-flex align-items-center\">\n <div\n #dotBtn\n class=\"btn btn-tertiary-ghost btn-icon btn-sm pe-none\"\n [class.opacity-0]=\"totalPages() <= 5\"\n [class.position-absolute]=\"totalPages() <= 5\"\n >\n <span class=\"carousel-pager-small-dot d-block rounded-circle\"></span>\n </div>\n <div\n class=\"d-flex overflow-hidden\"\n [style.width.px]=\"dotBtn.clientWidth * (totalPages() > 5 ? 5 : totalPages())\"\n >\n <div\n class=\"d-flex page-buttons\"\n [style.transform]=\"'translateX(-' + edgeLeftIndex() * dotBtn.clientWidth + 'px)'\"\n >\n @for (page of items(); track page) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost focus-inside btn-icon btn-sm d-flex align-items-center justify-content-center\"\n [aria-label]=\"\n slidePageAriaLabel() | translate: { page: $index + 1, total: totalPages() }\n \"\n [tabIndex]=\"$index >= edgeLeftIndex() && $index <= edgeRightIndex() ? 0 : -1\"\n [aria-current]=\"currentPage() === $index ? 'true' : 'false'\"\n (click)=\"goToSlide($index)\"\n ><span\n class=\"carousel-pager-dot d-block\"\n [class.active]=\"currentPage() === $index\"\n [class.rounded-circle]=\"currentPage() !== $index\"\n ></span\n ></button>\n }\n </div>\n </div>\n <div\n #dotBtn\n class=\"btn btn-tertiary-ghost btn-icon btn-sm pe-none\"\n [class.opacity-0]=\"totalPages() <= 5\"\n [class.position-absolute]=\"totalPages() <= 5\"\n >\n <span class=\"carousel-pager-small-dot d-block rounded-circle\"></span>\n </div>\n </div>\n <button\n type=\"button\"\n class=\"btn btn-icon btn-tertiary-ghost flex-shrink-0\"\n [aria-label]=\"nextButtonAriaLabel() | translate\"\n (click)=\"next()\"\n >\n <si-icon [icon]=\"icons.elementRight2\"\n /></button>\n </div>\n }\n\n @if (autoPlay()) {\n <div\n #playPauseBtn\n class=\"position-absolute top-0 end-0\"\n [class.invisible]=\"insufficientSpace()\"\n >\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost ms-2\"\n [aria-label]=\"(isPaused() ? playButtonLabel() : pauseButtonLabel()) | translate\"\n (click)=\"toggleAutoPlay()\"\n >\n <si-icon class=\"icon\" [icon]=\"isPaused() ? icons.elementPlay : icons.elementPause\" />\n <span aria-hidden=\"true\">{{\n (isPaused() ? playButtonLabel() : pauseButtonLabel()) | translate\n }}</span>\n </button>\n </div>\n @if (insufficientSpace()) {\n <button\n type=\"button\"\n class=\"btn btn-icon btn-tertiary-ghost flex-shrink-0 align-items-center position-absolute top-0 end-0 ms-2\"\n [aria-label]=\"(isPaused() ? playButtonLabel() : pauseButtonLabel()) | translate\"\n (click)=\"toggleAutoPlay()\"\n >\n <si-icon [icon]=\"isPaused() ? icons.elementPlay : icons.elementPause\" />\n </button>\n }\n }\n </div>\n}\n","/**\n * Copyright (c) Siemens 2016 - 2026\n * SPDX-License-Identifier: MIT\n */\nexport * from './si-carousel.component';\nexport * from './si-carousel-item.directive';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { CdkMenuTrigger } from '@angular/cdk/menu';
2
2
  import * as i0 from '@angular/core';
3
- import { Directive, input, Component, viewChild, signal, effect, booleanAttribute, inject, output, PLATFORM_ID, model, computed } from '@angular/core';
3
+ import { Directive, input, ChangeDetectionStrategy, Component, viewChild, signal, effect, booleanAttribute, inject, output, PLATFORM_ID, model, computed } from '@angular/core';
4
4
  import { elementOptionsVertical, elementDocument, elementStateClose, elementStopFilled, elementSendFilled, elementPlus, elementAttachment } from '@siemens/element-icons';
5
5
  import { addIcons, SiIconComponent } from '@siemens/element-ng/icon';
6
6
  import { SiMenuFactoryComponent } from '@siemens/element-ng/menu';
@@ -99,11 +99,11 @@ class SiChatMessageComponent {
99
99
  */
100
100
  actionsPosition = input('side', ...(ngDevMode ? [{ debugName: "actionsPosition" }] : []));
101
101
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiChatMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
102
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiChatMessageComponent, isStandalone: true, selector: "si-chat-message", inputs: { loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, alignment: { classPropertyName: "alignment", publicName: "alignment", isSignal: true, isRequired: false, transformFunction: null }, actionsPosition: { classPropertyName: "actionsPosition", publicName: "actionsPosition", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "d-block" }, hostDirectives: [{ directive: i1.SiResponsiveContainerDirective }], ngImport: i0, template: "<!--- Flex-row if alignment start, flex-row-reverse if alignment end, flex-column if mobile -->\n<div class=\"d-flex si-body-2 chat-message-container\" [class.start]=\"alignment() === 'start'\">\n <div class=\"avatar-wrapper flex-shrink-0\" [class.end]=\"alignment() === 'end'\">\n <ng-content select=\"si-icon,si-avatar,img\" />\n </div>\n\n <div class=\"d-flex flex-column flex-grow-1 w-100\">\n <div class=\"attachment-slot\" [class.align-self-end]=\"alignment() === 'end'\">\n <ng-content select=\"si-attachment-list,si-badge\" />\n </div>\n\n @if (loading()) {\n <div\n class=\"message-wrapper rounded-3 w-75 text-break loading-message-bubble mb-2\"\n [class.align-self-end]=\"alignment() === 'end'\"\n >\n <div class=\"d-flex flex-column w-100 gap-2\">\n <div class=\"si-skeleton skeleton-line skeleton-line-full\"></div>\n <div class=\"si-skeleton skeleton-line skeleton-line-half\"></div>\n </div>\n </div>\n } @else {\n <!-- Flex-column if actions bottom, flex-row/flex-row-reverse if actions start -->\n <div\n class=\"message-wrapper mw-0 d-flex mb-2\"\n [class.start]=\"alignment() === 'start'\"\n [class.end]=\"alignment() === 'end'\"\n [class.flex-column]=\"actionsPosition() === 'bottom'\"\n [class.flex-row]=\"actionsPosition() === 'side' && alignment() === 'start'\"\n [class.flex-row-reverse]=\"actionsPosition() === 'side' && alignment() === 'end'\"\n [class.align-items-start]=\"actionsPosition() === 'side'\"\n [class.align-items-end]=\"actionsPosition() === 'bottom' && alignment() === 'end'\"\n [class.justify-content-end]=\"alignment() === 'end' && actionsPosition() === 'bottom'\"\n [class.justify-content-start]=\"alignment() === 'start' && actionsPosition() === 'bottom'\"\n >\n <div\n class=\"rounded-3 text-break message-bubble\"\n [class.end]=\"alignment() === 'end' && actionsPosition() === 'bottom'\"\n >\n <ng-content />\n </div>\n\n <div\n class=\"actions-wrapper d-flex gap-4\"\n [class.ms-3]=\"actionsPosition() === 'side' && alignment() === 'start'\"\n [class.me-3]=\"actionsPosition() === 'side' && alignment() === 'end'\"\n [class.mt-2]=\"actionsPosition() === 'bottom'\"\n [class.actions-horizontal]=\"actionsPosition() !== 'bottom'\"\n [class.align-self-start]=\"actionsPosition() === 'side'\"\n >\n <ng-content select=\"[siChatMessageAction]\" />\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;--chat-message-bubble-bg: var(--element-base-1);--chat-message-bubble-padding: 12px}:host ::ng-deep si-loading-spinner{--loading-spinner-size: 1.5em}.skeleton-line-full{inline-size:100%}.skeleton-line-half{inline-size:50%}.loading-message-bubble,.message-bubble{padding:var(--chat-message-bubble-padding)}.loading-message-bubble{inline-size:max-content;min-inline-size:75%;margin-block-end:auto;background-color:var(--chat-message-bubble-bg)}.message-bubble{margin-block-end:auto;background-color:var(--chat-message-bubble-bg);min-inline-size:0;max-inline-size:100%;overflow-wrap:break-word;word-break:break-word}.message-bubble:empty{display:none}.message-bubble:empty~.actions-wrapper{margin-inline:0!important}.attachment-slot:empty{display:none}.attachment-slot:not(:empty)~.message-wrapper:not(:has(.message-bubble:empty)){margin-block-start:4px}.attachment-slot:not(:empty)~.message-wrapper:has(.message-bubble:empty) .actions-wrapper.actions-horizontal{margin-block-start:4px}.actions-wrapper:empty{display:none!important}.avatar-wrapper{align-self:flex-start}.avatar-wrapper:not(.end){margin-inline-end:6px}.avatar-wrapper.end{margin-inline-start:6px}.avatar-wrapper:empty{display:none}.message-wrapper{min-inline-size:0;max-inline-size:100%;inline-size:auto}.message-wrapper.start{margin-inline-end:auto}.message-wrapper.end{margin-inline-start:auto}:host-context(.si-container-md,.si-container-lg,.si-container-xl,.si-container-xxl) .chat-message-container{flex-direction:row}:host-context(.si-container-md,.si-container-lg,.si-container-xl,.si-container-xxl) .chat-message-container.start{align-items:flex-start}:host-context(.si-container-md,.si-container-lg,.si-container-xl,.si-container-xxl) .chat-message-container:not(.start){flex-direction:row-reverse}:host-context(.si-container-md,.si-container-lg,.si-container-xl,.si-container-xxl) .message-bubble.end{margin-inline-start:auto}.attachment-slot ::ng-deep si-attachment-list{--attachment-list-bg: transparent;--attachment-name-color: var(--element-text-secondary)}:host-context(.si-container-xs,.si-container-sm) .chat-message-container{flex-direction:column}:host-context(.si-container-xs,.si-container-sm) .avatar-wrapper{margin-block-end:6px}:host-context(.si-container-xs,.si-container-sm) .avatar-wrapper.end{align-self:flex-end}:host-context(.si-container-xs,.si-container-sm) .avatar-wrapper::ng-deep:has(si-icon) .end{margin-inline-end:4px!important}:host-context(.si-container-xs,.si-container-sm) .avatar-wrapper::ng-deep:has(si-icon):not(.end){margin-inline-start:4px!important}\n"] });
102
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiChatMessageComponent, isStandalone: true, selector: "si-chat-message", inputs: { loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, alignment: { classPropertyName: "alignment", publicName: "alignment", isSignal: true, isRequired: false, transformFunction: null }, actionsPosition: { classPropertyName: "actionsPosition", publicName: "actionsPosition", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "d-block" }, hostDirectives: [{ directive: i1.SiResponsiveContainerDirective }], ngImport: i0, template: "<!--- Flex-row if alignment start, flex-row-reverse if alignment end, flex-column if mobile -->\n<div class=\"d-flex si-body-2 chat-message-container\" [class.start]=\"alignment() === 'start'\">\n <div class=\"avatar-wrapper flex-shrink-0\" [class.end]=\"alignment() === 'end'\">\n <ng-content select=\"si-icon,si-avatar,img\" />\n </div>\n\n <div class=\"d-flex flex-column flex-grow-1 w-100\">\n <div class=\"attachment-slot\" [class.align-self-end]=\"alignment() === 'end'\">\n <ng-content select=\"si-attachment-list,si-badge\" />\n </div>\n\n @if (loading()) {\n <div\n class=\"message-wrapper rounded-3 w-75 text-break loading-message-bubble mb-2\"\n [class.align-self-end]=\"alignment() === 'end'\"\n >\n <div class=\"d-flex flex-column w-100 gap-2\">\n <div class=\"si-skeleton skeleton-line skeleton-line-full\"></div>\n <div class=\"si-skeleton skeleton-line skeleton-line-half\"></div>\n </div>\n </div>\n } @else {\n <!-- Flex-column if actions bottom, flex-row/flex-row-reverse if actions start -->\n <div\n class=\"message-wrapper mw-0 d-flex mb-2\"\n [class.start]=\"alignment() === 'start'\"\n [class.end]=\"alignment() === 'end'\"\n [class.flex-column]=\"actionsPosition() === 'bottom'\"\n [class.flex-row]=\"actionsPosition() === 'side' && alignment() === 'start'\"\n [class.flex-row-reverse]=\"actionsPosition() === 'side' && alignment() === 'end'\"\n [class.align-items-start]=\"actionsPosition() === 'side'\"\n [class.align-items-end]=\"actionsPosition() === 'bottom' && alignment() === 'end'\"\n [class.justify-content-end]=\"alignment() === 'end' && actionsPosition() === 'bottom'\"\n [class.justify-content-start]=\"alignment() === 'start' && actionsPosition() === 'bottom'\"\n >\n <div\n class=\"rounded-3 text-break message-bubble\"\n [class.end]=\"alignment() === 'end' && actionsPosition() === 'bottom'\"\n >\n <ng-content />\n </div>\n\n <div\n class=\"actions-wrapper d-flex gap-4\"\n [class.ms-3]=\"actionsPosition() === 'side' && alignment() === 'start'\"\n [class.me-3]=\"actionsPosition() === 'side' && alignment() === 'end'\"\n [class.mt-2]=\"actionsPosition() === 'bottom'\"\n [class.actions-horizontal]=\"actionsPosition() !== 'bottom'\"\n [class.align-self-start]=\"actionsPosition() === 'side'\"\n >\n <ng-content select=\"[siChatMessageAction]\" />\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;--chat-message-bubble-bg: var(--element-base-1);--chat-message-bubble-padding: 12px}:host ::ng-deep si-loading-spinner{--loading-spinner-size: 1.5em}.skeleton-line-full{inline-size:100%}.skeleton-line-half{inline-size:50%}.loading-message-bubble,.message-bubble{padding:var(--chat-message-bubble-padding)}.loading-message-bubble{inline-size:max-content;min-inline-size:75%;margin-block-end:auto;background-color:var(--chat-message-bubble-bg)}.message-bubble{margin-block-end:auto;background-color:var(--chat-message-bubble-bg);min-inline-size:0;max-inline-size:100%;overflow-wrap:break-word;word-break:break-word}.message-bubble:empty{display:none}.message-bubble:empty~.actions-wrapper{margin-inline:0!important}.attachment-slot:empty{display:none}.attachment-slot:not(:empty)~.message-wrapper:not(:has(.message-bubble:empty)){margin-block-start:4px}.attachment-slot:not(:empty)~.message-wrapper:has(.message-bubble:empty) .actions-wrapper.actions-horizontal{margin-block-start:4px}.actions-wrapper:empty{display:none!important}.avatar-wrapper{align-self:flex-start}.avatar-wrapper:not(.end){margin-inline-end:6px}.avatar-wrapper.end{margin-inline-start:6px}.avatar-wrapper:empty{display:none}.message-wrapper{min-inline-size:0;max-inline-size:100%;inline-size:auto}.message-wrapper.start{margin-inline-end:auto}.message-wrapper.end{margin-inline-start:auto}:host-context(.si-container-md,.si-container-lg,.si-container-xl,.si-container-xxl) .chat-message-container{flex-direction:row}:host-context(.si-container-md,.si-container-lg,.si-container-xl,.si-container-xxl) .chat-message-container.start{align-items:flex-start}:host-context(.si-container-md,.si-container-lg,.si-container-xl,.si-container-xxl) .chat-message-container:not(.start){flex-direction:row-reverse}:host-context(.si-container-md,.si-container-lg,.si-container-xl,.si-container-xxl) .message-bubble.end{margin-inline-start:auto}.attachment-slot ::ng-deep si-attachment-list{--attachment-list-bg: transparent;--attachment-name-color: var(--element-text-secondary)}:host-context(.si-container-xs,.si-container-sm) .chat-message-container{flex-direction:column}:host-context(.si-container-xs,.si-container-sm) .avatar-wrapper{margin-block-end:6px}:host-context(.si-container-xs,.si-container-sm) .avatar-wrapper.end{align-self:flex-end}:host-context(.si-container-xs,.si-container-sm) .avatar-wrapper::ng-deep:has(si-icon) .end{margin-inline-end:4px!important}:host-context(.si-container-xs,.si-container-sm) .avatar-wrapper::ng-deep:has(si-icon):not(.end){margin-inline-start:4px!important}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
103
103
  }
104
104
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiChatMessageComponent, decorators: [{
105
105
  type: Component,
106
- args: [{ selector: 'si-chat-message', host: {
106
+ args: [{ selector: 'si-chat-message', changeDetection: ChangeDetectionStrategy.OnPush, host: {
107
107
  class: 'd-block'
108
108
  }, hostDirectives: [SiResponsiveContainerDirective], template: "<!--- Flex-row if alignment start, flex-row-reverse if alignment end, flex-column if mobile -->\n<div class=\"d-flex si-body-2 chat-message-container\" [class.start]=\"alignment() === 'start'\">\n <div class=\"avatar-wrapper flex-shrink-0\" [class.end]=\"alignment() === 'end'\">\n <ng-content select=\"si-icon,si-avatar,img\" />\n </div>\n\n <div class=\"d-flex flex-column flex-grow-1 w-100\">\n <div class=\"attachment-slot\" [class.align-self-end]=\"alignment() === 'end'\">\n <ng-content select=\"si-attachment-list,si-badge\" />\n </div>\n\n @if (loading()) {\n <div\n class=\"message-wrapper rounded-3 w-75 text-break loading-message-bubble mb-2\"\n [class.align-self-end]=\"alignment() === 'end'\"\n >\n <div class=\"d-flex flex-column w-100 gap-2\">\n <div class=\"si-skeleton skeleton-line skeleton-line-full\"></div>\n <div class=\"si-skeleton skeleton-line skeleton-line-half\"></div>\n </div>\n </div>\n } @else {\n <!-- Flex-column if actions bottom, flex-row/flex-row-reverse if actions start -->\n <div\n class=\"message-wrapper mw-0 d-flex mb-2\"\n [class.start]=\"alignment() === 'start'\"\n [class.end]=\"alignment() === 'end'\"\n [class.flex-column]=\"actionsPosition() === 'bottom'\"\n [class.flex-row]=\"actionsPosition() === 'side' && alignment() === 'start'\"\n [class.flex-row-reverse]=\"actionsPosition() === 'side' && alignment() === 'end'\"\n [class.align-items-start]=\"actionsPosition() === 'side'\"\n [class.align-items-end]=\"actionsPosition() === 'bottom' && alignment() === 'end'\"\n [class.justify-content-end]=\"alignment() === 'end' && actionsPosition() === 'bottom'\"\n [class.justify-content-start]=\"alignment() === 'start' && actionsPosition() === 'bottom'\"\n >\n <div\n class=\"rounded-3 text-break message-bubble\"\n [class.end]=\"alignment() === 'end' && actionsPosition() === 'bottom'\"\n >\n <ng-content />\n </div>\n\n <div\n class=\"actions-wrapper d-flex gap-4\"\n [class.ms-3]=\"actionsPosition() === 'side' && alignment() === 'start'\"\n [class.me-3]=\"actionsPosition() === 'side' && alignment() === 'end'\"\n [class.mt-2]=\"actionsPosition() === 'bottom'\"\n [class.actions-horizontal]=\"actionsPosition() !== 'bottom'\"\n [class.align-self-start]=\"actionsPosition() === 'side'\"\n >\n <ng-content select=\"[siChatMessageAction]\" />\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;--chat-message-bubble-bg: var(--element-base-1);--chat-message-bubble-padding: 12px}:host ::ng-deep si-loading-spinner{--loading-spinner-size: 1.5em}.skeleton-line-full{inline-size:100%}.skeleton-line-half{inline-size:50%}.loading-message-bubble,.message-bubble{padding:var(--chat-message-bubble-padding)}.loading-message-bubble{inline-size:max-content;min-inline-size:75%;margin-block-end:auto;background-color:var(--chat-message-bubble-bg)}.message-bubble{margin-block-end:auto;background-color:var(--chat-message-bubble-bg);min-inline-size:0;max-inline-size:100%;overflow-wrap:break-word;word-break:break-word}.message-bubble:empty{display:none}.message-bubble:empty~.actions-wrapper{margin-inline:0!important}.attachment-slot:empty{display:none}.attachment-slot:not(:empty)~.message-wrapper:not(:has(.message-bubble:empty)){margin-block-start:4px}.attachment-slot:not(:empty)~.message-wrapper:has(.message-bubble:empty) .actions-wrapper.actions-horizontal{margin-block-start:4px}.actions-wrapper:empty{display:none!important}.avatar-wrapper{align-self:flex-start}.avatar-wrapper:not(.end){margin-inline-end:6px}.avatar-wrapper.end{margin-inline-start:6px}.avatar-wrapper:empty{display:none}.message-wrapper{min-inline-size:0;max-inline-size:100%;inline-size:auto}.message-wrapper.start{margin-inline-end:auto}.message-wrapper.end{margin-inline-start:auto}:host-context(.si-container-md,.si-container-lg,.si-container-xl,.si-container-xxl) .chat-message-container{flex-direction:row}:host-context(.si-container-md,.si-container-lg,.si-container-xl,.si-container-xxl) .chat-message-container.start{align-items:flex-start}:host-context(.si-container-md,.si-container-lg,.si-container-xl,.si-container-xxl) .chat-message-container:not(.start){flex-direction:row-reverse}:host-context(.si-container-md,.si-container-lg,.si-container-xl,.si-container-xxl) .message-bubble.end{margin-inline-start:auto}.attachment-slot ::ng-deep si-attachment-list{--attachment-list-bg: transparent;--attachment-name-color: var(--element-text-secondary)}:host-context(.si-container-xs,.si-container-sm) .chat-message-container{flex-direction:column}:host-context(.si-container-xs,.si-container-sm) .avatar-wrapper{margin-block-end:6px}:host-context(.si-container-xs,.si-container-sm) .avatar-wrapper.end{align-self:flex-end}:host-context(.si-container-xs,.si-container-sm) .avatar-wrapper::ng-deep:has(si-icon) .end{margin-inline-end:4px!important}:host-context(.si-container-xs,.si-container-sm) .avatar-wrapper::ng-deep:has(si-icon):not(.end){margin-inline-start:4px!important}\n"] }]
109
109
  }], propDecorators: { loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], alignment: [{ type: i0.Input, args: [{ isSignal: true, alias: "alignment", required: false }] }], actionsPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionsPosition", required: false }] }] } });
@@ -206,7 +206,7 @@ class SiAiMessageComponent {
206
206
  */
207
207
  secondaryActionsLabel = input(t(() => $localize `:@@SI_AI_MESSAGE.SECONDARY_ACTIONS:More actions`), ...(ngDevMode ? [{ debugName: "secondaryActionsLabel" }] : []));
208
208
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiAiMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
209
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiAiMessageComponent, isStandalone: true, selector: "si-ai-message", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, contentFormatter: { classPropertyName: "contentFormatter", publicName: "contentFormatter", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, secondaryActions: { classPropertyName: "secondaryActions", publicName: "secondaryActions", isSignal: true, isRequired: false, transformFunction: null }, actionParam: { classPropertyName: "actionParam", publicName: "actionParam", isSignal: true, isRequired: false, transformFunction: null }, secondaryActionsLabel: { classPropertyName: "secondaryActionsLabel", publicName: "secondaryActionsLabel", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "formattedContent", first: true, predicate: ["formattedContent"], descendants: true, isSignal: true }], ngImport: i0, template: "<si-chat-message alignment=\"start\" actionsPosition=\"bottom\" [loading]=\"loading()\">\n @if (content()) {\n @let content = textContent();\n @if (content) {\n <span class=\"text-pre-wrap\">{{ content }}</span>\n } @else {\n <div #formattedContent> </div>\n }\n }\n\n @if (actions().length > 0 || secondaryActions().length > 0) {\n <div class=\"btn-group ai-message-actions\" role=\"group\" siChatMessageAction>\n @for (action of actions(); track $index) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [disabled]=\"action.disabled\"\n [attr.aria-label]=\"action.label | translate\"\n (click)=\"action.action(actionParam(), action)\"\n >\n <si-icon [icon]=\"action.icon\" />\n </button>\n }\n\n @if (secondaryActions().length > 0) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [cdkMenuTriggerFor]=\"secondaryActionsMenu\"\n [attr.aria-label]=\"secondaryActionsLabel() | translate\"\n [attr.title]=\"secondaryActionsLabel() | translate\"\n >\n <si-icon [icon]=\"icons.elementOptionsVertical\" />\n </button>\n\n <ng-template #secondaryActionsMenu>\n <si-menu-factory [items]=\"secondaryActions()\" [actionParam]=\"actionParam()\" />\n </ng-template>\n }\n </div>\n }\n</si-chat-message>\n", styles: [":host{display:block}si-chat-message{--chat-message-bubble-bg: transparent;--chat-message-bubble-padding: 0;margin-block-end:-4px}.ai-message-actions{margin-block-start:8px}:host ::ng-deep si-loading-spinner{--loading-spinner-size: 1.5em}\n"], dependencies: [{ kind: "directive", type: CdkMenuTrigger, selector: "[cdkMenuTriggerFor]", inputs: ["cdkMenuTriggerFor", "cdkMenuPosition", "cdkMenuTriggerData", "cdkMenuTriggerTransformOriginOn"], outputs: ["cdkMenuOpened", "cdkMenuClosed"], exportAs: ["cdkMenuTriggerFor"] }, { kind: "component", type: SiChatMessageComponent, selector: "si-chat-message", inputs: ["loading", "alignment", "actionsPosition"] }, { kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "component", type: SiMenuFactoryComponent, selector: "si-menu-factory", inputs: ["items", "actionParam"] }, { kind: "directive", type: SiChatMessageActionDirective, selector: "[siChatMessageAction]" }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }] });
209
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiAiMessageComponent, isStandalone: true, selector: "si-ai-message", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, contentFormatter: { classPropertyName: "contentFormatter", publicName: "contentFormatter", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, secondaryActions: { classPropertyName: "secondaryActions", publicName: "secondaryActions", isSignal: true, isRequired: false, transformFunction: null }, actionParam: { classPropertyName: "actionParam", publicName: "actionParam", isSignal: true, isRequired: false, transformFunction: null }, secondaryActionsLabel: { classPropertyName: "secondaryActionsLabel", publicName: "secondaryActionsLabel", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "formattedContent", first: true, predicate: ["formattedContent"], descendants: true, isSignal: true }], ngImport: i0, template: "<si-chat-message alignment=\"start\" actionsPosition=\"bottom\" [loading]=\"loading()\">\n @if (content()) {\n @let content = textContent();\n @if (content) {\n <span class=\"text-pre-wrap\">{{ content }}</span>\n } @else {\n <div #formattedContent> </div>\n }\n }\n\n @if (actions().length > 0 || secondaryActions().length > 0) {\n <div class=\"btn-group ai-message-actions\" role=\"group\" siChatMessageAction>\n @for (action of actions(); track $index) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [disabled]=\"action.disabled\"\n [attr.aria-label]=\"action.label | translate\"\n (click)=\"action.action(actionParam(), action)\"\n >\n <si-icon [icon]=\"action.icon\" />\n </button>\n }\n\n @if (secondaryActions().length > 0) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [cdkMenuTriggerFor]=\"secondaryActionsMenu\"\n [attr.aria-label]=\"secondaryActionsLabel() | translate\"\n [attr.title]=\"secondaryActionsLabel() | translate\"\n >\n <si-icon [icon]=\"icons.elementOptionsVertical\" />\n </button>\n\n <ng-template #secondaryActionsMenu>\n <si-menu-factory [items]=\"secondaryActions()\" [actionParam]=\"actionParam()\" />\n </ng-template>\n }\n </div>\n }\n</si-chat-message>\n", styles: [":host{display:block}si-chat-message{--chat-message-bubble-bg: transparent;--chat-message-bubble-padding: 0;margin-block-end:-4px}.ai-message-actions{margin-block-start:8px}:host ::ng-deep si-loading-spinner{--loading-spinner-size: 1.5em}\n"], dependencies: [{ kind: "directive", type: CdkMenuTrigger, selector: "[cdkMenuTriggerFor]", inputs: ["cdkMenuTriggerFor", "cdkMenuPosition", "cdkMenuTriggerData", "cdkMenuTriggerTransformOriginOn"], outputs: ["cdkMenuOpened", "cdkMenuClosed"], exportAs: ["cdkMenuTriggerFor"] }, { kind: "component", type: SiChatMessageComponent, selector: "si-chat-message", inputs: ["loading", "alignment", "actionsPosition"] }, { kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "component", type: SiMenuFactoryComponent, selector: "si-menu-factory", inputs: ["items", "actionParam"] }, { kind: "directive", type: SiChatMessageActionDirective, selector: "[siChatMessageAction]" }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
210
210
  }
211
211
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiAiMessageComponent, decorators: [{
212
212
  type: Component,
@@ -217,7 +217,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
217
217
  SiMenuFactoryComponent,
218
218
  SiChatMessageActionDirective,
219
219
  SiTranslatePipe
220
- ], template: "<si-chat-message alignment=\"start\" actionsPosition=\"bottom\" [loading]=\"loading()\">\n @if (content()) {\n @let content = textContent();\n @if (content) {\n <span class=\"text-pre-wrap\">{{ content }}</span>\n } @else {\n <div #formattedContent> </div>\n }\n }\n\n @if (actions().length > 0 || secondaryActions().length > 0) {\n <div class=\"btn-group ai-message-actions\" role=\"group\" siChatMessageAction>\n @for (action of actions(); track $index) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [disabled]=\"action.disabled\"\n [attr.aria-label]=\"action.label | translate\"\n (click)=\"action.action(actionParam(), action)\"\n >\n <si-icon [icon]=\"action.icon\" />\n </button>\n }\n\n @if (secondaryActions().length > 0) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [cdkMenuTriggerFor]=\"secondaryActionsMenu\"\n [attr.aria-label]=\"secondaryActionsLabel() | translate\"\n [attr.title]=\"secondaryActionsLabel() | translate\"\n >\n <si-icon [icon]=\"icons.elementOptionsVertical\" />\n </button>\n\n <ng-template #secondaryActionsMenu>\n <si-menu-factory [items]=\"secondaryActions()\" [actionParam]=\"actionParam()\" />\n </ng-template>\n }\n </div>\n }\n</si-chat-message>\n", styles: [":host{display:block}si-chat-message{--chat-message-bubble-bg: transparent;--chat-message-bubble-padding: 0;margin-block-end:-4px}.ai-message-actions{margin-block-start:8px}:host ::ng-deep si-loading-spinner{--loading-spinner-size: 1.5em}\n"] }]
220
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<si-chat-message alignment=\"start\" actionsPosition=\"bottom\" [loading]=\"loading()\">\n @if (content()) {\n @let content = textContent();\n @if (content) {\n <span class=\"text-pre-wrap\">{{ content }}</span>\n } @else {\n <div #formattedContent> </div>\n }\n }\n\n @if (actions().length > 0 || secondaryActions().length > 0) {\n <div class=\"btn-group ai-message-actions\" role=\"group\" siChatMessageAction>\n @for (action of actions(); track $index) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [disabled]=\"action.disabled\"\n [attr.aria-label]=\"action.label | translate\"\n (click)=\"action.action(actionParam(), action)\"\n >\n <si-icon [icon]=\"action.icon\" />\n </button>\n }\n\n @if (secondaryActions().length > 0) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [cdkMenuTriggerFor]=\"secondaryActionsMenu\"\n [attr.aria-label]=\"secondaryActionsLabel() | translate\"\n [attr.title]=\"secondaryActionsLabel() | translate\"\n >\n <si-icon [icon]=\"icons.elementOptionsVertical\" />\n </button>\n\n <ng-template #secondaryActionsMenu>\n <si-menu-factory [items]=\"secondaryActions()\" [actionParam]=\"actionParam()\" />\n </ng-template>\n }\n </div>\n }\n</si-chat-message>\n", styles: [":host{display:block}si-chat-message{--chat-message-bubble-bg: transparent;--chat-message-bubble-padding: 0;margin-block-end:-4px}.ai-message-actions{margin-block-start:8px}:host ::ng-deep si-loading-spinner{--loading-spinner-size: 1.5em}\n"] }]
221
221
  }], ctorParameters: () => [], propDecorators: { formattedContent: [{ type: i0.ViewChild, args: ['formattedContent', { isSignal: true }] }], content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }], contentFormatter: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentFormatter", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], secondaryActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryActions", required: false }] }], actionParam: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionParam", required: false }] }], secondaryActionsLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryActionsLabel", required: false }] }] } });
222
222
 
223
223
  /**
@@ -299,11 +299,11 @@ class SiAttachmentListComponent {
299
299
  return this.icons.elementDocument;
300
300
  }
301
301
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiAttachmentListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
302
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiAttachmentListComponent, isStandalone: true, selector: "si-attachment-list", inputs: { attachments: { classPropertyName: "attachments", publicName: "attachments", isSignal: true, isRequired: false, transformFunction: null }, alignment: { classPropertyName: "alignment", publicName: "alignment", isSignal: true, isRequired: false, transformFunction: null }, removable: { classPropertyName: "removable", publicName: "removable", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { remove: "remove" }, ngImport: i0, template: "<div class=\"d-flex flex-wrap gap-4\" [class.justify-content-end]=\"alignment() === 'end'\">\n @for (attachment of attachments(); track $index) {\n <div class=\"attachment-item d-flex align-items-stretch\" role=\"group\">\n @if (attachment.previewTemplate) {\n <button\n type=\"button\"\n class=\"attachment-main focus-inside d-flex align-items-center flex-grow-1 min-width-0\"\n [attr.title]=\"attachment.name\"\n [attr.aria-label]=\"attachment.name\"\n (click)=\"openPreview($event, attachment)\"\n (keydown.enter)=\"openPreview($event, attachment)\"\n (keydown.space)=\"openPreview($event, attachment)\"\n >\n <si-icon\n class=\"attachment-icon icon flex-shrink-0 m-2\"\n [icon]=\"getFileIcon(attachment.name)\"\n />\n <div class=\"attachment-info flex-grow-1 min-width-0\">\n <span\n class=\"attachment-name me-4 text-truncate si-body-2 d-block\"\n [title]=\"attachment.name\"\n >\n {{ attachment.name }}\n </span>\n </div>\n </button>\n } @else {\n <div class=\"attachment-main--static d-flex align-items-center flex-grow-1 min-width-0\">\n <si-icon\n class=\"attachment-icon icon flex-shrink-0 m-2\"\n [icon]=\"getFileIcon(attachment.name)\"\n />\n <div class=\"attachment-info flex-grow-1 min-width-0\">\n <span\n class=\"attachment-name me-4 text-truncate si-body-2 d-block\"\n [title]=\"attachment.name\"\n >\n {{ attachment.name }}\n </span>\n </div>\n </div>\n }\n\n @if (removable()) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-sm btn-icon expand-button flex-shrink-0 ms-auto align-self-center focus-inside m-2\"\n [attr.aria-label]=\"(removeLabel() | translate) + ' ' + attachment.name\"\n (click)=\"remove.emit(attachment); $event.stopPropagation()\"\n >\n <si-icon class=\"icon\" [icon]=\"icons.elementStateClose\" />\n </button>\n }\n </div>\n }\n</div>\n", styles: [":host{--attachment-list-bg: transparent;--attachment-name-color: var(--element-text-secondary)}.attachment-item{border-radius:var(--element-radius-2);overflow:hidden;background-color:var(--attachment-list-bg);color:var(--attachment-name-color);border:1px solid var(--element-ui-4)}.attachment-main{appearance:none;border:0;background:none;padding:0;margin:0;inline-size:100%;text-align:inherit;color:inherit;cursor:pointer}.attachment-icon{display:flex;align-items:center;justify-content:center;color:var(--element-text-primary)}.attachment-info{display:flex;flex-direction:column;gap:2px;min-inline-size:0}.attachment-info .attachment-name{line-height:1.2}.attachment-info .attachment-size{line-height:1}.expand-button{border-radius:var(--element-radius-2)}\n"], dependencies: [{ kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }] });
302
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiAttachmentListComponent, isStandalone: true, selector: "si-attachment-list", inputs: { attachments: { classPropertyName: "attachments", publicName: "attachments", isSignal: true, isRequired: false, transformFunction: null }, alignment: { classPropertyName: "alignment", publicName: "alignment", isSignal: true, isRequired: false, transformFunction: null }, removable: { classPropertyName: "removable", publicName: "removable", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { remove: "remove" }, ngImport: i0, template: "<div class=\"d-flex flex-wrap gap-4\" [class.justify-content-end]=\"alignment() === 'end'\">\n @for (attachment of attachments(); track $index) {\n <div class=\"attachment-item d-flex align-items-stretch\" role=\"group\">\n @if (attachment.previewTemplate) {\n <button\n type=\"button\"\n class=\"attachment-main focus-inside d-flex align-items-center flex-grow-1 min-width-0\"\n [attr.title]=\"attachment.name\"\n [attr.aria-label]=\"attachment.name\"\n (click)=\"openPreview($event, attachment)\"\n (keydown.enter)=\"openPreview($event, attachment)\"\n (keydown.space)=\"openPreview($event, attachment)\"\n >\n <si-icon\n class=\"attachment-icon icon flex-shrink-0 m-2\"\n [icon]=\"getFileIcon(attachment.name)\"\n />\n <div class=\"attachment-info flex-grow-1 min-width-0\">\n <span\n class=\"attachment-name me-4 text-truncate si-body-2 d-block\"\n [title]=\"attachment.name\"\n >\n {{ attachment.name }}\n </span>\n </div>\n </button>\n } @else {\n <div class=\"attachment-main--static d-flex align-items-center flex-grow-1 min-width-0\">\n <si-icon\n class=\"attachment-icon icon flex-shrink-0 m-2\"\n [icon]=\"getFileIcon(attachment.name)\"\n />\n <div class=\"attachment-info flex-grow-1 min-width-0\">\n <span\n class=\"attachment-name me-4 text-truncate si-body-2 d-block\"\n [title]=\"attachment.name\"\n >\n {{ attachment.name }}\n </span>\n </div>\n </div>\n }\n\n @if (removable()) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-sm btn-icon expand-button flex-shrink-0 ms-auto align-self-center focus-inside m-2\"\n [attr.aria-label]=\"(removeLabel() | translate) + ' ' + attachment.name\"\n (click)=\"remove.emit(attachment); $event.stopPropagation()\"\n >\n <si-icon class=\"icon\" [icon]=\"icons.elementStateClose\" />\n </button>\n }\n </div>\n }\n</div>\n", styles: [":host{--attachment-list-bg: transparent;--attachment-name-color: var(--element-text-secondary)}.attachment-item{border-radius:var(--element-radius-2);overflow:hidden;background-color:var(--attachment-list-bg);color:var(--attachment-name-color);border:1px solid var(--element-ui-4)}.attachment-main{appearance:none;border:0;background:none;padding:0;margin:0;inline-size:100%;text-align:inherit;color:inherit;cursor:pointer}.attachment-icon{display:flex;align-items:center;justify-content:center;color:var(--element-text-primary)}.attachment-info{display:flex;flex-direction:column;gap:2px;min-inline-size:0}.attachment-info .attachment-name{line-height:1.2}.attachment-info .attachment-size{line-height:1}.expand-button{border-radius:var(--element-radius-2)}\n"], dependencies: [{ kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
303
303
  }
304
304
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiAttachmentListComponent, decorators: [{
305
305
  type: Component,
306
- args: [{ selector: 'si-attachment-list', imports: [SiIconComponent, SiTranslatePipe], template: "<div class=\"d-flex flex-wrap gap-4\" [class.justify-content-end]=\"alignment() === 'end'\">\n @for (attachment of attachments(); track $index) {\n <div class=\"attachment-item d-flex align-items-stretch\" role=\"group\">\n @if (attachment.previewTemplate) {\n <button\n type=\"button\"\n class=\"attachment-main focus-inside d-flex align-items-center flex-grow-1 min-width-0\"\n [attr.title]=\"attachment.name\"\n [attr.aria-label]=\"attachment.name\"\n (click)=\"openPreview($event, attachment)\"\n (keydown.enter)=\"openPreview($event, attachment)\"\n (keydown.space)=\"openPreview($event, attachment)\"\n >\n <si-icon\n class=\"attachment-icon icon flex-shrink-0 m-2\"\n [icon]=\"getFileIcon(attachment.name)\"\n />\n <div class=\"attachment-info flex-grow-1 min-width-0\">\n <span\n class=\"attachment-name me-4 text-truncate si-body-2 d-block\"\n [title]=\"attachment.name\"\n >\n {{ attachment.name }}\n </span>\n </div>\n </button>\n } @else {\n <div class=\"attachment-main--static d-flex align-items-center flex-grow-1 min-width-0\">\n <si-icon\n class=\"attachment-icon icon flex-shrink-0 m-2\"\n [icon]=\"getFileIcon(attachment.name)\"\n />\n <div class=\"attachment-info flex-grow-1 min-width-0\">\n <span\n class=\"attachment-name me-4 text-truncate si-body-2 d-block\"\n [title]=\"attachment.name\"\n >\n {{ attachment.name }}\n </span>\n </div>\n </div>\n }\n\n @if (removable()) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-sm btn-icon expand-button flex-shrink-0 ms-auto align-self-center focus-inside m-2\"\n [attr.aria-label]=\"(removeLabel() | translate) + ' ' + attachment.name\"\n (click)=\"remove.emit(attachment); $event.stopPropagation()\"\n >\n <si-icon class=\"icon\" [icon]=\"icons.elementStateClose\" />\n </button>\n }\n </div>\n }\n</div>\n", styles: [":host{--attachment-list-bg: transparent;--attachment-name-color: var(--element-text-secondary)}.attachment-item{border-radius:var(--element-radius-2);overflow:hidden;background-color:var(--attachment-list-bg);color:var(--attachment-name-color);border:1px solid var(--element-ui-4)}.attachment-main{appearance:none;border:0;background:none;padding:0;margin:0;inline-size:100%;text-align:inherit;color:inherit;cursor:pointer}.attachment-icon{display:flex;align-items:center;justify-content:center;color:var(--element-text-primary)}.attachment-info{display:flex;flex-direction:column;gap:2px;min-inline-size:0}.attachment-info .attachment-name{line-height:1.2}.attachment-info .attachment-size{line-height:1}.expand-button{border-radius:var(--element-radius-2)}\n"] }]
306
+ args: [{ selector: 'si-attachment-list', imports: [SiIconComponent, SiTranslatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"d-flex flex-wrap gap-4\" [class.justify-content-end]=\"alignment() === 'end'\">\n @for (attachment of attachments(); track $index) {\n <div class=\"attachment-item d-flex align-items-stretch\" role=\"group\">\n @if (attachment.previewTemplate) {\n <button\n type=\"button\"\n class=\"attachment-main focus-inside d-flex align-items-center flex-grow-1 min-width-0\"\n [attr.title]=\"attachment.name\"\n [attr.aria-label]=\"attachment.name\"\n (click)=\"openPreview($event, attachment)\"\n (keydown.enter)=\"openPreview($event, attachment)\"\n (keydown.space)=\"openPreview($event, attachment)\"\n >\n <si-icon\n class=\"attachment-icon icon flex-shrink-0 m-2\"\n [icon]=\"getFileIcon(attachment.name)\"\n />\n <div class=\"attachment-info flex-grow-1 min-width-0\">\n <span\n class=\"attachment-name me-4 text-truncate si-body-2 d-block\"\n [title]=\"attachment.name\"\n >\n {{ attachment.name }}\n </span>\n </div>\n </button>\n } @else {\n <div class=\"attachment-main--static d-flex align-items-center flex-grow-1 min-width-0\">\n <si-icon\n class=\"attachment-icon icon flex-shrink-0 m-2\"\n [icon]=\"getFileIcon(attachment.name)\"\n />\n <div class=\"attachment-info flex-grow-1 min-width-0\">\n <span\n class=\"attachment-name me-4 text-truncate si-body-2 d-block\"\n [title]=\"attachment.name\"\n >\n {{ attachment.name }}\n </span>\n </div>\n </div>\n }\n\n @if (removable()) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-sm btn-icon expand-button flex-shrink-0 ms-auto align-self-center focus-inside m-2\"\n [attr.aria-label]=\"(removeLabel() | translate) + ' ' + attachment.name\"\n (click)=\"remove.emit(attachment); $event.stopPropagation()\"\n >\n <si-icon class=\"icon\" [icon]=\"icons.elementStateClose\" />\n </button>\n }\n </div>\n }\n</div>\n", styles: [":host{--attachment-list-bg: transparent;--attachment-name-color: var(--element-text-secondary)}.attachment-item{border-radius:var(--element-radius-2);overflow:hidden;background-color:var(--attachment-list-bg);color:var(--attachment-name-color);border:1px solid var(--element-ui-4)}.attachment-main{appearance:none;border:0;background:none;padding:0;margin:0;inline-size:100%;text-align:inherit;color:inherit;cursor:pointer}.attachment-icon{display:flex;align-items:center;justify-content:center;color:var(--element-text-primary)}.attachment-info{display:flex;flex-direction:column;gap:2px;min-inline-size:0}.attachment-info .attachment-name{line-height:1.2}.attachment-info .attachment-size{line-height:1}.expand-button{border-radius:var(--element-radius-2)}\n"] }]
307
307
  }], propDecorators: { attachments: [{ type: i0.Input, args: [{ isSignal: true, alias: "attachments", required: false }] }], alignment: [{ type: i0.Input, args: [{ isSignal: true, alias: "alignment", required: false }] }], removable: [{ type: i0.Input, args: [{ isSignal: true, alias: "removable", required: false }] }], removeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeLabel", required: false }] }], remove: [{ type: i0.Output, args: ["remove"] }] } });
308
308
 
309
309
  /**
@@ -476,11 +476,11 @@ class SiChatContainerComponent {
476
476
  container?.nativeElement.focus();
477
477
  }
478
478
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiChatContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
479
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.8", type: SiChatContainerComponent, isStandalone: true, selector: "si-chat-container", inputs: { colorVariant: { classPropertyName: "colorVariant", publicName: "colorVariant", isSignal: true, isRequired: false, transformFunction: null }, noAutoScroll: { classPropertyName: "noAutoScroll", publicName: "noAutoScroll", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "colorVariant()" }, classAttribute: "d-flex si-layout-inner flex-grow-1 flex-column h-100 w-100" }, viewQueries: [{ propertyName: "messagesContainer", first: true, predicate: ["messagesContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"chat-container d-flex flex-column flex-grow-1 px-6 px-md-9 py-6 w-100\">\n <div\n #messagesContainer\n class=\"messages-container d-flex flex-column flex-grow-1 w-100 align-self-center\"\n tabindex=\"0\"\n (scroll)=\"onScroll()\"\n >\n <ng-content />\n </div>\n\n <div class=\"chat-input-area py-3 pt-0 mt-6 d-flex flex-column align-items-center\">\n <ng-content select=\"si-inline-notification\" />\n <ng-content select=\"si-chat-input,[siChatContainerInput]\" />\n </div>\n</div>\n", styles: [":host{overflow-y:hidden;overflow-x:visible}:host.base-0{background-color:var(--element-base-0)}:host.base-1{background-color:var(--element-base-1)}.chat-container.initialized{scroll-behavior:smooth}::ng-deep .chat-container:has(si-ai-welcome-screen){inline-size:100%;padding-inline-start:0!important;padding-inline-end:0!important}::ng-deep .chat-container:has(si-ai-welcome-screen) .chat-input-area,::ng-deep .chat-container:has(si-ai-welcome-screen) si-ai-welcome-screen{padding-inline-start:16px;padding-inline-end:16px}.chat-container{min-block-size:0;overflow-y:auto;overflow-x:visible}.messages-container{overflow-y:auto;overflow-x:visible;padding-inline:8px;min-block-size:5rem;gap:40px}.messages-container ::ng-deep si-user-message:not(.last){margin-block-end:-40px}::ng-deep .messages-container:not(:has(si-ai-welcome-screen)){max-inline-size:720px}::ng-deep .messages-container:has(si-ai-welcome-screen){inline-size:100%}.chat-input-area{justify-self:flex-end;align-self:center;overflow:visible;inline-size:100%}.chat-input-area>::ng-deep *{max-inline-size:720px}::ng-deep .chat-input-area:empty:not(:has(si-inline-notification)),::ng-deep .chat-input-area:has([sichatcontainerinput]:empty):not(:has(si-inline-notification)){display:none!important}.chat-input-area:empty ::ng-deep>si-inline-notification,.chat-input-area:empty ::ng-deep *>si-inline-notification,.chat-input-area:has([sichatcontainerinput]:empty) ::ng-deep>si-inline-notification,.chat-input-area:has([sichatcontainerinput]:empty) ::ng-deep *>si-inline-notification{margin-block-end:0!important}.chat-container:has(.messages-container:not(:empty)) .messages-empty-state{display:none!important}:host-context(.si-container-xs,.si-container-sm) ::ng-deep si-inline-notification .alert,:host-context(.si-container-xs,.si-container-sm) ::ng-deep si-inline-notification .alert-link{font-size:.875rem}\n"] });
479
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.8", type: SiChatContainerComponent, isStandalone: true, selector: "si-chat-container", inputs: { colorVariant: { classPropertyName: "colorVariant", publicName: "colorVariant", isSignal: true, isRequired: false, transformFunction: null }, noAutoScroll: { classPropertyName: "noAutoScroll", publicName: "noAutoScroll", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "colorVariant()" }, classAttribute: "d-flex si-layout-inner flex-grow-1 flex-column h-100 w-100" }, viewQueries: [{ propertyName: "messagesContainer", first: true, predicate: ["messagesContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"chat-container d-flex flex-column flex-grow-1 px-6 px-md-9 py-6 w-100\">\n <div\n #messagesContainer\n class=\"messages-container d-flex flex-column flex-grow-1 w-100 align-self-center\"\n tabindex=\"0\"\n (scroll)=\"onScroll()\"\n >\n <ng-content />\n </div>\n\n <div class=\"chat-input-area py-3 pt-0 mt-6 d-flex flex-column align-items-center\">\n <ng-content select=\"si-inline-notification\" />\n <ng-content select=\"si-chat-input,[siChatContainerInput]\" />\n </div>\n</div>\n", styles: [":host{overflow-y:hidden;overflow-x:visible}:host.base-0{background-color:var(--element-base-0)}:host.base-1{background-color:var(--element-base-1)}.chat-container.initialized{scroll-behavior:smooth}::ng-deep .chat-container:has(si-ai-welcome-screen){inline-size:100%;padding-inline-start:0!important;padding-inline-end:0!important}::ng-deep .chat-container:has(si-ai-welcome-screen) .chat-input-area,::ng-deep .chat-container:has(si-ai-welcome-screen) si-ai-welcome-screen{padding-inline-start:16px;padding-inline-end:16px}.chat-container{min-block-size:0;overflow-y:auto;overflow-x:visible}.messages-container{overflow-y:auto;overflow-x:visible;padding-inline:8px;min-block-size:5rem;gap:40px}.messages-container ::ng-deep si-user-message:not(.last){margin-block-end:-40px}::ng-deep .messages-container:not(:has(si-ai-welcome-screen)){max-inline-size:720px}::ng-deep .messages-container:has(si-ai-welcome-screen){inline-size:100%}.chat-input-area{justify-self:flex-end;align-self:center;overflow:visible;inline-size:100%}.chat-input-area>::ng-deep *{max-inline-size:720px}::ng-deep .chat-input-area:empty:not(:has(si-inline-notification)),::ng-deep .chat-input-area:has([sichatcontainerinput]:empty):not(:has(si-inline-notification)){display:none!important}.chat-input-area:empty ::ng-deep>si-inline-notification,.chat-input-area:empty ::ng-deep *>si-inline-notification,.chat-input-area:has([sichatcontainerinput]:empty) ::ng-deep>si-inline-notification,.chat-input-area:has([sichatcontainerinput]:empty) ::ng-deep *>si-inline-notification{margin-block-end:0!important}.chat-container:has(.messages-container:not(:empty)) .messages-empty-state{display:none!important}:host-context(.si-container-xs,.si-container-sm) ::ng-deep si-inline-notification .alert,:host-context(.si-container-xs,.si-container-sm) ::ng-deep si-inline-notification .alert-link{font-size:.875rem}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
480
480
  }
481
481
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiChatContainerComponent, decorators: [{
482
482
  type: Component,
483
- args: [{ selector: 'si-chat-container', host: {
483
+ args: [{ selector: 'si-chat-container', changeDetection: ChangeDetectionStrategy.OnPush, host: {
484
484
  class: 'd-flex si-layout-inner flex-grow-1 flex-column h-100 w-100',
485
485
  '[class]': 'colorVariant()'
486
486
  }, template: "<div class=\"chat-container d-flex flex-column flex-grow-1 px-6 px-md-9 py-6 w-100\">\n <div\n #messagesContainer\n class=\"messages-container d-flex flex-column flex-grow-1 w-100 align-self-center\"\n tabindex=\"0\"\n (scroll)=\"onScroll()\"\n >\n <ng-content />\n </div>\n\n <div class=\"chat-input-area py-3 pt-0 mt-6 d-flex flex-column align-items-center\">\n <ng-content select=\"si-inline-notification\" />\n <ng-content select=\"si-chat-input,[siChatContainerInput]\" />\n </div>\n</div>\n", styles: [":host{overflow-y:hidden;overflow-x:visible}:host.base-0{background-color:var(--element-base-0)}:host.base-1{background-color:var(--element-base-1)}.chat-container.initialized{scroll-behavior:smooth}::ng-deep .chat-container:has(si-ai-welcome-screen){inline-size:100%;padding-inline-start:0!important;padding-inline-end:0!important}::ng-deep .chat-container:has(si-ai-welcome-screen) .chat-input-area,::ng-deep .chat-container:has(si-ai-welcome-screen) si-ai-welcome-screen{padding-inline-start:16px;padding-inline-end:16px}.chat-container{min-block-size:0;overflow-y:auto;overflow-x:visible}.messages-container{overflow-y:auto;overflow-x:visible;padding-inline:8px;min-block-size:5rem;gap:40px}.messages-container ::ng-deep si-user-message:not(.last){margin-block-end:-40px}::ng-deep .messages-container:not(:has(si-ai-welcome-screen)){max-inline-size:720px}::ng-deep .messages-container:has(si-ai-welcome-screen){inline-size:100%}.chat-input-area{justify-self:flex-end;align-self:center;overflow:visible;inline-size:100%}.chat-input-area>::ng-deep *{max-inline-size:720px}::ng-deep .chat-input-area:empty:not(:has(si-inline-notification)),::ng-deep .chat-input-area:has([sichatcontainerinput]:empty):not(:has(si-inline-notification)){display:none!important}.chat-input-area:empty ::ng-deep>si-inline-notification,.chat-input-area:empty ::ng-deep *>si-inline-notification,.chat-input-area:has([sichatcontainerinput]:empty) ::ng-deep>si-inline-notification,.chat-input-area:has([sichatcontainerinput]:empty) ::ng-deep *>si-inline-notification{margin-block-end:0!important}.chat-container:has(.messages-container:not(:empty)) .messages-empty-state{display:none!important}:host-context(.si-container-xs,.si-container-sm) ::ng-deep si-inline-notification .alert,:host-context(.si-container-xs,.si-container-sm) ::ng-deep si-inline-notification .alert-link{font-size:.875rem}\n"] }]
@@ -750,10 +750,7 @@ class SiChatInputComponent {
750
750
  }, ...(ngDevMode ? [{ debugName: "buttonDisabled" }] : []));
751
751
  buttonIcon = computed(() => this.showInterruptButton() ? this.icons.elementStopFilled : this.sendButtonIcon(), ...(ngDevMode ? [{ debugName: "buttonIcon" }] : []));
752
752
  buttonLabel = computed(() => this.showInterruptButton() ? this.interruptButtonLabel() : this.sendButtonLabel(), ...(ngDevMode ? [{ debugName: "buttonLabel" }] : []));
753
- dragOver = false;
754
- get attachmentList() {
755
- return this.attachments();
756
- }
753
+ dragOver = signal(false, ...(ngDevMode ? [{ debugName: "dragOver" }] : []));
757
754
  onInputChange(value) {
758
755
  this.value.set(value);
759
756
  }
@@ -849,7 +846,7 @@ class SiChatInputComponent {
849
846
  dropHandler(event) {
850
847
  event.preventDefault();
851
848
  event.stopPropagation();
852
- this.dragOver = false;
849
+ this.dragOver.set(false);
853
850
  if (!this.allowAttachments() || this.disabled()) {
854
851
  return;
855
852
  }
@@ -864,7 +861,7 @@ class SiChatInputComponent {
864
861
  }
865
862
  event.preventDefault();
866
863
  event.stopPropagation();
867
- this.dragOver = true;
864
+ this.dragOver.set(true);
868
865
  }
869
866
  setTextareaHeight(textarea) {
870
867
  textarea.style.blockSize = 'auto';
@@ -882,7 +879,7 @@ class SiChatInputComponent {
882
879
  textarea.style.height = finalHeight + 'px';
883
880
  }
884
881
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiChatInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
885
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiChatInputComponent, isStandalone: true, selector: "si-chat-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, sending: { classPropertyName: "sending", publicName: "sending", isSignal: true, isRequired: false, transformFunction: null }, interruptible: { classPropertyName: "interruptible", publicName: "interruptible", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, disclaimer: { classPropertyName: "disclaimer", publicName: "disclaimer", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, secondaryActions: { classPropertyName: "secondaryActions", publicName: "secondaryActions", isSignal: true, isRequired: false, transformFunction: null }, allowAttachments: { classPropertyName: "allowAttachments", publicName: "allowAttachments", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, attachments: { classPropertyName: "attachments", publicName: "attachments", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, actionParam: { classPropertyName: "actionParam", publicName: "actionParam", isSignal: true, isRequired: false, transformFunction: null }, sendButtonLabel: { classPropertyName: "sendButtonLabel", publicName: "sendButtonLabel", isSignal: true, isRequired: false, transformFunction: null }, sendButtonIcon: { classPropertyName: "sendButtonIcon", publicName: "sendButtonIcon", isSignal: true, isRequired: false, transformFunction: null }, interruptButtonLabel: { classPropertyName: "interruptButtonLabel", publicName: "interruptButtonLabel", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, attachFileLabel: { classPropertyName: "attachFileLabel", publicName: "attachFileLabel", isSignal: true, isRequired: false, transformFunction: null }, removeAttachmentLabel: { classPropertyName: "removeAttachmentLabel", publicName: "removeAttachmentLabel", isSignal: true, isRequired: false, transformFunction: null }, secondaryActionsLabel: { classPropertyName: "secondaryActionsLabel", publicName: "secondaryActionsLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", attachments: "attachmentsChange", send: "send", interrupt: "interrupt", fileError: "fileError" }, viewQueries: [{ propertyName: "textInput", first: true, predicate: ["textInput"], descendants: true, isSignal: true }, { propertyName: "fileUploadDirective", first: true, predicate: SiFileUploadDirective, descendants: true, isSignal: true }, { propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"input-wrapper border rounded-3\"\n [class.drag-over]=\"dragOver\"\n (click)=\"onContainerClick($event)\"\n (drop)=\"dropHandler($event)\"\n (dragover)=\"dragOverHandler($event)\"\n (dragleave)=\"dragOver = false\"\n>\n @if (hasAttachments()) {\n <si-attachment-list\n [attachments]=\"attachmentList\"\n [removeLabel]=\"removeAttachmentLabel()\"\n [removable]=\"true\"\n (remove)=\"removeAttachment($event)\"\n />\n }\n\n <div class=\"si-body-2\">\n <label class=\"form-label d-none\" [for]=\"id\">{{ label() | translate }}</label>\n <textarea\n #textInput\n class=\"chat-textarea w-100 border-0\"\n rows=\"1\"\n [id]=\"id\"\n [placeholder]=\"placeholder() | translate\"\n [disabled]=\"disabled()\"\n [maxlength]=\"maxLength() || null\"\n [(ngModel)]=\"value\"\n (keydown)=\"onKeyDown($event)\"\n (input)=\"adjustTextareaHeight($event)\"\n ></textarea>\n </div>\n\n <div class=\"d-flex align-items-center justify-content-between\">\n <div class=\"btn-group\" role=\"group\">\n <input\n #fileInput\n type=\"file\"\n class=\"d-none\"\n siFileUpload\n [accept]=\"accept()\"\n [maxFileSize]=\"maxFileSize()\"\n [multiple]=\"true\"\n (validFiles)=\"onFilesAdded($event)\"\n (fileError)=\"onFileError($event)\"\n />\n\n @if (hasMenuActions()) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [cdkMenuTriggerFor]=\"allActionsMenu\"\n [attr.aria-label]=\"secondaryActionsLabel() | translate\"\n [attr.title]=\"secondaryActionsLabel() | translate\"\n >\n <si-icon [icon]=\"icons.elementPlus\" />\n </button>\n\n <ng-template #allActionsMenu>\n <si-menu-factory [items]=\"allMenuActions()\" [actionParam]=\"actionParam()\" />\n </ng-template>\n }\n <ng-content />\n </div>\n\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [disabled]=\"buttonDisabled()\"\n [attr.aria-label]=\"buttonLabel() | translate\"\n (click)=\"onButtonClick()\"\n >\n <si-icon class=\"text-primary\" [icon]=\"buttonIcon()\" />\n </button>\n </div>\n</div>\n\n<div class=\"disclaimer-wrapper text-center mt-4 px-3\">\n @if (disclaimer()) {\n <span class=\"si-caption text-secondary d-block\">{{ disclaimer() | translate }}</span>\n }\n <ng-content select=\"[siChatInputDisclaimer]\" />\n</div>\n", styles: [":host{max-inline-size:720px}.input-wrapper{border-color:var(--element-ui-4);background-color:var(--element-base-1);padding-block:12px 8px;padding-inline:12px;display:flex;flex-direction:column;gap:12px}.input-wrapper:hover,.input-wrapper:active{background-color:var(--element-base-input-experimental);border-color:var(--element-ui-1)}.input-wrapper.drag-over{border:1px solid var(--element-focus-default);box-shadow:0 0 0 1px var(--element-focus-default)}.chat-textarea{min-block-size:1lh;font-family:inherit;padding-block:0;display:block;outline:none;resize:none;background-color:transparent}.chat-textarea::placeholder{color:var(--element-text-secondary)}.chat-textarea:disabled{background-color:transparent;color:var(--element-text-disabled);cursor:not-allowed}.chat-textarea:disabled::placeholder{color:var(--element-text-disabled)}.input-wrapper:has(.chat-textarea:focus-visible){outline:var(--element-button-focus-width) solid var(--element-focus-default);outline-offset:var(--element-button-focus-overlay-width);border-color:var(--element-ui-1)}.disclaimer-wrapper:empty{display:none}\n"], dependencies: [{ kind: "directive", type: CdkMenuTrigger, selector: "[cdkMenuTriggerFor]", inputs: ["cdkMenuTriggerFor", "cdkMenuPosition", "cdkMenuTriggerData", "cdkMenuTriggerTransformOriginOn"], outputs: ["cdkMenuOpened", "cdkMenuClosed"], exportAs: ["cdkMenuTriggerFor"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "component", type: SiAttachmentListComponent, selector: "si-attachment-list", inputs: ["attachments", "alignment", "removable", "removeLabel"], outputs: ["remove"] }, { kind: "component", type: SiMenuFactoryComponent, selector: "si-menu-factory", inputs: ["items", "actionParam"] }, { kind: "directive", type: SiFileUploadDirective, selector: "input[type=\"file\"][siFileUpload]", inputs: ["errorTextFileType", "errorTextFileMaxSize", "accept", "maxFileSize", "multiple", "directoryUpload"], outputs: ["validFiles", "filesAdded", "fileError"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }] });
882
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiChatInputComponent, isStandalone: true, selector: "si-chat-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, sending: { classPropertyName: "sending", publicName: "sending", isSignal: true, isRequired: false, transformFunction: null }, interruptible: { classPropertyName: "interruptible", publicName: "interruptible", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, disclaimer: { classPropertyName: "disclaimer", publicName: "disclaimer", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, secondaryActions: { classPropertyName: "secondaryActions", publicName: "secondaryActions", isSignal: true, isRequired: false, transformFunction: null }, allowAttachments: { classPropertyName: "allowAttachments", publicName: "allowAttachments", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, attachments: { classPropertyName: "attachments", publicName: "attachments", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, actionParam: { classPropertyName: "actionParam", publicName: "actionParam", isSignal: true, isRequired: false, transformFunction: null }, sendButtonLabel: { classPropertyName: "sendButtonLabel", publicName: "sendButtonLabel", isSignal: true, isRequired: false, transformFunction: null }, sendButtonIcon: { classPropertyName: "sendButtonIcon", publicName: "sendButtonIcon", isSignal: true, isRequired: false, transformFunction: null }, interruptButtonLabel: { classPropertyName: "interruptButtonLabel", publicName: "interruptButtonLabel", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, attachFileLabel: { classPropertyName: "attachFileLabel", publicName: "attachFileLabel", isSignal: true, isRequired: false, transformFunction: null }, removeAttachmentLabel: { classPropertyName: "removeAttachmentLabel", publicName: "removeAttachmentLabel", isSignal: true, isRequired: false, transformFunction: null }, secondaryActionsLabel: { classPropertyName: "secondaryActionsLabel", publicName: "secondaryActionsLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", attachments: "attachmentsChange", send: "send", interrupt: "interrupt", fileError: "fileError" }, viewQueries: [{ propertyName: "textInput", first: true, predicate: ["textInput"], descendants: true, isSignal: true }, { propertyName: "fileUploadDirective", first: true, predicate: SiFileUploadDirective, descendants: true, isSignal: true }, { propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"input-wrapper border rounded-3\"\n [class.drag-over]=\"dragOver()\"\n (click)=\"onContainerClick($event)\"\n (drop)=\"dropHandler($event)\"\n (dragover)=\"dragOverHandler($event)\"\n (dragleave)=\"dragOver.set(false)\"\n>\n @if (hasAttachments()) {\n <si-attachment-list\n [attachments]=\"attachments()\"\n [removeLabel]=\"removeAttachmentLabel()\"\n [removable]=\"true\"\n (remove)=\"removeAttachment($event)\"\n />\n }\n\n <div class=\"si-body-2\">\n <label class=\"form-label d-none\" [for]=\"id\">{{ label() | translate }}</label>\n <textarea\n #textInput\n class=\"chat-textarea w-100 border-0\"\n rows=\"1\"\n [id]=\"id\"\n [placeholder]=\"placeholder() | translate\"\n [disabled]=\"disabled()\"\n [maxlength]=\"maxLength() || null\"\n [(ngModel)]=\"value\"\n (keydown)=\"onKeyDown($event)\"\n (input)=\"adjustTextareaHeight($event)\"\n ></textarea>\n </div>\n\n <div class=\"d-flex align-items-center justify-content-between\">\n <div class=\"btn-group\" role=\"group\">\n <input\n #fileInput\n type=\"file\"\n class=\"d-none\"\n siFileUpload\n [accept]=\"accept()\"\n [maxFileSize]=\"maxFileSize()\"\n [multiple]=\"true\"\n (validFiles)=\"onFilesAdded($event)\"\n (fileError)=\"onFileError($event)\"\n />\n\n @if (hasMenuActions()) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [cdkMenuTriggerFor]=\"allActionsMenu\"\n [attr.aria-label]=\"secondaryActionsLabel() | translate\"\n [attr.title]=\"secondaryActionsLabel() | translate\"\n >\n <si-icon [icon]=\"icons.elementPlus\" />\n </button>\n\n <ng-template #allActionsMenu>\n <si-menu-factory [items]=\"allMenuActions()\" [actionParam]=\"actionParam()\" />\n </ng-template>\n }\n <ng-content />\n </div>\n\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [disabled]=\"buttonDisabled()\"\n [attr.aria-label]=\"buttonLabel() | translate\"\n (click)=\"onButtonClick()\"\n >\n <si-icon class=\"text-primary\" [icon]=\"buttonIcon()\" />\n </button>\n </div>\n</div>\n\n<div class=\"disclaimer-wrapper text-center mt-4 px-3\">\n @if (disclaimer()) {\n <span class=\"si-caption text-secondary d-block\">{{ disclaimer() | translate }}</span>\n }\n <ng-content select=\"[siChatInputDisclaimer]\" />\n</div>\n", styles: [":host{max-inline-size:720px}.input-wrapper{border-color:var(--element-ui-4);background-color:var(--element-base-1);padding-block:12px 8px;padding-inline:12px;display:flex;flex-direction:column;gap:12px}.input-wrapper:hover,.input-wrapper:active,.input-wrapper:focus-within{background-color:var(--element-base-input-experimental);border-color:var(--element-ui-1)}.input-wrapper.drag-over{border:1px solid var(--element-focus-default);box-shadow:0 0 0 1px var(--element-focus-default)}.chat-textarea{min-block-size:1lh;font-family:inherit;padding-block:0;display:block;outline:none;resize:none;background-color:transparent}.chat-textarea::placeholder{color:var(--element-text-secondary)}.chat-textarea:disabled{background-color:transparent;color:var(--element-text-disabled);cursor:not-allowed}.chat-textarea:disabled::placeholder{color:var(--element-text-disabled)}.input-wrapper:has(.chat-textarea:focus-visible){outline:var(--element-button-focus-width) solid var(--element-focus-default);outline-offset:var(--element-button-focus-overlay-width)}.disclaimer-wrapper:empty{display:none}\n"], dependencies: [{ kind: "directive", type: CdkMenuTrigger, selector: "[cdkMenuTriggerFor]", inputs: ["cdkMenuTriggerFor", "cdkMenuPosition", "cdkMenuTriggerData", "cdkMenuTriggerTransformOriginOn"], outputs: ["cdkMenuOpened", "cdkMenuClosed"], exportAs: ["cdkMenuTriggerFor"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "component", type: SiAttachmentListComponent, selector: "si-attachment-list", inputs: ["attachments", "alignment", "removable", "removeLabel"], outputs: ["remove"] }, { kind: "component", type: SiMenuFactoryComponent, selector: "si-menu-factory", inputs: ["items", "actionParam"] }, { kind: "directive", type: SiFileUploadDirective, selector: "input[type=\"file\"][siFileUpload]", inputs: ["errorTextFileType", "errorTextFileMaxSize", "accept", "maxFileSize", "multiple", "directoryUpload"], outputs: ["validFiles", "filesAdded", "fileError"] }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
886
883
  }
887
884
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiChatInputComponent, decorators: [{
888
885
  type: Component,
@@ -894,7 +891,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
894
891
  SiAttachmentListComponent,
895
892
  SiMenuFactoryComponent,
896
893
  SiFileUploadDirective
897
- ], template: "<div\n class=\"input-wrapper border rounded-3\"\n [class.drag-over]=\"dragOver\"\n (click)=\"onContainerClick($event)\"\n (drop)=\"dropHandler($event)\"\n (dragover)=\"dragOverHandler($event)\"\n (dragleave)=\"dragOver = false\"\n>\n @if (hasAttachments()) {\n <si-attachment-list\n [attachments]=\"attachmentList\"\n [removeLabel]=\"removeAttachmentLabel()\"\n [removable]=\"true\"\n (remove)=\"removeAttachment($event)\"\n />\n }\n\n <div class=\"si-body-2\">\n <label class=\"form-label d-none\" [for]=\"id\">{{ label() | translate }}</label>\n <textarea\n #textInput\n class=\"chat-textarea w-100 border-0\"\n rows=\"1\"\n [id]=\"id\"\n [placeholder]=\"placeholder() | translate\"\n [disabled]=\"disabled()\"\n [maxlength]=\"maxLength() || null\"\n [(ngModel)]=\"value\"\n (keydown)=\"onKeyDown($event)\"\n (input)=\"adjustTextareaHeight($event)\"\n ></textarea>\n </div>\n\n <div class=\"d-flex align-items-center justify-content-between\">\n <div class=\"btn-group\" role=\"group\">\n <input\n #fileInput\n type=\"file\"\n class=\"d-none\"\n siFileUpload\n [accept]=\"accept()\"\n [maxFileSize]=\"maxFileSize()\"\n [multiple]=\"true\"\n (validFiles)=\"onFilesAdded($event)\"\n (fileError)=\"onFileError($event)\"\n />\n\n @if (hasMenuActions()) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [cdkMenuTriggerFor]=\"allActionsMenu\"\n [attr.aria-label]=\"secondaryActionsLabel() | translate\"\n [attr.title]=\"secondaryActionsLabel() | translate\"\n >\n <si-icon [icon]=\"icons.elementPlus\" />\n </button>\n\n <ng-template #allActionsMenu>\n <si-menu-factory [items]=\"allMenuActions()\" [actionParam]=\"actionParam()\" />\n </ng-template>\n }\n <ng-content />\n </div>\n\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [disabled]=\"buttonDisabled()\"\n [attr.aria-label]=\"buttonLabel() | translate\"\n (click)=\"onButtonClick()\"\n >\n <si-icon class=\"text-primary\" [icon]=\"buttonIcon()\" />\n </button>\n </div>\n</div>\n\n<div class=\"disclaimer-wrapper text-center mt-4 px-3\">\n @if (disclaimer()) {\n <span class=\"si-caption text-secondary d-block\">{{ disclaimer() | translate }}</span>\n }\n <ng-content select=\"[siChatInputDisclaimer]\" />\n</div>\n", styles: [":host{max-inline-size:720px}.input-wrapper{border-color:var(--element-ui-4);background-color:var(--element-base-1);padding-block:12px 8px;padding-inline:12px;display:flex;flex-direction:column;gap:12px}.input-wrapper:hover,.input-wrapper:active{background-color:var(--element-base-input-experimental);border-color:var(--element-ui-1)}.input-wrapper.drag-over{border:1px solid var(--element-focus-default);box-shadow:0 0 0 1px var(--element-focus-default)}.chat-textarea{min-block-size:1lh;font-family:inherit;padding-block:0;display:block;outline:none;resize:none;background-color:transparent}.chat-textarea::placeholder{color:var(--element-text-secondary)}.chat-textarea:disabled{background-color:transparent;color:var(--element-text-disabled);cursor:not-allowed}.chat-textarea:disabled::placeholder{color:var(--element-text-disabled)}.input-wrapper:has(.chat-textarea:focus-visible){outline:var(--element-button-focus-width) solid var(--element-focus-default);outline-offset:var(--element-button-focus-overlay-width);border-color:var(--element-ui-1)}.disclaimer-wrapper:empty{display:none}\n"] }]
894
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"input-wrapper border rounded-3\"\n [class.drag-over]=\"dragOver()\"\n (click)=\"onContainerClick($event)\"\n (drop)=\"dropHandler($event)\"\n (dragover)=\"dragOverHandler($event)\"\n (dragleave)=\"dragOver.set(false)\"\n>\n @if (hasAttachments()) {\n <si-attachment-list\n [attachments]=\"attachments()\"\n [removeLabel]=\"removeAttachmentLabel()\"\n [removable]=\"true\"\n (remove)=\"removeAttachment($event)\"\n />\n }\n\n <div class=\"si-body-2\">\n <label class=\"form-label d-none\" [for]=\"id\">{{ label() | translate }}</label>\n <textarea\n #textInput\n class=\"chat-textarea w-100 border-0\"\n rows=\"1\"\n [id]=\"id\"\n [placeholder]=\"placeholder() | translate\"\n [disabled]=\"disabled()\"\n [maxlength]=\"maxLength() || null\"\n [(ngModel)]=\"value\"\n (keydown)=\"onKeyDown($event)\"\n (input)=\"adjustTextareaHeight($event)\"\n ></textarea>\n </div>\n\n <div class=\"d-flex align-items-center justify-content-between\">\n <div class=\"btn-group\" role=\"group\">\n <input\n #fileInput\n type=\"file\"\n class=\"d-none\"\n siFileUpload\n [accept]=\"accept()\"\n [maxFileSize]=\"maxFileSize()\"\n [multiple]=\"true\"\n (validFiles)=\"onFilesAdded($event)\"\n (fileError)=\"onFileError($event)\"\n />\n\n @if (hasMenuActions()) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [cdkMenuTriggerFor]=\"allActionsMenu\"\n [attr.aria-label]=\"secondaryActionsLabel() | translate\"\n [attr.title]=\"secondaryActionsLabel() | translate\"\n >\n <si-icon [icon]=\"icons.elementPlus\" />\n </button>\n\n <ng-template #allActionsMenu>\n <si-menu-factory [items]=\"allMenuActions()\" [actionParam]=\"actionParam()\" />\n </ng-template>\n }\n <ng-content />\n </div>\n\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [disabled]=\"buttonDisabled()\"\n [attr.aria-label]=\"buttonLabel() | translate\"\n (click)=\"onButtonClick()\"\n >\n <si-icon class=\"text-primary\" [icon]=\"buttonIcon()\" />\n </button>\n </div>\n</div>\n\n<div class=\"disclaimer-wrapper text-center mt-4 px-3\">\n @if (disclaimer()) {\n <span class=\"si-caption text-secondary d-block\">{{ disclaimer() | translate }}</span>\n }\n <ng-content select=\"[siChatInputDisclaimer]\" />\n</div>\n", styles: [":host{max-inline-size:720px}.input-wrapper{border-color:var(--element-ui-4);background-color:var(--element-base-1);padding-block:12px 8px;padding-inline:12px;display:flex;flex-direction:column;gap:12px}.input-wrapper:hover,.input-wrapper:active,.input-wrapper:focus-within{background-color:var(--element-base-input-experimental);border-color:var(--element-ui-1)}.input-wrapper.drag-over{border:1px solid var(--element-focus-default);box-shadow:0 0 0 1px var(--element-focus-default)}.chat-textarea{min-block-size:1lh;font-family:inherit;padding-block:0;display:block;outline:none;resize:none;background-color:transparent}.chat-textarea::placeholder{color:var(--element-text-secondary)}.chat-textarea:disabled{background-color:transparent;color:var(--element-text-disabled);cursor:not-allowed}.chat-textarea:disabled::placeholder{color:var(--element-text-disabled)}.input-wrapper:has(.chat-textarea:focus-visible){outline:var(--element-button-focus-width) solid var(--element-focus-default);outline-offset:var(--element-button-focus-overlay-width)}.disclaimer-wrapper:empty{display:none}\n"] }]
898
895
  }], propDecorators: { textInput: [{ type: i0.ViewChild, args: ['textInput', { isSignal: true }] }], fileUploadDirective: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SiFileUploadDirective), { isSignal: true }] }], fileInput: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], sending: [{ type: i0.Input, args: [{ isSignal: true, alias: "sending", required: false }] }], interruptible: [{ type: i0.Input, args: [{ isSignal: true, alias: "interruptible", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], disclaimer: [{ type: i0.Input, args: [{ isSignal: true, alias: "disclaimer", required: false }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], secondaryActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryActions", required: false }] }], allowAttachments: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowAttachments", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], maxFileSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFileSize", required: false }] }], attachments: [{ type: i0.Input, args: [{ isSignal: true, alias: "attachments", required: false }] }, { type: i0.Output, args: ["attachmentsChange"] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], actionParam: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionParam", required: false }] }], sendButtonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendButtonLabel", required: false }] }], sendButtonIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendButtonIcon", required: false }] }], interruptButtonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "interruptButtonLabel", required: false }] }], autoFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFocus", required: false }] }], attachFileLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "attachFileLabel", required: false }] }], removeAttachmentLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeAttachmentLabel", required: false }] }], secondaryActionsLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryActionsLabel", required: false }] }], send: [{ type: i0.Output, args: ["send"] }], interrupt: [{ type: i0.Output, args: ["interrupt"] }], fileError: [{ type: i0.Output, args: ["fileError"] }] } });
899
896
 
900
897
  /**
@@ -1029,7 +1026,7 @@ class SiUserMessageComponent {
1029
1026
  });
1030
1027
  }
1031
1028
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiUserMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1032
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiUserMessageComponent, isStandalone: true, selector: "si-user-message", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, contentFormatter: { classPropertyName: "contentFormatter", publicName: "contentFormatter", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, secondaryActions: { classPropertyName: "secondaryActions", publicName: "secondaryActions", isSignal: true, isRequired: false, transformFunction: null }, attachments: { classPropertyName: "attachments", publicName: "attachments", isSignal: true, isRequired: false, transformFunction: null }, actionParam: { classPropertyName: "actionParam", publicName: "actionParam", isSignal: true, isRequired: false, transformFunction: null }, secondaryActionsLabel: { classPropertyName: "secondaryActionsLabel", publicName: "secondaryActionsLabel", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "formattedContent", first: true, predicate: ["formattedContent"], descendants: true, isSignal: true }], ngImport: i0, template: "<si-chat-message alignment=\"end\" actionsPosition=\"bottom\" [loading]=\"false\">\n @if (hasAttachments()) {\n <si-attachment-list alignment=\"end\" [attachments]=\"attachments()\" [removable]=\"false\" />\n }\n\n @if (content()) {\n @let content = textContent();\n @if (content) {\n <span class=\"text-pre-wrap\">{{ content }}</span>\n } @else {\n <div #formattedContent> </div>\n }\n }\n @if (actions().length > 0 || secondaryActions().length > 0) {\n <div class=\"btn-group user-message-actions\" role=\"group\" siChatMessageAction>\n @for (action of actions(); track $index) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [disabled]=\"action.disabled\"\n [attr.aria-label]=\"action.label | translate\"\n (click)=\"action.action(actionParam(), action)\"\n >\n <si-icon [icon]=\"action.icon\" />\n </button>\n }\n\n @if (secondaryActions().length > 0) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [cdkMenuTriggerFor]=\"secondaryActionsMenu\"\n [attr.aria-label]=\"secondaryActionsLabel() | translate\"\n [attr.title]=\"secondaryActionsLabel() | translate\"\n >\n <si-icon [icon]=\"icons.elementOptionsVertical\" />\n </button>\n\n <ng-template #secondaryActionsMenu>\n <si-menu-factory [items]=\"secondaryActions()\" [actionParam]=\"actionParam()\" />\n </ng-template>\n }\n </div>\n }\n</si-chat-message>\n", styles: [":host{display:block}:host:not(:has([siChatMessageAction])) si-chat-message{padding-block-end:36px!important}.user-message-actions{opacity:0;transition:opacity .2s ease}si-chat-message{--chat-message-bubble-bg: var(--element-base-4);max-inline-size:600px;margin-inline-start:auto}:host:hover .user-message-actions,.user-message-actions:hover,.user-message-actions:has(::ng-deep [aria-expanded=true]),:host-context(.si-container-xs,.si-container-sm) .user-message-actions:active{opacity:1}\n"], dependencies: [{ kind: "directive", type: CdkMenuTrigger, selector: "[cdkMenuTriggerFor]", inputs: ["cdkMenuTriggerFor", "cdkMenuPosition", "cdkMenuTriggerData", "cdkMenuTriggerTransformOriginOn"], outputs: ["cdkMenuOpened", "cdkMenuClosed"], exportAs: ["cdkMenuTriggerFor"] }, { kind: "component", type: SiAttachmentListComponent, selector: "si-attachment-list", inputs: ["attachments", "alignment", "removable", "removeLabel"], outputs: ["remove"] }, { kind: "component", type: SiChatMessageComponent, selector: "si-chat-message", inputs: ["loading", "alignment", "actionsPosition"] }, { kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "component", type: SiMenuFactoryComponent, selector: "si-menu-factory", inputs: ["items", "actionParam"] }, { kind: "directive", type: SiChatMessageActionDirective, selector: "[siChatMessageAction]" }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }] });
1029
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiUserMessageComponent, isStandalone: true, selector: "si-user-message", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, contentFormatter: { classPropertyName: "contentFormatter", publicName: "contentFormatter", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, secondaryActions: { classPropertyName: "secondaryActions", publicName: "secondaryActions", isSignal: true, isRequired: false, transformFunction: null }, attachments: { classPropertyName: "attachments", publicName: "attachments", isSignal: true, isRequired: false, transformFunction: null }, actionParam: { classPropertyName: "actionParam", publicName: "actionParam", isSignal: true, isRequired: false, transformFunction: null }, secondaryActionsLabel: { classPropertyName: "secondaryActionsLabel", publicName: "secondaryActionsLabel", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "formattedContent", first: true, predicate: ["formattedContent"], descendants: true, isSignal: true }], ngImport: i0, template: "<si-chat-message alignment=\"end\" actionsPosition=\"bottom\" [loading]=\"false\">\n @if (hasAttachments()) {\n <si-attachment-list alignment=\"end\" [attachments]=\"attachments()\" [removable]=\"false\" />\n }\n\n @if (content()) {\n @let content = textContent();\n @if (content) {\n <span class=\"text-pre-wrap\">{{ content }}</span>\n } @else {\n <div #formattedContent> </div>\n }\n }\n @if (actions().length > 0 || secondaryActions().length > 0) {\n <div class=\"btn-group user-message-actions\" role=\"group\" siChatMessageAction>\n @for (action of actions(); track $index) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [disabled]=\"action.disabled\"\n [attr.aria-label]=\"action.label | translate\"\n (click)=\"action.action(actionParam(), action)\"\n >\n <si-icon [icon]=\"action.icon\" />\n </button>\n }\n\n @if (secondaryActions().length > 0) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [cdkMenuTriggerFor]=\"secondaryActionsMenu\"\n [attr.aria-label]=\"secondaryActionsLabel() | translate\"\n [attr.title]=\"secondaryActionsLabel() | translate\"\n >\n <si-icon [icon]=\"icons.elementOptionsVertical\" />\n </button>\n\n <ng-template #secondaryActionsMenu>\n <si-menu-factory [items]=\"secondaryActions()\" [actionParam]=\"actionParam()\" />\n </ng-template>\n }\n </div>\n }\n</si-chat-message>\n", styles: [":host{display:block}:host:not(:has([siChatMessageAction])) si-chat-message{padding-block-end:36px!important}.user-message-actions{opacity:0;transition:opacity .2s ease}si-chat-message{--chat-message-bubble-bg: var(--element-base-4);max-inline-size:600px;margin-inline-start:auto}:host:hover .user-message-actions,.user-message-actions:hover,.user-message-actions:has(::ng-deep [aria-expanded=true]),:host-context(.si-container-xs,.si-container-sm) .user-message-actions:active{opacity:1}\n"], dependencies: [{ kind: "directive", type: CdkMenuTrigger, selector: "[cdkMenuTriggerFor]", inputs: ["cdkMenuTriggerFor", "cdkMenuPosition", "cdkMenuTriggerData", "cdkMenuTriggerTransformOriginOn"], outputs: ["cdkMenuOpened", "cdkMenuClosed"], exportAs: ["cdkMenuTriggerFor"] }, { kind: "component", type: SiAttachmentListComponent, selector: "si-attachment-list", inputs: ["attachments", "alignment", "removable", "removeLabel"], outputs: ["remove"] }, { kind: "component", type: SiChatMessageComponent, selector: "si-chat-message", inputs: ["loading", "alignment", "actionsPosition"] }, { kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }, { kind: "component", type: SiMenuFactoryComponent, selector: "si-menu-factory", inputs: ["items", "actionParam"] }, { kind: "directive", type: SiChatMessageActionDirective, selector: "[siChatMessageAction]" }, { kind: "pipe", type: SiTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1033
1030
  }
1034
1031
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiUserMessageComponent, decorators: [{
1035
1032
  type: Component,
@@ -1041,7 +1038,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImpor
1041
1038
  SiMenuFactoryComponent,
1042
1039
  SiChatMessageActionDirective,
1043
1040
  SiTranslatePipe
1044
- ], template: "<si-chat-message alignment=\"end\" actionsPosition=\"bottom\" [loading]=\"false\">\n @if (hasAttachments()) {\n <si-attachment-list alignment=\"end\" [attachments]=\"attachments()\" [removable]=\"false\" />\n }\n\n @if (content()) {\n @let content = textContent();\n @if (content) {\n <span class=\"text-pre-wrap\">{{ content }}</span>\n } @else {\n <div #formattedContent> </div>\n }\n }\n @if (actions().length > 0 || secondaryActions().length > 0) {\n <div class=\"btn-group user-message-actions\" role=\"group\" siChatMessageAction>\n @for (action of actions(); track $index) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [disabled]=\"action.disabled\"\n [attr.aria-label]=\"action.label | translate\"\n (click)=\"action.action(actionParam(), action)\"\n >\n <si-icon [icon]=\"action.icon\" />\n </button>\n }\n\n @if (secondaryActions().length > 0) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [cdkMenuTriggerFor]=\"secondaryActionsMenu\"\n [attr.aria-label]=\"secondaryActionsLabel() | translate\"\n [attr.title]=\"secondaryActionsLabel() | translate\"\n >\n <si-icon [icon]=\"icons.elementOptionsVertical\" />\n </button>\n\n <ng-template #secondaryActionsMenu>\n <si-menu-factory [items]=\"secondaryActions()\" [actionParam]=\"actionParam()\" />\n </ng-template>\n }\n </div>\n }\n</si-chat-message>\n", styles: [":host{display:block}:host:not(:has([siChatMessageAction])) si-chat-message{padding-block-end:36px!important}.user-message-actions{opacity:0;transition:opacity .2s ease}si-chat-message{--chat-message-bubble-bg: var(--element-base-4);max-inline-size:600px;margin-inline-start:auto}:host:hover .user-message-actions,.user-message-actions:hover,.user-message-actions:has(::ng-deep [aria-expanded=true]),:host-context(.si-container-xs,.si-container-sm) .user-message-actions:active{opacity:1}\n"] }]
1041
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<si-chat-message alignment=\"end\" actionsPosition=\"bottom\" [loading]=\"false\">\n @if (hasAttachments()) {\n <si-attachment-list alignment=\"end\" [attachments]=\"attachments()\" [removable]=\"false\" />\n }\n\n @if (content()) {\n @let content = textContent();\n @if (content) {\n <span class=\"text-pre-wrap\">{{ content }}</span>\n } @else {\n <div #formattedContent> </div>\n }\n }\n @if (actions().length > 0 || secondaryActions().length > 0) {\n <div class=\"btn-group user-message-actions\" role=\"group\" siChatMessageAction>\n @for (action of actions(); track $index) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [disabled]=\"action.disabled\"\n [attr.aria-label]=\"action.label | translate\"\n (click)=\"action.action(actionParam(), action)\"\n >\n <si-icon [icon]=\"action.icon\" />\n </button>\n }\n\n @if (secondaryActions().length > 0) {\n <button\n type=\"button\"\n class=\"btn btn-tertiary-ghost btn-icon\"\n [cdkMenuTriggerFor]=\"secondaryActionsMenu\"\n [attr.aria-label]=\"secondaryActionsLabel() | translate\"\n [attr.title]=\"secondaryActionsLabel() | translate\"\n >\n <si-icon [icon]=\"icons.elementOptionsVertical\" />\n </button>\n\n <ng-template #secondaryActionsMenu>\n <si-menu-factory [items]=\"secondaryActions()\" [actionParam]=\"actionParam()\" />\n </ng-template>\n }\n </div>\n }\n</si-chat-message>\n", styles: [":host{display:block}:host:not(:has([siChatMessageAction])) si-chat-message{padding-block-end:36px!important}.user-message-actions{opacity:0;transition:opacity .2s ease}si-chat-message{--chat-message-bubble-bg: var(--element-base-4);max-inline-size:600px;margin-inline-start:auto}:host:hover .user-message-actions,.user-message-actions:hover,.user-message-actions:has(::ng-deep [aria-expanded=true]),:host-context(.si-container-xs,.si-container-sm) .user-message-actions:active{opacity:1}\n"] }]
1045
1042
  }], ctorParameters: () => [], propDecorators: { formattedContent: [{ type: i0.ViewChild, args: ['formattedContent', { isSignal: true }] }], content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }], contentFormatter: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentFormatter", required: false }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], secondaryActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryActions", required: false }] }], attachments: [{ type: i0.Input, args: [{ isSignal: true, alias: "attachments", required: false }] }], actionParam: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionParam", required: false }] }], secondaryActionsLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryActionsLabel", required: false }] }] } });
1046
1043
 
1047
1044
  /**
@@ -1093,11 +1090,11 @@ class SiAiWelcomeScreenComponent {
1093
1090
  this.promptSelected.emit(suggestion);
1094
1091
  }
1095
1092
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiAiWelcomeScreenComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1096
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiAiWelcomeScreenComponent, isStandalone: true, selector: "si-ai-welcome-screen", inputs: { categories: { classPropertyName: "categories", publicName: "categories", isSignal: true, isRequired: false, transformFunction: null }, selectedCategory: { classPropertyName: "selectedCategory", publicName: "selectedCategory", isSignal: true, isRequired: false, transformFunction: null }, promptSuggestions: { classPropertyName: "promptSuggestions", publicName: "promptSuggestions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedCategory: "selectedCategoryChange", promptSelected: "promptSelected" }, host: { classAttribute: "d-block" }, ngImport: i0, template: "<div class=\"d-flex flex-column gap-10 align-items-center w-100\">\n <!-- Welcome Header -->\n <div class=\"welcome-header d-flex flex-column gap-4 w-100 pt-10 pb-8\">\n <ng-content />\n </div>\n\n <!-- Prompt Categories and Suggestions -->\n <div class=\"prompt-suggestions d-flex flex-column gap-6 align-items-center w-100\">\n @if (categories().length > 0) {\n <div class=\"d-flex gap-4 align-items-center w-100\">\n @for (category of categories(); track $index) {\n <si-summary-chip\n class=\"user-select-none\"\n [label]=\"category.label\"\n [selected]=\"selectedCategory() === category.label\"\n (selectedChange)=\"onCategoryClick(category.label)\"\n />\n }\n </div>\n }\n\n @if (promptSuggestions().length > 0) {\n <div class=\"d-flex flex-column gap-4 w-100\">\n @for (suggestion of promptSuggestions(); track $index) {\n <button si-action-card type=\"button\" class=\"w-100\" (click)=\"onPromptClick(suggestion)\">\n <div body class=\"card-body card-text\">\n {{ suggestion.text }}\n </div>\n </button>\n }\n </div>\n }\n </div>\n</div>\n", styles: [".welcome-header{max-inline-size:720px;overflow-x:visible;position:relative}.welcome-header:before{position:absolute;content:\"\";inset-inline-start:-104px;inset-block-start:50%;transform:translateY(-50%);inline-size:168px;block-size:168px;background-image:var(--element-brand-ai-key-visual);background-size:contain;background-repeat:no-repeat;background-position:center}:host{container-type:inline-size}@container (max-width: 767.98px){:host .welcome-header:before{display:none}}.prompt-suggestions{max-inline-size:720px}.prompt-suggestions>div:first-child{flex-wrap:wrap}:host{inline-size:100%}::ng-deep button[si-action-card]{background-color:transparent;border-radius:var(--element-radius-2);border:1px solid var(--element-ui-4)}\n"], dependencies: [{ kind: "component", type: SiActionCardComponent, selector: "button[si-action-card]", inputs: ["selectable", "selected"], outputs: ["selectedChange"] }, { kind: "component", type: SiSummaryChipComponent, selector: "si-summary-chip", inputs: ["status", "icon", "color", "stackedIcon", "stackedColor", "label", "value", "selected", "disabled", "hideLabel"], outputs: ["selectedChange"] }] });
1093
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: SiAiWelcomeScreenComponent, isStandalone: true, selector: "si-ai-welcome-screen", inputs: { categories: { classPropertyName: "categories", publicName: "categories", isSignal: true, isRequired: false, transformFunction: null }, selectedCategory: { classPropertyName: "selectedCategory", publicName: "selectedCategory", isSignal: true, isRequired: false, transformFunction: null }, promptSuggestions: { classPropertyName: "promptSuggestions", publicName: "promptSuggestions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedCategory: "selectedCategoryChange", promptSelected: "promptSelected" }, host: { classAttribute: "d-block" }, ngImport: i0, template: "<div class=\"d-flex flex-column gap-10 align-items-center w-100\">\n <!-- Welcome Header -->\n <div class=\"welcome-header d-flex flex-column gap-4 w-100 pt-10 pb-8\">\n <ng-content />\n </div>\n\n <!-- Prompt Categories and Suggestions -->\n <div class=\"prompt-suggestions d-flex flex-column gap-6 align-items-center w-100\">\n @if (categories().length > 0) {\n <div class=\"d-flex gap-4 align-items-center w-100\">\n @for (category of categories(); track $index) {\n <si-summary-chip\n class=\"user-select-none\"\n [label]=\"category.label\"\n [selected]=\"selectedCategory() === category.label\"\n (selectedChange)=\"onCategoryClick(category.label)\"\n />\n }\n </div>\n }\n\n @if (promptSuggestions().length > 0) {\n <div class=\"d-flex flex-column gap-4 w-100\">\n @for (suggestion of promptSuggestions(); track $index) {\n <button si-action-card type=\"button\" class=\"w-100\" (click)=\"onPromptClick(suggestion)\">\n <div body class=\"card-body card-text\">\n {{ suggestion.text }}\n </div>\n </button>\n }\n </div>\n }\n </div>\n</div>\n", styles: [".welcome-header{max-inline-size:720px;overflow-x:visible;position:relative}.welcome-header:before{position:absolute;content:\"\";inset-inline-start:-104px;inset-block-start:50%;transform:translateY(-50%);inline-size:168px;block-size:168px;background-image:var(--element-brand-ai-key-visual);background-size:contain;background-repeat:no-repeat;background-position:center}:host{container-type:inline-size}@container (max-width: 767.98px){:host .welcome-header:before{display:none}}.prompt-suggestions{max-inline-size:720px}.prompt-suggestions>div:first-child{flex-wrap:wrap}:host{inline-size:100%}::ng-deep button[si-action-card]{background-color:transparent;border-radius:var(--element-radius-2);border:1px solid var(--element-ui-4)}\n"], dependencies: [{ kind: "component", type: SiActionCardComponent, selector: "button[si-action-card]", inputs: ["selectable", "selected"], outputs: ["selectedChange"] }, { kind: "component", type: SiSummaryChipComponent, selector: "si-summary-chip", inputs: ["status", "icon", "color", "stackedIcon", "stackedColor", "label", "value", "selected", "disabled", "hideLabel"], outputs: ["selectedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1097
1094
  }
1098
1095
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiAiWelcomeScreenComponent, decorators: [{
1099
1096
  type: Component,
1100
- args: [{ selector: 'si-ai-welcome-screen', imports: [SiActionCardComponent, SiSummaryChipComponent], host: {
1097
+ args: [{ selector: 'si-ai-welcome-screen', imports: [SiActionCardComponent, SiSummaryChipComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
1101
1098
  class: 'd-block'
1102
1099
  }, template: "<div class=\"d-flex flex-column gap-10 align-items-center w-100\">\n <!-- Welcome Header -->\n <div class=\"welcome-header d-flex flex-column gap-4 w-100 pt-10 pb-8\">\n <ng-content />\n </div>\n\n <!-- Prompt Categories and Suggestions -->\n <div class=\"prompt-suggestions d-flex flex-column gap-6 align-items-center w-100\">\n @if (categories().length > 0) {\n <div class=\"d-flex gap-4 align-items-center w-100\">\n @for (category of categories(); track $index) {\n <si-summary-chip\n class=\"user-select-none\"\n [label]=\"category.label\"\n [selected]=\"selectedCategory() === category.label\"\n (selectedChange)=\"onCategoryClick(category.label)\"\n />\n }\n </div>\n }\n\n @if (promptSuggestions().length > 0) {\n <div class=\"d-flex flex-column gap-4 w-100\">\n @for (suggestion of promptSuggestions(); track $index) {\n <button si-action-card type=\"button\" class=\"w-100\" (click)=\"onPromptClick(suggestion)\">\n <div body class=\"card-body card-text\">\n {{ suggestion.text }}\n </div>\n </button>\n }\n </div>\n }\n </div>\n</div>\n", styles: [".welcome-header{max-inline-size:720px;overflow-x:visible;position:relative}.welcome-header:before{position:absolute;content:\"\";inset-inline-start:-104px;inset-block-start:50%;transform:translateY(-50%);inline-size:168px;block-size:168px;background-image:var(--element-brand-ai-key-visual);background-size:contain;background-repeat:no-repeat;background-position:center}:host{container-type:inline-size}@container (max-width: 767.98px){:host .welcome-header:before{display:none}}.prompt-suggestions{max-inline-size:720px}.prompt-suggestions>div:first-child{flex-wrap:wrap}:host{inline-size:100%}::ng-deep button[si-action-card]{background-color:transparent;border-radius:var(--element-radius-2);border:1px solid var(--element-ui-4)}\n"] }]
1103
1100
  }], propDecorators: { categories: [{ type: i0.Input, args: [{ isSignal: true, alias: "categories", required: false }] }], selectedCategory: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedCategory", required: false }] }, { type: i0.Output, args: ["selectedCategoryChange"] }], promptSuggestions: [{ type: i0.Input, args: [{ isSignal: true, alias: "promptSuggestions", required: false }] }], promptSelected: [{ type: i0.Output, args: ["promptSelected"] }] } });