@basis-ng/primitives 0.0.1-alpha.9 → 0.0.1-alpha.91

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 (47) hide show
  1. package/fesm2022/basis-ng-primitives.mjs +2344 -1291
  2. package/fesm2022/basis-ng-primitives.mjs.map +1 -1
  3. package/index.d.ts +1754 -3
  4. package/package.json +11 -3
  5. package/core/components/alert/alert.component.d.ts +0 -20
  6. package/core/components/attached-box/attached-box.component.d.ts +0 -125
  7. package/core/components/attached-box/types/alignment.type.d.ts +0 -1
  8. package/core/components/attached-box/types/direction.type.d.ts +0 -1
  9. package/core/components/badge/badge.component.d.ts +0 -9
  10. package/core/components/bottom-sheet/bottom-sheet.component.d.ts +0 -60
  11. package/core/components/button/button.component.d.ts +0 -22
  12. package/core/components/button-group/button-group.component.d.ts +0 -9
  13. package/core/components/checkbox/checkbox.component.d.ts +0 -26
  14. package/core/components/color-picker/color-picker.component.d.ts +0 -61
  15. package/core/components/icon/icon.component.d.ts +0 -29
  16. package/core/components/input/input.component.d.ts +0 -78
  17. package/core/components/input-group/input-group.component.d.ts +0 -13
  18. package/core/components/menu/menu.component.d.ts +0 -9
  19. package/core/components/menu/shared/components/menu-item/menu-item.component.d.ts +0 -9
  20. package/core/components/menu/shared/components/menu-item-checkbox/menu-item-checkbox.component.d.ts +0 -9
  21. package/core/components/menu/shared/components/menu-item-radio/menu-item-radio.component.d.ts +0 -9
  22. package/core/components/menu/shared/components/menu-label/menu-label.component.d.ts +0 -8
  23. package/core/components/menu/shared/directives/menu-trigger.directive.d.ts +0 -14
  24. package/core/components/range/range.component.d.ts +0 -26
  25. package/core/components/select/select-options.component.d.ts +0 -51
  26. package/core/components/select/select.component.d.ts +0 -127
  27. package/core/components/side-sheet/side-sheet.component.d.ts +0 -46
  28. package/core/components/spinner/spinner.component.d.ts +0 -9
  29. package/core/components/switch/switch.component.d.ts +0 -35
  30. package/core/components/table/components/row/components/row-item/row-item.component.d.ts +0 -12
  31. package/core/components/table/components/row/row.component.d.ts +0 -9
  32. package/core/components/table/table.component.d.ts +0 -5
  33. package/core/components/tabs/components/tab/tab.component.d.ts +0 -25
  34. package/core/components/tabs/tabs.component.d.ts +0 -60
  35. package/core/components/textarea/textarea.component.d.ts +0 -48
  36. package/core/components/tooltip/tooltip.component.d.ts +0 -36
  37. package/core/components/tree/shared/components/tree-node/tree-node.component.d.ts +0 -43
  38. package/core/components/tree/tree.component.d.ts +0 -56
  39. package/core/directives/in-viewport.directive.d.ts +0 -13
  40. package/core/services/in-viewport.service.d.ts +0 -23
  41. package/core/services/responsive.service.d.ts +0 -47
  42. package/core/services/theme.service.d.ts +0 -44
  43. package/public-api.d.ts +0 -41
  44. package/shared/components/label.component.d.ts +0 -30
  45. package/shared/components/option.component.d.ts +0 -22
  46. package/shared/directives/lazy-content.directive.d.ts +0 -7
  47. package/shared/types/position.type.d.ts +0 -1
@@ -1,18 +1,25 @@
1
1
  import * as i0 from '@angular/core';
2
- import { signal, inject, RendererFactory2, Injectable, input, Component, ElementRef, TemplateRef, Directive, model, computed, output, contentChildren, viewChild, contentChild, linkedSignal, forwardRef, effect, HostListener, afterNextRender, afterRenderEffect } from '@angular/core';
3
- import { NgStyle, NgClass, CommonModule } from '@angular/common';
2
+ import { signal, inject, RendererFactory2, PLATFORM_ID, Injectable, input, ElementRef, Component, TemplateRef, Directive, computed, model, linkedSignal, output, effect, contentChildren, contentChild, forwardRef, HostListener, afterRenderEffect, ViewEncapsulation, ChangeDetectorRef, Pipe } from '@angular/core';
3
+ import { isPlatformBrowser, NgClass, NgStyle, CommonModule } from '@angular/common';
4
4
  import { NgModel, NG_VALUE_ACCESSOR, ControlContainer } from '@angular/forms';
5
- import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay';
6
- import * as i1 from '@angular/cdk/listbox';
7
- import { CdkOption, CdkListbox } from '@angular/cdk/listbox';
8
- import { DomSanitizer } from '@angular/platform-browser';
9
- import { icons, createElement } from 'lucide';
10
- import * as i1$1 from '@angular/cdk/drag-drop';
5
+ import * as i1 from '@angular/cdk/overlay';
6
+ import { CdkConnectedOverlay, Overlay, CdkOverlayOrigin } from '@angular/cdk/overlay';
7
+ import { ActiveDescendantKeyManager, CdkTrapFocus } from '@angular/cdk/a11y';
8
+ import * as i1$1 from '@angular/cdk/listbox';
9
+ import { CdkListbox, CdkOption } from '@angular/cdk/listbox';
10
+ import { ConnectedOverlay as ConnectedOverlay$1 } from 'projects/primitives/src/core/directives/connected-overlay';
11
+ import { NgIcon, provideIcons } from '@ng-icons/core';
12
+ import { lucideLoaderCircle, lucideLoader, lucideGripVertical, lucideX } from '@ng-icons/lucide';
13
+ import * as i1$2 from '@angular/cdk/drag-drop';
11
14
  import { CdkDrag, CdkDragHandle, CdkDropList, CdkDropListGroup } from '@angular/cdk/drag-drop';
12
- import * as i1$2 from '@angular/cdk/menu';
13
- import { CdkMenu, CdkMenuItem, CdkMenuItemCheckbox, CdkMenuItemRadio, CdkMenuTrigger } from '@angular/cdk/menu';
15
+ import * as i1$3 from '@angular/cdk/menu';
16
+ import { CdkMenu, CdkMenuGroup, CdkMenuItem, CdkMenuItemCheckbox, CdkMenuItemRadio, CdkMenuTrigger } from '@angular/cdk/menu';
17
+ import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
18
+ import { CdkDialogContainer, DialogRef, Dialog as Dialog$1 } from '@angular/cdk/dialog';
19
+ import { CdkPortalOutlet } from '@angular/cdk/portal';
20
+ import { HttpClient } from '@angular/common/http';
14
21
 
15
- class ThemeService {
22
+ class ThemeManager {
16
23
  /**
17
24
  * Signal representing the current theme.
18
25
  *
@@ -21,7 +28,7 @@ class ThemeService {
21
28
  * - `'dark'`: Dark theme.
22
29
  * - `'auto'`: Automatically determine the theme.
23
30
  */
24
- theme = signal('auto');
31
+ theme = signal('auto', ...(ngDevMode ? [{ debugName: "theme" }] : []));
25
32
  /**
26
33
  * Renderer2 instance for manipulating the DOM.
27
34
  * Used to set the `data-theme` attribute on the document root (`<html>`).
@@ -32,6 +39,14 @@ class ThemeService {
32
39
  * Injected to create the renderer.
33
40
  */
34
41
  rendererFactory = inject(RendererFactory2);
42
+ /**
43
+ * PLATFORM_ID token to identify the platform.
44
+ */
45
+ platformId = inject(PLATFORM_ID);
46
+ /**
47
+ * Flag indicating whether the application is running in a browser.
48
+ */
49
+ isBrowser = isPlatformBrowser(this.platformId);
35
50
  constructor() {
36
51
  this.renderer = this.rendererFactory.createRenderer(null, null);
37
52
  }
@@ -49,7 +64,10 @@ class ThemeService {
49
64
  this.removeTheme();
50
65
  return;
51
66
  }
52
- this.renderer.setAttribute(document.documentElement, 'data-theme', theme);
67
+ if (this.isBrowser) {
68
+ // Safe DOM access only in browser
69
+ this.renderer.setAttribute(document.documentElement, 'data-theme', theme);
70
+ }
53
71
  }
54
72
  /**
55
73
  * Toggles the theme between `'light'` and `'dark'`.
@@ -63,71 +81,81 @@ class ThemeService {
63
81
  * This is used when the theme is set to `'auto'`.
64
82
  */
65
83
  removeTheme() {
66
- this.renderer.removeAttribute(document.documentElement, 'data-theme');
84
+ if (this.isBrowser) {
85
+ this.renderer.removeAttribute(document.documentElement, 'data-theme');
86
+ }
67
87
  }
68
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
69
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ThemeService, providedIn: 'root' });
88
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ThemeManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
89
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ThemeManager, providedIn: 'root' });
70
90
  }
71
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ThemeService, decorators: [{
91
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ThemeManager, decorators: [{
72
92
  type: Injectable,
73
93
  args: [{
74
94
  providedIn: 'root',
75
95
  }]
76
96
  }], ctorParameters: () => [] });
77
97
 
78
- class Spinner {
79
- active = input(true);
80
- color = input('var(--foreground)');
81
- backgroundColor = input('transparent');
82
- size = input(20);
83
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Spinner, deps: [], target: i0.ɵɵFactoryTarget.Component });
84
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.7", type: Spinner, isStandalone: true, selector: "b-spinner", inputs: { active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, backgroundColor: { classPropertyName: "backgroundColor", publicName: "backgroundColor", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (active()) {\r\n <section [ngStyle]=\"{ background: backgroundColor() }\" class=\"background\">\r\n <svg\r\n [attr.height]=\"size()\"\r\n [attr.width]=\"size()\"\r\n preserveAspectRatio=\"xMidYMid\"\r\n style=\"\r\n shape-rendering: auto;\r\n display: block;\r\n background: rgba(122, 122, 122, 0);\r\n \"\r\n viewBox=\"0 0 100 100\"\r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <g>\r\n <g transform=\"rotate(0 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.9166666666666666s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(30 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.8333333333333334s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(60 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.75s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(90 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.6666666666666666s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(120 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.5833333333333334s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(150 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.5s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(180 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.4166666666666667s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(210 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.3333333333333333s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(240 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.25s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(270 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.16666666666666666s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(300 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.08333333333333333s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(330 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"0s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g />\r\n </g>\r\n </svg>\r\n </section>\r\n}\r\n", dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
85
- }
86
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Spinner, decorators: [{
87
- type: Component,
88
- args: [{ selector: 'b-spinner', imports: [NgStyle], template: "@if (active()) {\r\n <section [ngStyle]=\"{ background: backgroundColor() }\" class=\"background\">\r\n <svg\r\n [attr.height]=\"size()\"\r\n [attr.width]=\"size()\"\r\n preserveAspectRatio=\"xMidYMid\"\r\n style=\"\r\n shape-rendering: auto;\r\n display: block;\r\n background: rgba(122, 122, 122, 0);\r\n \"\r\n viewBox=\"0 0 100 100\"\r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <g>\r\n <g transform=\"rotate(0 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.9166666666666666s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(30 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.8333333333333334s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(60 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.75s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(90 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.6666666666666666s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(120 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.5833333333333334s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(150 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.5s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(180 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.4166666666666667s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(210 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.3333333333333333s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(240 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.25s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(270 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.16666666666666666s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(300 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"-0.08333333333333333s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g transform=\"rotate(330 50 50)\">\r\n <rect\r\n [attr.fill]=\"color()\"\r\n height=\"20\"\r\n rx=\"3\"\r\n ry=\"3.2800000000000002\"\r\n width=\"6\"\r\n x=\"47\"\r\n y=\"10\">\r\n <animate\r\n attributeName=\"opacity\"\r\n begin=\"0s\"\r\n dur=\"1s\"\r\n keyTimes=\"0;1\"\r\n repeatCount=\"indefinite\"\r\n values=\"1;0\" />\r\n </rect>\r\n </g>\r\n <g />\r\n </g>\r\n </svg>\r\n </section>\r\n}\r\n" }]
89
- }] });
90
-
98
+ /**
99
+ * Button component for displaying a clickable button element with configurable variant, size, and shape.
100
+ *
101
+ * @public
102
+ */
91
103
  class Button {
92
- /** The variant of the button. */
93
- variant = input('primary');
94
- /** The size of the button. */
95
- size = input('default');
96
- /** Whether is loading. */
97
- loading = input(false);
98
- /** Whether the padding should be equal vertically and horizontally. */
99
- equalPadding = input(false);
100
- /** Whether the button is toggleable. */
101
- toggle = input(false);
102
- /** The value of the button when it is toggled. */
103
- isToggled = input(false);
104
- /** Whether the button active animation is enabled. */
105
- activeEnabled = input(true);
106
- /** The element reference of the button. */
104
+ /**
105
+ * The visual variant of the button.
106
+ *
107
+ * @defaultValue 'primary'
108
+ */
109
+ variant = input('primary', ...(ngDevMode ? [{ debugName: "variant" }] : []));
110
+ /**
111
+ * The size of the button.
112
+ *
113
+ * @defaultValue 'md'
114
+ */
115
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
116
+ /**
117
+ * If true, the button will have squared edges.
118
+ *
119
+ * @defaultValue false
120
+ */
121
+ squared = input(false, ...(ngDevMode ? [{ debugName: "squared" }] : []));
122
+ /**
123
+ * Reference to the underlying DOM element.
124
+ */
107
125
  el = inject(ElementRef);
108
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Button, deps: [], target: i0.ɵɵFactoryTarget.Component });
109
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.7", type: Button, isStandalone: true, selector: "button[b-button]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, equalPadding: { classPropertyName: "equalPadding", publicName: "equalPadding", isSignal: true, isRequired: false, transformFunction: null }, toggle: { classPropertyName: "toggle", publicName: "toggle", isSignal: true, isRequired: false, transformFunction: null }, isToggled: { classPropertyName: "isToggled", publicName: "isToggled", isSignal: true, isRequired: false, transformFunction: null }, activeEnabled: { classPropertyName: "activeEnabled", publicName: "activeEnabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "variant() + \" size-\" + size()", "class.equal-padding": "equalPadding()", "class.loading": "loading()", "class.toggled": "isToggled()", "class.active": "activeEnabled()" } }, ngImport: i0, template: "@if (loading()) {\r\n <b-spinner\r\n [active]=\"loading()\"\r\n [size]=\"18\"\r\n [color]=\"\r\n variant() === 'primary'\r\n ? 'var(--primary-foreground)'\r\n : 'var(--secondary-foreground)'\r\n \" />\r\n}\r\n<ng-content />\r\n", dependencies: [{ kind: "component", type: Spinner, selector: "b-spinner", inputs: ["active", "color", "backgroundColor", "size"] }] });
126
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Button, deps: [], target: i0.ɵɵFactoryTarget.Component });
127
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: Button, isStandalone: true, selector: "button[b-button]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, squared: { classPropertyName: "squared", publicName: "squared", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.b-variant-primary": "variant() === \"primary\"", "class.b-variant-secondary": "variant() === \"secondary\"", "class.b-variant-ghost": "variant() === \"ghost\"", "class.b-variant-outlined": "variant() === \"outlined\"", "class.b-variant-destructive": "variant() === \"destructive\"", "class.b-size-sm": "size() === \"sm\"", "class.b-size-md": "size() === \"md\"", "class.b-size-lg": "size() === \"lg\"", "class.b-squared": "squared()" } }, ngImport: i0, template: ` <ng-content /> `, isInline: true });
110
128
  }
111
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Button, decorators: [{
129
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Button, decorators: [{
112
130
  type: Component,
113
- args: [{ selector: 'button[b-button]', imports: [Spinner], host: {
114
- '[class]': 'variant() + " size-" + size()',
115
- '[class.equal-padding]': 'equalPadding()',
116
- '[class.loading]': 'loading()',
117
- '[class.toggled]': 'isToggled()',
118
- '[class.active]': 'activeEnabled()',
119
- }, template: "@if (loading()) {\r\n <b-spinner\r\n [active]=\"loading()\"\r\n [size]=\"18\"\r\n [color]=\"\r\n variant() === 'primary'\r\n ? 'var(--primary-foreground)'\r\n : 'var(--secondary-foreground)'\r\n \" />\r\n}\r\n<ng-content />\r\n" }]
131
+ args: [{
132
+ selector: 'button[b-button]',
133
+ template: ` <ng-content /> `,
134
+ host: {
135
+ '[class.b-variant-primary]': 'variant() === "primary"',
136
+ '[class.b-variant-secondary]': 'variant() === "secondary"',
137
+ '[class.b-variant-ghost]': 'variant() === "ghost"',
138
+ '[class.b-variant-outlined]': 'variant() === "outlined"',
139
+ '[class.b-variant-destructive]': 'variant() === "destructive"',
140
+ '[class.b-size-sm]': 'size() === "sm"',
141
+ '[class.b-size-md]': 'size() === "md"',
142
+ '[class.b-size-lg]': 'size() === "lg"',
143
+ '[class.b-squared]': 'squared()',
144
+ },
145
+ }]
120
146
  }] });
121
147
 
122
148
  class ButtonGroup {
123
149
  /**
124
150
  * Whether the buttons should be spaced.
151
+ *
152
+ * @defaultValue false
125
153
  */
126
- spaced = input(false);
127
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ButtonGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
128
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.7", type: ButtonGroup, isStandalone: true, selector: "b-button-group", inputs: { spaced: { classPropertyName: "spaced", publicName: "spaced", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.spaced": "spaced()" }, classAttribute: "button-group" }, ngImport: i0, template: `<ng-content />`, isInline: true });
154
+ spaced = input(false, ...(ngDevMode ? [{ debugName: "spaced" }] : []));
155
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ButtonGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
156
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: ButtonGroup, isStandalone: true, selector: "b-button-group", inputs: { spaced: { classPropertyName: "spaced", publicName: "spaced", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.spaced": "spaced()" }, classAttribute: "button-group" }, ngImport: i0, template: `<ng-content />`, isInline: true });
129
157
  }
130
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ButtonGroup, decorators: [{
158
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ButtonGroup, decorators: [{
131
159
  type: Component,
132
160
  args: [{
133
161
  selector: 'b-button-group',
@@ -141,10 +169,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
141
169
 
142
170
  class LazyContentDirective {
143
171
  tpl = inject(TemplateRef);
144
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: LazyContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
145
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.7", type: LazyContentDirective, isStandalone: true, selector: "[b-lazy]", ngImport: i0 });
172
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: LazyContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
173
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.3", type: LazyContentDirective, isStandalone: true, selector: "[b-lazy]", ngImport: i0 });
146
174
  }
147
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: LazyContentDirective, decorators: [{
175
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: LazyContentDirective, decorators: [{
148
176
  type: Directive,
149
177
  args: [{
150
178
  selector: '[b-lazy]',
@@ -156,47 +184,19 @@ class Input {
156
184
  /**
157
185
  * The type of the input.
158
186
  */
159
- type = input('text');
160
- /**
161
- * The placeholder text for the input.
162
- */
163
- placeholder = input('');
164
- /**
165
- * The value of the input.
166
- */
167
- value = signal(null);
168
- /**
169
- * Whether the input is invalid.
170
- */
171
- invalid = model(false);
172
- /**
173
- * Whether the input is disabled.
174
- */
175
- disabled = model(false);
176
- /**
177
- * The maximum width of the input.
178
- */
179
- maxWidth = input('');
187
+ type = input('text', ...(ngDevMode ? [{ debugName: "type" }] : []));
180
188
  /**
181
189
  * The number of decimal places for number input.
182
190
  */
183
- decimals = input(2);
191
+ decimals = input(2, ...(ngDevMode ? [{ debugName: "decimals" }] : []));
184
192
  /**
185
193
  * The type of number input (integer or decimal).
186
194
  */
187
- numberType = input('integer');
195
+ numberType = input('integer', ...(ngDevMode ? [{ debugName: "numberType" }] : []));
188
196
  /**
189
197
  * Whether the input type is number.
190
198
  */
191
- isNumberType = computed(() => this.type() === 'number');
192
- /**
193
- * Whether the input is focused.
194
- */
195
- focused = signal(false);
196
- /**
197
- * Event emitted when the value changes.
198
- */
199
- valueChange = output();
199
+ isNumberType = computed(() => this.type() === 'number', ...(ngDevMode ? [{ debugName: "isNumberType" }] : []));
200
200
  /**
201
201
  * Reference to the input element.
202
202
  */
@@ -205,12 +205,26 @@ class Input {
205
205
  * Reference to the ngModel directive.
206
206
  */
207
207
  ngModel = inject(NgModel, { optional: true });
208
+ /**
209
+ * The size of the input.
210
+ */
211
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
208
212
  /**
209
213
  * After the view has been initialized, set the value of the select.
210
214
  */
211
215
  ngAfterViewInit() {
212
216
  const value = this.el.nativeElement.value || this.ngModel?.model;
213
- this.value.set(this.isNumberType() ? this.formatNumber(value) : value);
217
+ if (this.isNumberType()) {
218
+ const formattedValue = this.formatNumber(value) || '';
219
+ this.setValue(formattedValue);
220
+ }
221
+ }
222
+ /**
223
+ * Sets the value of the input element.
224
+ * @param value The value to set.
225
+ */
226
+ setValue(value) {
227
+ this.el.nativeElement.value = value;
214
228
  }
215
229
  /**
216
230
  * Handles the input event.
@@ -220,8 +234,7 @@ class Input {
220
234
  const target = event.target;
221
235
  // If the input is not of number type, update the value and emit the value change event.
222
236
  if (!this.isNumberType()) {
223
- this.value.set(target.value);
224
- this.valueChange.emit(target.value);
237
+ this.setValue(target.value);
225
238
  }
226
239
  }
227
240
  /**
@@ -229,13 +242,10 @@ class Input {
229
242
  * @param event - The blur event.
230
243
  */
231
244
  onBlur(event) {
232
- this.focused.set(false);
233
245
  // If the input is of number type, format the value and emit the value change event.
234
246
  if (this.isNumberType()) {
235
247
  const formattedValue = this.formatNumber(event.target.value);
236
- this.el.nativeElement.value = formattedValue || '';
237
- this.value.set(formattedValue);
238
- this.valueChange.emit(formattedValue);
248
+ this.setValue(formattedValue || '');
239
249
  }
240
250
  }
241
251
  /**
@@ -254,332 +264,625 @@ class Input {
254
264
  return null;
255
265
  }
256
266
  }
257
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Input, deps: [], target: i0.ɵɵFactoryTarget.Component });
258
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.7", type: Input, isStandalone: true, selector: "input[b-input]", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, decimals: { classPropertyName: "decimals", publicName: "decimals", isSignal: true, isRequired: false, transformFunction: null }, numberType: { classPropertyName: "numberType", publicName: "numberType", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { invalid: "invalidChange", disabled: "disabledChange", valueChange: "valueChange" }, host: { listeners: { "input": "onInput($event)", "focus": "focused.set(true)", "blur": "onBlur($event)" }, properties: { "type": "type()", "placeholder": "placeholder() || \"\"", "class.ng-invalid": "invalid()", "class.disabled": "disabled()", "style.max-width": "maxWidth()" } }, ngImport: i0, template: ``, isInline: true });
267
+ /**
268
+ * Método público para disparar el formateo como si se hiciera blur.
269
+ */
270
+ blur() {
271
+ if (this.isNumberType()) {
272
+ const value = this.el.nativeElement.value;
273
+ const formattedValue = this.formatNumber(value);
274
+ this.setValue(formattedValue || '');
275
+ }
276
+ }
277
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Input, deps: [], target: i0.ɵɵFactoryTarget.Component });
278
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: Input, isStandalone: true, selector: "input[b-input]", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, decimals: { classPropertyName: "decimals", publicName: "decimals", isSignal: true, isRequired: false, transformFunction: null }, numberType: { classPropertyName: "numberType", publicName: "numberType", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "input": "onInput($event)", "blur": "onBlur($event)" }, properties: { "type": "type()", "class.b-size-sm": "size() === \"sm\"", "class.b-size-md": "size() === \"md\"", "class.b-size-lg": "size() === \"lg\"" } }, exportAs: ["bInput"], ngImport: i0, template: ``, isInline: true });
259
279
  }
260
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Input, decorators: [{
280
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Input, decorators: [{
261
281
  type: Component,
262
282
  args: [{
263
283
  selector: 'input[b-input]',
264
284
  template: ``,
265
285
  host: {
266
286
  '[type]': 'type()',
267
- '[placeholder]': 'placeholder() || ""',
268
- '[class.ng-invalid]': 'invalid()',
269
- '[class.disabled]': 'disabled()',
270
- '[style.max-width]': 'maxWidth()',
271
287
  '(input)': 'onInput($event)',
272
- '(focus)': 'focused.set(true)',
273
288
  '(blur)': 'onBlur($event)',
289
+ '[class.b-size-sm]': 'size() === "sm"',
290
+ '[class.b-size-md]': 'size() === "md"',
291
+ '[class.b-size-lg]': 'size() === "lg"',
274
292
  },
293
+ exportAs: 'bInput',
275
294
  }]
276
295
  }] });
277
296
 
278
297
  /**
279
- * Component representing an individual option in a select or combobox.
280
- * This component integrates with Angular CDK Option to manage the option's state and behavior.
298
+ * Directive to manage overlay behavior and positioning.
299
+ * Integrates with Angular CDK's `CdkConnectedOverlay` to provide
300
+ * flexible overlay positioning and triggering mechanisms.
281
301
  */
282
- class OptionComponent {
302
+ class ConnectedOverlay {
303
+ /**
304
+ * Controls whether the overlay is open.
305
+ * @default false
306
+ */
307
+ open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : []));
308
+ /**
309
+ * The trigger directive that activates the overlay.
310
+ * This input is required.
311
+ */
312
+ trigger = input.required(...(ngDevMode ? [{ debugName: "trigger" }] : []));
313
+ /**
314
+ * A computed map of positions to their corresponding `ConnectedPosition` configurations.
315
+ */
316
+ positionsMap = computed(() => ({
317
+ 'top-left': {
318
+ originX: 'start',
319
+ originY: 'top',
320
+ overlayX: 'start',
321
+ overlayY: 'bottom',
322
+ offsetX: 0,
323
+ offsetY: -4,
324
+ },
325
+ 'top-center': {
326
+ originX: 'center',
327
+ originY: 'top',
328
+ overlayX: 'center',
329
+ overlayY: 'bottom',
330
+ offsetX: 0,
331
+ offsetY: -4,
332
+ },
333
+ 'top-right': {
334
+ originX: 'end',
335
+ originY: 'top',
336
+ overlayX: 'end',
337
+ overlayY: 'bottom',
338
+ offsetX: 0,
339
+ offsetY: -4,
340
+ },
341
+ 'bottom-left': {
342
+ originX: 'start',
343
+ originY: 'bottom',
344
+ overlayX: 'start',
345
+ overlayY: 'top',
346
+ offsetX: 0,
347
+ offsetY: 4,
348
+ },
349
+ 'bottom-center': {
350
+ originX: 'center',
351
+ originY: 'bottom',
352
+ overlayX: 'center',
353
+ overlayY: 'top',
354
+ offsetX: 0,
355
+ offsetY: 4,
356
+ },
357
+ 'bottom-right': {
358
+ originX: 'end',
359
+ originY: 'bottom',
360
+ overlayX: 'end',
361
+ overlayY: 'top',
362
+ offsetX: 0,
363
+ offsetY: 4,
364
+ },
365
+ 'left-top': {
366
+ originX: 'start',
367
+ originY: 'top',
368
+ overlayX: 'end',
369
+ overlayY: 'top',
370
+ offsetX: -4,
371
+ offsetY: 0,
372
+ },
373
+ 'left-center': {
374
+ originX: 'start',
375
+ originY: 'center',
376
+ overlayX: 'end',
377
+ overlayY: 'center',
378
+ offsetX: -4,
379
+ offsetY: 0,
380
+ },
381
+ 'left-bottom': {
382
+ originX: 'start',
383
+ originY: 'bottom',
384
+ overlayX: 'end',
385
+ overlayY: 'bottom',
386
+ offsetX: -4,
387
+ offsetY: 0,
388
+ },
389
+ 'right-top': {
390
+ originX: 'end',
391
+ originY: 'top',
392
+ overlayX: 'start',
393
+ overlayY: 'top',
394
+ offsetX: 4,
395
+ offsetY: 0,
396
+ },
397
+ 'right-center': {
398
+ originX: 'end',
399
+ originY: 'center',
400
+ overlayX: 'start',
401
+ overlayY: 'center',
402
+ offsetX: 4,
403
+ offsetY: 0,
404
+ },
405
+ 'right-bottom': {
406
+ originX: 'end',
407
+ originY: 'bottom',
408
+ overlayX: 'start',
409
+ overlayY: 'bottom',
410
+ offsetX: 4,
411
+ offsetY: 0,
412
+ },
413
+ }), ...(ngDevMode ? [{ debugName: "positionsMap" }] : []));
414
+ /**
415
+ * List of positions for the overlay.
416
+ * @default ['bottom-left']
417
+ */
418
+ positions = input(['bottom-left'], ...(ngDevMode ? [{ debugName: "positions" }] : []));
419
+ /**
420
+ * Controls whether the trigger element should be focused when the overlay is closed.
421
+ * @default true
422
+ */
423
+ focusTriggerOnClose = input(true, ...(ngDevMode ? [{ debugName: "focusTriggerOnClose" }] : []));
424
+ /**
425
+ * Computed list of `ConnectedPosition` objects based on the `positions` input.
426
+ */
427
+ connectedPositions = computed(() => this.positions().map(position => this.positionsMap()[position]), ...(ngDevMode ? [{ debugName: "connectedPositions" }] : []));
428
+ /**
429
+ * Signal to track the currently active `ConnectionPositionPair`.
430
+ */
431
+ connectedPositionPair = linkedSignal(() => this.connectedPositions()[0]);
432
+ /**
433
+ * Injected instance of `CdkConnectedOverlay`.
434
+ */
435
+ cdkConnectedOverlay = inject(CdkConnectedOverlay);
436
+ /**
437
+ * Injected instance of `Overlay`.
438
+ */
439
+ overlay = inject(Overlay);
440
+ /**
441
+ * Computed direction of the overlay based on the active position pair.
442
+ */
443
+ direction = computed(() => {
444
+ const pair = this.connectedPositionPair();
445
+ return Object.entries(this.positionsMap())
446
+ .find(([, position]) => position.originX === pair.originX &&
447
+ position.originY === pair.originY &&
448
+ position.overlayX === pair.overlayX &&
449
+ position.overlayY === pair.overlayY)?.[0]
450
+ .split('-')[0];
451
+ }, ...(ngDevMode ? [{ debugName: "direction" }] : []));
452
+ /**
453
+ * Event emitter for overlay detach events.
454
+ */
455
+ detachEmitter = output();
456
+ /**
457
+ * Event emitter for overlay attach events.
458
+ */
459
+ attachEmitter = output();
460
+ /**
461
+ * Event emitter for overlay outside click events.
462
+ */
463
+ outsideClickEmitter = output();
464
+ /**
465
+ * Event emitter for overlay backdrop click events.
466
+ */
467
+ backdropClickEmitter = output();
283
468
  /**
284
- * The `ElementRef` of the option.
285
- * This provides direct access to the DOM element of the option.
469
+ * Flag to indicate if this is the first load of the overlay.
286
470
  */
287
- el = inject(ElementRef);
471
+ firstLoad = true;
288
472
  /**
289
- * The `CdkOption` instance associated with this option.
290
- * This provides methods and properties for managing the option's state, such as selection and value.
473
+ * Constructor to initialize the directive and set up reactive effects.
291
474
  */
292
- cdkOption = inject(CdkOption);
293
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: OptionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
294
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.7", type: OptionComponent, isStandalone: true, selector: "li[b-option]", hostDirectives: [{ directive: i1.CdkOption, inputs: ["cdkOption", "value"] }], ngImport: i0, template: `<ng-content />`, isInline: true });
475
+ constructor() {
476
+ effect(() => {
477
+ this.handleOrigin();
478
+ this.handleConnectedPositions();
479
+ this.handleOpen();
480
+ });
481
+ }
482
+ /**
483
+ * Handles the origin of the overlay.
484
+ * This method sets the `cdkConnectedOverlay.origin` to the trigger element.
485
+ */
486
+ handleOrigin() {
487
+ this.cdkConnectedOverlay.origin = this.trigger().trigger;
488
+ }
489
+ /**
490
+ * Handles the connected positions for the overlay.
491
+ * This method updates the `cdkConnectedOverlay` positions based on the current state.
492
+ */
493
+ handleConnectedPositions() {
494
+ this.cdkConnectedOverlay.positions = this.connectedPositions();
495
+ }
496
+ /**
497
+ * Handles the opening and closing of the overlay based on the `open` input.
498
+ * Determines whether to open or close the overlay and invokes the appropriate method.
499
+ */
500
+ handleOpen() {
501
+ if (this.open()) {
502
+ this.cdkConnectedOverlay.attachOverlay();
503
+ }
504
+ else {
505
+ this.cdkConnectedOverlay.detachOverlay();
506
+ if (this.focusTriggerOnClose())
507
+ this.trigger().el.nativeElement.focus();
508
+ }
509
+ }
510
+ /**
511
+ * Toggles the open state of the overlay.
512
+ * If the overlay is open, it will be closed, and vice versa.
513
+ */
514
+ toggleOverlay() {
515
+ this.open.set(!this.open());
516
+ }
517
+ /**
518
+ * Closes the overlay by setting the `open` state to false.
519
+ */
520
+ closeOverlay() {
521
+ this.open.set(false);
522
+ }
523
+ /**
524
+ * Opens the overlay by setting the `open` state to true.
525
+ */
526
+ openOverlay() {
527
+ this.open.set(true);
528
+ }
529
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ConnectedOverlay, deps: [], target: i0.ɵɵFactoryTarget.Directive });
530
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.2.3", type: ConnectedOverlay, isStandalone: true, selector: "[bConnectedOverlay]", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: true, transformFunction: null }, positions: { classPropertyName: "positions", publicName: "positions", isSignal: true, isRequired: false, transformFunction: null }, focusTriggerOnClose: { classPropertyName: "focusTriggerOnClose", publicName: "focusTriggerOnClose", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", detachEmitter: "detachEmitter", attachEmitter: "attachEmitter", outsideClickEmitter: "outsideClickEmitter", backdropClickEmitter: "backdropClickEmitter" }, host: { listeners: { "positionChange": "connectedPositionPair.set($event.connectionPair)", "detach": "detachEmitter.emit()", "attach": "attachEmitter.emit()", "outsideClick": "outsideClickEmitter.emit()", "backdropClick": "backdropClickEmitter.emit()" } }, hostDirectives: [{ directive: i1.CdkConnectedOverlay, inputs: ["cdkConnectedOverlayWidth", "width", "cdkConnectedOverlayMinWidth", "minWidth", "cdkConnectedOverlayBackdropClass", "customBackdropClass", "cdkConnectedOverlayPanelClass", "panelClass"], outputs: ["detach", "detach", "attach", "attach", "overlayOutsideClick", "outsideClick", "backdropClick", "backdropClick", "positionChange", "positionChange"] }], ngImport: i0 });
295
531
  }
296
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: OptionComponent, decorators: [{
297
- type: Component,
532
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ConnectedOverlay, decorators: [{
533
+ type: Directive,
298
534
  args: [{
299
- selector: 'li[b-option]',
300
- imports: [],
301
- template: `<ng-content />`,
535
+ selector: '[bConnectedOverlay]',
302
536
  hostDirectives: [
303
537
  {
304
- directive: CdkOption,
305
- inputs: ['cdkOption: value'],
538
+ directive: CdkConnectedOverlay,
539
+ inputs: [
540
+ 'cdkConnectedOverlayWidth: width',
541
+ 'cdkConnectedOverlayMinWidth: minWidth',
542
+ 'cdkConnectedOverlayBackdropClass: customBackdropClass',
543
+ 'cdkConnectedOverlayPanelClass: panelClass',
544
+ ],
545
+ outputs: [
546
+ 'detach: detach',
547
+ 'attach: attach',
548
+ 'overlayOutsideClick: outsideClick',
549
+ 'backdropClick: backdropClick',
550
+ 'positionChange: positionChange',
551
+ ],
306
552
  },
307
553
  ],
554
+ host: {
555
+ '(positionChange)': 'connectedPositionPair.set($event.connectionPair)',
556
+ '(detach)': 'detachEmitter.emit()',
557
+ '(attach)': 'attachEmitter.emit()',
558
+ '(outsideClick)': 'outsideClickEmitter.emit()',
559
+ '(backdropClick)': 'backdropClickEmitter.emit()',
560
+ },
308
561
  }]
309
- }] });
562
+ }], ctorParameters: () => [] });
310
563
 
311
564
  /**
312
- * Component representing the list of options in a select.
313
- * This component integrates with Angular CDK Listbox to manage options and their selection.
565
+ * Component representing the trigger button for the select dropdown.
566
+ * Handles user interactions to open or close the select.
314
567
  */
315
- class SelectOptionsComponent {
316
- /**
317
- * Signal representing the selected values in the listbox.
318
- * This is an array of strings corresponding to the selected option values.
319
- */
320
- value = signal([]);
568
+ class SelectTrigger {
321
569
  /**
322
- * Event emitter triggered when the dropdown should close.
323
- * This is used to notify the parent component to close the dropdown.
324
- */
325
- closeEmitter = output();
326
- /**
327
- * Reference to the host element of the component.
328
- * This provides access to the DOM element of the options list.
570
+ * Reference to the host element of the trigger button.
329
571
  */
330
572
  el = inject(ElementRef);
331
573
  /**
332
- * Input for setting the maximum height of the dropdown.
333
- * Defaults to '300px'. This controls the vertical size of the dropdown.
334
- */
335
- maxHeight = input('300px');
574
+ * Event emitter for button click and keydown events.
575
+ */
576
+ buttonClicked = output();
577
+ /**
578
+ * Signal indicating whether the trigger is disabled.
579
+ */
580
+ disabled = signal(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
581
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: SelectTrigger, deps: [], target: i0.ɵɵFactoryTarget.Component });
582
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.3", type: SelectTrigger, isStandalone: true, selector: "button[b-select-trigger]", outputs: { buttonClicked: "buttonClicked" }, host: { listeners: { "keydown.arrowUp": "buttonClicked.emit()", "keydown.arrowDown": "buttonClicked.emit()", "click": "buttonClicked.emit()" }, properties: { "disabled": "disabled()" } }, ngImport: i0, template: `<ng-content />
583
+ <svg
584
+ xmlns="http://www.w3.org/2000/svg"
585
+ width="16"
586
+ height="16"
587
+ viewBox="0 0 24 24"
588
+ fill="none"
589
+ stroke="currentColor"
590
+ stroke-width="2"
591
+ stroke-linecap="round"
592
+ stroke-linejoin="round"
593
+ class="lucide lucide-chevron-down-icon lucide-chevron-down">
594
+ <path d="m6 9 6 6 6-6" />
595
+ </svg> `, isInline: true });
596
+ }
597
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: SelectTrigger, decorators: [{
598
+ type: Component,
599
+ args: [{
600
+ selector: 'button[b-select-trigger]',
601
+ template: `<ng-content />
602
+ <svg
603
+ xmlns="http://www.w3.org/2000/svg"
604
+ width="16"
605
+ height="16"
606
+ viewBox="0 0 24 24"
607
+ fill="none"
608
+ stroke="currentColor"
609
+ stroke-width="2"
610
+ stroke-linecap="round"
611
+ stroke-linejoin="round"
612
+ class="lucide lucide-chevron-down-icon lucide-chevron-down">
613
+ <path d="m6 9 6 6 6-6" />
614
+ </svg> `,
615
+ host: {
616
+ '(keydown.arrowUp)': 'buttonClicked.emit()',
617
+ '(keydown.arrowDown)': 'buttonClicked.emit()',
618
+ '(click)': 'buttonClicked.emit()',
619
+ '[disabled]': 'disabled()',
620
+ },
621
+ }]
622
+ }] });
623
+
624
+ /**
625
+ * Component for displaying the selected value or a placeholder in the select dropdown.
626
+ */
627
+ class SelectValue {
336
628
  /**
337
- * Reference to the CDK Listbox directive.
338
- * This is used to manage the options and their selection state.
629
+ * Reference to the host element of the value display.
339
630
  */
340
- listBox = inject(CdkListbox);
631
+ el = inject(ElementRef);
341
632
  /**
342
- * Reference to the list of options in the dropdown.
343
- * This is a collection of `OptionComponent` instances representing the available options.
633
+ * Signal holding the display content for the selected value.
344
634
  */
345
- options = contentChildren(OptionComponent);
635
+ content = signal('', ...(ngDevMode ? [{ debugName: "content" }] : []));
346
636
  /**
347
- * Handles changes to the selected value in the listbox.
348
- * This method updates the `value` signal, emits the `closeEmitter` event,
349
- * and ensures the parent component is notified of the selection change.
350
- *
351
- * @param value - The new array of selected values.
637
+ * Input signal for the placeholder text when no value is selected.
638
+ * @param value - The placeholder string to display.
352
639
  */
353
- handleValueChange(value) {
354
- this.value.set(value);
355
- this.closeEmitter.emit();
356
- }
357
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SelectOptionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
358
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.7", type: SelectOptionsComponent, isStandalone: true, selector: "ul[b-select-options]", inputs: { maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closeEmitter: "closeEmitter" }, host: { listeners: { "cdkListboxValueChange": "handleValueChange($event.value)" }, properties: { "cdkListboxValue": "value()", "style.max-height": "maxHeight()" } }, queries: [{ propertyName: "options", predicate: OptionComponent, isSignal: true }], hostDirectives: [{ directive: i1.CdkListbox, inputs: ["cdkListboxValue", "cdkListboxValue"], outputs: ["cdkListboxValueChange", "cdkListboxValueChange"] }], ngImport: i0, template: `<ng-content />`, isInline: true });
640
+ placeholder = input('Select an option', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
641
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: SelectValue, deps: [], target: i0.ɵɵFactoryTarget.Component });
642
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: SelectValue, isStandalone: true, selector: "b-select-value", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `{{ content() || placeholder() }}`, isInline: true });
359
643
  }
360
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SelectOptionsComponent, decorators: [{
644
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: SelectValue, decorators: [{
361
645
  type: Component,
362
646
  args: [{
363
- selector: 'ul[b-select-options]',
364
- imports: [],
365
- template: `<ng-content />`,
366
- hostDirectives: [
367
- {
368
- directive: CdkListbox,
369
- inputs: ['cdkListboxValue'],
370
- outputs: ['cdkListboxValueChange'],
371
- },
372
- ],
373
- host: {
374
- '[cdkListboxValue]': 'value()',
375
- '(cdkListboxValueChange)': 'handleValueChange($event.value)',
376
- '[style.max-height]': 'maxHeight()',
377
- },
647
+ selector: 'b-select-value',
648
+ template: `{{ content() || placeholder() }}`,
378
649
  }]
379
650
  }] });
380
651
 
381
- class Icon {
652
+ /**
653
+ * Component representing the content of a select dropdown.
654
+ * Manages the list of options and their selection state.
655
+ */
656
+ class SelectContent {
382
657
  /**
383
- * The sanitizer service.
658
+ * Reference to the host element of the component.
384
659
  */
385
- sanitizer = inject(DomSanitizer);
660
+ el = inject(ElementRef);
386
661
  /**
387
- * The icon of the text field.
662
+ * Reference to the CDK Listbox directive.
388
663
  */
389
- icon = input.required();
664
+ listBox = inject(CdkListbox);
390
665
  /**
391
- * The size of the icon.
666
+ * Collection of CdkOption elements within the listbox.
392
667
  */
393
- size = input(24);
668
+ options = contentChildren(CdkOption, ...(ngDevMode ? [{ debugName: "options" }] : []));
394
669
  /**
395
- * The stroke of the icon.
670
+ * Key manager for handling keyboard navigation and active descendant management.
396
671
  */
397
- strokeWidth = input(1.8);
672
+ listKeyManager = computed(() => new ActiveDescendantKeyManager(this.options())
673
+ .withWrap()
674
+ .withVerticalOrientation(), ...(ngDevMode ? [{ debugName: "listKeyManager" }] : []));
398
675
  /**
399
- * The color of the icon.
676
+ * Event emitter that emits when the value changes.
400
677
  */
401
- color = input('var(--foreground, #798194)');
678
+ changeValueEmitter = output();
402
679
  /**
403
- * The svg of the icon.
680
+ * Input signal indicating whether multiple selections are allowed.
404
681
  */
405
- iconSvg = computed(() => {
406
- if (!icons[this.icon()]) {
407
- console.error(`Icon '${this.icon()}' not found in Lucide icons.`);
408
- return this.sanitizer.bypassSecurityTrustHtml('');
409
- }
410
- const iconSvg = createElement(icons[this.icon()], {
411
- width: this.size(),
412
- height: this.size(),
413
- stroke: this.color(),
414
- 'stroke-width': this.strokeWidth(),
415
- });
416
- return this.sanitizer.bypassSecurityTrustHtml(iconSvg.outerHTML);
417
- });
418
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Icon, deps: [], target: i0.ɵɵFactoryTarget.Component });
419
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.7", type: Icon, isStandalone: true, selector: "i[b-icon]", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, strokeWidth: { classPropertyName: "strokeWidth", publicName: "strokeWidth", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "innerHTML": "iconSvg()" } }, ngImport: i0, template: ``, isInline: true });
682
+ multiple = model(false, ...(ngDevMode ? [{ debugName: "multiple" }] : []));
683
+ /**
684
+ * Reference to the ConnectedOverlay to determine the direction of the overlay.
685
+ */
686
+ overlay = inject(ConnectedOverlay$1);
687
+ /**
688
+ * Computed signal representing the direction of the overlay.
689
+ */
690
+ direction = computed(() => this.overlay.direction(), ...(ngDevMode ? [{ debugName: "direction" }] : []));
691
+ /**
692
+ * Lifecycle hook that initializes the component.
693
+ * Enables the use of active descendant for the listbox.
694
+ */
695
+ ngOnInit() {
696
+ this.listBox.useActiveDescendant = true;
697
+ }
698
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: SelectContent, deps: [], target: i0.ɵɵFactoryTarget.Component });
699
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.2.3", type: SelectContent, isStandalone: true, selector: "ul[b-select-content]", inputs: { multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { changeValueEmitter: "changeValueEmitter", multiple: "multipleChange" }, host: { listeners: { "cdkListboxValueChange": "changeValueEmitter.emit($event.value)" }, properties: { "animate.enter": "\"b-select-content-entering-\" + this.direction()", "animate.leave": "\"b-select-content-leaving-\" + this.direction()" } }, queries: [{ propertyName: "options", predicate: CdkOption, isSignal: true }], hostDirectives: [{ directive: i1$1.CdkListbox, inputs: ["cdkListboxMultiple", "multiple"], outputs: ["cdkListboxValueChange", "cdkListboxValueChange"] }], ngImport: i0, template: `<ng-content />`, isInline: true });
420
700
  }
421
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Icon, decorators: [{
701
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: SelectContent, decorators: [{
422
702
  type: Component,
423
703
  args: [{
424
- selector: 'i[b-icon]',
704
+ selector: 'ul[b-select-content]',
425
705
  imports: [],
426
- template: ``,
706
+ template: `<ng-content />`,
707
+ hostDirectives: [
708
+ {
709
+ directive: CdkListbox,
710
+ inputs: ['cdkListboxMultiple: multiple'],
711
+ outputs: ['cdkListboxValueChange'],
712
+ },
713
+ ],
427
714
  host: {
428
- '[innerHTML]': 'iconSvg()',
715
+ '(cdkListboxValueChange)': 'changeValueEmitter.emit($event.value)',
716
+ '[animate.enter]': '"b-select-content-entering-" + this.direction()',
717
+ '[animate.leave]': '"b-select-content-leaving-" + this.direction()',
429
718
  },
430
719
  }]
431
720
  }] });
432
721
 
433
722
  /**
434
- * Component representing a custom select dropdown.
435
- * This component provides a button to toggle the dropdown and displays the selected option(s).
723
+ * Select component that provides a customizable dropdown selection interface.
724
+ * Implements ControlValueAccessor for form integration.
436
725
  */
437
- class SelectComponent {
726
+ class Select {
438
727
  /**
439
- * Placeholder text displayed when no option is selected.
440
- * Defaults to 'Select an option'.
728
+ * Reference to the overlay directive instance.
729
+ * Used to control the dropdown overlay for the select component.
441
730
  */
442
- placeholder = input('Select an option');
731
+ overlay = contentChild(ConnectedOverlay, ...(ngDevMode ? [{ debugName: "overlay" }] : []));
443
732
  /**
444
- * Signal indicating whether the dropdown is currently open.
733
+ * Reference to the select trigger component.
734
+ * Used to handle trigger events (click, keydown) for opening/closing the select.
445
735
  */
446
- isOpen = signal(false);
736
+ selectTrigger = contentChild(SelectTrigger, ...(ngDevMode ? [{ debugName: "selectTrigger" }] : []));
447
737
  /**
448
- * Reference to the button element used to toggle the dropdown.
449
- * This is used for managing focus and interactions.
738
+ * Reference to the select value component.
739
+ * Used to display the selected value(s).
450
740
  */
451
- button = viewChild(Button);
741
+ selectValue = contentChild(SelectValue, ...(ngDevMode ? [{ debugName: "selectValue" }] : []));
452
742
  /**
453
- * Reference to the content component of the dropdown.
454
- * This contains the list of selectable options.
743
+ * Reference to the select content component.
744
+ * Used to manage the list of selectable options.
455
745
  */
456
- optionsList = contentChild(SelectOptionsComponent);
746
+ selectContent = contentChild(SelectContent, ...(ngDevMode ? [{ debugName: "selectContent" }] : []));
457
747
  /**
458
- * Computed signal representing the selected values from the dropdown.
459
- * This is linked to the value of the `OptionsListComponent`.
748
+ * Input signal for the size of the select component.
749
+ * Can be 'sm', 'md', or 'lg'. Default is 'md'.
460
750
  */
461
- value = linkedSignal(() => this.optionsList()?.value());
751
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
462
752
  /**
463
- * Input for setting the maximum width of the dropdown.
464
- * Defaults to '100%'.
753
+ * Input signal for a function to display the selected value(s).
754
+ * This function receives the value array and returns a string for display.
465
755
  */
466
- maxWidth = input('100%');
756
+ displayWith = input.required(...(ngDevMode ? [{ debugName: "displayWith" }] : []));
467
757
  /**
468
- * Computed signal for the width of the button element.
469
- * This is used to set the width of the dropdown overlay.
758
+ * Signal holding the current selected value(s).
470
759
  */
471
- buttonWidth = computed(() => this.button()?.el.nativeElement.offsetWidth);
760
+ value = signal([], ...(ngDevMode ? [{ debugName: "value" }] : []));
472
761
  /**
473
- * Model indicating whether the select component is disabled.
474
- * When disabled, the dropdown cannot be opened or interacted with.
762
+ * Initializes effects for value changes and content width adjustment.
475
763
  */
476
- disabled = model(false);
764
+ constructor() {
765
+ effect(() => {
766
+ this.handleValueChanges();
767
+ this.handleSelectContentWidth();
768
+ });
769
+ }
477
770
  /**
478
- * Computed signal representing the options available in the dropdown.
479
- * This retrieves the options from the `OptionsListComponent`.
771
+ * Subscribes to value changes from the select content and updates the model.
772
+ * Closes the overlay if not in multiple selection mode.
480
773
  */
481
- options = computed(() => this.optionsList()?.options());
774
+ handleValueChanges() {
775
+ this.selectContent()?.changeValueEmitter.subscribe((value) => {
776
+ this.onChange(value);
777
+ if (!this.selectContent()?.listBox.multiple) {
778
+ this.overlay()?.closeOverlay();
779
+ }
780
+ this.onTouched();
781
+ });
782
+ }
482
783
  /**
483
- * Computed signal representing the content of the selected option(s).
484
- * If no option is selected, it returns the placeholder text.
784
+ * Sets the minimum width of the select content to match the trigger width.
485
785
  */
486
- content = computed(() => {
487
- const selected = this.value();
488
- if (selected && selected.length > 0) {
489
- return this.options()?.reduce((acc, option) => {
490
- if (selected.includes(option.cdkOption.value)) {
491
- return acc
492
- ? acc + ', ' + option.el.nativeElement.innerText
493
- : option.el.nativeElement.innerText;
494
- }
495
- return acc;
496
- }, '');
497
- }
498
- else {
499
- return this.placeholder();
786
+ handleSelectContentWidth() {
787
+ const selectContentEl = this.selectContent()?.el.nativeElement;
788
+ if (selectContentEl) {
789
+ selectContentEl.style.minWidth = `${this.selectTrigger()?.el.nativeElement.offsetWidth}px`;
500
790
  }
501
- });
502
- /**
503
- * Signal representing the delay before closing the dropdown.
504
- * This is used to provide a smooth transition when closing the dropdown.
505
- */
506
- closeDelay = signal(150);
791
+ }
507
792
  /**
508
- * Reference to the CdkConnectedOverlay directive.
509
- * This is used to manage the positioning and visibility of the dropdown overlay.
793
+ * Angular lifecycle hook. Sets up event handlers for overlay and trigger interactions.
510
794
  */
511
- cdkConnectedOverlay = viewChild(CdkConnectedOverlay);
795
+ ngOnInit() {
796
+ this.handleTriggerClicks();
797
+ this.handleOverlayAttached();
798
+ this.handleOverlayDetached();
799
+ this.handleOverlayOutsideClick();
800
+ this.handleOverlayBackdropClick();
801
+ this.handlePanelSizeClass();
802
+ }
512
803
  /**
513
- * Lifecycle hook that is called after the component is initialized.
514
- * It sets up the necessary subscriptions for handling value changes.
804
+ * Handles clicks and keydown events on the select trigger to toggle the overlay.
515
805
  */
516
- ngOnInit() {
517
- this.handleSelectedValueChange();
806
+ handleTriggerClicks() {
807
+ this.selectTrigger().buttonClicked.subscribe(() => {
808
+ this.overlay()?.toggleOverlay();
809
+ });
518
810
  }
519
811
  /**
520
- * Subscribes to the `closeEmitter` of the `OptionsListComponent` to handle
521
- * changes to the selected value. This ensures the dropdown closes and the
522
- * value is propagated to Angular Forms.
812
+ * Handles overlay attachment event. Selects current values and focuses the content.
523
813
  */
524
- handleSelectedValueChange() {
525
- this.optionsList()?.closeEmitter.subscribe(() => {
526
- this.onChange(this.value()); // Notify Angular Forms about the change
527
- this.onTouched(); // Mark the component as touched
528
- this.close(); // Close the dropdown
814
+ handleOverlayAttached() {
815
+ this.overlay()?.attachEmitter.subscribe(() => {
816
+ if (this.value().length === 0) {
817
+ this.selectContent()?.el.nativeElement.focus();
818
+ return;
819
+ }
820
+ this.value().forEach(val => {
821
+ this.selectContent()?.listBox?.selectValue(val);
822
+ // Focus the selected option
823
+ this.selectContent()
824
+ ?.options()
825
+ .find(opt => opt.value === val)
826
+ ?.focus();
827
+ });
529
828
  });
530
829
  }
531
830
  /**
532
- * Opens the dropdown and focuses the listbox.
533
- * This method sets the `isOpen` signal to `true` and ensures the listbox gains focus.
831
+ * Handles overlay detachment event. Closes the overlay.
534
832
  */
535
- open() {
536
- this.isOpen.set(true);
537
- setTimeout(() => this.optionsList()?.el.nativeElement.focus(), 0);
833
+ handleOverlayDetached() {
834
+ this.overlay()?.detachEmitter.subscribe(() => {
835
+ this.overlay()?.closeOverlay();
836
+ });
538
837
  }
539
838
  /**
540
- * Closes the dropdown with a transition effect and refocuses the button.
541
- * This method sets the `isOpen` signal to `false` after a delay and removes
542
- * the transition class from the overlay panel.
839
+ * Handles outside click event on the overlay. Closes the overlay.
543
840
  */
544
- close() {
545
- this.cdkConnectedOverlay()?.overlayRef.addPanelClass('cdk-overlay-pane-closing');
546
- setTimeout(() => {
547
- this.isOpen.set(false);
548
- this.cdkConnectedOverlay()?.overlayRef.removePanelClass('cdk-overlay-pane-closing');
549
- this.button()?.el.nativeElement.focus();
550
- }, this.closeDelay());
841
+ handleOverlayOutsideClick() {
842
+ this.overlay()?.outsideClickEmitter.subscribe(() => {
843
+ this.overlay()?.closeOverlay();
844
+ });
551
845
  }
552
- // Control Value Accessor methods
553
846
  /**
554
- * Callback function to propagate changes to the model.
555
- * This is called whenever the value changes.
847
+ * Handles backdrop click event on the overlay. Closes the overlay.
556
848
  */
557
- onChange = () => undefined;
849
+ handleOverlayBackdropClick() {
850
+ this.overlay()?.backdropClickEmitter.subscribe(() => {
851
+ this.overlay()?.closeOverlay();
852
+ });
853
+ }
558
854
  /**
559
- * Callback function to mark the component as touched.
560
- * This is called when the component loses focus.
855
+ * Sets the panel size class on the overlay based on the select size input.
561
856
  */
562
- onTouched = () => undefined;
857
+ handlePanelSizeClass() {
858
+ this.overlay().cdkConnectedOverlay.panelClass = `b-size-${this.size()}`;
859
+ }
860
+ // Control value accessor methods
563
861
  /**
564
- * Writes a new value to the component.
565
- * This method is called by Angular Forms to update the value of the select component.
566
- * @param value - The new value to set.
862
+ * Writes a new value to the select component.
863
+ * @param value - The new value array to set.
567
864
  */
568
865
  writeValue(value) {
569
- if (value) {
570
- value.forEach(value => {
571
- this.optionsList()?.listBox?.selectValue(value);
572
- });
573
- this.value.set(value);
574
- }
866
+ this.setValue(value);
575
867
  }
868
+ /**
869
+ * Callback for value changes. Set by registerOnChange.
870
+ */
871
+ onChange = () => undefined;
576
872
  /**
577
873
  * Registers a callback function to be called when the value changes.
578
874
  * @param fn - The callback function.
579
875
  */
580
876
  registerOnChange(fn) {
581
- this.onChange = fn;
877
+ this.onChange = (val) => {
878
+ fn(val);
879
+ this.setValue(val);
880
+ };
582
881
  }
882
+ /**
883
+ * Callback for touch events. Set by registerOnTouched.
884
+ */
885
+ onTouched = () => undefined;
583
886
  /**
584
887
  * Registers a callback function to be called when the component is touched.
585
888
  * @param fn - The callback function.
@@ -588,139 +891,193 @@ class SelectComponent {
588
891
  this.onTouched = fn;
589
892
  }
590
893
  /**
591
- * Sets the disabled state of the component.
592
- * This method is called by Angular Forms to enable or disable the component.
593
- * @param isDisabled - A boolean indicating whether the component should be disabled.
894
+ * Sets the disabled state of the select trigger.
895
+ * @param isDisabled - Whether the select should be disabled.
594
896
  */
595
897
  setDisabledState(isDisabled) {
596
- this.disabled.set(isDisabled);
898
+ this.selectTrigger()?.disabled.set(isDisabled);
899
+ }
900
+ /**
901
+ * Sets the value signal and updates the display value.
902
+ * @param value - The new value array to set.
903
+ */
904
+ setValue(value) {
905
+ this.value.set(value);
906
+ this.selectValue()?.content.set(this.displayWith()(value));
597
907
  }
598
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
599
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.7", type: SelectComponent, isStandalone: true, selector: "b-select", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange" }, host: { properties: { "style.max-width": "maxWidth()", "class.disabled": "disabled()" } }, providers: [
908
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Select, deps: [], target: i0.ɵɵFactoryTarget.Component });
909
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.2.3", type: Select, isStandalone: true, selector: "b-select", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, displayWith: { classPropertyName: "displayWith", publicName: "displayWith", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class.b-size-sm": "size() === \"sm\"", "class.b-size-md": "size() === \"md\"", "class.b-size-lg": "size() === \"lg\"" } }, providers: [
600
910
  {
601
911
  provide: NG_VALUE_ACCESSOR,
602
- useExisting: forwardRef(() => SelectComponent),
912
+ useExisting: forwardRef(() => Select),
603
913
  multi: true,
604
914
  },
605
- ], queries: [{ propertyName: "optionsList", first: true, predicate: SelectOptionsComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "button", first: true, predicate: Button, descendants: true, isSignal: true }, { propertyName: "cdkConnectedOverlay", first: true, predicate: CdkConnectedOverlay, descendants: true, isSignal: true }], ngImport: i0, template: ` <button
606
- b-button
607
- variant="outlined"
608
- (click)="isOpen() ? close() : open()"
609
- (keydown.arrowUp)="!isOpen() && open()"
610
- (keydown.arrowDown)="!isOpen() && open()"
611
- cdkOverlayOrigin
612
- [activeEnabled]="false"
613
- #trigger="cdkOverlayOrigin">
614
- {{ content() }}
615
- <i b-icon icon="ChevronDown" [size]="20"></i>
616
- </button>
617
- <ng-template
618
- cdkConnectedOverlay
619
- [cdkConnectedOverlayOrigin]="trigger"
620
- [cdkConnectedOverlayOpen]="isOpen()"
621
- [cdkConnectedOverlayWidth]="buttonWidth()"
622
- [cdkConnectedOverlayHasBackdrop]="true"
623
- cdkConnectedOverlayBackdropClass="cdk-overlay-transparent-backdrop"
624
- [cdkConnectedOverlayPositions]="[
625
- {
626
- originX: 'start',
627
- originY: 'bottom',
628
- overlayX: 'start',
629
- overlayY: 'top',
630
- offsetY: 5,
631
- },
632
- {
633
- originX: 'start',
634
- originY: 'top',
635
- overlayX: 'start',
636
- overlayY: 'bottom',
637
- offsetY: -5,
638
- },
639
- ]"
640
- (backdropClick)="close()"
641
- (detach)="close()">
642
- <ng-content />
643
- </ng-template>`, isInline: true, dependencies: [{ kind: "component", type: Button, selector: "button[b-button]", inputs: ["variant", "size", "loading", "equalPadding", "toggle", "isToggled", "activeEnabled"] }, { kind: "component", type: Icon, selector: "i[b-icon]", inputs: ["icon", "size", "strokeWidth", "color"] }, { kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }] });
915
+ ], queries: [{ propertyName: "overlay", first: true, predicate: ConnectedOverlay, descendants: true, isSignal: true }, { propertyName: "selectTrigger", first: true, predicate: SelectTrigger, descendants: true, isSignal: true }, { propertyName: "selectValue", first: true, predicate: SelectValue, descendants: true, isSignal: true }, { propertyName: "selectContent", first: true, predicate: SelectContent, descendants: true, isSignal: true }], ngImport: i0, template: `<ng-content />`, isInline: true });
644
916
  }
645
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SelectComponent, decorators: [{
917
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Select, decorators: [{
646
918
  type: Component,
647
919
  args: [{
648
920
  selector: 'b-select',
649
- imports: [Button, Icon, CdkConnectedOverlay, CdkOverlayOrigin],
650
- template: ` <button
651
- b-button
652
- variant="outlined"
653
- (click)="isOpen() ? close() : open()"
654
- (keydown.arrowUp)="!isOpen() && open()"
655
- (keydown.arrowDown)="!isOpen() && open()"
656
- cdkOverlayOrigin
657
- [activeEnabled]="false"
658
- #trigger="cdkOverlayOrigin">
659
- {{ content() }}
660
- <i b-icon icon="ChevronDown" [size]="20"></i>
661
- </button>
662
- <ng-template
663
- cdkConnectedOverlay
664
- [cdkConnectedOverlayOrigin]="trigger"
665
- [cdkConnectedOverlayOpen]="isOpen()"
666
- [cdkConnectedOverlayWidth]="buttonWidth()"
667
- [cdkConnectedOverlayHasBackdrop]="true"
668
- cdkConnectedOverlayBackdropClass="cdk-overlay-transparent-backdrop"
669
- [cdkConnectedOverlayPositions]="[
670
- {
671
- originX: 'start',
672
- originY: 'bottom',
673
- overlayX: 'start',
674
- overlayY: 'top',
675
- offsetY: 5,
676
- },
677
- {
678
- originX: 'start',
679
- originY: 'top',
680
- overlayX: 'start',
681
- overlayY: 'bottom',
682
- offsetY: -5,
683
- },
684
- ]"
685
- (backdropClick)="close()"
686
- (detach)="close()">
687
- <ng-content />
688
- </ng-template>`,
689
- host: {
690
- '[style.max-width]': 'maxWidth()',
691
- '[class.disabled]': 'disabled()',
692
- },
921
+ template: `<ng-content />`,
693
922
  providers: [
694
923
  {
695
924
  provide: NG_VALUE_ACCESSOR,
696
- useExisting: forwardRef(() => SelectComponent),
925
+ useExisting: forwardRef(() => Select),
697
926
  multi: true,
698
927
  },
699
928
  ],
929
+ host: {
930
+ '[class.b-size-sm]': 'size() === "sm"',
931
+ '[class.b-size-md]': 'size() === "md"',
932
+ '[class.b-size-lg]': 'size() === "lg"',
933
+ },
700
934
  }]
701
- }] });
935
+ }], ctorParameters: () => [] });
702
936
 
703
- class Switch {
937
+ /**
938
+ * Component representing an individual option in a select or combobox.
939
+ * This component integrates with Angular CDK Option to manage the option's state and behavior.
940
+ */
941
+ class Option {
704
942
  /**
705
- * Value of the switch.
943
+ * The `ElementRef` of the option.
944
+ * This provides direct access to the DOM element of the option.
706
945
  */
707
- value = model(false);
946
+ el = inject(ElementRef);
708
947
  /**
709
- * The size of the switch.
948
+ * The `CdkOption` instance associated with this option.
949
+ * This provides methods and properties for managing the option's state, such as selection and value.
710
950
  */
711
- size = input('default');
951
+ cdkOption = inject(CdkOption);
952
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Option, deps: [], target: i0.ɵɵFactoryTarget.Component });
953
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.3", type: Option, isStandalone: true, selector: "li[b-option]", hostDirectives: [{ directive: i1$1.CdkOption, inputs: ["cdkOption", "value", "cdkOptionDisabled", "disabled"] }], ngImport: i0, template: `<ng-content />`, isInline: true });
954
+ }
955
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Option, decorators: [{
956
+ type: Component,
957
+ args: [{
958
+ selector: 'li[b-option]',
959
+ imports: [],
960
+ template: `<ng-content />`,
961
+ hostDirectives: [
962
+ {
963
+ directive: CdkOption,
964
+ inputs: ['cdkOption: value', 'cdkOptionDisabled: disabled'],
965
+ },
966
+ ],
967
+ }]
968
+ }] });
969
+
970
+ /**
971
+ * Adds automatic focus and blur behavior to a select filter input element.
972
+ *
973
+ * Applies focus on initialization and refocuses on blur events.
974
+ */
975
+ class SelectFilter {
712
976
  /**
713
- * Reference to the switch element.
977
+ * Reference to the host DOM element.
714
978
  */
715
979
  el = inject(ElementRef);
716
980
  /**
717
- * Event emitted when the value changes.
718
- */
719
- valueChange = output();
720
- /**
721
- * Initializes the switch value after the view is initialized.
981
+ * Sets focus to the host element when the directive initializes.
722
982
  */
723
- ngAfterViewInit() {
983
+ ngOnInit() {
984
+ this.el.nativeElement.focus();
985
+ }
986
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: SelectFilter, deps: [], target: i0.ɵɵFactoryTarget.Directive });
987
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.3", type: SelectFilter, isStandalone: true, selector: "[bSelectFilter]", host: { listeners: { "blur": "el.nativeElement.focus()" } }, ngImport: i0 });
988
+ }
989
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: SelectFilter, decorators: [{
990
+ type: Directive,
991
+ args: [{
992
+ selector: '[bSelectFilter]',
993
+ host: {
994
+ '(blur)': 'el.nativeElement.focus()',
995
+ },
996
+ }]
997
+ }] });
998
+
999
+ /**
1000
+ * Spinner component for loading indicators.
1001
+ *
1002
+ * Displays an animated spinner SVG. The size can be adjusted for use in buttons or standalone.
1003
+ */
1004
+ class Spinner {
1005
+ /**
1006
+ * Size of the spinner.
1007
+ *
1008
+ * - 'sm': Small (for compact UI, e.g. inside buttons)
1009
+ * - 'md': Medium (default)
1010
+ * - 'lg': Large (for standalone loading indicators)
1011
+ *
1012
+ * @default 'md'
1013
+ */
1014
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
1015
+ /**
1016
+ * Computed size in pixels based on the size input.
1017
+ * - 'sm': 16px
1018
+ * - 'md': 20px
1019
+ * - 'lg': 28px
1020
+ */
1021
+ sizeInPx = computed(() => {
1022
+ switch (this.size()) {
1023
+ case 'sm':
1024
+ return 16;
1025
+ case 'md':
1026
+ return 20;
1027
+ case 'lg':
1028
+ return 28;
1029
+ default:
1030
+ return 20;
1031
+ }
1032
+ }, ...(ngDevMode ? [{ debugName: "sizeInPx" }] : []));
1033
+ /**
1034
+ * Type of spinner: 'bars' (default) or 'circle'.
1035
+ *
1036
+ * - 'bars': classic spinner with bars
1037
+ * - 'circle': circular spinner
1038
+ *
1039
+ * @default 'bars'
1040
+ */
1041
+ type = input('bars', ...(ngDevMode ? [{ debugName: "type" }] : []));
1042
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Spinner, deps: [], target: i0.ɵɵFactoryTarget.Component });
1043
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: Spinner, isStandalone: true, selector: "b-spinner", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideIcons({ lucideLoader, lucideLoaderCircle })], ngImport: i0, template: `
1044
+ <ng-icon
1045
+ [name]="type() === 'bars' ? 'lucideLoader' : 'lucideLoaderCircle'"
1046
+ color="currentColor"
1047
+ [size]="sizeInPx() + 'px'" />
1048
+ `, isInline: true, styles: [":host{animation:b-spinner-rotate 1s linear infinite}@keyframes b-spinner-rotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }] });
1049
+ }
1050
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Spinner, decorators: [{
1051
+ type: Component,
1052
+ args: [{ selector: 'b-spinner', imports: [NgIcon], providers: [provideIcons({ lucideLoader, lucideLoaderCircle })], template: `
1053
+ <ng-icon
1054
+ [name]="type() === 'bars' ? 'lucideLoader' : 'lucideLoaderCircle'"
1055
+ color="currentColor"
1056
+ [size]="sizeInPx() + 'px'" />
1057
+ `, styles: [":host{animation:b-spinner-rotate 1s linear infinite}@keyframes b-spinner-rotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
1058
+ }] });
1059
+
1060
+ class SwitchComponent {
1061
+ /**
1062
+ * Value of the switch.
1063
+ */
1064
+ value = signal(false, ...(ngDevMode ? [{ debugName: "value" }] : []));
1065
+ /**
1066
+ * The size of the switch.
1067
+ */
1068
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
1069
+ /**
1070
+ * Reference to the switch element.
1071
+ */
1072
+ el = inject(ElementRef);
1073
+ /**
1074
+ * Event emitted when the value changes.
1075
+ */
1076
+ valueChange = output();
1077
+ /**
1078
+ * Initializes the switch value after the view is initialized.
1079
+ */
1080
+ ngAfterViewInit() {
724
1081
  this.value.set(this.el.nativeElement.checked);
725
1082
  }
726
1083
  /**
@@ -739,10 +1096,10 @@ class Switch {
739
1096
  this.value.set(newValue);
740
1097
  this.valueChange.emit(newValue);
741
1098
  }
742
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Switch, deps: [], target: i0.ɵɵFactoryTarget.Component });
743
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.7", type: Switch, isStandalone: true, selector: "input[b-switch]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", valueChange: "valueChange" }, host: { listeners: { "click": "toggleValue()", "keydown.enter": "toggleValue()", "keydown.arrowleft": "setValue(false)", "keydown.arrowright": "setValue(true)" }, properties: { "attr.role": "switch", "attr.checked": "value()", "attr.aria-checked": "value()", "class": "size()" } }, ngImport: i0, template: ``, isInline: true });
1099
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: SwitchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1100
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: SwitchComponent, isStandalone: true, selector: "input[b-switch]", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, host: { listeners: { "click": "toggleValue()", "keydown.enter": "toggleValue()", "keydown.arrowleft": "setValue(false)", "keydown.arrowright": "setValue(true)" }, properties: { "attr.role": "switch", "attr.checked": "value()", "attr.aria-checked": "value()", "class.b-size-sm": "size() === \"sm\"", "class.b-size-md": "size() === \"md\"", "class.b-size-lg": "size() === \"lg\"" } }, ngImport: i0, template: ``, isInline: true });
744
1101
  }
745
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Switch, decorators: [{
1102
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: SwitchComponent, decorators: [{
746
1103
  type: Component,
747
1104
  args: [{
748
1105
  selector: 'input[b-switch]',
@@ -752,7 +1109,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
752
1109
  '[attr.checked]': 'value()',
753
1110
  '[attr.aria-checked]': 'value()',
754
1111
  '(click)': 'toggleValue()',
755
- '[class]': 'size()',
1112
+ '[class.b-size-sm]': 'size() === "sm"',
1113
+ '[class.b-size-md]': 'size() === "md"',
1114
+ '[class.b-size-lg]': 'size() === "lg"',
756
1115
  '(keydown.enter)': 'toggleValue()',
757
1116
  '(keydown.arrowleft)': 'setValue(false)',
758
1117
  '(keydown.arrowright)': 'setValue(true)',
@@ -760,345 +1119,156 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
760
1119
  }]
761
1120
  }] });
762
1121
 
763
- class Table {
764
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Table, deps: [], target: i0.ɵɵFactoryTarget.Component });
765
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.7", type: Table, isStandalone: true, selector: "b-table", ngImport: i0, template: "<ng-content select=\"[b-row-header]\" />\r\n<ng-content select=\"[b-row-subheader]\" />\r\n<div class=\"scroll-section\">\r\n <ng-content />\r\n</div>\r\n" });
1122
+ class TableComponent {
1123
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1124
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.3", type: TableComponent, isStandalone: true, selector: "b-table", ngImport: i0, template: "<ng-content select=\"[b-row-header]\" />\n<ng-content select=\"[b-row-subheader]\" />\n<div class=\"scroll-section\">\n <ng-content />\n</div>\n" });
766
1125
  }
767
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Table, decorators: [{
1126
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: TableComponent, decorators: [{
768
1127
  type: Component,
769
- args: [{ selector: 'b-table', template: "<ng-content select=\"[b-row-header]\" />\r\n<ng-content select=\"[b-row-subheader]\" />\r\n<div class=\"scroll-section\">\r\n <ng-content />\r\n</div>\r\n" }]
1128
+ args: [{ selector: 'b-table', template: "<ng-content select=\"[b-row-header]\" />\n<ng-content select=\"[b-row-subheader]\" />\n<div class=\"scroll-section\">\n <ng-content />\n</div>\n" }]
770
1129
  }] });
771
1130
 
772
- class Row {
773
- header = input(false);
774
- subheader = input(false);
775
- clickable = input(false);
776
- highlighted = input(false);
777
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Row, deps: [], target: i0.ɵɵFactoryTarget.Component });
778
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.7", type: Row, isStandalone: true, selector: "b-row", inputs: { header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, subheader: { classPropertyName: "subheader", publicName: "subheader", isSignal: true, isRequired: false, transformFunction: null }, clickable: { classPropertyName: "clickable", publicName: "clickable", isSignal: true, isRequired: false, transformFunction: null }, highlighted: { classPropertyName: "highlighted", publicName: "highlighted", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\r\n class=\"row-container\"\r\n [ngClass]=\"{\r\n clickable: clickable(),\r\n header: header(),\r\n subheader: subheader(),\r\n highlighted: highlighted(),\r\n }\">\r\n <ng-content />\r\n</div>\r\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
1131
+ class RowComponent {
1132
+ header = input(false, ...(ngDevMode ? [{ debugName: "header" }] : []));
1133
+ subheader = input(false, ...(ngDevMode ? [{ debugName: "subheader" }] : []));
1134
+ clickable = input(false, ...(ngDevMode ? [{ debugName: "clickable" }] : []));
1135
+ highlighted = input(false, ...(ngDevMode ? [{ debugName: "highlighted" }] : []));
1136
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: RowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1137
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: RowComponent, isStandalone: true, selector: "b-row", inputs: { header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, subheader: { classPropertyName: "subheader", publicName: "subheader", isSignal: true, isRequired: false, transformFunction: null }, clickable: { classPropertyName: "clickable", publicName: "clickable", isSignal: true, isRequired: false, transformFunction: null }, highlighted: { classPropertyName: "highlighted", publicName: "highlighted", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n class=\"row-container\"\n [ngClass]=\"{\n clickable: clickable(),\n header: header(),\n subheader: subheader(),\n highlighted: highlighted(),\n }\">\n <ng-content />\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
779
1138
  }
780
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Row, decorators: [{
1139
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: RowComponent, decorators: [{
781
1140
  type: Component,
782
- args: [{ selector: 'b-row', imports: [NgClass], template: "<div\r\n class=\"row-container\"\r\n [ngClass]=\"{\r\n clickable: clickable(),\r\n header: header(),\r\n subheader: subheader(),\r\n highlighted: highlighted(),\r\n }\">\r\n <ng-content />\r\n</div>\r\n" }]
1141
+ args: [{ selector: 'b-row', imports: [NgClass], template: "<div\n class=\"row-container\"\n [ngClass]=\"{\n clickable: clickable(),\n header: header(),\n subheader: subheader(),\n highlighted: highlighted(),\n }\">\n <ng-content />\n</div>\n" }]
783
1142
  }] });
784
1143
 
785
- class RowItem {
786
- widthPx = input();
787
- alignedLeft = input(false);
788
- isHeader = input(false);
1144
+ class RowItemComponent {
1145
+ widthPx = input(...(ngDevMode ? [undefined, { debugName: "widthPx" }] : []));
1146
+ alignedLeft = input(false, ...(ngDevMode ? [{ debugName: "alignedLeft" }] : []));
1147
+ isHeader = input(false, ...(ngDevMode ? [{ debugName: "isHeader" }] : []));
789
1148
  style = computed(() => {
790
1149
  return {
791
1150
  width: `${this.widthPx()}px`,
792
1151
  justifyContent: this.alignedLeft() ? 'flex-start' : 'center',
793
1152
  };
794
- });
795
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: RowItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
796
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.7", type: RowItem, isStandalone: true, selector: "b-row-item", inputs: { widthPx: { classPropertyName: "widthPx", publicName: "widthPx", isSignal: true, isRequired: false, transformFunction: null }, alignedLeft: { classPropertyName: "alignedLeft", publicName: "alignedLeft", isSignal: true, isRequired: false, transformFunction: null }, isHeader: { classPropertyName: "isHeader", publicName: "isHeader", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div [ngStyle]=\"style()\" class=\"row-item-container\">\r\n <ng-content />\r\n</div>\r\n", dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
1153
+ }, ...(ngDevMode ? [{ debugName: "style" }] : []));
1154
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: RowItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1155
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: RowItemComponent, isStandalone: true, selector: "b-row-item", inputs: { widthPx: { classPropertyName: "widthPx", publicName: "widthPx", isSignal: true, isRequired: false, transformFunction: null }, alignedLeft: { classPropertyName: "alignedLeft", publicName: "alignedLeft", isSignal: true, isRequired: false, transformFunction: null }, isHeader: { classPropertyName: "isHeader", publicName: "isHeader", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div [ngStyle]=\"style()\" class=\"row-item-container\">\n <ng-content />\n</div>\n", dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
797
1156
  }
798
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: RowItem, decorators: [{
1157
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: RowItemComponent, decorators: [{
799
1158
  type: Component,
800
- args: [{ selector: 'b-row-item', imports: [NgStyle], template: "<div [ngStyle]=\"style()\" class=\"row-item-container\">\r\n <ng-content />\r\n</div>\r\n" }]
1159
+ args: [{ selector: 'b-row-item', imports: [NgStyle], template: "<div [ngStyle]=\"style()\" class=\"row-item-container\">\n <ng-content />\n</div>\n" }]
801
1160
  }] });
802
1161
 
803
1162
  class Tab {
804
- el;
805
- value = input.required();
806
- disabled = input(false);
807
- selected = signal(false);
808
- highlighted = signal(false);
809
- selectEmitter = output();
810
- constructor(el) {
811
- this.el = el;
812
- }
813
- /**
814
- * Emit the select event when the tab is selected.
815
- */
816
- onSelect() {
817
- this.selectEmitter.emit(this);
818
- }
819
1163
  /**
820
- * Highlight the tab on mouse enter if it is not disabled and not in keyboard-active mode.
1164
+ * Reference to the injected CDK Option instance.
821
1165
  */
822
- onMouseEnter() {
823
- if (!this.disabled() &&
824
- !this.el.nativeElement.parentElement.parentElement.classList.contains('keyboard-active')) {
825
- this.highlighted.set(true);
826
- }
827
- }
828
- /**
829
- * Remove the highlight from the tab on mouse leave if it is not disabled and not in keyboard-active mode.
830
- */
831
- onMouseLeave() {
832
- if (!this.disabled() &&
833
- !this.el.nativeElement.parentElement.parentElement.classList.contains('keyboard-active')) {
834
- this.highlighted.set(false);
835
- }
836
- }
837
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Tab, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
838
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.7", type: Tab, isStandalone: true, selector: "b-tab", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectEmitter: "selectEmitter" }, ngImport: i0, template: "<span\r\n tabindex=\"0\"\r\n (click)=\"onSelect()\"\r\n (keydown.enter)=\"onSelect()\"\r\n (mouseenter)=\"onMouseEnter()\"\r\n (mouseleave)=\"onMouseLeave()\"\r\n [ngClass]=\"{ selected: selected(), highlighted: highlighted() }\">\r\n <ng-content\r\n/></span>\r\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
1166
+ cdkOption = inject(CdkOption);
1167
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Tab, deps: [], target: i0.ɵɵFactoryTarget.Component });
1168
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.3", type: Tab, isStandalone: true, selector: "b-tab", hostDirectives: [{ directive: i1$1.CdkOption, inputs: ["cdkOption", "value"] }], ngImport: i0, template: `<ng-content />`, isInline: true });
839
1169
  }
840
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Tab, decorators: [{
1170
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Tab, decorators: [{
841
1171
  type: Component,
842
- args: [{ selector: 'b-tab', imports: [NgClass], template: "<span\r\n tabindex=\"0\"\r\n (click)=\"onSelect()\"\r\n (keydown.enter)=\"onSelect()\"\r\n (mouseenter)=\"onMouseEnter()\"\r\n (mouseleave)=\"onMouseLeave()\"\r\n [ngClass]=\"{ selected: selected(), highlighted: highlighted() }\">\r\n <ng-content\r\n/></span>\r\n" }]
843
- }], ctorParameters: () => [{ type: i0.ElementRef }] });
1172
+ args: [{
1173
+ selector: 'b-tab',
1174
+ imports: [],
1175
+ template: `<ng-content />`,
1176
+ hostDirectives: [
1177
+ {
1178
+ directive: CdkOption,
1179
+ inputs: ['cdkOption: value'],
1180
+ },
1181
+ ],
1182
+ }]
1183
+ }] });
844
1184
 
845
1185
  class Tabs {
846
- tabs = contentChildren(Tab);
847
- selectedIndex = signal(-1);
848
- selectedValue = model(null);
849
- highlightedIndex = signal(-1);
850
- changesEmitter = output();
851
- lastSelectedValue = null;
852
- constructor() {
853
- effect(() => {
854
- this.handleTabSelection();
855
- this.handleExternalSelectedValue();
856
- this.handleScrollToSelectedTab();
857
- });
858
- }
859
- /**
860
- * Handle the selection of a tab.
861
- */
862
- handleTabSelection() {
863
- this.tabs().forEach((tab, index) => {
864
- tab.selectEmitter.subscribe(tabEmitted => {
865
- this.selectTab(tabEmitted, index);
866
- this.highlightTab(index);
867
- this.handleTabStates();
868
- this.changesEmitter.emit(tab.value());
869
- });
870
- });
871
- }
872
- /**
873
- * Select a tab.
874
- * @param {Tab} tab - The tab to select.
875
- * @param {number} index - The index of the tab.
876
- */
877
- selectTab(tab, index) {
878
- this.selectedValue.set(tab.value());
879
- this.lastSelectedValue = tab.value();
880
- this.selectedIndex.set(index);
881
- }
882
1186
  /**
883
- * Highlight a tab.
884
- * @param {number} index - The index of the tab to highlight.
1187
+ * Reference to the injected CDK Listbox instance.
885
1188
  */
886
- highlightTab(index) {
887
- this.highlightedIndex.set(index);
888
- }
1189
+ cdkListbox = inject(CdkListbox);
889
1190
  /**
890
- * Handle the states of the tabs.
1191
+ * The size of the tabs.
1192
+ *
1193
+ * @defaultValue 'md'
891
1194
  */
892
- handleTabStates() {
893
- this.tabs().forEach((tab, index) => {
894
- tab.selected.set(index === this.selectedIndex());
895
- tab.highlighted.set(index === this.highlightedIndex());
896
- });
897
- }
1195
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
898
1196
  /**
899
- * Handle the external selected value.
1197
+ * Collection of child options within the listbox.
900
1198
  */
901
- handleExternalSelectedValue() {
902
- if (this.lastSelectedValue !== this.selectedValue()) {
903
- const selectedOptionIndex = this.tabs().findIndex(tab => tab.value() === this.selectedValue());
904
- if (selectedOptionIndex !== -1) {
905
- this.selectTab(this.tabs()[selectedOptionIndex], selectedOptionIndex);
906
- this.highlightTab(selectedOptionIndex);
907
- this.handleTabStates();
908
- }
909
- }
910
- }
1199
+ tabs = contentChildren(Tab, ...(ngDevMode ? [{ debugName: "tabs" }] : []));
911
1200
  /**
912
- * Scroll to the selected tab.
1201
+ * Collection of cdk options within the listbox.
913
1202
  */
914
- handleScrollToSelectedTab() {
915
- if (this.selectedIndex() !== -1) {
916
- this.scrollToTab(this.selectedIndex(), 'smooth');
917
- }
918
- }
919
- /**
920
- * Handle keyboard events for navigation and selection.
921
- * @param {KeyboardEvent} event - The keyboard event.
922
- */
923
- handleKeyboard(event) {
924
- switch (event.key) {
925
- case 'ArrowRight':
926
- event.preventDefault();
927
- this.focusOption('next');
928
- break;
929
- case 'ArrowLeft':
930
- event.preventDefault();
931
- this.focusOption('previous');
932
- break;
933
- case 'Enter':
934
- event.preventDefault();
935
- this.selectFocusedTab();
936
- break;
937
- }
938
- }
1203
+ cdkOptions = computed(() => this.tabs().map(tab => tab.cdkOption), ...(ngDevMode ? [{ debugName: "cdkOptions" }] : []));
939
1204
  /**
940
- * Focus on the next or previous tab.
941
- * @param {'next' | 'previous'} direction - The direction to move the focus.
1205
+ * Key manager for handling keyboard navigation and active descendant management.
942
1206
  */
943
- focusOption(direction) {
944
- let index = this.highlightedIndex();
945
- const increment = direction === 'next' ? 1 : -1;
946
- index += increment;
947
- while (index >= 0 &&
948
- index < this.tabs().length &&
949
- this.tabs()[index].disabled()) {
950
- index += increment;
951
- }
952
- if (index >= 0 && index < this.tabs().length) {
953
- this.highlightTab(index);
954
- this.handleTabStates();
955
- this.scrollToTab(this.highlightedIndex(), 'smooth');
956
- }
1207
+ listKeyManager = computed(() => new ActiveDescendantKeyManager(this.cdkOptions())
1208
+ .withWrap()
1209
+ .withHorizontalOrientation('ltr'), ...(ngDevMode ? [{ debugName: "listKeyManager" }] : []));
1210
+ previousTab() {
1211
+ this.listKeyManager().setPreviousItemActive();
957
1212
  }
958
- /**
959
- * Select the currently focused tab.
960
- */
961
- selectFocusedTab() {
962
- this.selectTab(this.tabs()[this.highlightedIndex()], this.highlightedIndex());
963
- this.handleTabStates();
1213
+ nextTab() {
1214
+ this.listKeyManager().setNextItemActive();
964
1215
  }
965
- /**
966
- * Scroll to a specific tab.
967
- * @param {number} index - The index of the tab to scroll to.
968
- * @param {string} behavior - The scroll behavior ('instant' or 'smooth').
969
- */
970
- scrollToTab(index, behavior) {
971
- const tabsElements = this.tabs();
972
- if (tabsElements[index].el.nativeElement) {
973
- tabsElements[index].el.nativeElement.scrollIntoView({
974
- block: 'nearest',
975
- behavior: behavior,
976
- });
977
- }
1216
+ ngOnInit() {
1217
+ this.cdkListbox.useActiveDescendant = true;
1218
+ this.cdkListbox.orientation = 'horizontal';
978
1219
  }
979
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Tabs, deps: [], target: i0.ɵɵFactoryTarget.Component });
980
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.7", type: Tabs, isStandalone: true, selector: "b-tabs", inputs: { selectedValue: { classPropertyName: "selectedValue", publicName: "selectedValue", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedValue: "selectedValueChange", changesEmitter: "changesEmitter" }, host: { listeners: { "keydown": "handleKeyboard($event)" } }, queries: [{ propertyName: "tabs", predicate: Tab, isSignal: true }], ngImport: i0, template: "<div class=\"tabs\" [tabIndex]=\"0\">\r\n <ng-content />\r\n</div>\r\n" });
1220
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Tabs, deps: [], target: i0.ɵɵFactoryTarget.Component });
1221
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.2.3", type: Tabs, isStandalone: true, selector: "b-tabs", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "keydown.arrowLeft": "previousTab()", "keydown.arrowUp": "previousTab()", "keydown.arrowRight": "nextTab()", "keydown.arrowDown": "nextTab()" }, properties: { "class.b-size-sm": "size() === \"sm\"", "class.b-size-md": "size() === \"md\"", "class.b-size-lg": "size() === \"lg\"" } }, queries: [{ propertyName: "tabs", predicate: Tab, isSignal: true }], hostDirectives: [{ directive: i1$1.CdkListbox }], ngImport: i0, template: `<ng-content />`, isInline: true });
981
1222
  }
982
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Tabs, decorators: [{
1223
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Tabs, decorators: [{
983
1224
  type: Component,
984
- args: [{ selector: 'b-tabs', template: "<div class=\"tabs\" [tabIndex]=\"0\">\r\n <ng-content />\r\n</div>\r\n" }]
985
- }], ctorParameters: () => [], propDecorators: { handleKeyboard: [{
986
- type: HostListener,
987
- args: ['keydown', ['$event']]
988
- }] } });
989
-
990
- class InViewportService {
991
- elements = signal({});
992
- observer;
993
- /**
994
- * Register an element to be tracked by the service.
995
- * @param {string} id - The id of the element to register.
996
- */
997
- registerElement(id, nativeElement, initialVisibility) {
998
- if (!(id in this.elements())) {
999
- this.elements.set({ ...this.elements(), [id]: initialVisibility });
1000
- // Create an IntersectionObserver to track the element's visibility.
1001
- this.observer = new IntersectionObserver(entries => {
1002
- entries.forEach(entry => {
1003
- const isVisible = entry.isIntersecting;
1004
- this.updateElementVisibility(id, isVisible);
1005
- });
1006
- });
1007
- // Start observing the element.
1008
- this.observer.observe(nativeElement);
1009
- }
1010
- }
1011
- /**
1012
- * Unregister an element from being tracked by the service.
1013
- * @param {string} id - The id of the element to unregister.
1014
- */
1015
- unregisterElement(id) {
1016
- if (id in this.elements()) {
1017
- delete this.elements()[id];
1018
- this.observer.disconnect();
1019
- }
1020
- }
1021
- /**
1022
- * Update the visibility of an element.
1023
- * @param {string} id - The id of the element to update.
1024
- * @param {boolean} isVisible - The new visibility state of the element.
1025
- */
1026
- updateElementVisibility(id, isVisible) {
1027
- this.elements.set({ ...this.elements(), [id]: isVisible });
1028
- }
1029
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: InViewportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1030
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: InViewportService, providedIn: 'root' });
1031
- }
1032
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: InViewportService, decorators: [{
1033
- type: Injectable,
1034
1225
  args: [{
1035
- providedIn: 'root',
1226
+ selector: 'b-tabs',
1227
+ imports: [],
1228
+ template: `<ng-content />`,
1229
+ hostDirectives: [CdkListbox],
1230
+ host: {
1231
+ '[class.b-size-sm]': 'size() === "sm"',
1232
+ '[class.b-size-md]': 'size() === "md"',
1233
+ '[class.b-size-lg]': 'size() === "lg"',
1234
+ '(keydown.arrowLeft)': 'previousTab()',
1235
+ '(keydown.arrowUp)': 'previousTab()',
1236
+ '(keydown.arrowRight)': 'nextTab()',
1237
+ '(keydown.arrowDown)': 'nextTab()',
1238
+ },
1036
1239
  }]
1037
1240
  }] });
1038
1241
 
1039
- class InViewportDirective {
1040
- inViewportId = input.required();
1041
- inViewportInitialVisibility = input(false);
1042
- el = inject(ElementRef);
1043
- inViewportService = inject(InViewportService);
1044
- constructor() {
1045
- afterNextRender({
1046
- write: () => {
1047
- this.inViewportService.registerElement(this.inViewportId(), this.el.nativeElement, this.inViewportInitialVisibility());
1048
- },
1049
- });
1050
- }
1051
- ngOnDestroy() {
1052
- this.inViewportService.unregisterElement(this.inViewportId());
1053
- }
1054
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: InViewportDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1055
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.7", type: InViewportDirective, isStandalone: true, selector: "[b-in-viewport]", inputs: { inViewportId: { classPropertyName: "inViewportId", publicName: "inViewportId", isSignal: true, isRequired: true, transformFunction: null }, inViewportInitialVisibility: { classPropertyName: "inViewportInitialVisibility", publicName: "inViewportInitialVisibility", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
1056
- }
1057
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: InViewportDirective, decorators: [{
1058
- type: Directive,
1059
- args: [{
1060
- selector: '[b-in-viewport]',
1061
- }]
1062
- }], ctorParameters: () => [] });
1063
-
1064
1242
  /**
1065
1243
  * A sliding sheet component that can be positioned on either side of the screen.
1066
1244
  * The sheet slides in from the left or right edge and includes an overlay backdrop.
1067
1245
  *
1068
- * @selector b-side-sheet
1246
+ * @selector b-sheet
1069
1247
  */
1070
- class SideSheet {
1248
+ class Sheet {
1071
1249
  /**
1072
- * Indicates whether the side sheet is open.
1250
+ * Indicates whether the sheet is open.
1073
1251
  */
1074
- isOpen = model(false);
1252
+ isOpen = model(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
1075
1253
  /**
1076
1254
  * Specifies the side of the screen where the sheet is positioned.
1077
1255
  * Can be either 'left' or 'right'.
1078
1256
  */
1079
- side = input('right');
1080
- /**
1081
- * Specifies the width of the side sheet.
1082
- */
1083
- width = input('300px');
1084
- /**
1085
- * Computes whether the side sheet is positioned on the left side.
1086
- */
1087
- isLeft = computed(() => this.side() === 'left');
1257
+ side = input('right', ...(ngDevMode ? [{ debugName: "side" }] : []));
1088
1258
  /**
1089
- * Computes whether the side sheet is positioned on the right side.
1259
+ * Computes whether the sheet is positioned on the right side.
1090
1260
  */
1091
- isRight = computed(() => this.side() === 'right');
1261
+ isRight = computed(() => this.side() === 'right', ...(ngDevMode ? [{ debugName: "isRight" }] : []));
1092
1262
  /**
1093
- * Event emitted when the side sheet is closed.
1263
+ * Event emitted when the sheet is closed.
1094
1264
  */
1095
1265
  closeSheet = output();
1096
1266
  /**
1097
- * Reference to the host element of the side sheet.
1267
+ * Reference to the host element of the sheet.
1098
1268
  */
1099
1269
  el = inject(ElementRef);
1100
1270
  /**
1101
- * Closes the side sheet when clicking outside of it.
1271
+ * Closes the sheet when clicking outside of it.
1102
1272
  *
1103
1273
  * @param event - The click event.
1104
1274
  */
@@ -1107,65 +1277,98 @@ class SideSheet {
1107
1277
  this.isOpen.set(false);
1108
1278
  }
1109
1279
  }
1110
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SideSheet, deps: [], target: i0.ɵɵFactoryTarget.Component });
1111
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.7", type: SideSheet, isStandalone: true, selector: "b-side-sheet", inputs: { isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: false, transformFunction: null }, side: { classPropertyName: "side", publicName: "side", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isOpen: "isOpenChange", closeSheet: "closeSheet" }, host: { listeners: { "document:click": "closeOnOutsideClick($event)" }, properties: { "class.left": "isLeft()", "class.right": "!isLeft()", "class.open": "isOpen()", "style.width": "width()" } }, ngImport: i0, template: "<button class=\"close-button\" (click)=\"isOpen.set(false)\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"19\"\r\n height=\"19\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"0.094rem\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n class=\"lucide lucide-x\">\r\n <path d=\"M18 6 6 18\" />\r\n <path d=\"m6 6 12 12\" />\r\n </svg>\r\n</button>\r\n<ng-content />\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] });
1280
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Sheet, deps: [], target: i0.ɵɵFactoryTarget.Component });
1281
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: Sheet, isStandalone: true, selector: "b-sheet", inputs: { isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: false, transformFunction: null }, side: { classPropertyName: "side", publicName: "side", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isOpen: "isOpenChange", closeSheet: "closeSheet" }, host: { listeners: { "document:click": "closeOnOutsideClick($event)" }, properties: { "class.left": "side() === \"left\"", "class.right": "side() === \"right\"", "class.open": "isOpen()" } }, ngImport: i0, template: `<button class="close-button" (click)="isOpen.set(false)">
1282
+ <svg
1283
+ xmlns="http://www.w3.org/2000/svg"
1284
+ width="20"
1285
+ height="20"
1286
+ viewBox="0 0 24 24"
1287
+ fill="none"
1288
+ stroke="currentColor"
1289
+ stroke-width="0.094rem"
1290
+ stroke-linecap="round"
1291
+ stroke-linejoin="round"
1292
+ class="lucide lucide-x">
1293
+ <path d="M18 6 6 18" />
1294
+ <path d="m6 6 12 12" />
1295
+ </svg>
1296
+ </button>
1297
+ <ng-content /> `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] });
1112
1298
  }
1113
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: SideSheet, decorators: [{
1299
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Sheet, decorators: [{
1114
1300
  type: Component,
1115
- args: [{ selector: 'b-side-sheet', standalone: true, imports: [CommonModule], host: {
1116
- '[class.left]': 'isLeft()',
1117
- '[class.right]': '!isLeft()',
1301
+ args: [{
1302
+ selector: 'b-sheet',
1303
+ standalone: true,
1304
+ imports: [CommonModule],
1305
+ template: `<button class="close-button" (click)="isOpen.set(false)">
1306
+ <svg
1307
+ xmlns="http://www.w3.org/2000/svg"
1308
+ width="20"
1309
+ height="20"
1310
+ viewBox="0 0 24 24"
1311
+ fill="none"
1312
+ stroke="currentColor"
1313
+ stroke-width="0.094rem"
1314
+ stroke-linecap="round"
1315
+ stroke-linejoin="round"
1316
+ class="lucide lucide-x">
1317
+ <path d="M18 6 6 18" />
1318
+ <path d="m6 6 12 12" />
1319
+ </svg>
1320
+ </button>
1321
+ <ng-content /> `,
1322
+ host: {
1323
+ '[class.left]': 'side() === "left"',
1324
+ '[class.right]': 'side() === "right"',
1118
1325
  '[class.open]': 'isOpen()',
1119
- '[style.width]': 'width()',
1120
- }, template: "<button class=\"close-button\" (click)=\"isOpen.set(false)\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"19\"\r\n height=\"19\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"0.094rem\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n class=\"lucide lucide-x\">\r\n <path d=\"M18 6 6 18\" />\r\n <path d=\"m6 6 12 12\" />\r\n </svg>\r\n</button>\r\n<ng-content />\r\n" }]
1326
+ },
1327
+ }]
1121
1328
  }], propDecorators: { closeOnOutsideClick: [{
1122
1329
  type: HostListener,
1123
1330
  args: ['document:click', ['$event']]
1124
1331
  }] } });
1125
1332
 
1126
- class BottomSheet {
1127
- /**
1128
- * Indicates whether the bottom sheet is open.
1129
- */
1130
- isOpen = model(false);
1333
+ class Drawer {
1131
1334
  /**
1132
- * The height of the bottom sheet.
1335
+ * Indicates whether the drawer is open.
1133
1336
  */
1134
- height = input('30dvh');
1337
+ isOpen = model(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
1135
1338
  /**
1136
- * Event emitted when the bottom sheet is closed.
1339
+ * Event emitted when the drawer is closed.
1137
1340
  */
1138
1341
  closeSheet = output();
1139
1342
  /**
1140
1343
  * Indicates whether a drag event is in progress.
1141
1344
  */
1142
- isDragging = signal(false);
1345
+ isDragging = signal(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : []));
1143
1346
  /**
1144
1347
  * The starting Y position of the drag event.
1145
1348
  */
1146
- startY = signal(0);
1349
+ startY = signal(0, ...(ngDevMode ? [{ debugName: "startY" }] : []));
1147
1350
  /**
1148
- * The current Y translation of the bottom sheet in percentage.
1351
+ * The current Y translation of the drawer in percentage.
1149
1352
  */
1150
- translateY = signal(100);
1353
+ translateY = signal(100, ...(ngDevMode ? [{ debugName: "translateY" }] : []));
1151
1354
  /**
1152
- * The threshold for closing the bottom sheet, in percentage.
1355
+ * The threshold for closing the drawer, in percentage.
1153
1356
  */
1154
- closeThreshold = input(30);
1357
+ closeThreshold = input(30, ...(ngDevMode ? [{ debugName: "closeThreshold" }] : []));
1155
1358
  /**
1156
- * The computed transform property for the bottom sheet.
1359
+ * The computed transform property for the drawer.
1157
1360
  */
1158
1361
  transform = computed(() => this.isDragging()
1159
1362
  ? `translateY(${this.translateY()}%)`
1160
1363
  : this.isOpen()
1161
1364
  ? 'translateY(0%)'
1162
- : 'translateY(100%)');
1365
+ : 'translateY(100%)', ...(ngDevMode ? [{ debugName: "transform" }] : []));
1163
1366
  /**
1164
- * The reference to the Bottom Sheet DOM element.
1367
+ * The reference to the drawer DOM element.
1165
1368
  */
1166
1369
  el = inject(ElementRef);
1167
1370
  /**
1168
- * Closes the bottom sheet when clicking outside of it.
1371
+ * Closes the drawer when clicking outside of it.
1169
1372
  * @param event The click event.
1170
1373
  */
1171
1374
  closeOnOutsideClick(event) {
@@ -1175,7 +1378,7 @@ class BottomSheet {
1175
1378
  }
1176
1379
  }
1177
1380
  /**
1178
- * Starts the drag event for the bottom sheet.
1381
+ * Starts the drag event for the drawer.
1179
1382
  * @param event The pointer event that starts the drag.
1180
1383
  */
1181
1384
  startDrag(event) {
@@ -1198,7 +1401,7 @@ class BottomSheet {
1198
1401
  window.addEventListener('pointerup', end);
1199
1402
  }
1200
1403
  /**
1201
- * Updates the drag position of the bottom sheet.
1404
+ * Updates the drag position of the drawer.
1202
1405
  * @param clientY The current Y position of the pointer.
1203
1406
  */
1204
1407
  updateDrag(clientY) {
@@ -1211,7 +1414,7 @@ class BottomSheet {
1211
1414
  this.translateY.set(newPos);
1212
1415
  }
1213
1416
  /**
1214
- * Snaps the bottom sheet to either open or closed state based on the drag position.
1417
+ * Snaps the drawer to either open or closed state based on the drag position.
1215
1418
  */
1216
1419
  snapToOpenOrClose() {
1217
1420
  if (this.translateY() > this.closeThreshold()) {
@@ -1221,17 +1424,16 @@ class BottomSheet {
1221
1424
  this.isOpen.set(true);
1222
1425
  }
1223
1426
  }
1224
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: BottomSheet, deps: [], target: i0.ɵɵFactoryTarget.Component });
1225
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.7", type: BottomSheet, isStandalone: true, selector: "b-bottom-sheet", inputs: { isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, closeThreshold: { classPropertyName: "closeThreshold", publicName: "closeThreshold", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isOpen: "isOpenChange", closeSheet: "closeSheet" }, host: { listeners: { "document:click": "closeOnOutsideClick($event)" }, properties: { "style.height": "height()", "class.dragging": "isDragging()", "style.transform": "transform()", "class.open": "isOpen()" } }, ngImport: i0, template: "<div class=\"drag-section\" (pointerdown)=\"startDrag($event)\">\r\n <div class=\"drag-indicator\"></div>\r\n</div>\r\n<ng-content />\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] });
1427
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Drawer, deps: [], target: i0.ɵɵFactoryTarget.Component });
1428
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: Drawer, isStandalone: true, selector: "b-drawer", inputs: { isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: false, transformFunction: null }, closeThreshold: { classPropertyName: "closeThreshold", publicName: "closeThreshold", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isOpen: "isOpenChange", closeSheet: "closeSheet" }, host: { listeners: { "document:click": "closeOnOutsideClick($event)" }, properties: { "class.dragging": "isDragging()", "style.transform": "transform()", "class.open": "isOpen()" } }, ngImport: i0, template: "<div class=\"drag-section\" (pointerdown)=\"startDrag($event)\">\n <div class=\"drag-indicator\"></div>\n</div>\n<ng-content />\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] });
1226
1429
  }
1227
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: BottomSheet, decorators: [{
1430
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Drawer, decorators: [{
1228
1431
  type: Component,
1229
- args: [{ selector: 'b-bottom-sheet', standalone: true, imports: [CommonModule], host: {
1230
- '[style.height]': 'height()',
1432
+ args: [{ selector: 'b-drawer', standalone: true, imports: [CommonModule], host: {
1231
1433
  '[class.dragging]': 'isDragging()',
1232
1434
  '[style.transform]': 'transform()',
1233
1435
  '[class.open]': 'isOpen()',
1234
- }, template: "<div class=\"drag-section\" (pointerdown)=\"startDrag($event)\">\r\n <div class=\"drag-indicator\"></div>\r\n</div>\r\n<ng-content />\r\n" }]
1436
+ }, template: "<div class=\"drag-section\" (pointerdown)=\"startDrag($event)\">\n <div class=\"drag-indicator\"></div>\n</div>\n<ng-content />\n" }]
1235
1437
  }], propDecorators: { closeOnOutsideClick: [{
1236
1438
  type: HostListener,
1237
1439
  args: ['document:click', ['$event']]
@@ -1241,15 +1443,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
1241
1443
  * Service that handles responsive design functionality
1242
1444
  * Detects current device type based on window width and configurable breakpoints
1243
1445
  */
1244
- class ResponsiveService {
1446
+ class ResponsiveManager {
1245
1447
  /** Signal that holds the breakpoint configuration */
1246
1448
  breakpoints = signal({
1247
- mobile: 576,
1248
- tablet: 992,
1249
- desktop: 1200,
1250
- });
1449
+ mobile: 640,
1450
+ tablet: 1024,
1451
+ desktop: 1280,
1452
+ }, ...(ngDevMode ? [{ debugName: "breakpoints" }] : []));
1251
1453
  /** Signal that holds the current window width */
1252
- windowWidth = signal(0);
1454
+ windowWidth = signal(0, ...(ngDevMode ? [{ debugName: "windowWidth" }] : []));
1253
1455
  /**
1254
1456
  * Computed signal that returns the current device type based on window width
1255
1457
  * @returns The current device type ('mobile', 'tablet', or 'desktop')
@@ -1264,7 +1466,7 @@ class ResponsiveService {
1264
1466
  return 'tablet';
1265
1467
  }
1266
1468
  return 'desktop';
1267
- });
1469
+ }, ...(ngDevMode ? [{ debugName: "currentDevice" }] : []));
1268
1470
  constructor() {
1269
1471
  afterRenderEffect(() => {
1270
1472
  this.initializeWindowWidth();
@@ -1297,403 +1499,295 @@ class ResponsiveService {
1297
1499
  ...newBreakpoints,
1298
1500
  }));
1299
1501
  }
1300
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ResponsiveService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1301
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ResponsiveService, providedIn: 'root' });
1502
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ResponsiveManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1503
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ResponsiveManager, providedIn: 'root' });
1302
1504
  }
1303
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ResponsiveService, decorators: [{
1505
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ResponsiveManager, decorators: [{
1304
1506
  type: Injectable,
1305
1507
  args: [{
1306
1508
  providedIn: 'root',
1307
1509
  }]
1308
1510
  }], ctorParameters: () => [] });
1309
1511
 
1310
- class AttachedBox {
1311
- /**
1312
- * Input signal to define the interaction type: 'click' or 'hover'.
1313
- * Default is 'click'.
1314
- */
1315
- type = input('click');
1512
+ /**
1513
+ * Component representing a One-Time Password (OTP) input group.
1514
+ *
1515
+ * This component manages a set of digit inputs for entering OTP codes, handling keyboard navigation,
1516
+ * paste events, and integration with Angular Forms via ControlValueAccessor.
1517
+ *
1518
+ * @example
1519
+ * <b-otp>
1520
+ * <input b-otp-digit />
1521
+ * <input b-otp-digit />
1522
+ * <input b-otp-digit />
1523
+ * <input b-otp-digit />
1524
+ * </b-otp>
1525
+ */
1526
+ /**
1527
+ * Otp manages a group of digit inputs for OTP entry.
1528
+ * Implements keyboard navigation, paste handling, and ControlValueAccessor for Angular Forms.
1529
+ */
1530
+ class Otp {
1316
1531
  /**
1317
- * The trigger element that will be used to open the content.
1532
+ * The visual size of the OTP inputs. Accepts 'sm', 'md', or 'lg'. Default is 'md'.
1318
1533
  */
1319
- trigger = inject(ElementRef);
1534
+ size = model('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
1320
1535
  /**
1321
- * The content that will be displayed when the trigger is activated.
1536
+ * Computed signal for the number of digit inputs.
1322
1537
  */
1323
- content = viewChild('content');
1538
+ length = computed(() => this.digitInputs().length, ...(ngDevMode ? [{ debugName: "length" }] : []));
1324
1539
  /**
1325
- * The position of the content relative to the trigger.
1326
- * Example values: 'top-left', 'bottom-center', etc.
1540
+ * Emits the full OTP value when changed.
1327
1541
  */
1328
- position = model('right-top');
1542
+ otpChange = output();
1329
1543
  /**
1330
- * Signal indicating whether the content is visible or not.
1544
+ * Query for all child digit inputs (OtpDigitDirective).
1331
1545
  */
1332
- isContentVisible = signal(false);
1546
+ digitInputs = contentChildren(OtpDigitDirective, ...(ngDevMode ? [{ debugName: "digitInputs" }] : []));
1333
1547
  /**
1334
- * The gap (spacing) between the trigger and the content.
1548
+ * Internal array holding the current values of each digit input.
1335
1549
  */
1336
- gap = model(10);
1550
+ values = [];
1337
1551
  /**
1338
- * Signal that dynamically calculates and provides the adjusted position of the content.
1339
- * This position is adjusted to prevent overflow and ensure optimal visibility.
1552
+ * Model indicating whether the OTP input group is disabled.
1340
1553
  */
1341
- adjustedPosition = linkedSignal(() => this.calculateAdjustedPosition());
1554
+ disabled = model(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
1342
1555
  /**
1343
- * Signal that provides the animation parameters based on the adjusted
1344
- * position of the content. These parameters are used to animate the content.
1556
+ * Callback for propagating value changes to Angular Forms.
1345
1557
  */
1346
- animationParams = computed(() => {
1347
- const position = this.adjustedPosition();
1348
- const direction = position.split('-')[0];
1349
- const isCenter = position.includes('center');
1350
- const defaultParams = {
1351
- duration: '0.15s',
1352
- enterDelay: '0s',
1353
- leaveDelay: '0.1s',
1354
- scaleFrom: 0.99,
1355
- scaleTo: 1,
1356
- translateFrom: '',
1357
- translateTo: '',
1358
- };
1359
- switch (direction) {
1360
- case 'top':
1361
- return {
1362
- ...defaultParams,
1363
- translateFrom: isCenter
1364
- ? 'translate(-50%, 10px)'
1365
- : 'translateY(10px)',
1366
- translateTo: isCenter ? 'translate(-50%, 0)' : 'translateY(0)',
1367
- };
1368
- case 'bottom':
1369
- return {
1370
- ...defaultParams,
1371
- translateFrom: isCenter
1372
- ? 'translate(-50%, -10px)'
1373
- : 'translateY(-10px)',
1374
- translateTo: isCenter ? 'translate(-50%, 0)' : 'translateY(0)',
1375
- };
1376
- case 'left':
1377
- return {
1378
- ...defaultParams,
1379
- translateFrom: isCenter
1380
- ? 'translate(10px, -50%)'
1381
- : 'translateX(10px)',
1382
- translateTo: isCenter ? 'translate(0, -50%)' : 'translateX(0)',
1383
- };
1384
- case 'right':
1385
- return {
1386
- ...defaultParams,
1387
- translateFrom: isCenter
1388
- ? 'translate(-10px, -50%)'
1389
- : 'translateX(-10px)',
1390
- translateTo: isCenter ? 'translate(0, -50%)' : 'translateX(0)',
1391
- };
1392
- default:
1393
- return defaultParams;
1394
- }
1395
- });
1558
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
1559
+ onChange = () => { };
1396
1560
  /**
1397
- * Recalculates and updates the content's adjusted position when the window is scrolled.
1398
- * This ensures the content remains correctly positioned relative to the trigger even when scrolling.
1561
+ * Callback for marking the component as touched in Angular Forms.
1399
1562
  */
1400
- onWindowEvent() {
1401
- this.adjustedPosition.set(this.calculateAdjustedPosition());
1563
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
1564
+ onTouched = () => { };
1565
+ ngAfterContentInit() {
1566
+ // Inicializar listeners en los inputs hijos
1567
+ this.digitInputs().forEach((input, idx) => {
1568
+ const el = input.el.nativeElement;
1569
+ // maxLength y type se aplican por la directiva
1570
+ el.disabled = this.disabled();
1571
+ el.classList.remove('b-size-sm', 'b-size-md', 'b-size-lg');
1572
+ el.classList.add(`b-size-${this.size()}`);
1573
+ el.addEventListener('input', (event) => {
1574
+ this.onInput(event, idx);
1575
+ });
1576
+ el.addEventListener('keydown', (event) => {
1577
+ this.onKeyDown(event, idx);
1578
+ });
1579
+ el.addEventListener('paste', (event) => {
1580
+ this.onPaste(event);
1581
+ });
1582
+ });
1583
+ this.resetValues();
1402
1584
  }
1403
1585
  /**
1404
- * Closes the content when a click event occurs outside both the trigger and content elements.
1405
- * @param event The mouse event representing the click.
1406
- */
1407
- onClickOutside(event) {
1408
- if (this.isContentVisible() &&
1409
- this.isClickedOutsideContent(event) &&
1410
- this.isClickedOutsideTrigger(event)) {
1411
- this.isContentVisible.set(false);
1586
+ * Handles input event for each digit input.
1587
+ * Moves focus to next input if value entered.
1588
+ *
1589
+ * @param event - Input event
1590
+ *
1591
+ * @param idx - Index of the digit input
1592
+ */
1593
+ onInput(event, idx) {
1594
+ const input = event.target;
1595
+ const val = input.value;
1596
+ this.values[idx] = val;
1597
+ if (val && idx < this.length() - 1) {
1598
+ this.focusDigit(idx + 1);
1412
1599
  }
1600
+ this.emitValue();
1413
1601
  }
1414
1602
  /**
1415
- * Determines if a click event occurred outside the trigger and content elements.
1416
- * @param event The mouse event representing the click.
1417
- * @returns True if the click was outside both the trigger and content elements, false otherwise.
1603
+ * Handles keyboard navigation for digit inputs.
1604
+ * Supports Backspace, ArrowLeft, ArrowRight.
1605
+ *
1606
+ * @param event - Keyboard event
1607
+ *
1608
+ * @param idx - Index of the digit input
1418
1609
  */
1419
- isClickedOutsideContent(event) {
1420
- const contentElement = this.content()?.nativeElement;
1421
- if (!contentElement) {
1422
- return false;
1610
+ onKeyDown(event, idx) {
1611
+ const input = event.target;
1612
+ if (event.key === 'Backspace') {
1613
+ if (!input.value && idx > 0) {
1614
+ this.focusDigit(idx - 1);
1615
+ }
1616
+ this.values[idx] = '';
1617
+ this.emitValue();
1423
1618
  }
1424
- return !contentElement.contains(event.target);
1425
- }
1426
- /**
1427
- * Determines if a click event occurred outside the trigger element.
1428
- * @param event The mouse event representing the click.
1429
- * @returns True if the click was outside the trigger element, false otherwise.
1430
- */
1431
- isClickedOutsideTrigger(event) {
1432
- const triggerElement = this.trigger?.nativeElement;
1433
- if (!triggerElement) {
1434
- return false;
1619
+ else if (event.key === 'ArrowLeft' && idx > 0) {
1620
+ this.focusDigit(idx - 1);
1435
1621
  }
1436
- return !triggerElement.contains(event.target);
1437
- }
1438
- /**
1439
- * Handles keyboard events for the component.
1440
- * @param event The keyboard event to handle.
1441
- */
1442
- handleKeyboardEvent(event) {
1443
- if (event.key === 'Escape' || event.key === 'Enter') {
1444
- this.toggleContentVisibility();
1622
+ else if (event.key === 'ArrowRight' && idx < this.length() - 1) {
1623
+ this.focusDigit(idx + 1);
1445
1624
  }
1446
1625
  }
1447
1626
  /**
1448
- * Handles mouse events for the component.
1449
- * @param event The mouse event to handle.
1450
- */
1451
- handleMouseEvent(event) {
1452
- if (this.isClickedOutsideContent(event) &&
1453
- !this.isClickedOutsideTrigger(event)) {
1454
- this.toggleContentVisibility();
1455
- }
1627
+ * Handles paste event for the OTP input group.
1628
+ * Distributes pasted characters across digit inputs.
1629
+ *
1630
+ * @param event - Clipboard event
1631
+ */
1632
+ onPaste(event) {
1633
+ event.preventDefault();
1634
+ const paste = event.clipboardData?.getData('text') ?? '';
1635
+ const chars = paste.slice(0, this.length()).split('');
1636
+ chars.forEach((c, i) => {
1637
+ this.values[i] = c;
1638
+ const input = this.digitInputs()[i];
1639
+ if (input) {
1640
+ input.el.nativeElement.value = c;
1641
+ }
1642
+ });
1643
+ this.emitValue();
1644
+ this.focusDigit(chars.length - 1);
1456
1645
  }
1457
1646
  /**
1458
- * Toggles the visibility of the content, switching between visible and hidden states.
1459
- * This method is typically called in response to user interaction with the trigger element.
1647
+ * Focuses the digit input at the given index.
1648
+ *
1649
+ * @param idx - Index of the digit input to focus
1460
1650
  */
1461
- toggleContentVisibility() {
1462
- this.isContentVisible.set(!this.isContentVisible());
1651
+ focusDigit(idx) {
1652
+ const input = this.digitInputs()[idx];
1653
+ if (input) {
1654
+ input.el.nativeElement.focus();
1655
+ }
1463
1656
  }
1464
1657
  /**
1465
- * Shows the content (used for hover interaction).
1658
+ * Emits the full OTP value via output and ControlValueAccessor.
1466
1659
  */
1467
- showContent() {
1468
- this.isContentVisible.set(true);
1660
+ emitValue() {
1661
+ const otp = this.values.join('');
1662
+ this.otpChange.emit(otp);
1663
+ this.onChange(otp);
1664
+ this.onTouched();
1469
1665
  }
1470
1666
  /**
1471
- * Hides the content (used for hover interaction).
1667
+ * Resets all digit input values to empty.
1472
1668
  */
1473
- hideContent() {
1474
- this.isContentVisible.set(false);
1669
+ resetValues() {
1670
+ this.values = Array(this.length()).fill('');
1671
+ this.digitInputs().forEach(input => {
1672
+ input.el.nativeElement.value = '';
1673
+ });
1475
1674
  }
1675
+ // ControlValueAccessor implementation
1476
1676
  /**
1477
- * Calculates the optimal adjusted position for the content relative to the trigger.
1478
- * This method considers available space in the viewport to prevent content overflow
1479
- * and ensures the content is fully visible to the user.
1480
- * @returns The adjusted position as a Position type string (e.g., 'bottom-left').
1677
+ * Writes a new value to the OTP input group.
1678
+ * Called by Angular Forms to update the value.
1679
+ *
1680
+ * @param value - New OTP value
1481
1681
  */
1482
- calculateAdjustedPosition() {
1483
- if (!this.trigger?.nativeElement || !this.content()?.nativeElement) {
1484
- return this.position();
1485
- }
1486
- const triggerElement = this.trigger.nativeElement;
1487
- const contentElement = this.content().nativeElement;
1488
- const triggerRect = triggerElement.getBoundingClientRect();
1489
- const contentRect = contentElement.getBoundingClientRect();
1490
- const extraMargin = this.gap();
1491
- const [primary, secondary] = this.position().split('-');
1492
- const adjustedPrimary = this.adjustPrimaryDirection(primary, triggerRect, contentRect, extraMargin);
1493
- const adjustedSecondary = this.adjustSecondaryAlignment(secondary, adjustedPrimary, triggerRect, contentRect);
1494
- return `${adjustedPrimary}-${adjustedSecondary}`;
1495
- }
1496
- /**
1497
- * Adjusts the primary direction (top, bottom, left, right) of the content's position
1498
- * based on available viewport space. This ensures the content does not overflow the screen
1499
- * in the primary direction.
1500
- * @param primary The initially desired primary direction.
1501
- * @param triggerRect The bounding rectangle of the trigger element.
1502
- * @param contentRect The bounding rectangle of the content element.
1503
- * @param margin Extra margin to consider for spacing around the content.
1504
- * @returns The adjusted primary direction.
1505
- */
1506
- adjustPrimaryDirection(primary, triggerRect, contentRect, margin) {
1507
- if (['top', 'bottom'].includes(primary)) {
1508
- const neededSpace = contentRect.height + margin;
1509
- const spaceBelow = window.innerHeight - triggerRect.bottom;
1510
- const spaceAbove = triggerRect.top;
1511
- if (primary === 'bottom' &&
1512
- spaceBelow < neededSpace &&
1513
- spaceAbove > spaceBelow) {
1514
- return 'top';
1515
- }
1516
- if (primary === 'top' &&
1517
- spaceAbove < neededSpace &&
1518
- spaceBelow > spaceAbove) {
1519
- return 'bottom';
1520
- }
1521
- }
1522
- else {
1523
- const neededSpace = contentRect.width + margin;
1524
- const spaceRight = window.innerWidth - triggerRect.right;
1525
- const spaceLeft = triggerRect.left;
1526
- if (primary === 'right' &&
1527
- spaceRight < neededSpace &&
1528
- spaceLeft > spaceRight) {
1529
- return 'left';
1530
- }
1531
- if (primary === 'left' &&
1532
- spaceLeft < neededSpace &&
1533
- spaceRight > spaceLeft) {
1534
- return 'right';
1535
- }
1536
- }
1537
- return primary;
1538
- }
1539
- /**
1540
- * Adjusts the secondary alignment (left, right, center for top/bottom primary, top, bottom, center for left/right primary)
1541
- * of the content's position to prevent horizontal or vertical overflow. This method ensures that
1542
- * the content is fully visible within the viewport in the secondary dimension.
1543
- * @param secondary The initially desired secondary alignment.
1544
- * @param primary The already adjusted primary direction.
1545
- * @param triggerRect The bounding rectangle of the trigger element.
1546
- * @param contentRect The bounding rectangle of the content element.
1547
- * @returns The adjusted secondary alignment.
1548
- */
1549
- adjustSecondaryAlignment(secondary, primary, triggerRect, contentRect) {
1550
- if (['top', 'bottom'].includes(primary)) {
1551
- if (secondary === 'left') {
1552
- const contentRightPos = triggerRect.left + contentRect.width;
1553
- if (contentRightPos > window.innerWidth) {
1554
- return 'right';
1555
- }
1556
- }
1557
- else if (secondary === 'right') {
1558
- const contentLeftPos = triggerRect.right - contentRect.width;
1559
- if (contentLeftPos < 0) {
1560
- return 'left';
1561
- }
1562
- }
1563
- else if (secondary === 'center') {
1564
- const triggerCenter = triggerRect.left + triggerRect.width / 2;
1565
- const contentLeftPos = triggerCenter - contentRect.width / 2;
1566
- const contentRightPos = contentLeftPos + contentRect.width;
1567
- if (contentLeftPos < 0) {
1568
- return 'left';
1569
- }
1570
- else if (contentRightPos > window.innerWidth) {
1571
- return 'right';
1682
+ writeValue(value) {
1683
+ this.values = Array(this.length()).fill('');
1684
+ if (value) {
1685
+ value
1686
+ .slice(0, this.length())
1687
+ .split('')
1688
+ .forEach((c, i) => {
1689
+ this.values[i] = c;
1690
+ const input = this.digitInputs()[i];
1691
+ if (input) {
1692
+ input.el.nativeElement.value = c;
1572
1693
  }
1573
- }
1694
+ });
1574
1695
  }
1575
- else if (['left', 'right'].includes(primary)) {
1576
- if (secondary === 'top') {
1577
- const contentBottomPos = triggerRect.top + contentRect.height;
1578
- if (contentBottomPos > window.innerHeight) {
1579
- return 'bottom';
1580
- }
1581
- }
1582
- else if (secondary === 'bottom') {
1583
- const contentTopPos = triggerRect.bottom - contentRect.height;
1584
- if (contentTopPos < 0) {
1585
- return 'top';
1586
- }
1587
- }
1588
- else if (secondary === 'center') {
1589
- const triggerCenter = triggerRect.top + triggerRect.height / 2;
1590
- const contentTopPos = triggerCenter - contentRect.height / 2;
1591
- const contentBottomPos = contentTopPos + contentRect.height;
1592
- if (contentTopPos < 0) {
1593
- return 'top';
1594
- }
1595
- else if (contentBottomPos > window.innerHeight) {
1596
- return 'bottom';
1597
- }
1598
- }
1696
+ else {
1697
+ this.resetValues();
1599
1698
  }
1600
- return secondary;
1601
1699
  }
1602
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: AttachedBox, deps: [], target: i0.ɵɵFactoryTarget.Component });
1603
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.7", type: AttachedBox, isStandalone: true, selector: "b-attached-box", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { position: "positionChange", gap: "gapChange" }, host: { listeners: { "click": "type() === \"click\" ? handleMouseEvent($event) : null", "keydown": "handleKeyboardEvent($event)", "mouseenter": "type() === \"hover\" ? showContent() : null", "mouseleave": "type() === \"hover\" ? hideContent() : null", "window:scroll": "onWindowEvent()", "window:resize": "onWindowEvent()", "document:click": "onClickOutside($event)" }, properties: { "attr.tabindex": "0" } }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-content select=\"[b-attached-box-trigger]\" />\r\n<div\r\n #content\r\n class=\"b-attached-box-content\"\r\n [class]=\"adjustedPosition()\"\r\n [class.visible]=\"isContentVisible()\"\r\n [style.--gap.px]=\"gap()\"\r\n [style.--duration]=\"animationParams().duration\"\r\n [style.--enter-delay]=\"animationParams().enterDelay\"\r\n [style.--leave-delay]=\"animationParams().leaveDelay\"\r\n [style.--scale-from]=\"animationParams().scaleFrom\"\r\n [style.--scale-to]=\"animationParams().scaleTo\"\r\n [style.--translate-from]=\"animationParams().translateFrom\"\r\n [style.--translate-to]=\"animationParams().translateTo\">\r\n <ng-content select=\"[b-attached-box-content]\" />\r\n</div>\r\n" });
1604
- }
1605
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: AttachedBox, decorators: [{
1606
- type: Component,
1607
- args: [{ selector: 'b-attached-box', host: {
1608
- '[attr.tabindex]': '0',
1609
- '(click)': 'type() === "click" ? handleMouseEvent($event) : null',
1610
- '(keydown)': 'handleKeyboardEvent($event)',
1611
- '(mouseenter)': 'type() === "hover" ? showContent() : null',
1612
- '(mouseleave)': 'type() === "hover" ? hideContent() : null',
1613
- }, template: "<ng-content select=\"[b-attached-box-trigger]\" />\r\n<div\r\n #content\r\n class=\"b-attached-box-content\"\r\n [class]=\"adjustedPosition()\"\r\n [class.visible]=\"isContentVisible()\"\r\n [style.--gap.px]=\"gap()\"\r\n [style.--duration]=\"animationParams().duration\"\r\n [style.--enter-delay]=\"animationParams().enterDelay\"\r\n [style.--leave-delay]=\"animationParams().leaveDelay\"\r\n [style.--scale-from]=\"animationParams().scaleFrom\"\r\n [style.--scale-to]=\"animationParams().scaleTo\"\r\n [style.--translate-from]=\"animationParams().translateFrom\"\r\n [style.--translate-to]=\"animationParams().translateTo\">\r\n <ng-content select=\"[b-attached-box-content]\" />\r\n</div>\r\n" }]
1614
- }], propDecorators: { onWindowEvent: [{
1615
- type: HostListener,
1616
- args: ['window:scroll']
1617
- }, {
1618
- type: HostListener,
1619
- args: ['window:resize']
1620
- }], onClickOutside: [{
1621
- type: HostListener,
1622
- args: ['document:click', ['$event']]
1623
- }] } });
1624
-
1625
- class Label {
1626
- /**
1627
- * The input element.
1628
- */
1629
- input = contentChild(Input);
1630
- /**
1631
- * The switch element.
1632
- */
1633
- switch = contentChild(Switch);
1634
1700
  /**
1635
- * The checkbox element.
1636
- */
1637
- checkbox = contentChild(Checkbox);
1638
- /**
1639
- * The textarea element.
1701
+ * Registers a callback to be called when the value changes.
1702
+ *
1703
+ * @param fn - Callback function
1640
1704
  */
1641
- textarea = contentChild(Textarea);
1705
+ registerOnChange(fn) {
1706
+ this.onChange = fn;
1707
+ }
1642
1708
  /**
1643
- * Whether the label should be up.
1709
+ * Registers a callback to be called when the component is touched.
1710
+ *
1711
+ * @param fn - Callback function
1644
1712
  */
1645
- labelUp = computed(() => {
1646
- const input = this.input();
1647
- const textarea = this.textarea();
1648
- return (input?.focused() ||
1649
- input?.value() ||
1650
- input?.placeholder() ||
1651
- textarea?.focused() ||
1652
- textarea?.value() ||
1653
- textarea?.placeholder());
1654
- });
1713
+ registerOnTouched(fn) {
1714
+ this.onTouched = fn;
1715
+ }
1655
1716
  /**
1656
- * The label width.
1717
+ * Sets the disabled state of the OTP input group.
1718
+ * Called by Angular Forms to enable/disable the component.
1719
+ *
1720
+ * @param isDisabled - Boolean indicating disabled state
1657
1721
  */
1658
- maxWidth = computed(() => {
1659
- const input = this.input();
1660
- const textarea = this.textarea();
1661
- return input?.maxWidth() || textarea?.cols();
1662
- });
1663
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Label, deps: [], target: i0.ɵɵFactoryTarget.Component });
1664
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.7", type: Label, isStandalone: true, selector: "b-label", host: { properties: { "class.up": "labelUp()", "style.max-width": "maxWidth()", "class.is-switch": "switch()", "class.is-checkbox": "checkbox()", "class.is-textarea": "textarea()" } }, queries: [{ propertyName: "input", first: true, predicate: Input, descendants: true, isSignal: true }, { propertyName: "switch", first: true, predicate: Switch, descendants: true, isSignal: true }, { propertyName: "checkbox", first: true, predicate: Checkbox, descendants: true, isSignal: true }, { propertyName: "textarea", first: true, predicate: Textarea, descendants: true, isSignal: true }], ngImport: i0, template: `<ng-content />`, isInline: true });
1722
+ setDisabledState(isDisabled) {
1723
+ this.disabled.set(isDisabled);
1724
+ this.digitInputs().forEach(input => {
1725
+ input.el.nativeElement.disabled = isDisabled;
1726
+ input.el.nativeElement.classList.remove('b-size-sm', 'b-size-md', 'b-size-lg');
1727
+ input.el.nativeElement.classList.add(`b-size-${this.size()}`);
1728
+ });
1729
+ }
1730
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Otp, deps: [], target: i0.ɵɵFactoryTarget.Component });
1731
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.2.3", type: Otp, isStandalone: true, selector: "b-otp", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { size: "sizeChange", otpChange: "otpChange", disabled: "disabledChange" }, providers: [
1732
+ {
1733
+ provide: NG_VALUE_ACCESSOR,
1734
+ useExisting: forwardRef(() => Otp),
1735
+ multi: true,
1736
+ },
1737
+ ], queries: [{ propertyName: "digitInputs", predicate: OtpDigitDirective, isSignal: true }], ngImport: i0, template: `<ng-content />`, isInline: true });
1665
1738
  }
1666
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Label, decorators: [{
1739
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Otp, decorators: [{
1667
1740
  type: Component,
1668
1741
  args: [{
1669
- selector: 'b-label',
1670
- imports: [],
1742
+ selector: 'b-otp',
1671
1743
  template: `<ng-content />`,
1744
+ providers: [
1745
+ {
1746
+ provide: NG_VALUE_ACCESSOR,
1747
+ useExisting: forwardRef(() => Otp),
1748
+ multi: true,
1749
+ },
1750
+ ],
1751
+ }]
1752
+ }] });
1753
+ class OtpDigitDirective {
1754
+ /** Reference to the native input element. */
1755
+ el = inject((ElementRef));
1756
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: OtpDigitDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1757
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.3", type: OtpDigitDirective, isStandalone: true, selector: "input[b-otp-digit]", host: { attributes: { "maxlength": "1" } }, ngImport: i0 });
1758
+ }
1759
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: OtpDigitDirective, decorators: [{
1760
+ type: Directive,
1761
+ args: [{
1762
+ selector: 'input[b-otp-digit]',
1672
1763
  host: {
1673
- '[class.up]': 'labelUp()',
1674
- '[style.max-width]': 'maxWidth()',
1675
- '[class.is-switch]': 'switch()',
1676
- '[class.is-checkbox]': 'checkbox()',
1677
- '[class.is-textarea]': 'textarea()',
1764
+ maxlength: '1',
1678
1765
  },
1679
1766
  }]
1680
1767
  }] });
1681
1768
 
1682
1769
  class Badge {
1683
1770
  /** The variant of the badge. */
1684
- variant = input('primary');
1771
+ variant = input('primary', ...(ngDevMode ? [{ debugName: "variant" }] : []));
1685
1772
  /** The size of the badge. */
1686
- size = input('default');
1687
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Badge, deps: [], target: i0.ɵɵFactoryTarget.Component });
1688
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.7", type: Badge, isStandalone: true, selector: "span[b-badge]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "variant() + \" size-\" + size()" } }, ngImport: i0, template: `<ng-content />`, isInline: true });
1773
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
1774
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Badge, deps: [], target: i0.ɵɵFactoryTarget.Component });
1775
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: Badge, isStandalone: true, selector: "span[b-badge]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.b-variant-primary": "variant() === \"primary\"", "class.b-variant-secondary": "variant() === \"secondary\"", "class.b-variant-ghost": "variant() === \"ghost\"", "class.b-variant-outlined": "variant() === \"outlined\"", "class.b-variant-destructive": "variant() === \"destructive\"", "class.b-size-sm": "size() === \"sm\"", "class.b-size-md": "size() === \"md\"", "class.b-size-lg": "size() === \"lg\"" } }, ngImport: i0, template: `<ng-content />`, isInline: true });
1689
1776
  }
1690
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Badge, decorators: [{
1777
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Badge, decorators: [{
1691
1778
  type: Component,
1692
1779
  args: [{
1693
1780
  selector: 'span[b-badge]',
1694
1781
  template: `<ng-content />`,
1695
1782
  host: {
1696
- '[class]': 'variant() + " size-" + size()',
1783
+ '[class.b-variant-primary]': 'variant() === "primary"',
1784
+ '[class.b-variant-secondary]': 'variant() === "secondary"',
1785
+ '[class.b-variant-ghost]': 'variant() === "ghost"',
1786
+ '[class.b-variant-outlined]': 'variant() === "outlined"',
1787
+ '[class.b-variant-destructive]': 'variant() === "destructive"',
1788
+ '[class.b-size-sm]': 'size() === "sm"',
1789
+ '[class.b-size-md]': 'size() === "md"',
1790
+ '[class.b-size-lg]': 'size() === "lg"',
1697
1791
  },
1698
1792
  }]
1699
1793
  }] });
@@ -1702,7 +1796,7 @@ class Checkbox {
1702
1796
  /**
1703
1797
  * Value of the checkbox.
1704
1798
  */
1705
- value = model(false);
1799
+ value = signal(false, ...(ngDevMode ? [{ debugName: "value" }] : []));
1706
1800
  /**
1707
1801
  * Reference to the checkbox element.
1708
1802
  */
@@ -1711,6 +1805,10 @@ class Checkbox {
1711
1805
  * Event emitted when the value changes.
1712
1806
  */
1713
1807
  valueChange = output();
1808
+ /**
1809
+ * Tamaño del checkbox: 'sm', 'md', 'lg'.
1810
+ */
1811
+ size = model('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
1714
1812
  /**
1715
1813
  * Initializes the checkbox value after the view is initialized.
1716
1814
  */
@@ -1725,10 +1823,10 @@ class Checkbox {
1725
1823
  this.value.set(newValue);
1726
1824
  this.valueChange.emit(newValue);
1727
1825
  }
1728
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Checkbox, deps: [], target: i0.ɵɵFactoryTarget.Component });
1729
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.7", type: Checkbox, isStandalone: true, selector: "input[b-checkbox]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", valueChange: "valueChange" }, host: { listeners: { "click": "toggleValue()", "keydown.enter": "toggleValue()", "keydown.space": "toggleValue()" }, properties: { "attr.role": "checkbox", "attr.checked": "value()", "attr.aria-checked": "value()" } }, ngImport: i0, template: ``, isInline: true });
1826
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Checkbox, deps: [], target: i0.ɵɵFactoryTarget.Component });
1827
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: Checkbox, isStandalone: true, selector: "input[b-checkbox]", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", size: "sizeChange" }, host: { listeners: { "click": "toggleValue()", "keydown.enter": "toggleValue()", "keydown.space": "toggleValue()" }, properties: { "attr.role": "checkbox", "attr.checked": "value()", "attr.aria-checked": "value()", "class.b-size-sm": "size() === \"sm\"", "class.b-size-md": "size() === \"md\"", "class.b-size-lg": "size() === \"lg\"" } }, ngImport: i0, template: ``, isInline: true });
1730
1828
  }
1731
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Checkbox, decorators: [{
1829
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Checkbox, decorators: [{
1732
1830
  type: Component,
1733
1831
  args: [{
1734
1832
  selector: 'input[b-checkbox]',
@@ -1740,222 +1838,227 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
1740
1838
  '(click)': 'toggleValue()',
1741
1839
  '(keydown.enter)': 'toggleValue()',
1742
1840
  '(keydown.space)': 'toggleValue()',
1841
+ '[class.b-size-sm]': 'size() === "sm"',
1842
+ '[class.b-size-md]': 'size() === "md"',
1843
+ '[class.b-size-lg]': 'size() === "lg"',
1743
1844
  },
1744
1845
  }]
1745
1846
  }] });
1746
1847
 
1747
- class Textarea {
1748
- /**
1749
- * The placeholder text for the textarea.
1750
- */
1751
- placeholder = input('');
1752
- /**
1753
- * The value of the textarea.
1754
- */
1755
- value = signal(null);
1756
- /**
1757
- * The number of rows for the textarea.
1758
- */
1759
- rows = input(3);
1848
+ class TextareaComponent {
1760
1849
  /**
1761
- * The number of columns for the textarea.
1850
+ * The size of the textarea.
1762
1851
  */
1763
- cols = input(30);
1764
- /**
1765
- * Whether the textarea is invalid.
1766
- */
1767
- invalid = model(false);
1852
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
1853
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: TextareaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1854
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: TextareaComponent, isStandalone: true, selector: "textarea[b-textarea]", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.b-size-sm": "size() === \"sm\"", "class.b-size-md": "size() === \"md\"", "class.b-size-lg": "size() === \"lg\"" } }, ngImport: i0, template: ``, isInline: true });
1855
+ }
1856
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: TextareaComponent, decorators: [{
1857
+ type: Component,
1858
+ args: [{
1859
+ selector: 'textarea[b-textarea]',
1860
+ template: ``,
1861
+ host: {
1862
+ '[class.b-size-sm]': 'size() === "sm"',
1863
+ '[class.b-size-md]': 'size() === "md"',
1864
+ '[class.b-size-lg]': 'size() === "lg"',
1865
+ },
1866
+ }]
1867
+ }] });
1868
+
1869
+ class Range {
1768
1870
  /**
1769
- * Whether the textarea is disabled.
1871
+ * Current value of the range.
1770
1872
  */
1771
- disabled = model(false);
1873
+ value = model('0', ...(ngDevMode ? [{ debugName: "value" }] : []));
1772
1874
  /**
1773
- * Whether the textarea is focused.
1774
- * This will be used by the Label component.
1875
+ * Size of the range slider (sm, md, lg)
1775
1876
  */
1776
- focused = signal(false);
1877
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
1777
1878
  /**
1778
- * Event emitted when the value changes.
1879
+ * Reference to the range element.
1779
1880
  */
1780
- valueChange = output();
1881
+ el = inject(ElementRef);
1781
1882
  /**
1782
- * Reference to the textarea element.
1883
+ * Initializes the range value after the view is initialized.
1783
1884
  */
1784
- el = inject(ElementRef);
1885
+ ngAfterViewInit() {
1886
+ this.value.set(this.el.nativeElement.value);
1887
+ }
1785
1888
  /**
1786
- * Handles the input event.
1787
- * @param event The input event.
1889
+ * Handles the input event to update the value.
1788
1890
  */
1789
1891
  onInput(event) {
1790
- const target = event.target;
1791
- this.value.set(target.value);
1792
- this.valueChange.emit(target.value);
1892
+ this.value.set(event.target.value);
1793
1893
  }
1794
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Textarea, deps: [], target: i0.ɵɵFactoryTarget.Component });
1795
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.7", type: Textarea, isStandalone: true, selector: "textarea[b-textarea]", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, cols: { classPropertyName: "cols", publicName: "cols", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { invalid: "invalidChange", disabled: "disabledChange", valueChange: "valueChange" }, host: { listeners: { "input": "onInput($event)", "focus": "focused.set(true)", "blur": "focused.set(false)" }, properties: { "placeholder": "placeholder() || \"\"", "rows": "rows()", "cols": "cols()", "class.ng-invalid": "invalid()", "class.disabled": "disabled()" } }, ngImport: i0, template: ``, isInline: true });
1894
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Range, deps: [], target: i0.ɵɵFactoryTarget.Component });
1895
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: Range, isStandalone: true, selector: "input[b-range]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { listeners: { "input": "onInput($event)" }, properties: { "attr.value": "value()", "class.b-size-sm": "size() === \"sm\"", "class.b-size-md": "size() === \"md\"", "class.b-size-lg": "size() === \"lg\"" } }, ngImport: i0, template: ``, isInline: true });
1796
1896
  }
1797
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Textarea, decorators: [{
1897
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Range, decorators: [{
1798
1898
  type: Component,
1799
1899
  args: [{
1800
- selector: 'textarea[b-textarea]',
1900
+ selector: 'input[b-range]',
1801
1901
  template: ``,
1802
1902
  host: {
1803
- '[placeholder]': 'placeholder() || ""',
1804
- '[rows]': 'rows()',
1805
- '[cols]': 'cols()',
1806
- '[class.ng-invalid]': 'invalid()',
1807
- '[class.disabled]': 'disabled()',
1903
+ '[attr.value]': 'value()',
1808
1904
  '(input)': 'onInput($event)',
1809
- '(focus)': 'focused.set(true)',
1810
- '(blur)': 'focused.set(false)',
1905
+ '[class.b-size-sm]': 'size() === "sm"',
1906
+ '[class.b-size-md]': 'size() === "md"',
1907
+ '[class.b-size-lg]': 'size() === "lg"',
1811
1908
  },
1812
1909
  }]
1813
1910
  }] });
1814
1911
 
1815
- class InputGroup {
1912
+ class TooltipTrigger {
1816
1913
  /**
1817
- * Whether the input group elements are separated by a border.
1914
+ * Emits when the tooltip should become active/visible (mouseover or focus).
1818
1915
  */
1819
- bordered = input(true);
1916
+ activeEmitter = output();
1820
1917
  /**
1821
- * The maximum width of the input.
1918
+ * Emits when the tooltip should become inactive/hidden (mouseout or blur).
1822
1919
  */
1823
- maxWidth = input('');
1824
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: InputGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
1825
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.7", type: InputGroup, isStandalone: true, selector: "b-input-group", inputs: { bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.bordered": "bordered()", "style.max-width": "maxWidth()" } }, ngImport: i0, template: `<ng-content />`, isInline: true });
1920
+ inactiveEmitter = output();
1921
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: TooltipTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1922
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.3", type: TooltipTrigger, isStandalone: true, selector: "[bTooltipTrigger]", outputs: { activeEmitter: "activeEmitter", inactiveEmitter: "inactiveEmitter" }, host: { listeners: { "mouseover": "activeEmitter.emit()", "focus": "activeEmitter.emit()", "mouseout": "inactiveEmitter.emit()", "blur": "inactiveEmitter.emit()" } }, ngImport: i0 });
1826
1923
  }
1827
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: InputGroup, decorators: [{
1924
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: TooltipTrigger, decorators: [{
1925
+ type: Directive,
1926
+ args: [{
1927
+ selector: '[bTooltipTrigger]',
1928
+ host: {
1929
+ '(mouseover)': 'activeEmitter.emit()',
1930
+ '(focus)': 'activeEmitter.emit()',
1931
+ '(mouseout)': 'inactiveEmitter.emit()',
1932
+ '(blur)': 'inactiveEmitter.emit()',
1933
+ },
1934
+ }]
1935
+ }] });
1936
+
1937
+ class TooltipContent {
1938
+ /**
1939
+ * Reference to the ConnectedOverlay to determine the direction of the overlay.
1940
+ */
1941
+ overlay = inject(ConnectedOverlay$1);
1942
+ /**
1943
+ * Computed signal representing the direction of the overlay.
1944
+ */
1945
+ direction = computed(() => this.overlay.direction(), ...(ngDevMode ? [{ debugName: "direction" }] : []));
1946
+ constructor() {
1947
+ effect(() => console.log(this.direction()));
1948
+ }
1949
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: TooltipContent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1950
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.3", type: TooltipContent, isStandalone: true, selector: "b-tooltip-content", host: { properties: { "animate.enter": "\"b-tooltip-content-entering-\" + this.direction()", "animate.leave": "\"b-tooltip-content-leaving-\" + this.direction()" } }, ngImport: i0, template: `<ng-content />`, isInline: true });
1951
+ }
1952
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: TooltipContent, decorators: [{
1828
1953
  type: Component,
1829
1954
  args: [{
1830
- selector: 'b-input-group',
1955
+ selector: 'b-tooltip-content',
1956
+ imports: [],
1831
1957
  template: `<ng-content />`,
1832
1958
  host: {
1833
- '[class.bordered]': 'bordered()',
1834
- '[style.max-width]': 'maxWidth()',
1959
+ '[animate.enter]': '"b-tooltip-content-entering-" + this.direction()',
1960
+ '[animate.leave]': '"b-tooltip-content-leaving-" + this.direction()',
1835
1961
  },
1836
1962
  }]
1837
- }] });
1963
+ }], ctorParameters: () => [] });
1838
1964
 
1839
- class Range {
1965
+ class Tooltip {
1840
1966
  /**
1841
- * Current value of the range.
1967
+ * Reference to the overlay directive instance.
1968
+ * Used to control the dropdown overlay for the select component.
1969
+ *
1970
+ * @readonly
1842
1971
  */
1843
- value = model('0');
1972
+ overlay = contentChild(ConnectedOverlay, ...(ngDevMode ? [{ debugName: "overlay" }] : []));
1844
1973
  /**
1845
- * Maximum width of the range slider.
1974
+ * Reference to the tooltip trigger directive.
1975
+ * Used to handle trigger events (click, keydown) for opening/closing the tooltip.
1976
+ *
1977
+ * @readonly
1846
1978
  */
1847
- maxWidth = input('100%');
1979
+ tooltipTrigger = contentChild(TooltipTrigger, ...(ngDevMode ? [{ debugName: "tooltipTrigger" }] : []));
1848
1980
  /**
1849
- * Reference to the range element.
1981
+ * Reference to the tooltip content component.
1982
+ * Used to manage the content of the tooltip.
1983
+ *
1984
+ * @readonly
1850
1985
  */
1851
- el = inject(ElementRef);
1986
+ tooltipContent = contentChild(TooltipContent, ...(ngDevMode ? [{ debugName: "tooltipContent" }] : []));
1852
1987
  /**
1853
- * Initializes the range value after the view is initialized.
1988
+ * Input signal to set the size of the tooltip.
1989
+ * Can be 'sm', 'md', or 'lg'. Default is 'md'.
1990
+ *
1991
+ * @readonly
1992
+ * @defaultValue 'md'
1854
1993
  */
1855
- ngAfterViewInit() {
1856
- this.value.set(this.el.nativeElement.value);
1994
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
1995
+ /**
1996
+ * Input signal to set the visual variant of the tooltip.
1997
+ * Can be 'primary', 'secondary', 'ghost', 'outlined', or 'destructive'.
1998
+ * Default is 'primary'.
1999
+ *
2000
+ * @readonly
2001
+ * @defaultValue 'primary'
2002
+ */
2003
+ variant = input('primary', ...(ngDevMode ? [{ debugName: "variant" }] : []));
2004
+ /**
2005
+ * Lifecycle hook that is called after data-bound properties are initialized.
2006
+ * Sets up mouse event handling for the tooltip trigger.
2007
+ */
2008
+ ngAfterContentInit() {
2009
+ this.handleTooltipEvents();
2010
+ this.handlePanelClasses();
1857
2011
  }
1858
2012
  /**
1859
- * Handles the input event to update the value.
2013
+ * Sets up subscriptions to mouse events from the tooltip trigger.
2014
+ * Logs messages to the console on mouse over and mouse out events.
2015
+ *
2016
+ * @private
1860
2017
  */
1861
- onInput(event) {
1862
- this.value.set(event.target.value);
2018
+ handleTooltipEvents() {
2019
+ this.tooltipTrigger()?.activeEmitter.subscribe(() => {
2020
+ this.overlay()?.openOverlay();
2021
+ });
2022
+ this.tooltipTrigger()?.inactiveEmitter.subscribe(() => {
2023
+ this.overlay()?.closeOverlay();
2024
+ });
1863
2025
  }
1864
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Range, deps: [], target: i0.ɵɵFactoryTarget.Component });
1865
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.7", type: Range, isStandalone: true, selector: "input[b-range]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { listeners: { "input": "onInput($event)" }, properties: { "attr.value": "value()", "style.max-width": "maxWidth()" } }, ngImport: i0, template: ``, isInline: true });
2026
+ /**
2027
+ * Sets the panel size class on the overlay based on the tooltip size input.
2028
+ */
2029
+ handlePanelClasses() {
2030
+ this.overlay().cdkConnectedOverlay.panelClass = [
2031
+ `b-size-${this.size()}`,
2032
+ `b-variant-${this.variant()}`,
2033
+ ];
2034
+ }
2035
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Tooltip, deps: [], target: i0.ɵɵFactoryTarget.Component });
2036
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.2.3", type: Tooltip, isStandalone: true, selector: "b-tooltip", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.b-size-sm": "size() === \"sm\"", "class.b-size-md": "size() === \"md\"", "class.b-size-lg": "size() === \"lg\"" } }, queries: [{ propertyName: "overlay", first: true, predicate: ConnectedOverlay, descendants: true, isSignal: true }, { propertyName: "tooltipTrigger", first: true, predicate: TooltipTrigger, descendants: true, isSignal: true }, { propertyName: "tooltipContent", first: true, predicate: TooltipContent, descendants: true, isSignal: true }], ngImport: i0, template: `<ng-content />`, isInline: true });
1866
2037
  }
1867
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Range, decorators: [{
2038
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Tooltip, decorators: [{
1868
2039
  type: Component,
1869
2040
  args: [{
1870
- selector: 'input[b-range]',
1871
- template: ``,
2041
+ selector: 'b-tooltip',
2042
+ template: `<ng-content />`,
1872
2043
  host: {
1873
- '[attr.value]': 'value()',
1874
- '[style.max-width]': 'maxWidth()',
1875
- '(input)': 'onInput($event)',
2044
+ '[class.b-size-sm]': 'size() === "sm"',
2045
+ '[class.b-size-md]': 'size() === "md"',
2046
+ '[class.b-size-lg]': 'size() === "lg"',
1876
2047
  },
1877
2048
  }]
1878
2049
  }] });
1879
2050
 
1880
- /**
1881
- * TooltipComponent is a reusable UI component that displays a tooltip
1882
- * with customizable position, gap, variant, and size.
1883
- */
1884
- class TooltipComponent {
1885
- /**
1886
- * The position of the tooltip relative to its trigger element.
1887
- * Defaults to 'top-center'.
1888
- */
1889
- position = input('top-center');
1890
- /**
1891
- * The gap (in pixels) between the tooltip and its trigger element.
1892
- * Defaults to 8.
1893
- */
1894
- gap = input(8);
1895
- /**
1896
- * The visual variant of the tooltip. Options include:
1897
- * - 'primary'
1898
- * - 'secondary'
1899
- * - 'ghost'
1900
- * - 'outlined'
1901
- * Defaults to 'primary'.
1902
- */
1903
- variant = input('primary');
1904
- /**
1905
- * The size of the tooltip. Options include:
1906
- * - 'small'
1907
- * - 'default'
1908
- * Defaults to 'default'.
1909
- */
1910
- size = input('default');
1911
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: TooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1912
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.7", type: TooltipComponent, isStandalone: true, selector: "b-tooltip", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
1913
- <b-attached-box [type]="'hover'" [position]="position()" [gap]="gap()">
1914
- <ng-content b-attached-box-trigger />
1915
- <div
1916
- b-attached-box-content
1917
- class="b-tooltip-content"
1918
- [class]="variant() + ' size-' + size()">
1919
- <ng-content select="[b-tooltip-content]" />
1920
- </div>
1921
- </b-attached-box>
1922
- `, isInline: true, dependencies: [{ kind: "component", type: AttachedBox, selector: "b-attached-box", inputs: ["type", "position", "gap"], outputs: ["positionChange", "gapChange"] }] });
1923
- }
1924
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: TooltipComponent, decorators: [{
1925
- type: Component,
1926
- args: [{
1927
- selector: 'b-tooltip',
1928
- template: `
1929
- <b-attached-box [type]="'hover'" [position]="position()" [gap]="gap()">
1930
- <ng-content b-attached-box-trigger />
1931
- <div
1932
- b-attached-box-content
1933
- class="b-tooltip-content"
1934
- [class]="variant() + ' size-' + size()">
1935
- <ng-content select="[b-tooltip-content]" />
1936
- </div>
1937
- </b-attached-box>
1938
- `,
1939
- standalone: true,
1940
- imports: [AttachedBox],
1941
- }]
1942
- }] });
1943
-
1944
2051
  class ColorPicker {
1945
- /**
1946
- * Specifies the maximum width of the input.
1947
- */
1948
- maxWidth = input('');
1949
2052
  /**
1950
2053
  * Represents the value of the input.
1951
2054
  */
1952
- value = signal('#ffffff');
2055
+ value = signal('#ffffff', ...(ngDevMode ? [{ debugName: "value" }] : []));
1953
2056
  /**
1954
2057
  * Computed signal for the text color with single quotes.
1955
2058
  */
1956
2059
  valueWithSingleQuotes = computed(() => {
1957
2060
  return `'${this.value()}'`;
1958
- });
2061
+ }, ...(ngDevMode ? [{ debugName: "valueWithSingleQuotes" }] : []));
1959
2062
  /**
1960
2063
  * A computed signal that dynamically calculates the text color based on the resolved value.
1961
2064
  */
@@ -1967,19 +2070,23 @@ class ColorPicker {
1967
2070
  const b = parseInt(hex.substring(4, 6), 16);
1968
2071
  const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
1969
2072
  return luminance > 128 ? '#000000' : '#FFFFFF';
1970
- });
2073
+ }, ...(ngDevMode ? [{ debugName: "textColor" }] : []));
1971
2074
  /**
1972
2075
  * Indicates whether the input is focused.
1973
2076
  */
1974
- focused = signal(false);
2077
+ focused = signal(false, ...(ngDevMode ? [{ debugName: "focused" }] : []));
1975
2078
  /**
1976
2079
  * A reference to the `NgModel` directive.
1977
2080
  */
1978
- ngModel = contentChild(NgModel);
2081
+ ngModel = contentChild(NgModel, ...(ngDevMode ? [{ debugName: "ngModel" }] : []));
1979
2082
  /**
1980
2083
  * Indicates whether to show the color value.
1981
2084
  */
1982
- showColor = input(true);
2085
+ showColor = input(true, ...(ngDevMode ? [{ debugName: "showColor" }] : []));
2086
+ /**
2087
+ * The size of the color picker input.
2088
+ */
2089
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
1983
2090
  /**
1984
2091
  * A reference to the native element.
1985
2092
  */
@@ -2043,10 +2150,10 @@ class ColorPicker {
2043
2150
  const b = Math.round(rgb1.b * (1 - percentage) + rgb2.b * percentage);
2044
2151
  return rgbToHex(r, g, b);
2045
2152
  }
2046
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ColorPicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
2047
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.7", type: ColorPicker, isStandalone: true, selector: "input[b-color-picker]", inputs: { maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, showColor: { classPropertyName: "showColor", publicName: "showColor", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "focus": "focused.set(true)", "blur": "focused.set(false)", "input": "value.set($event.target.value)" }, properties: { "class.focused": "focused()", "style.max-width": "maxWidth()", "style.--value": "valueWithSingleQuotes()", "style.--text-color": "textColor()", "class.show-color": "showColor()" } }, queries: [{ propertyName: "ngModel", first: true, predicate: NgModel, descendants: true, isSignal: true }], ngImport: i0, template: ``, isInline: true });
2153
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ColorPicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
2154
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.2.3", type: ColorPicker, isStandalone: true, selector: "input[b-color-picker]", inputs: { showColor: { classPropertyName: "showColor", publicName: "showColor", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "focus": "focused.set(true)", "blur": "focused.set(false)", "input": "value.set($event.target.value)" }, properties: { "class.focused": "focused()", "style.--value": "valueWithSingleQuotes()", "style.--text-color": "textColor()", "class.show-color": "showColor()", "class.b-size-sm": "size() === \"sm\"", "class.b-size-md": "size() === \"md\"", "class.b-size-lg": "size() === \"lg\"" } }, queries: [{ propertyName: "ngModel", first: true, predicate: NgModel, descendants: true, isSignal: true }], ngImport: i0, template: ``, isInline: true });
2048
2155
  }
2049
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ColorPicker, decorators: [{
2156
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ColorPicker, decorators: [{
2050
2157
  type: Component,
2051
2158
  args: [{
2052
2159
  selector: 'input[b-color-picker]',
@@ -2054,13 +2161,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
2054
2161
  template: ``,
2055
2162
  host: {
2056
2163
  '[class.focused]': 'focused()',
2057
- '[style.max-width]': 'maxWidth()',
2058
2164
  '[style.--value]': 'valueWithSingleQuotes()',
2059
2165
  '[style.--text-color]': 'textColor()',
2060
2166
  '[class.show-color]': 'showColor()',
2061
2167
  '(focus)': 'focused.set(true)',
2062
2168
  '(blur)': 'focused.set(false)',
2063
2169
  '(input)': 'value.set($event.target.value)',
2170
+ '[class.b-size-sm]': 'size() === "sm"',
2171
+ '[class.b-size-md]': 'size() === "md"',
2172
+ '[class.b-size-lg]': 'size() === "lg"',
2064
2173
  },
2065
2174
  }]
2066
2175
  }] });
@@ -2073,7 +2182,7 @@ class TreeNode {
2073
2182
  /**
2074
2183
  * Indicates whether the node is extended (expanded).
2075
2184
  */
2076
- extended = model(false);
2185
+ extended = model(false, ...(ngDevMode ? [{ debugName: "extended" }] : []));
2077
2186
  /**
2078
2187
  * Reference to the `CdkDrag` directive for drag-and-drop functionality.
2079
2188
  */
@@ -2081,7 +2190,7 @@ class TreeNode {
2081
2190
  /**
2082
2191
  * Reference to a nested `Tree` component, if present.
2083
2192
  */
2084
- nestedTree = contentChild(Tree);
2193
+ nestedTree = contentChild(Tree, ...(ngDevMode ? [{ debugName: "nestedTree" }] : []));
2085
2194
  /**
2086
2195
  * Emits an event when the node is closed.
2087
2196
  */
@@ -2110,17 +2219,103 @@ class TreeNode {
2110
2219
  this.closeEmitter.emit();
2111
2220
  }
2112
2221
  }
2113
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: TreeNode, deps: [], target: i0.ɵɵFactoryTarget.Component });
2114
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.7", type: TreeNode, isStandalone: true, selector: "b-tree-node", inputs: { extended: { classPropertyName: "extended", publicName: "extended", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { extended: "extendedChange", closeEmitter: "closeEmitter" }, queries: [{ propertyName: "nestedTree", first: true, predicate: Tree, descendants: true, isSignal: true }], hostDirectives: [{ directive: i1$1.CdkDrag, inputs: ["cdkDragDisabled", "disabled"] }], ngImport: i0, template: "<section>\r\n @if (!node.disabled) {\r\n <i b-icon icon=\"GripVertical\" [size]=\"15\" cdkDragHandle></i>\r\n }\r\n <div\r\n class=\"projected-content\"\r\n (click)=\"nestedTree() && handleExtension()\"\r\n (keydown.enter)=\"nestedTree() && handleExtension()\"\r\n (keydown.space)=\"nestedTree() && handleExtension()\"\r\n role=\"button\"\r\n tabindex=\"0\">\r\n <ng-content />\r\n </div>\r\n @if (nestedTree()) {\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\">\r\n <path d=\"m6 9 6 6 6-6\" />\r\n </svg>\r\n }\r\n</section>\r\n@if (nestedTree() && extended()) {\r\n <div class=\"nested\">\r\n <ng-content select=\"b-tree\" />\r\n </div>\r\n}\r\n", dependencies: [{ kind: "component", type: Icon, selector: "i[b-icon]", inputs: ["icon", "size", "strokeWidth", "color"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }] });
2222
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: TreeNode, deps: [], target: i0.ɵɵFactoryTarget.Component });
2223
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.3", type: TreeNode, isStandalone: true, selector: "b-tree-node", inputs: { extended: { classPropertyName: "extended", publicName: "extended", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { extended: "extendedChange", closeEmitter: "closeEmitter" }, providers: [
2224
+ provideIcons({
2225
+ lucideGripVertical,
2226
+ }),
2227
+ ], queries: [{ propertyName: "nestedTree", first: true, predicate: Tree, descendants: true, isSignal: true }], hostDirectives: [{ directive: i1$2.CdkDrag, inputs: ["cdkDragDisabled", "disabled"] }], ngImport: i0, template: `<section>
2228
+ @if (!node.disabled) {
2229
+ <ng-icon
2230
+ name="lucideGripVertical"
2231
+ size="16"
2232
+ color="currentColor"
2233
+ cdkDragHandle />
2234
+ }
2235
+ <div
2236
+ class="projected-content"
2237
+ (click)="nestedTree() && handleExtension()"
2238
+ (keydown.enter)="nestedTree() && handleExtension()"
2239
+ (keydown.space)="nestedTree() && handleExtension()"
2240
+ role="button"
2241
+ tabindex="0">
2242
+ <ng-content />
2243
+ </div>
2244
+ @if (nestedTree()) {
2245
+ <svg
2246
+ xmlns="http://www.w3.org/2000/svg"
2247
+ width="20"
2248
+ height="20"
2249
+ viewBox="0 0 24 24"
2250
+ fill="none"
2251
+ stroke="currentColor"
2252
+ stroke-width="2"
2253
+ stroke-linecap="round"
2254
+ stroke-linejoin="round">
2255
+ <path d="m6 9 6 6 6-6" />
2256
+ </svg>
2257
+ }
2258
+ </section>
2259
+ @if (nestedTree() && extended()) {
2260
+ <div class="nested">
2261
+ <ng-content select="b-tree" />
2262
+ </div>
2263
+ } `, isInline: true, dependencies: [{ kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }] });
2115
2264
  }
2116
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: TreeNode, decorators: [{
2265
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: TreeNode, decorators: [{
2117
2266
  type: Component,
2118
- args: [{ selector: 'b-tree-node', imports: [Icon, CdkDragHandle], hostDirectives: [
2267
+ args: [{
2268
+ selector: 'b-tree-node',
2269
+ imports: [CdkDragHandle, NgIcon],
2270
+ template: `<section>
2271
+ @if (!node.disabled) {
2272
+ <ng-icon
2273
+ name="lucideGripVertical"
2274
+ size="16"
2275
+ color="currentColor"
2276
+ cdkDragHandle />
2277
+ }
2278
+ <div
2279
+ class="projected-content"
2280
+ (click)="nestedTree() && handleExtension()"
2281
+ (keydown.enter)="nestedTree() && handleExtension()"
2282
+ (keydown.space)="nestedTree() && handleExtension()"
2283
+ role="button"
2284
+ tabindex="0">
2285
+ <ng-content />
2286
+ </div>
2287
+ @if (nestedTree()) {
2288
+ <svg
2289
+ xmlns="http://www.w3.org/2000/svg"
2290
+ width="20"
2291
+ height="20"
2292
+ viewBox="0 0 24 24"
2293
+ fill="none"
2294
+ stroke="currentColor"
2295
+ stroke-width="2"
2296
+ stroke-linecap="round"
2297
+ stroke-linejoin="round">
2298
+ <path d="m6 9 6 6 6-6" />
2299
+ </svg>
2300
+ }
2301
+ </section>
2302
+ @if (nestedTree() && extended()) {
2303
+ <div class="nested">
2304
+ <ng-content select="b-tree" />
2305
+ </div>
2306
+ } `,
2307
+ hostDirectives: [
2119
2308
  {
2120
2309
  directive: CdkDrag,
2121
2310
  inputs: ['cdkDragDisabled: disabled'],
2122
2311
  },
2123
- ], template: "<section>\r\n @if (!node.disabled) {\r\n <i b-icon icon=\"GripVertical\" [size]=\"15\" cdkDragHandle></i>\r\n }\r\n <div\r\n class=\"projected-content\"\r\n (click)=\"nestedTree() && handleExtension()\"\r\n (keydown.enter)=\"nestedTree() && handleExtension()\"\r\n (keydown.space)=\"nestedTree() && handleExtension()\"\r\n role=\"button\"\r\n tabindex=\"0\">\r\n <ng-content />\r\n </div>\r\n @if (nestedTree()) {\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\">\r\n <path d=\"m6 9 6 6 6-6\" />\r\n </svg>\r\n }\r\n</section>\r\n@if (nestedTree() && extended()) {\r\n <div class=\"nested\">\r\n <ng-content select=\"b-tree\" />\r\n </div>\r\n}\r\n" }]
2312
+ ],
2313
+ providers: [
2314
+ provideIcons({
2315
+ lucideGripVertical,
2316
+ }),
2317
+ ],
2318
+ }]
2124
2319
  }] });
2125
2320
 
2126
2321
  /**
@@ -2128,14 +2323,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
2128
2323
  * and manages nested tree nodes.
2129
2324
  */
2130
2325
  class Tree {
2131
- /**
2132
- * The ID of the tree component.
2133
- */
2134
- maxWidth = input('100%');
2135
2326
  /**
2136
2327
  * Determines whether the tree is draggable.
2137
2328
  */
2138
- draggable = input(false);
2329
+ draggable = input(false, ...(ngDevMode ? [{ debugName: "draggable" }] : []));
2139
2330
  /**
2140
2331
  * Reference to the `CdkDropList` directive used for drag-and-drop.
2141
2332
  */
@@ -2143,11 +2334,11 @@ class Tree {
2143
2334
  /**
2144
2335
  * Collection of nested `TreeNode` components.
2145
2336
  */
2146
- nestedNodes = contentChildren(TreeNode);
2337
+ nestedNodes = contentChildren(TreeNode, ...(ngDevMode ? [{ debugName: "nestedNodes" }] : []));
2147
2338
  /**
2148
2339
  * Determines whether to close nodes recursively.
2149
2340
  */
2150
- closeRecursively = input(false);
2341
+ closeRecursively = input(false, ...(ngDevMode ? [{ debugName: "closeRecursively" }] : []));
2151
2342
  /**
2152
2343
  * Emits an event when a drop occurs in the tree.
2153
2344
  */
@@ -2196,17 +2387,16 @@ class Tree {
2196
2387
  node.nestedTree()?.closeNestedNodes();
2197
2388
  });
2198
2389
  }
2199
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Tree, deps: [], target: i0.ɵɵFactoryTarget.Component });
2200
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.7", type: Tree, isStandalone: true, selector: "b-tree", inputs: { maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, closeRecursively: { classPropertyName: "closeRecursively", publicName: "closeRecursively", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dropEmitter: "dropEmitter" }, host: { listeners: { "cdkDropListDropped": "dropEmitter.emit($event)" }, properties: { "style.max-width": "maxWidth()" } }, queries: [{ propertyName: "nestedNodes", predicate: TreeNode, isSignal: true }], hostDirectives: [{ directive: i1$1.CdkDropList, inputs: ["id", "id", "cdkDropListConnectedTo", "connectedTo"], outputs: ["cdkDropListDropped", "cdkDropListDropped"] }, { directive: i1$1.CdkDropListGroup }], ngImport: i0, template: `<ng-content />`, isInline: true });
2390
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Tree, deps: [], target: i0.ɵɵFactoryTarget.Component });
2391
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.2.3", type: Tree, isStandalone: true, selector: "b-tree", inputs: { draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, closeRecursively: { classPropertyName: "closeRecursively", publicName: "closeRecursively", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dropEmitter: "dropEmitter" }, host: { listeners: { "cdkDropListDropped": "dropEmitter.emit($event)" } }, queries: [{ propertyName: "nestedNodes", predicate: TreeNode, isSignal: true }], hostDirectives: [{ directive: i1$2.CdkDropList, inputs: ["id", "id", "cdkDropListConnectedTo", "connectedTo"], outputs: ["cdkDropListDropped", "cdkDropListDropped"] }, { directive: i1$2.CdkDropListGroup }], ngImport: i0, template: `<ng-content />`, isInline: true });
2201
2392
  }
2202
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Tree, decorators: [{
2393
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Tree, decorators: [{
2203
2394
  type: Component,
2204
2395
  args: [{
2205
2396
  selector: 'b-tree',
2206
2397
  template: `<ng-content />`,
2207
2398
  host: {
2208
2399
  '(cdkDropListDropped)': 'dropEmitter.emit($event)',
2209
- '[style.max-width]': 'maxWidth()',
2210
2400
  },
2211
2401
  hostDirectives: [
2212
2402
  {
@@ -2223,16 +2413,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
2223
2413
  * Represents a menu component that can optionally float.
2224
2414
  */
2225
2415
  class Menu {
2226
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Menu, deps: [], target: i0.ɵɵFactoryTarget.Component });
2227
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.7", type: Menu, isStandalone: true, selector: "b-menu", hostDirectives: [{ directive: i1$2.CdkMenu }], ngImport: i0, template: `<ng-content />`, isInline: true });
2416
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
2417
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Menu, deps: [], target: i0.ɵɵFactoryTarget.Component });
2418
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: Menu, isStandalone: true, selector: "b-menu", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.b-size-sm": "size() === 'sm'", "class.b-size-md": "size() === 'md'", "class.b-size-lg": "size() === 'lg'" } }, hostDirectives: [{ directive: i1$3.CdkMenu }], ngImport: i0, template: `<ng-content />`, isInline: true });
2228
2419
  }
2229
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Menu, decorators: [{
2420
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Menu, decorators: [{
2230
2421
  type: Component,
2231
2422
  args: [{
2232
2423
  selector: 'b-menu',
2233
- imports: [],
2234
2424
  template: `<ng-content />`,
2235
2425
  hostDirectives: [CdkMenu],
2426
+ host: {
2427
+ '[class.b-size-sm]': "size() === 'sm'",
2428
+ '[class.b-size-md]': "size() === 'md'",
2429
+ '[class.b-size-lg]': "size() === 'lg'",
2430
+ },
2431
+ }]
2432
+ }] });
2433
+
2434
+ /**
2435
+ * Represents a group of menu items.
2436
+ */
2437
+ class MenuGroup {
2438
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: MenuGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
2439
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.3", type: MenuGroup, isStandalone: true, selector: "b-menu-group", hostDirectives: [{ directive: i1$3.CdkMenuGroup }], ngImport: i0, template: `<ng-content />`, isInline: true });
2440
+ }
2441
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: MenuGroup, decorators: [{
2442
+ type: Component,
2443
+ args: [{
2444
+ selector: 'b-menu-group',
2445
+ template: `<ng-content />`,
2446
+ hostDirectives: [CdkMenuGroup],
2236
2447
  }]
2237
2448
  }] });
2238
2449
 
@@ -2240,14 +2451,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
2240
2451
  * Represents a label for a menu.
2241
2452
  */
2242
2453
  class MenuLabel {
2243
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: MenuLabel, deps: [], target: i0.ɵɵFactoryTarget.Component });
2244
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.7", type: MenuLabel, isStandalone: true, selector: "b-menu-label", ngImport: i0, template: `<ng-content />`, isInline: true });
2454
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: MenuLabel, deps: [], target: i0.ɵɵFactoryTarget.Component });
2455
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.3", type: MenuLabel, isStandalone: true, selector: "b-menu-label", ngImport: i0, template: `<ng-content />`, isInline: true });
2245
2456
  }
2246
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: MenuLabel, decorators: [{
2457
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: MenuLabel, decorators: [{
2247
2458
  type: Component,
2248
2459
  args: [{
2249
2460
  selector: 'b-menu-label',
2250
- imports: [],
2251
2461
  template: `<ng-content />`,
2252
2462
  }]
2253
2463
  }] });
@@ -2255,15 +2465,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
2255
2465
  /**
2256
2466
  * Represents a menu item with support for typeahead and disabled states.
2257
2467
  */
2258
- class MenuItemComponent {
2259
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: MenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2260
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.7", type: MenuItemComponent, isStandalone: true, selector: "b-menu-item", hostDirectives: [{ directive: i1$2.CdkMenuItem, inputs: ["cdkMenuItemDisabled", "disabled", "cdkMenuitemTypeaheadLabel", "typeaheadLabel"], outputs: ["cdkMenuItemTriggered", "triggered"] }], ngImport: i0, template: `<ng-content />`, isInline: true });
2468
+ class MenuItem {
2469
+ /**
2470
+ * Input to set the squared state of the menu item.
2471
+ */
2472
+ squared = input(false, ...(ngDevMode ? [{ debugName: "squared" }] : []));
2473
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: MenuItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
2474
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: MenuItem, isStandalone: true, selector: "button[b-menu-item]", inputs: { squared: { classPropertyName: "squared", publicName: "squared", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.squared": "squared()" } }, hostDirectives: [{ directive: i1$3.CdkMenuItem, inputs: ["cdkMenuItemDisabled", "disabled", "cdkMenuitemTypeaheadLabel", "typeaheadLabel"], outputs: ["cdkMenuItemTriggered", "triggered"] }], ngImport: i0, template: `<ng-content />`, isInline: true });
2261
2475
  }
2262
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: MenuItemComponent, decorators: [{
2476
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: MenuItem, decorators: [{
2263
2477
  type: Component,
2264
2478
  args: [{
2265
- selector: 'b-menu-item',
2266
- imports: [],
2479
+ selector: 'button[b-menu-item]',
2267
2480
  template: `<ng-content />`,
2268
2481
  hostDirectives: [
2269
2482
  {
@@ -2275,21 +2488,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
2275
2488
  outputs: ['cdkMenuItemTriggered: triggered'],
2276
2489
  },
2277
2490
  ],
2491
+ host: {
2492
+ '[class.squared]': 'squared()',
2493
+ },
2278
2494
  }]
2279
2495
  }] });
2280
2496
 
2281
2497
  /**
2282
2498
  * Represents a checkbox menu item.
2283
2499
  */
2284
- class MenuItemCheckboxComponent {
2285
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: MenuItemCheckboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2286
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.7", type: MenuItemCheckboxComponent, isStandalone: true, selector: "b-menu-item-checkbox", hostDirectives: [{ directive: i1$2.CdkMenuItemCheckbox, inputs: ["cdkMenuItemDisabled", "disabled", "cdkMenuitemTypeaheadLabel", "typeaheadLabel", "cdkMenuItemChecked", "active"], outputs: ["cdkMenuItemTriggered", "triggered"] }], ngImport: i0, template: `<ng-content />`, isInline: true });
2500
+ class MenuItemCheckbox {
2501
+ /**
2502
+ * Input to set the squared state of the menu item.
2503
+ */
2504
+ squared = input(false, ...(ngDevMode ? [{ debugName: "squared" }] : []));
2505
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: MenuItemCheckbox, deps: [], target: i0.ɵɵFactoryTarget.Component });
2506
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: MenuItemCheckbox, isStandalone: true, selector: "button[b-menu-item-checkbox]", inputs: { squared: { classPropertyName: "squared", publicName: "squared", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.squared": "squared()" } }, hostDirectives: [{ directive: i1$3.CdkMenuItemCheckbox, inputs: ["cdkMenuItemDisabled", "disabled", "cdkMenuitemTypeaheadLabel", "typeaheadLabel", "cdkMenuItemChecked", "active"], outputs: ["cdkMenuItemTriggered", "triggered"] }], ngImport: i0, template: `<ng-content />`, isInline: true });
2287
2507
  }
2288
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: MenuItemCheckboxComponent, decorators: [{
2508
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: MenuItemCheckbox, decorators: [{
2289
2509
  type: Component,
2290
2510
  args: [{
2291
- selector: 'b-menu-item-checkbox',
2292
- imports: [],
2511
+ selector: 'button[b-menu-item-checkbox]',
2293
2512
  template: `<ng-content />`,
2294
2513
  hostDirectives: [
2295
2514
  {
@@ -2302,21 +2521,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
2302
2521
  outputs: ['cdkMenuItemTriggered: triggered'],
2303
2522
  },
2304
2523
  ],
2524
+ host: {
2525
+ '[class.squared]': 'squared()',
2526
+ },
2305
2527
  }]
2306
2528
  }] });
2307
2529
 
2308
2530
  /**
2309
2531
  * Represents a radio menu item.
2310
2532
  */
2311
- class MenuItemRadioComponent {
2312
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: MenuItemRadioComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2313
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.7", type: MenuItemRadioComponent, isStandalone: true, selector: "b-menu-item-radio", hostDirectives: [{ directive: i1$2.CdkMenuItemRadio, inputs: ["cdkMenuItemDisabled", "disabled", "cdkMenuitemTypeaheadLabel", "typeaheadLabel", "cdkMenuItemChecked", "active"], outputs: ["cdkMenuItemTriggered", "triggered"] }], ngImport: i0, template: `<ng-content />`, isInline: true });
2533
+ class MenuItemRadio {
2534
+ /**
2535
+ * Input to set the squared state of the menu item.
2536
+ */
2537
+ squared = input(false, ...(ngDevMode ? [{ debugName: "squared" }] : []));
2538
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: MenuItemRadio, deps: [], target: i0.ɵɵFactoryTarget.Component });
2539
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.3", type: MenuItemRadio, isStandalone: true, selector: "button[b-menu-item-radio]", inputs: { squared: { classPropertyName: "squared", publicName: "squared", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.squared": "squared()" } }, hostDirectives: [{ directive: i1$3.CdkMenuItemRadio, inputs: ["cdkMenuItemDisabled", "disabled", "cdkMenuitemTypeaheadLabel", "typeaheadLabel", "cdkMenuItemChecked", "active"], outputs: ["cdkMenuItemTriggered", "triggered"] }], ngImport: i0, template: `<ng-content />`, isInline: true });
2314
2540
  }
2315
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: MenuItemRadioComponent, decorators: [{
2541
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: MenuItemRadio, decorators: [{
2316
2542
  type: Component,
2317
2543
  args: [{
2318
- selector: 'b-menu-item-radio',
2319
- imports: [],
2544
+ selector: 'button[b-menu-item-radio]',
2320
2545
  template: `<ng-content />`,
2321
2546
  hostDirectives: [
2322
2547
  {
@@ -2329,13 +2554,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
2329
2554
  outputs: ['cdkMenuItemTriggered: triggered'],
2330
2555
  },
2331
2556
  ],
2557
+ host: {
2558
+ '[class.squared]': 'squared()',
2559
+ },
2332
2560
  }]
2333
2561
  }] });
2334
2562
 
2335
- class MenuTrigger {
2563
+ class MenuTriggerDirective {
2336
2564
  trigger = inject(CdkMenuTrigger);
2337
- menuTriggerPosition = input('right-top');
2338
- submenu = input(false);
2565
+ menuTriggerPosition = input('right-top', ...(ngDevMode ? [{ debugName: "menuTriggerPosition" }] : []));
2566
+ submenu = input(false, ...(ngDevMode ? [{ debugName: "submenu" }] : []));
2339
2567
  ngOnInit() {
2340
2568
  this.setPosition();
2341
2569
  }
@@ -2426,13 +2654,18 @@ class MenuTrigger {
2426
2654
  offsetX: !this.submenu() ? 5 : undefined,
2427
2655
  },
2428
2656
  };
2429
- const connectedPosition = positionMap[this.menuTriggerPosition()];
2430
- this.trigger.menuPosition = [connectedPosition];
2657
+ const pos = this.menuTriggerPosition();
2658
+ if (Array.isArray(pos)) {
2659
+ this.trigger.menuPosition = pos.map(p => positionMap[p]);
2660
+ }
2661
+ else {
2662
+ this.trigger.menuPosition = [positionMap[pos]];
2663
+ }
2431
2664
  }
2432
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: MenuTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2433
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.7", type: MenuTrigger, isStandalone: true, selector: "[menuTriggerFor]", inputs: { menuTriggerPosition: { classPropertyName: "menuTriggerPosition", publicName: "menuTriggerPosition", isSignal: true, isRequired: false, transformFunction: null }, submenu: { classPropertyName: "submenu", publicName: "submenu", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1$2.CdkMenuTrigger, inputs: ["cdkMenuTriggerFor", "menuTriggerFor"] }], ngImport: i0 });
2665
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: MenuTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2666
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.2.3", type: MenuTriggerDirective, isStandalone: true, selector: "[menuTriggerFor]", inputs: { menuTriggerPosition: { classPropertyName: "menuTriggerPosition", publicName: "menuTriggerPosition", isSignal: true, isRequired: false, transformFunction: null }, submenu: { classPropertyName: "submenu", publicName: "submenu", isSignal: true, isRequired: false, transformFunction: null } }, hostDirectives: [{ directive: i1$3.CdkMenuTrigger, inputs: ["cdkMenuTriggerFor", "menuTriggerFor"] }], ngImport: i0 });
2434
2667
  }
2435
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: MenuTrigger, decorators: [{
2668
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: MenuTriggerDirective, decorators: [{
2436
2669
  type: Directive,
2437
2670
  args: [{
2438
2671
  selector: '[menuTriggerFor]',
@@ -2447,45 +2680,865 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
2447
2680
 
2448
2681
  class Alert {
2449
2682
  /** The type of the alert. */
2450
- type = input('info');
2683
+ type = input('info', ...(ngDevMode ? [{ debugName: "type" }] : []));
2451
2684
  /** The title of the alert. */
2452
- title = input(null);
2453
- /** The icon of the alert. */
2454
- icon = input(null);
2685
+ title = input(null, ...(ngDevMode ? [{ debugName: "title" }] : []));
2686
+ /** The icon name for ng-icon. */
2687
+ icon = input(null, ...(ngDevMode ? [{ debugName: "icon" }] : []));
2455
2688
  /** Whether the alert is dismissible. */
2456
- dismissible = input(false);
2689
+ dismissible = input(false, ...(ngDevMode ? [{ debugName: "dismissible" }] : []));
2457
2690
  /** Event emitted when the alert is dismissed. */
2458
2691
  dismissed = output();
2459
- /** The maximum width of the alert. */
2460
- maxWidth = input(null);
2461
- /** The color foreground of the alert. */
2462
- colorForeground = computed(() => {
2463
- return this.type() === 'info'
2464
- ? 'var(--secondary-foreground)'
2465
- : `var(--${this.type()}-foreground)`;
2466
- });
2467
2692
  dismiss() {
2468
2693
  this.dismissed.emit();
2469
2694
  }
2470
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Alert, deps: [], target: i0.ɵɵFactoryTarget.Component });
2471
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.7", type: Alert, isStandalone: true, selector: "b-alert", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dismissed: "dismissed" }, host: { properties: { "class": "type()", "style.max-width": "maxWidth()" } }, ngImport: i0, template: "@if (icon()) {\r\n <div class=\"icon\">\r\n <i b-icon [icon]=\"icon()!\" [size]=\"20\" [color]=\"colorForeground()\"></i>\r\n </div>\r\n}\r\n<div class=\"content\">\r\n @if (title()) {\r\n <div class=\"title\">\r\n {{ title() }}\r\n </div>\r\n }\r\n\r\n <div class=\"body\">\r\n <ng-content />\r\n </div>\r\n</div>\r\n@if (dismissible()) {\r\n <button class=\"close-btn\" (click)=\"dismiss()\">\r\n <i b-icon icon=\"X\" [size]=\"20\" [color]=\"colorForeground()\"></i>\r\n </button>\r\n}\r\n", dependencies: [{ kind: "component", type: Icon, selector: "i[b-icon]", inputs: ["icon", "size", "strokeWidth", "color"] }] });
2695
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Alert, deps: [], target: i0.ɵɵFactoryTarget.Component });
2696
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.3", type: Alert, isStandalone: true, selector: "b-alert", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dismissed: "dismissed" }, host: { properties: { "class": "type()" } }, providers: [provideIcons({ lucideX })], ngImport: i0, template: `
2697
+ @if (icon()) {
2698
+ <div class="icon">
2699
+ <ng-icon [name]="icon()!" size="20" color="currentColor" />
2700
+ </div>
2701
+ }
2702
+ <div class="content">
2703
+ @if (title()) {
2704
+ <div class="title">{{ title() }}</div>
2705
+ }
2706
+ <div class="body">
2707
+ <ng-content />
2708
+ </div>
2709
+ </div>
2710
+ @if (dismissible()) {
2711
+ <button class="close-btn" (click)="dismiss()" aria-label="Close">
2712
+ <ng-icon name="lucideX" size="16" color="currentColor" />
2713
+ </button>
2714
+ }
2715
+ `, isInline: true, dependencies: [{ kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }] });
2472
2716
  }
2473
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: Alert, decorators: [{
2717
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Alert, decorators: [{
2474
2718
  type: Component,
2475
- args: [{ selector: 'b-alert', imports: [Icon], host: {
2719
+ args: [{
2720
+ selector: 'b-alert',
2721
+ template: `
2722
+ @if (icon()) {
2723
+ <div class="icon">
2724
+ <ng-icon [name]="icon()!" size="20" color="currentColor" />
2725
+ </div>
2726
+ }
2727
+ <div class="content">
2728
+ @if (title()) {
2729
+ <div class="title">{{ title() }}</div>
2730
+ }
2731
+ <div class="body">
2732
+ <ng-content />
2733
+ </div>
2734
+ </div>
2735
+ @if (dismissible()) {
2736
+ <button class="close-btn" (click)="dismiss()" aria-label="Close">
2737
+ <ng-icon name="lucideX" size="16" color="currentColor" />
2738
+ </button>
2739
+ }
2740
+ `,
2741
+ imports: [NgIcon],
2742
+ host: {
2476
2743
  '[class]': 'type()',
2477
- '[style.max-width]': 'maxWidth()',
2478
- }, template: "@if (icon()) {\r\n <div class=\"icon\">\r\n <i b-icon [icon]=\"icon()!\" [size]=\"20\" [color]=\"colorForeground()\"></i>\r\n </div>\r\n}\r\n<div class=\"content\">\r\n @if (title()) {\r\n <div class=\"title\">\r\n {{ title() }}\r\n </div>\r\n }\r\n\r\n <div class=\"body\">\r\n <ng-content />\r\n </div>\r\n</div>\r\n@if (dismissible()) {\r\n <button class=\"close-btn\" (click)=\"dismiss()\">\r\n <i b-icon icon=\"X\" [size]=\"20\" [color]=\"colorForeground()\"></i>\r\n </button>\r\n}\r\n" }]
2744
+ },
2745
+ providers: [provideIcons({ lucideX })],
2746
+ }]
2747
+ }] });
2748
+
2749
+ /**
2750
+ * Component representing a list of command options.
2751
+ * It uses Angular CDK's listbox and option utilities for accessibility and keyboard navigation.
2752
+ */
2753
+ class CommandOptionsComponent {
2754
+ /**
2755
+ * Collection of child options within the listbox.
2756
+ */
2757
+ options = contentChildren(CdkOption, ...(ngDevMode ? [{ debugName: "options" }] : []));
2758
+ /**
2759
+ * Key manager for handling keyboard navigation and active descendant management.
2760
+ */
2761
+ listKeyManager = computed(() => new ActiveDescendantKeyManager(this.options())
2762
+ .withWrap()
2763
+ .withVerticalOrientation(), ...(ngDevMode ? [{ debugName: "listKeyManager" }] : []));
2764
+ /**
2765
+ * Signal representing the currently selected values.
2766
+ */
2767
+ value = signal([], ...(ngDevMode ? [{ debugName: "value" }] : []));
2768
+ /**
2769
+ * Signal representing the currently highlighted option.
2770
+ */
2771
+ highlightedOption = signal('1', ...(ngDevMode ? [{ debugName: "highlightedOption" }] : []));
2772
+ /**
2773
+ * No options message displayed when there are no available options in the dropdown.
2774
+ */
2775
+ noOptionsMessage = input('', ...(ngDevMode ? [{ debugName: "noOptionsMessage" }] : []));
2776
+ /**
2777
+ * Reference to the injected CDK Listbox instance.
2778
+ */
2779
+ cdkListbox = inject(CdkListbox);
2780
+ /**
2781
+ * Emitter for closing the command options.
2782
+ */
2783
+ closeEmitter = output();
2784
+ /**
2785
+ * Signal indicando si se permite selección múltiple.
2786
+ */
2787
+ multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : []));
2788
+ /**
2789
+ * Lifecycle hook that initializes the component.
2790
+ * Enables the use of active descendant for the listbox.
2791
+ */
2792
+ ngOnInit() {
2793
+ this.cdkListbox.useActiveDescendant = true;
2794
+ }
2795
+ /**
2796
+ * Selects the currently active option and updates the listbox value.
2797
+ */
2798
+ selectOption(value) {
2799
+ const selectValue = value
2800
+ ? value
2801
+ : (this.listKeyManager().activeItem?.value ?? []);
2802
+ // If the selectValue is an empty array or contains only an empty string, clear the selection
2803
+ if (selectValue.length === 1 && selectValue[0] === '') {
2804
+ this.value.set([]);
2805
+ this.cdkListbox.value = [];
2806
+ this.closeEmitter.emit();
2807
+ return;
2808
+ }
2809
+ this.value.set(selectValue);
2810
+ this.cdkListbox.value = this.value();
2811
+ this.closeEmitter.emit();
2812
+ }
2813
+ /**
2814
+ * Moves the active item to the next option and updates the highlighted option.
2815
+ */
2816
+ nextOption() {
2817
+ this.listKeyManager().setNextItemActive();
2818
+ this.highlightedOption.set(this.listKeyManager().activeItem?.value ?? '');
2819
+ this.updateHighlightedOption();
2820
+ }
2821
+ /**
2822
+ * Moves the active item to the previous option and updates the highlighted option.
2823
+ */
2824
+ previousOption() {
2825
+ this.listKeyManager().setPreviousItemActive();
2826
+ this.highlightedOption.set(this.listKeyManager().activeItem?.value ?? '');
2827
+ this.updateHighlightedOption();
2828
+ }
2829
+ /**
2830
+ * Updates the CSS class of options to reflect the currently highlighted option.
2831
+ */
2832
+ updateHighlightedOption() {
2833
+ this.options().forEach(option => {
2834
+ if (option.value === this.highlightedOption()) {
2835
+ option.element.classList.add('cdk-option-highlighted');
2836
+ }
2837
+ else {
2838
+ option.element.classList.remove('cdk-option-highlighted');
2839
+ }
2840
+ });
2841
+ }
2842
+ handleValueChange(value) {
2843
+ // If the value is an empty array or contains a single empty string, clear the selection.
2844
+ if (value.length === 1 && value[0] === '') {
2845
+ this.value.set([]);
2846
+ if (!this.multiple()) {
2847
+ this.closeEmitter.emit();
2848
+ }
2849
+ return;
2850
+ }
2851
+ this.value.set(value);
2852
+ if (!this.multiple()) {
2853
+ this.closeEmitter.emit();
2854
+ }
2855
+ }
2856
+ onEnter() {
2857
+ if (!this.multiple()) {
2858
+ this.closeEmitter.emit();
2859
+ }
2860
+ }
2861
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: CommandOptionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2862
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.3", type: CommandOptionsComponent, isStandalone: true, selector: "ul[b-command-options]", inputs: { noOptionsMessage: { classPropertyName: "noOptionsMessage", publicName: "noOptionsMessage", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closeEmitter: "closeEmitter" }, host: { listeners: { "cdkListboxValueChange": "handleValueChange($event.value)", "keydown.enter": "onEnter()" }, properties: { "cdkListboxValue": "value()", "cdkListboxMultiple": "multiple()" } }, queries: [{ propertyName: "options", predicate: CdkOption, isSignal: true }], hostDirectives: [{ directive: i1$1.CdkListbox, inputs: ["cdkListboxValue", "cdkListboxValue", "cdkListboxMultiple", "multiple"], outputs: ["cdkListboxValueChange", "cdkListboxValueChange"] }], ngImport: i0, template: `<ng-content />
2863
+ @if (options().length === 0) {
2864
+ <div class="no-options-message">
2865
+ {{ noOptionsMessage() }}
2866
+ </div>
2867
+ }`, isInline: true });
2868
+ }
2869
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: CommandOptionsComponent, decorators: [{
2870
+ type: Component,
2871
+ args: [{
2872
+ selector: 'ul[b-command-options]',
2873
+ imports: [],
2874
+ template: `<ng-content />
2875
+ @if (options().length === 0) {
2876
+ <div class="no-options-message">
2877
+ {{ noOptionsMessage() }}
2878
+ </div>
2879
+ }`,
2880
+ hostDirectives: [
2881
+ {
2882
+ directive: CdkListbox,
2883
+ inputs: ['cdkListboxValue', 'cdkListboxMultiple: multiple'],
2884
+ outputs: ['cdkListboxValueChange'],
2885
+ },
2886
+ ],
2887
+ host: {
2888
+ '[cdkListboxValue]': 'value()',
2889
+ '[cdkListboxMultiple]': 'multiple()',
2890
+ '(cdkListboxValueChange)': 'handleValueChange($event.value)',
2891
+ '(keydown.enter)': 'onEnter()',
2892
+ },
2893
+ }]
2894
+ }] });
2895
+
2896
+ /**
2897
+ * Utility service for common operations.
2898
+ */
2899
+ class Utils {
2900
+ debounceTimers = new Map();
2901
+ /**
2902
+ * Executes a function after a delay, canceling any previous calls with the same key.
2903
+ *
2904
+ * @param key - Unique key to identify the debounce timer.
2905
+ * @param func - The function to debounce.
2906
+ * @param delay - The delay in milliseconds before executing the function.
2907
+ */
2908
+ debounce(key, func, delay) {
2909
+ clearTimeout(this.debounceTimers.get(key));
2910
+ this.debounceTimers.set(key, setTimeout(func, delay));
2911
+ }
2912
+ /**
2913
+ * Cancels the debounce timer for a specific key.
2914
+ *
2915
+ * @param key - Unique key to identify the debounce timer.
2916
+ */
2917
+ stopDebounce(key) {
2918
+ clearTimeout(this.debounceTimers.get(key));
2919
+ this.debounceTimers.delete(key);
2920
+ }
2921
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Utils, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2922
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Utils, providedIn: 'root' });
2923
+ }
2924
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Utils, decorators: [{
2925
+ type: Injectable,
2926
+ args: [{
2927
+ providedIn: 'root',
2928
+ }]
2929
+ }] });
2930
+
2931
+ /**
2932
+ * Component representing a command input with associated options.
2933
+ * It provides keyboard navigation and focus trapping for accessibility.
2934
+ */
2935
+ class CommandComponent {
2936
+ /**
2937
+ * Reference to the child `CommandOptionsComponent` if present.
2938
+ * Used to interact with the options for navigation and selection.
2939
+ */
2940
+ commandOptions = contentChild(CommandOptionsComponent, ...(ngDevMode ? [{ debugName: "commandOptions" }] : []));
2941
+ /**
2942
+ * Input representing the maximum height of the component.
2943
+ * This can be used to control the visual appearance of the command component.
2944
+ */
2945
+ maxHeight = input('300px', ...(ngDevMode ? [{ debugName: "maxHeight" }] : []));
2946
+ /**
2947
+ * Computed signal representing the selected value from the command options.
2948
+ * This is linked to the value of the `CommandOptionsComponent`.
2949
+ */
2950
+ value = computed(() => this.commandOptions()?.value(), ...(ngDevMode ? [{ debugName: "value" }] : []));
2951
+ /**
2952
+ * Computed signal representing the options available in the command options.
2953
+ * This is linked to the options of the `CommandOptionsComponent`.
2954
+ */
2955
+ options = computed(() => this.commandOptions()?.options(), ...(ngDevMode ? [{ debugName: "options" }] : []));
2956
+ /**
2957
+ * Reference to the BreakpointObserver service for responsive design.
2958
+ */
2959
+ breakpointObserver = inject(BreakpointObserver);
2960
+ /**
2961
+ * Signal representing whether the current viewport is desktop or not.
2962
+ * This is determined by checking if the Handset breakpoint is matched.
2963
+ */
2964
+ isDesktop = signal(!this.breakpointObserver.isMatched(Breakpoints.Handset), ...(ngDevMode ? [{ debugName: "isDesktop" }] : []));
2965
+ /**
2966
+ * Reference to the host element of the component.
2967
+ * This provides access to the DOM element of the command component.
2968
+ */
2969
+ el = inject(ElementRef);
2970
+ /**
2971
+ * Output that emits the current input value.
2972
+ */
2973
+ inputValueChange = output();
2974
+ /**
2975
+ * Input to control debounce time (ms) for valueChange emission.
2976
+ */
2977
+ debounce = input(0, ...(ngDevMode ? [{ debugName: "debounce" }] : []));
2978
+ /**
2979
+ * Reference to the Utils for debounce logic.
2980
+ */
2981
+ utils = inject(Utils);
2982
+ /**
2983
+ * Unique key for debounce timer.
2984
+ */
2985
+ debounceKey = 'command-input';
2986
+ /**
2987
+ * Handler for input event, emits value with debounce if set.
2988
+ */
2989
+ onInput(event) {
2990
+ const value = event.target.value;
2991
+ const debounceMs = this.debounce();
2992
+ if (debounceMs && debounceMs > 0) {
2993
+ this.utils.debounce(this.debounceKey, () => this.inputValueChange.emit(value), debounceMs);
2994
+ }
2995
+ else {
2996
+ this.inputValueChange.emit(value);
2997
+ }
2998
+ }
2999
+ ngOnDestroy() {
3000
+ this.utils.stopDebounce(this.debounceKey);
3001
+ }
3002
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: CommandComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3003
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.2.3", type: CommandComponent, isStandalone: true, selector: "b-command", inputs: { maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, debounce: { classPropertyName: "debounce", publicName: "debounce", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { inputValueChange: "inputValueChange" }, host: { properties: { "style.maxHeight": "maxHeight()" } }, queries: [{ propertyName: "commandOptions", first: true, predicate: CommandOptionsComponent, descendants: true, isSignal: true }], ngImport: i0, template: `<input
3004
+ type="text"
3005
+ b-input
3006
+ cdkTrapFocus
3007
+ [cdkTrapFocusAutoCapture]="isDesktop()"
3008
+ #trappedInput
3009
+ (keydown.arrowDown)="commandOptions()?.nextOption()"
3010
+ (keydown.arrowUp)="commandOptions()?.previousOption()"
3011
+ (keydown.enter)="commandOptions()?.selectOption()"
3012
+ (blur)="isDesktop() && trappedInput.el.nativeElement.focus()"
3013
+ (input)="onInput($event)" />
3014
+ <ng-content />`, isInline: true, dependencies: [{ kind: "component", type: Input, selector: "input[b-input]", inputs: ["type", "decimals", "numberType", "size"], exportAs: ["bInput"] }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }] });
3015
+ }
3016
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: CommandComponent, decorators: [{
3017
+ type: Component,
3018
+ args: [{
3019
+ selector: 'b-command',
3020
+ imports: [Input, CdkTrapFocus],
3021
+ template: `<input
3022
+ type="text"
3023
+ b-input
3024
+ cdkTrapFocus
3025
+ [cdkTrapFocusAutoCapture]="isDesktop()"
3026
+ #trappedInput
3027
+ (keydown.arrowDown)="commandOptions()?.nextOption()"
3028
+ (keydown.arrowUp)="commandOptions()?.previousOption()"
3029
+ (keydown.enter)="commandOptions()?.selectOption()"
3030
+ (blur)="isDesktop() && trappedInput.el.nativeElement.focus()"
3031
+ (input)="onInput($event)" />
3032
+ <ng-content />`,
3033
+ host: {
3034
+ '[style.maxHeight]': 'maxHeight()',
3035
+ },
3036
+ }]
3037
+ }] });
3038
+
3039
+ /**
3040
+ * Directive to mark an element as a trigger for an overlay.
3041
+ * Integrates with Angular CDK's `CdkOverlayOrigin` to provide
3042
+ * a reference point for overlay positioning.
3043
+ */
3044
+ class OverlayOrigin {
3045
+ /**
3046
+ * Reference to the `CdkOverlayOrigin` instance.
3047
+ * Used as the origin point for overlay positioning.
3048
+ */
3049
+ trigger = inject(CdkOverlayOrigin);
3050
+ /**
3051
+ * Reference to the `ElementRef` of the host element.
3052
+ * This is used to access the native DOM element.
3053
+ */
3054
+ el = inject(ElementRef);
3055
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: OverlayOrigin, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3056
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.3", type: OverlayOrigin, isStandalone: true, selector: "[bOverlayOrigin]", exportAs: ["bOverlayOrigin"], hostDirectives: [{ directive: i1.CdkOverlayOrigin }], ngImport: i0 });
3057
+ }
3058
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: OverlayOrigin, decorators: [{
3059
+ type: Directive,
3060
+ args: [{
3061
+ selector: '[bOverlayOrigin]',
3062
+ hostDirectives: [CdkOverlayOrigin],
3063
+ exportAs: 'bOverlayOrigin',
3064
+ }]
3065
+ }] });
3066
+
3067
+ class InputGroup {
3068
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: InputGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
3069
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.3", type: InputGroup, isStandalone: true, selector: "b-input-group", ngImport: i0, template: `<ng-content />`, isInline: true });
3070
+ }
3071
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: InputGroup, decorators: [{
3072
+ type: Component,
3073
+ args: [{
3074
+ selector: 'b-input-group',
3075
+ template: `<ng-content />`,
3076
+ }]
3077
+ }] });
3078
+
3079
+ /** Dialog content container that renders projected portal content for a dialog instance.
3080
+ *
3081
+ * @remarks Extends CdkDialogContainer to integrate with Angular CDK dialog infrastructure.
3082
+ */
3083
+ class DialogContent extends CdkDialogContainer {
3084
+ /** Reference to the active dialog instance used to control lifecycle and closing. */
3085
+ dialogRef = inject(DialogRef);
3086
+ /** Service that orchestrates opening and closing of dialog instances. */
3087
+ dialogManager = inject(DialogManager);
3088
+ /** Tracks whether the dialog is in its leaving (closing) animation state. */
3089
+ leaving = signal(false, ...(ngDevMode ? [{ debugName: "leaving" }] : []));
3090
+ /** Initializes the dialog content component by calling the superclass constructor. */
3091
+ constructor() {
3092
+ super();
3093
+ }
3094
+ /** Initializes component logic and subscribes to dialog events. */
3095
+ ngOnInit() {
3096
+ this.handleDialogEvents();
3097
+ }
3098
+ /** Handles all dialog behavioral event subscriptions based on provided configuration data. */
3099
+ handleDialogEvents() {
3100
+ const data = this._config?.data;
3101
+ if (!data) {
3102
+ return;
3103
+ }
3104
+ this.handleBackdropClose(data);
3105
+ this.handleEscapeKeyClose(data);
3106
+ }
3107
+ /** Subscribes to backdrop clicks to close the dialog when enabled in config.
3108
+ *
3109
+ * @param data - Dialog configuration containing close behavior flags.
3110
+ */
3111
+ handleBackdropClose(data) {
3112
+ if (data.closeOnBackdropClick) {
3113
+ this.dialogRef.backdropClick.subscribe(() => {
3114
+ this.dialogManager.closeDialog(this.dialogRef.id);
3115
+ });
3116
+ }
3117
+ }
3118
+ /** Subscribes to keydown events to close the dialog on Escape key when enabled.
3119
+ *
3120
+ * @param data - Dialog configuration containing close behavior flags.
3121
+ */
3122
+ handleEscapeKeyClose(data) {
3123
+ if (data.closeOnEscapeKey) {
3124
+ this.dialogRef.keydownEvents.subscribe((event) => {
3125
+ if (event.key === 'Escape') {
3126
+ this.dialogManager.closeDialog(this.dialogRef.id);
3127
+ }
3128
+ });
3129
+ }
3130
+ }
3131
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: DialogContent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3132
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.3", type: DialogContent, isStandalone: true, selector: "b-dialog-content", host: { properties: { "class.leaving": "leaving()" } }, usesInheritance: true, ngImport: i0, template: `<ng-template cdkPortalOutlet />`, isInline: true, dependencies: [{ kind: "directive", type: CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }], encapsulation: i0.ViewEncapsulation.None });
3133
+ }
3134
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: DialogContent, decorators: [{
3135
+ type: Component,
3136
+ args: [{
3137
+ selector: 'b-dialog-content',
3138
+ template: `<ng-template cdkPortalOutlet />`,
3139
+ encapsulation: ViewEncapsulation.None,
3140
+ imports: [CdkPortalOutlet],
3141
+ host: {
3142
+ '[class.leaving]': 'leaving()',
3143
+ },
3144
+ }]
3145
+ }], ctorParameters: () => [] });
3146
+
3147
+ /**
3148
+ * Provides registration and lifecycle control for application dialogs.
3149
+ */
3150
+ class DialogManager {
3151
+ /** Angular CDK dialog service used to manage overlay instances. */
3152
+ dialog = inject(Dialog$1);
3153
+ /** Utility service used for debounced close behavior. */
3154
+ utils = inject(Utils);
3155
+ /** Registry mapping dialog identifiers to their data. */
3156
+ dialogs = new Map();
3157
+ /**
3158
+ * Registers a dialog definition under a unique identifier, overwriting any existing entry.
3159
+ *
3160
+ * @param id - Unique identifier for the dialog.
3161
+ * @param data - Template and configuration to register.
3162
+ */
3163
+ registerDialog(id, data) {
3164
+ if (this.dialogs.has(id)) {
3165
+ console.warn(`[DialogManager] Dialog with id "${id}" is already registered. Overwriting.`);
3166
+ }
3167
+ this.dialogs.set(id, data);
3168
+ }
3169
+ /**
3170
+ * Removes a previously registered dialog definition.
3171
+ *
3172
+ * @param id - Identifier of the dialog to remove.
3173
+ */
3174
+ removeDialog(id) {
3175
+ this.dialogs.delete(id);
3176
+ }
3177
+ /**
3178
+ * Opens a dialog using its registered template and configuration.
3179
+ *
3180
+ * @param id - Identifier of the dialog to open.
3181
+ * @throws Error - When no dialog is registered with the provided identifier.
3182
+ */
3183
+ openDialog(id) {
3184
+ const dialogData = this.dialogs.get(id);
3185
+ if (!dialogData) {
3186
+ throw new Error(`[DialogManager] Dialog with id "${id}" not found. Ensure the bDialog directive is applied correctly.`);
3187
+ }
3188
+ this.dialog.open(dialogData.template, {
3189
+ id: id,
3190
+ disableClose: true,
3191
+ restoreFocus: dialogData.config.restoreFocus,
3192
+ backdropClass: 'b-dialog-content-backdrop',
3193
+ container: DialogContent,
3194
+ data: dialogData.config,
3195
+ });
3196
+ }
3197
+ /**
3198
+ * Closes a dialog by identifier applying any configured close delay.
3199
+ *
3200
+ * @param id - Identifier of the dialog to close.
3201
+ */
3202
+ closeDialog(id) {
3203
+ const config = this.dialogs.get(id)?.config;
3204
+ if (!config) {
3205
+ console.warn(`[DialogManager] Attempted to close dialog with id "${id}", but no open dialog with that id was found.`);
3206
+ return;
3207
+ }
3208
+ const dialogRef = this.dialog.getDialogById(id);
3209
+ if (dialogRef) {
3210
+ const container = dialogRef.containerInstance;
3211
+ if (container && container.leaving) {
3212
+ container.leaving.set(true);
3213
+ }
3214
+ this.utils.debounce('close-dialog-' + id, () => {
3215
+ dialogRef.close();
3216
+ if (container && container.leaving) {
3217
+ container.leaving.set(false);
3218
+ }
3219
+ }, config.closeDelay);
3220
+ }
3221
+ else {
3222
+ console.warn(`[DialogManager] Attempted to close dialog with id "${id}", but no open dialog with that id was found.`);
3223
+ }
3224
+ }
3225
+ /**
3226
+ * Closes all currently open dialogs immediately.
3227
+ */
3228
+ closeAllDialogs() {
3229
+ this.dialog.closeAll();
3230
+ }
3231
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: DialogManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3232
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: DialogManager, providedIn: 'root' });
3233
+ }
3234
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: DialogManager, decorators: [{
3235
+ type: Injectable,
3236
+ args: [{
3237
+ providedIn: 'root',
3238
+ }]
3239
+ }] });
3240
+
3241
+ /**
3242
+ * Directive that registers and controls a dialog template instance.
3243
+ *
3244
+ * Registers itself in the {@link DialogManager} on init and exposes open/close APIs.
3245
+ */
3246
+ class Dialog {
3247
+ /**
3248
+ * Unique dialog identifier bound from the `bDialog` attribute.
3249
+ */
3250
+ id = input.required(...(ngDevMode ? [{ debugName: "id", alias: 'bDialog' }] : [{ alias: 'bDialog' }]));
3251
+ /**
3252
+ * Whether the dialog renders a backdrop element.
3253
+ *
3254
+ * @defaultValue true
3255
+ */
3256
+ hasBackdrop = input(true, ...(ngDevMode ? [{ debugName: "hasBackdrop" }] : []));
3257
+ /**
3258
+ * Closes the dialog when the user clicks on the backdrop.
3259
+ *
3260
+ * @defaultValue true
3261
+ */
3262
+ closeOnBackdropClick = input(true, ...(ngDevMode ? [{ debugName: "closeOnBackdropClick" }] : []));
3263
+ /**
3264
+ * Closes the dialog when the Escape key is pressed while focused inside.
3265
+ *
3266
+ * @defaultValue true
3267
+ */
3268
+ closeOnEscapeKey = input(true, ...(ngDevMode ? [{ debugName: "closeOnEscapeKey" }] : []));
3269
+ /**
3270
+ * Restores focus to the previously focused element after the dialog closes.
3271
+ *
3272
+ * @defaultValue true
3273
+ */
3274
+ restoreFocus = input(true, ...(ngDevMode ? [{ debugName: "restoreFocus" }] : []));
3275
+ /**
3276
+ * Delay in milliseconds before the dialog is fully closed (useful for animations).
3277
+ *
3278
+ * @defaultValue 150
3279
+ */
3280
+ closeDelay = input(150, ...(ngDevMode ? [{ debugName: "closeDelay" }] : []));
3281
+ /**
3282
+ * Computed dialog data passed to the service containing template and configuration.
3283
+ */
3284
+ data = computed(() => ({
3285
+ template: this.templateRef,
3286
+ config: {
3287
+ hasBackdrop: this.hasBackdrop(),
3288
+ restoreFocus: this.restoreFocus(),
3289
+ closeDelay: this.closeDelay(),
3290
+ closeOnBackdropClick: this.closeOnBackdropClick(),
3291
+ closeOnEscapeKey: this.closeOnEscapeKey(),
3292
+ },
3293
+ }), ...(ngDevMode ? [{ debugName: "data" }] : []));
3294
+ /**
3295
+ * Delay in milliseconds before opening the dialog (for entrance timing / animations).
3296
+ *
3297
+ * @defaultValue 0
3298
+ */
3299
+ openDelay = input(0, ...(ngDevMode ? [{ debugName: "openDelay" }] : []));
3300
+ /**
3301
+ * Event emitted after the dialog has been programmatically or automatically closed.
3302
+ */
3303
+ closed = output();
3304
+ /**
3305
+ * Reference to the dialog service handling registration and state.
3306
+ */
3307
+ dialogManager = inject(DialogManager);
3308
+ /**
3309
+ * Template reference representing the dialog content projected when opened.
3310
+ */
3311
+ templateRef = inject((TemplateRef));
3312
+ /**
3313
+ * Lifecycle hook that registers the dialog with the dialog service.
3314
+ */
3315
+ ngOnInit() {
3316
+ this.dialogManager.registerDialog(this.id(), this.data());
3317
+ }
3318
+ /**
3319
+ * Opens the dialog via the dialog service using its identifier.
3320
+ */
3321
+ open() {
3322
+ this.dialogManager.openDialog(this.id());
3323
+ }
3324
+ /**
3325
+ * Closes the dialog and emits the `closed` output.
3326
+ */
3327
+ close() {
3328
+ this.dialogManager.closeDialog(this.id());
3329
+ this.closed.emit();
3330
+ }
3331
+ /**
3332
+ * Lifecycle hook that removes the dialog from the dialog service registry.
3333
+ */
3334
+ ngOnDestroy() {
3335
+ this.dialogManager.removeDialog(this.id());
3336
+ }
3337
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Dialog, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3338
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.2.3", type: Dialog, isStandalone: true, selector: "[bDialog]", inputs: { id: { classPropertyName: "id", publicName: "bDialog", isSignal: true, isRequired: true, transformFunction: null }, hasBackdrop: { classPropertyName: "hasBackdrop", publicName: "hasBackdrop", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdropClick: { classPropertyName: "closeOnBackdropClick", publicName: "closeOnBackdropClick", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscapeKey: { classPropertyName: "closeOnEscapeKey", publicName: "closeOnEscapeKey", isSignal: true, isRequired: false, transformFunction: null }, restoreFocus: { classPropertyName: "restoreFocus", publicName: "restoreFocus", isSignal: true, isRequired: false, transformFunction: null }, closeDelay: { classPropertyName: "closeDelay", publicName: "closeDelay", isSignal: true, isRequired: false, transformFunction: null }, openDelay: { classPropertyName: "openDelay", publicName: "openDelay", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, host: { listeners: { "keydown.escape": "closeOnEscapeKey() ? close() : null" } }, exportAs: ["bDialog"], ngImport: i0 });
3339
+ }
3340
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Dialog, decorators: [{
3341
+ type: Directive,
3342
+ args: [{
3343
+ selector: '[bDialog]',
3344
+ exportAs: 'bDialog',
3345
+ host: {
3346
+ '(keydown.escape)': 'closeOnEscapeKey() ? close() : null',
3347
+ },
3348
+ }]
3349
+ }] });
3350
+
3351
+ class Card {
3352
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Card, deps: [], target: i0.ɵɵFactoryTarget.Component });
3353
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.3", type: Card, isStandalone: true, selector: "b-card", ngImport: i0, template: ` <ng-content /> `, isInline: true });
3354
+ }
3355
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: Card, decorators: [{
3356
+ type: Component,
3357
+ args: [{
3358
+ selector: 'b-card',
3359
+ template: ` <ng-content /> `,
3360
+ }]
3361
+ }] });
3362
+
3363
+ class CardHeader {
3364
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: CardHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
3365
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.3", type: CardHeader, isStandalone: true, selector: "b-card-header", ngImport: i0, template: ` <ng-content /> `, isInline: true });
3366
+ }
3367
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: CardHeader, decorators: [{
3368
+ type: Component,
3369
+ args: [{
3370
+ selector: 'b-card-header',
3371
+ template: ` <ng-content /> `,
3372
+ }]
3373
+ }] });
3374
+
3375
+ class CardTitle {
3376
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: CardTitle, deps: [], target: i0.ɵɵFactoryTarget.Component });
3377
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.3", type: CardTitle, isStandalone: true, selector: "b-card-title", ngImport: i0, template: ` <ng-content /> `, isInline: true });
3378
+ }
3379
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: CardTitle, decorators: [{
3380
+ type: Component,
3381
+ args: [{
3382
+ selector: 'b-card-title',
3383
+ template: ` <ng-content /> `,
3384
+ }]
3385
+ }] });
3386
+
3387
+ class CardDescription {
3388
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: CardDescription, deps: [], target: i0.ɵɵFactoryTarget.Component });
3389
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.3", type: CardDescription, isStandalone: true, selector: "b-card-description", ngImport: i0, template: ` <ng-content /> `, isInline: true });
3390
+ }
3391
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: CardDescription, decorators: [{
3392
+ type: Component,
3393
+ args: [{
3394
+ selector: 'b-card-description',
3395
+ template: ` <ng-content /> `,
3396
+ }]
3397
+ }] });
3398
+
3399
+ class CardContent {
3400
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: CardContent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3401
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.3", type: CardContent, isStandalone: true, selector: "b-card-content", ngImport: i0, template: ` <ng-content /> `, isInline: true });
3402
+ }
3403
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: CardContent, decorators: [{
3404
+ type: Component,
3405
+ args: [{
3406
+ selector: 'b-card-content',
3407
+ template: ` <ng-content /> `,
3408
+ }]
3409
+ }] });
3410
+
3411
+ class CardFooter {
3412
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: CardFooter, deps: [], target: i0.ɵɵFactoryTarget.Component });
3413
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.3", type: CardFooter, isStandalone: true, selector: "b-card-footer", ngImport: i0, template: ` <ng-content /> `, isInline: true });
3414
+ }
3415
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: CardFooter, decorators: [{
3416
+ type: Component,
3417
+ args: [{
3418
+ selector: 'b-card-footer',
3419
+ template: ` <ng-content /> `,
3420
+ }]
3421
+ }] });
3422
+
3423
+ /**
3424
+ * Service for managing translations and language switching.
3425
+ *
3426
+ * @remarks
3427
+ * - Loads language files via HTTP.
3428
+ * - Provides reactive signals for language and dictionary.
3429
+ * - Use `translate(key)` to get the translated string for the current language.
3430
+ *
3431
+ * @example
3432
+ * ```typescript
3433
+ * translationManager.setLanguage('es');
3434
+ * translationManager.translate('home.title');
3435
+ * ```
3436
+ */
3437
+ class TranslationManager {
3438
+ /** Current language code. */
3439
+ _language = signal('en', ...(ngDevMode ? [{ debugName: "_language" }] : []));
3440
+ /** Dictionary of translations. */
3441
+ _dictionary = signal({}, ...(ngDevMode ? [{ debugName: "_dictionary" }] : []));
3442
+ /** Reactive signal for current language. */
3443
+ language = computed(() => this._language(), ...(ngDevMode ? [{ debugName: "language" }] : []));
3444
+ /** Reactive signal for current dictionary. */
3445
+ dictionary = computed(() => this._dictionary(), ...(ngDevMode ? [{ debugName: "dictionary" }] : []));
3446
+ /** HttpClient for loading language files. */
3447
+ http = inject(HttpClient);
3448
+ /**
3449
+ * Sets the current language and loads its dictionary.
3450
+ * @param lang - Language code (e.g., 'en', 'es').
3451
+ */
3452
+ setLanguage(lang) {
3453
+ this._language.set(lang);
3454
+ this.loadLanguage(lang);
3455
+ }
3456
+ /**
3457
+ * Sets the translation dictionary directly.
3458
+ * @param dict - Translation dictionary object.
3459
+ */
3460
+ setDictionary(dict) {
3461
+ this._dictionary.set(dict);
3462
+ }
3463
+ /**
3464
+ * Translates a key using the current language.
3465
+ * @param key - Dot-separated translation key (e.g., 'home.title').
3466
+ * @returns Translated string or the key if not found.
3467
+ */
3468
+ translate(key) {
3469
+ const lang = this._language();
3470
+ const dict = this._dictionary();
3471
+ const value = this.resolveKey(dict[lang], key);
3472
+ return value ?? key;
3473
+ }
3474
+ /**
3475
+ * Resolves a dot-separated key in an object.
3476
+ * @param obj - Object to resolve key in.
3477
+ * @param key - Dot-separated key string.
3478
+ * @returns Value or undefined if not found.
3479
+ */
3480
+ resolveKey(obj, key) {
3481
+ if (!obj)
3482
+ return undefined;
3483
+ return key
3484
+ .split('.')
3485
+ .reduce((acc, part) => (acc && acc[part] !== undefined ? acc[part] : undefined), obj);
3486
+ }
3487
+ /**
3488
+ * Loads a language file via HTTP and updates the dictionary.
3489
+ * @param lang - Language code to load.
3490
+ */
3491
+ loadLanguage(lang) {
3492
+ this.http.get(`/lang/${lang}.json`).subscribe({
3493
+ next: translations => {
3494
+ const dict = { ...this._dictionary() };
3495
+ dict[lang] = translations;
3496
+ this._dictionary.set(dict);
3497
+ },
3498
+ error: () => {
3499
+ // If loading fails, do not update the dictionary
3500
+ },
3501
+ });
3502
+ }
3503
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: TranslationManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3504
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: TranslationManager, providedIn: 'root' });
3505
+ }
3506
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: TranslationManager, decorators: [{
3507
+ type: Injectable,
3508
+ args: [{ providedIn: 'root' }]
3509
+ }] });
3510
+
3511
+ class TranslatePipe {
3512
+ translationManager = inject(TranslationManager);
3513
+ cdr = inject(ChangeDetectorRef);
3514
+ lastLang;
3515
+ transform(key) {
3516
+ const lang = this.translationManager.language();
3517
+ if (lang !== this.lastLang) {
3518
+ this.lastLang = lang;
3519
+ this.cdr.markForCheck();
3520
+ }
3521
+ return this.translationManager.translate(key);
3522
+ }
3523
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: TranslatePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
3524
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.2.3", ngImport: i0, type: TranslatePipe, isStandalone: true, name: "translate", pure: false });
3525
+ }
3526
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: TranslatePipe, decorators: [{
3527
+ type: Pipe,
3528
+ args: [{
3529
+ name: 'translate',
3530
+ pure: false,
3531
+ }]
2479
3532
  }] });
2480
3533
 
2481
3534
  /*
2482
3535
  * Public API Surface of basis-ng
2483
3536
  */
2484
- /* Theme Service */
3537
+ /* Theme Manager */
2485
3538
 
2486
3539
  /**
2487
3540
  * Generated bundle index. Do not edit.
2488
3541
  */
2489
3542
 
2490
- export { Alert, AttachedBox, Badge, BottomSheet, Button, ButtonGroup, Checkbox, ColorPicker, Icon, InViewportDirective, InViewportService, Input, InputGroup, Label, LazyContentDirective, Menu, MenuItemCheckboxComponent, MenuItemComponent, MenuItemRadioComponent, MenuLabel, MenuTrigger, OptionComponent, Range, ResponsiveService, Row, RowItem, SelectComponent, SelectOptionsComponent, SideSheet, Spinner, Switch, Tab, Table, Tabs, Textarea, ThemeService, TooltipComponent, Tree, TreeNode };
3543
+ export { Alert, Badge, Button, ButtonGroup, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, ColorPicker, CommandComponent, CommandOptionsComponent, ConnectedOverlay, Dialog, DialogManager, Drawer, Input, InputGroup, LazyContentDirective, Menu, MenuGroup, MenuItem, MenuItemCheckbox, MenuItemRadio, MenuLabel, MenuTriggerDirective, Option, Otp, OtpDigitDirective, OverlayOrigin, Range, ResponsiveManager, RowComponent, RowItemComponent, Select, SelectContent, SelectFilter, SelectTrigger, SelectValue, Sheet, Spinner, SwitchComponent, Tab, TableComponent, Tabs, TextareaComponent, ThemeManager, Tooltip, TooltipContent, TooltipTrigger, TranslatePipe, TranslationManager, Tree, TreeNode };
2491
3544
  //# sourceMappingURL=basis-ng-primitives.mjs.map