@weeehaoooz/talos-ui 0.1.1 → 0.1.2

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 (190) hide show
  1. package/README.md +2 -0
  2. package/fesm2022/{weeehaoooz-talos-ui-button-button-group.mjs → weeehaoooz-talos-ui-button.mjs} +91 -15
  3. package/fesm2022/weeehaoooz-talos-ui-button.mjs.map +1 -0
  4. package/fesm2022/weeehaoooz-talos-ui-data-display.mjs +3110 -0
  5. package/fesm2022/weeehaoooz-talos-ui-data-display.mjs.map +1 -0
  6. package/fesm2022/weeehaoooz-talos-ui-data-viz.mjs +2414 -0
  7. package/fesm2022/weeehaoooz-talos-ui-data-viz.mjs.map +1 -0
  8. package/fesm2022/weeehaoooz-talos-ui-dropdown.mjs +1039 -0
  9. package/fesm2022/weeehaoooz-talos-ui-dropdown.mjs.map +1 -0
  10. package/fesm2022/weeehaoooz-talos-ui-feedback.mjs +2885 -0
  11. package/fesm2022/weeehaoooz-talos-ui-feedback.mjs.map +1 -0
  12. package/fesm2022/weeehaoooz-talos-ui-form.mjs +10799 -0
  13. package/fesm2022/weeehaoooz-talos-ui-form.mjs.map +1 -0
  14. package/fesm2022/weeehaoooz-talos-ui-layout.mjs +1316 -7
  15. package/fesm2022/weeehaoooz-talos-ui-layout.mjs.map +1 -1
  16. package/fesm2022/weeehaoooz-talos-ui-nav.mjs +3 -3
  17. package/fesm2022/weeehaoooz-talos-ui-nav.mjs.map +1 -1
  18. package/fesm2022/weeehaoooz-talos-ui.mjs +21592 -16293
  19. package/fesm2022/weeehaoooz-talos-ui.mjs.map +1 -1
  20. package/package.json +20 -139
  21. package/styles/_breadcrumb.scss +16 -0
  22. package/styles/_button-group.scss +2 -1
  23. package/styles/_buttons.scss +51 -0
  24. package/styles/_dropdown.scss +438 -0
  25. package/styles/_form-controls.scss +13 -0
  26. package/styles/_progress-bar.scss +43 -0
  27. package/styles/_skeleton.scss +176 -0
  28. package/styles/_spinner.scss +58 -0
  29. package/styles/_variables.scss +33 -0
  30. package/styles/index.scss +6 -1
  31. package/types/weeehaoooz-talos-ui-button.d.ts +92 -0
  32. package/types/weeehaoooz-talos-ui-button.d.ts.map +1 -0
  33. package/types/weeehaoooz-talos-ui-data-display.d.ts +1018 -0
  34. package/types/weeehaoooz-talos-ui-data-display.d.ts.map +1 -0
  35. package/types/weeehaoooz-talos-ui-data-viz.d.ts +839 -0
  36. package/types/weeehaoooz-talos-ui-data-viz.d.ts.map +1 -0
  37. package/types/weeehaoooz-talos-ui-dropdown.d.ts +187 -0
  38. package/types/weeehaoooz-talos-ui-dropdown.d.ts.map +1 -0
  39. package/types/weeehaoooz-talos-ui-feedback.d.ts +1495 -0
  40. package/types/weeehaoooz-talos-ui-feedback.d.ts.map +1 -0
  41. package/types/weeehaoooz-talos-ui-form.d.ts +2639 -0
  42. package/types/weeehaoooz-talos-ui-form.d.ts.map +1 -0
  43. package/types/weeehaoooz-talos-ui-layout.d.ts +851 -3
  44. package/types/weeehaoooz-talos-ui-layout.d.ts.map +1 -1
  45. package/types/weeehaoooz-talos-ui-nav.d.ts +1 -1
  46. package/types/weeehaoooz-talos-ui.d.ts +7148 -4629
  47. package/types/weeehaoooz-talos-ui.d.ts.map +1 -1
  48. package/fesm2022/weeehaoooz-talos-ui-button-button-group.mjs.map +0 -1
  49. package/fesm2022/weeehaoooz-talos-ui-button-button.mjs +0 -94
  50. package/fesm2022/weeehaoooz-talos-ui-button-button.mjs.map +0 -1
  51. package/fesm2022/weeehaoooz-talos-ui-data-display-badge.mjs +0 -233
  52. package/fesm2022/weeehaoooz-talos-ui-data-display-badge.mjs.map +0 -1
  53. package/fesm2022/weeehaoooz-talos-ui-data-display-data-grid.mjs +0 -1627
  54. package/fesm2022/weeehaoooz-talos-ui-data-display-data-grid.mjs.map +0 -1
  55. package/fesm2022/weeehaoooz-talos-ui-data-display-status-tag.mjs +0 -361
  56. package/fesm2022/weeehaoooz-talos-ui-data-display-status-tag.mjs.map +0 -1
  57. package/fesm2022/weeehaoooz-talos-ui-data-display-timeline.mjs +0 -312
  58. package/fesm2022/weeehaoooz-talos-ui-data-display-timeline.mjs.map +0 -1
  59. package/fesm2022/weeehaoooz-talos-ui-data-display-trend-indicator.mjs +0 -235
  60. package/fesm2022/weeehaoooz-talos-ui-data-display-trend-indicator.mjs.map +0 -1
  61. package/fesm2022/weeehaoooz-talos-ui-data-viz-category-bar.mjs +0 -462
  62. package/fesm2022/weeehaoooz-talos-ui-data-viz-category-bar.mjs.map +0 -1
  63. package/fesm2022/weeehaoooz-talos-ui-data-viz-heatmap.mjs +0 -805
  64. package/fesm2022/weeehaoooz-talos-ui-data-viz-heatmap.mjs.map +0 -1
  65. package/fesm2022/weeehaoooz-talos-ui-data-viz-mini-donut.mjs +0 -267
  66. package/fesm2022/weeehaoooz-talos-ui-data-viz-mini-donut.mjs.map +0 -1
  67. package/fesm2022/weeehaoooz-talos-ui-data-viz-mini-gauge.mjs +0 -351
  68. package/fesm2022/weeehaoooz-talos-ui-data-viz-mini-gauge.mjs.map +0 -1
  69. package/fesm2022/weeehaoooz-talos-ui-data-viz-sparkline.mjs +0 -566
  70. package/fesm2022/weeehaoooz-talos-ui-data-viz-sparkline.mjs.map +0 -1
  71. package/fesm2022/weeehaoooz-talos-ui-feedback-alert.mjs +0 -534
  72. package/fesm2022/weeehaoooz-talos-ui-feedback-alert.mjs.map +0 -1
  73. package/fesm2022/weeehaoooz-talos-ui-feedback-dialog.mjs +0 -446
  74. package/fesm2022/weeehaoooz-talos-ui-feedback-dialog.mjs.map +0 -1
  75. package/fesm2022/weeehaoooz-talos-ui-feedback-snackbar.mjs +0 -376
  76. package/fesm2022/weeehaoooz-talos-ui-feedback-snackbar.mjs.map +0 -1
  77. package/fesm2022/weeehaoooz-talos-ui-feedback-tooltip.mjs +0 -147
  78. package/fesm2022/weeehaoooz-talos-ui-feedback-tooltip.mjs.map +0 -1
  79. package/fesm2022/weeehaoooz-talos-ui-form-affix.mjs +0 -242
  80. package/fesm2022/weeehaoooz-talos-ui-form-affix.mjs.map +0 -1
  81. package/fesm2022/weeehaoooz-talos-ui-form-autocomplete.mjs +0 -514
  82. package/fesm2022/weeehaoooz-talos-ui-form-autocomplete.mjs.map +0 -1
  83. package/fesm2022/weeehaoooz-talos-ui-form-checkbox.mjs +0 -548
  84. package/fesm2022/weeehaoooz-talos-ui-form-checkbox.mjs.map +0 -1
  85. package/fesm2022/weeehaoooz-talos-ui-form-chips.mjs +0 -692
  86. package/fesm2022/weeehaoooz-talos-ui-form-chips.mjs.map +0 -1
  87. package/fesm2022/weeehaoooz-talos-ui-form-color-picker.mjs +0 -761
  88. package/fesm2022/weeehaoooz-talos-ui-form-color-picker.mjs.map +0 -1
  89. package/fesm2022/weeehaoooz-talos-ui-form-date-picker.mjs +0 -896
  90. package/fesm2022/weeehaoooz-talos-ui-form-date-picker.mjs.map +0 -1
  91. package/fesm2022/weeehaoooz-talos-ui-form-date-range-picker.mjs +0 -872
  92. package/fesm2022/weeehaoooz-talos-ui-form-date-range-picker.mjs.map +0 -1
  93. package/fesm2022/weeehaoooz-talos-ui-form-date-time-picker.mjs +0 -119
  94. package/fesm2022/weeehaoooz-talos-ui-form-date-time-picker.mjs.map +0 -1
  95. package/fesm2022/weeehaoooz-talos-ui-form-date-time-range-picker.mjs +0 -135
  96. package/fesm2022/weeehaoooz-talos-ui-form-date-time-range-picker.mjs.map +0 -1
  97. package/fesm2022/weeehaoooz-talos-ui-form-drop-zone.mjs +0 -666
  98. package/fesm2022/weeehaoooz-talos-ui-form-drop-zone.mjs.map +0 -1
  99. package/fesm2022/weeehaoooz-talos-ui-form-form-field.mjs +0 -147
  100. package/fesm2022/weeehaoooz-talos-ui-form-form-field.mjs.map +0 -1
  101. package/fesm2022/weeehaoooz-talos-ui-form-input.mjs +0 -33
  102. package/fesm2022/weeehaoooz-talos-ui-form-input.mjs.map +0 -1
  103. package/fesm2022/weeehaoooz-talos-ui-form-otp.mjs +0 -455
  104. package/fesm2022/weeehaoooz-talos-ui-form-otp.mjs.map +0 -1
  105. package/fesm2022/weeehaoooz-talos-ui-form-password-input.mjs +0 -379
  106. package/fesm2022/weeehaoooz-talos-ui-form-password-input.mjs.map +0 -1
  107. package/fesm2022/weeehaoooz-talos-ui-form-radio.mjs +0 -297
  108. package/fesm2022/weeehaoooz-talos-ui-form-radio.mjs.map +0 -1
  109. package/fesm2022/weeehaoooz-talos-ui-form-range-input.mjs +0 -661
  110. package/fesm2022/weeehaoooz-talos-ui-form-range-input.mjs.map +0 -1
  111. package/fesm2022/weeehaoooz-talos-ui-form-rating.mjs +0 -346
  112. package/fesm2022/weeehaoooz-talos-ui-form-rating.mjs.map +0 -1
  113. package/fesm2022/weeehaoooz-talos-ui-form-select-input.mjs +0 -896
  114. package/fesm2022/weeehaoooz-talos-ui-form-select-input.mjs.map +0 -1
  115. package/fesm2022/weeehaoooz-talos-ui-form-slide-toggle.mjs +0 -252
  116. package/fesm2022/weeehaoooz-talos-ui-form-slide-toggle.mjs.map +0 -1
  117. package/fesm2022/weeehaoooz-talos-ui-form-transfer-list.mjs +0 -916
  118. package/fesm2022/weeehaoooz-talos-ui-form-transfer-list.mjs.map +0 -1
  119. package/types/weeehaoooz-talos-ui-button-button-group.d.ts +0 -62
  120. package/types/weeehaoooz-talos-ui-button-button-group.d.ts.map +0 -1
  121. package/types/weeehaoooz-talos-ui-button-button.d.ts +0 -38
  122. package/types/weeehaoooz-talos-ui-button-button.d.ts.map +0 -1
  123. package/types/weeehaoooz-talos-ui-data-display-badge.d.ts +0 -119
  124. package/types/weeehaoooz-talos-ui-data-display-badge.d.ts.map +0 -1
  125. package/types/weeehaoooz-talos-ui-data-display-data-grid.d.ts +0 -272
  126. package/types/weeehaoooz-talos-ui-data-display-data-grid.d.ts.map +0 -1
  127. package/types/weeehaoooz-talos-ui-data-display-status-tag.d.ts +0 -135
  128. package/types/weeehaoooz-talos-ui-data-display-status-tag.d.ts.map +0 -1
  129. package/types/weeehaoooz-talos-ui-data-display-timeline.d.ts +0 -144
  130. package/types/weeehaoooz-talos-ui-data-display-timeline.d.ts.map +0 -1
  131. package/types/weeehaoooz-talos-ui-data-display-trend-indicator.d.ts +0 -83
  132. package/types/weeehaoooz-talos-ui-data-display-trend-indicator.d.ts.map +0 -1
  133. package/types/weeehaoooz-talos-ui-data-viz-category-bar.d.ts +0 -255
  134. package/types/weeehaoooz-talos-ui-data-viz-category-bar.d.ts.map +0 -1
  135. package/types/weeehaoooz-talos-ui-data-viz-heatmap.d.ts +0 -204
  136. package/types/weeehaoooz-talos-ui-data-viz-heatmap.d.ts.map +0 -1
  137. package/types/weeehaoooz-talos-ui-data-viz-mini-donut.d.ts +0 -101
  138. package/types/weeehaoooz-talos-ui-data-viz-mini-donut.d.ts.map +0 -1
  139. package/types/weeehaoooz-talos-ui-data-viz-mini-gauge.d.ts +0 -138
  140. package/types/weeehaoooz-talos-ui-data-viz-mini-gauge.d.ts.map +0 -1
  141. package/types/weeehaoooz-talos-ui-data-viz-sparkline.d.ts +0 -161
  142. package/types/weeehaoooz-talos-ui-data-viz-sparkline.d.ts.map +0 -1
  143. package/types/weeehaoooz-talos-ui-feedback-alert.d.ts +0 -212
  144. package/types/weeehaoooz-talos-ui-feedback-alert.d.ts.map +0 -1
  145. package/types/weeehaoooz-talos-ui-feedback-dialog.d.ts +0 -259
  146. package/types/weeehaoooz-talos-ui-feedback-dialog.d.ts.map +0 -1
  147. package/types/weeehaoooz-talos-ui-feedback-snackbar.d.ts +0 -147
  148. package/types/weeehaoooz-talos-ui-feedback-snackbar.d.ts.map +0 -1
  149. package/types/weeehaoooz-talos-ui-feedback-tooltip.d.ts +0 -32
  150. package/types/weeehaoooz-talos-ui-feedback-tooltip.d.ts.map +0 -1
  151. package/types/weeehaoooz-talos-ui-form-affix.d.ts +0 -88
  152. package/types/weeehaoooz-talos-ui-form-affix.d.ts.map +0 -1
  153. package/types/weeehaoooz-talos-ui-form-autocomplete.d.ts +0 -113
  154. package/types/weeehaoooz-talos-ui-form-autocomplete.d.ts.map +0 -1
  155. package/types/weeehaoooz-talos-ui-form-checkbox.d.ts +0 -165
  156. package/types/weeehaoooz-talos-ui-form-checkbox.d.ts.map +0 -1
  157. package/types/weeehaoooz-talos-ui-form-chips.d.ts +0 -152
  158. package/types/weeehaoooz-talos-ui-form-chips.d.ts.map +0 -1
  159. package/types/weeehaoooz-talos-ui-form-color-picker.d.ts +0 -144
  160. package/types/weeehaoooz-talos-ui-form-color-picker.d.ts.map +0 -1
  161. package/types/weeehaoooz-talos-ui-form-date-picker.d.ts +0 -138
  162. package/types/weeehaoooz-talos-ui-form-date-picker.d.ts.map +0 -1
  163. package/types/weeehaoooz-talos-ui-form-date-range-picker.d.ts +0 -148
  164. package/types/weeehaoooz-talos-ui-form-date-range-picker.d.ts.map +0 -1
  165. package/types/weeehaoooz-talos-ui-form-date-time-picker.d.ts +0 -44
  166. package/types/weeehaoooz-talos-ui-form-date-time-picker.d.ts.map +0 -1
  167. package/types/weeehaoooz-talos-ui-form-date-time-range-picker.d.ts +0 -48
  168. package/types/weeehaoooz-talos-ui-form-date-time-range-picker.d.ts.map +0 -1
  169. package/types/weeehaoooz-talos-ui-form-drop-zone.d.ts +0 -227
  170. package/types/weeehaoooz-talos-ui-form-drop-zone.d.ts.map +0 -1
  171. package/types/weeehaoooz-talos-ui-form-form-field.d.ts +0 -42
  172. package/types/weeehaoooz-talos-ui-form-form-field.d.ts.map +0 -1
  173. package/types/weeehaoooz-talos-ui-form-input.d.ts +0 -15
  174. package/types/weeehaoooz-talos-ui-form-input.d.ts.map +0 -1
  175. package/types/weeehaoooz-talos-ui-form-otp.d.ts +0 -111
  176. package/types/weeehaoooz-talos-ui-form-otp.d.ts.map +0 -1
  177. package/types/weeehaoooz-talos-ui-form-password-input.d.ts +0 -145
  178. package/types/weeehaoooz-talos-ui-form-password-input.d.ts.map +0 -1
  179. package/types/weeehaoooz-talos-ui-form-radio.d.ts +0 -84
  180. package/types/weeehaoooz-talos-ui-form-radio.d.ts.map +0 -1
  181. package/types/weeehaoooz-talos-ui-form-range-input.d.ts +0 -181
  182. package/types/weeehaoooz-talos-ui-form-range-input.d.ts.map +0 -1
  183. package/types/weeehaoooz-talos-ui-form-rating.d.ts +0 -110
  184. package/types/weeehaoooz-talos-ui-form-rating.d.ts.map +0 -1
  185. package/types/weeehaoooz-talos-ui-form-select-input.d.ts +0 -195
  186. package/types/weeehaoooz-talos-ui-form-select-input.d.ts.map +0 -1
  187. package/types/weeehaoooz-talos-ui-form-slide-toggle.d.ts +0 -79
  188. package/types/weeehaoooz-talos-ui-form-slide-toggle.d.ts.map +0 -1
  189. package/types/weeehaoooz-talos-ui-form-transfer-list.d.ts +0 -192
  190. package/types/weeehaoooz-talos-ui-form-transfer-list.d.ts.map +0 -1
@@ -0,0 +1,1039 @@
1
+ import { Overlay } from '@angular/cdk/overlay';
2
+ import { TemplatePortal } from '@angular/cdk/portal';
3
+ import * as i0 from '@angular/core';
4
+ import { inject, ElementRef, ViewContainerRef, DestroyRef, input, output, signal, effect, Directive, computed, Component, contentChildren, ViewChild, NgModule } from '@angular/core';
5
+ import { filter } from 'rxjs/operators';
6
+ import * as i1 from '@angular/common';
7
+ import { CommonModule } from '@angular/common';
8
+ import { LucideChevronRight, LucideCheck } from '@lucide/angular';
9
+
10
+ class TalosDropdownTriggerDirective {
11
+ elementRef = inject(ElementRef);
12
+ overlay = inject(Overlay);
13
+ vcr = inject(ViewContainerRef);
14
+ destroyRef = inject(DestroyRef);
15
+ /** Menu component instance to trigger */
16
+ menu = input(null, { ...(ngDevMode ? { debugName: "menu" } : /* istanbul ignore next */ {}), alias: 'talosDropdownTrigger' });
17
+ /** Secondary alias for menu */
18
+ menuAlt = input(null, { ...(ngDevMode ? { debugName: "menuAlt" } : /* istanbul ignore next */ {}), alias: 'talosDropdown' });
19
+ /** Trigger activation mechanism: 'click', 'hover', or 'both' */
20
+ triggerOn = input('click', /* @ts-ignore */
21
+ ...(ngDevMode ? [{ debugName: "triggerOn" }] : /* istanbul ignore next */ []));
22
+ /** Desired placement around the trigger */
23
+ placement = input('bottom-start', /* @ts-ignore */
24
+ ...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
25
+ /** Element, ElementRef, or Component instance to which the dropdown overlay is anchored/attached */
26
+ connectedTo = input(null, /* @ts-ignore */
27
+ ...(ngDevMode ? [{ debugName: "connectedTo" }] : /* istanbul ignore next */ []));
28
+ /** Secondary alias for connectedTo */
29
+ origin = input(null, /* @ts-ignore */
30
+ ...(ngDevMode ? [{ debugName: "origin" }] : /* istanbul ignore next */ []));
31
+ /** Whether the dropdown overlay should match the width of the connected element */
32
+ matchWidth = input(false, /* @ts-ignore */
33
+ ...(ngDevMode ? [{ debugName: "matchWidth" }] : /* istanbul ignore next */ []));
34
+ /** Whether the dropdown trigger is disabled */
35
+ disabled = input(false, /* @ts-ignore */
36
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
37
+ /** Delay in milliseconds before closing on hover leave */
38
+ hoverDelay = input(150, /* @ts-ignore */
39
+ ...(ngDevMode ? [{ debugName: "hoverDelay" }] : /* istanbul ignore next */ []));
40
+ /** Vertical offset in pixels from the trigger */
41
+ offsetY = input(4, /* @ts-ignore */
42
+ ...(ngDevMode ? [{ debugName: "offsetY" }] : /* istanbul ignore next */ []));
43
+ /** Horizontal offset in pixels from the trigger */
44
+ offsetX = input(0, /* @ts-ignore */
45
+ ...(ngDevMode ? [{ debugName: "offsetX" }] : /* istanbul ignore next */ []));
46
+ /** Whether clicking any menu item automatically closes the menu */
47
+ closeOnItemClick = input(true, /* @ts-ignore */
48
+ ...(ngDevMode ? [{ debugName: "closeOnItemClick" }] : /* istanbul ignore next */ []));
49
+ /** Emitted when the dropdown opens */
50
+ opened = output();
51
+ /** Emitted when the dropdown closes */
52
+ closed = output();
53
+ /** Current open state signal */
54
+ isOpen = signal(false, /* @ts-ignore */
55
+ ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
56
+ overlayRef = null;
57
+ portal = null;
58
+ hoverTimer = null;
59
+ constructor() {
60
+ // Listen to menu panel mouse events for hover bridging
61
+ effect(() => {
62
+ const activeMenu = this.activeMenu;
63
+ if (!activeMenu)
64
+ return;
65
+ activeMenu.panelMouseEnter.subscribe(() => {
66
+ if (this.triggerOn() === 'hover' || this.triggerOn() === 'both') {
67
+ this.cancelHoverClose();
68
+ }
69
+ });
70
+ activeMenu.panelMouseLeave.subscribe(() => {
71
+ if (this.triggerOn() === 'hover' || this.triggerOn() === 'both') {
72
+ this.scheduleHoverClose();
73
+ }
74
+ });
75
+ activeMenu.itemActivated.subscribe(() => {
76
+ if (this.closeOnItemClick()) {
77
+ this.close();
78
+ }
79
+ });
80
+ });
81
+ // Listen to origin element mouse events for hover bridging when anchor differs from trigger
82
+ effect((onCleanup) => {
83
+ const originEl = this.targetOriginElement;
84
+ if (originEl && originEl !== this.elementRef.nativeElement) {
85
+ const onOriginEnter = () => {
86
+ if (this.isOpen() && (this.triggerOn() === 'hover' || this.triggerOn() === 'both')) {
87
+ this.cancelHoverClose();
88
+ }
89
+ };
90
+ const onOriginLeave = () => {
91
+ if (this.isOpen() && (this.triggerOn() === 'hover' || this.triggerOn() === 'both')) {
92
+ this.scheduleHoverClose();
93
+ }
94
+ };
95
+ originEl.addEventListener('mouseenter', onOriginEnter);
96
+ originEl.addEventListener('mouseleave', onOriginLeave);
97
+ onCleanup(() => {
98
+ originEl.removeEventListener('mouseenter', onOriginEnter);
99
+ originEl.removeEventListener('mouseleave', onOriginLeave);
100
+ });
101
+ }
102
+ });
103
+ this.destroyRef.onDestroy(() => {
104
+ this.clearHoverTimer();
105
+ this.disposeOverlay();
106
+ });
107
+ }
108
+ get activeMenu() {
109
+ return this.menu() || this.menuAlt();
110
+ }
111
+ get targetOrigin() {
112
+ const custom = this.connectedTo() || this.origin();
113
+ if (!custom) {
114
+ return this.elementRef;
115
+ }
116
+ if (custom instanceof ElementRef) {
117
+ return custom;
118
+ }
119
+ if (typeof HTMLElement !== 'undefined' && custom instanceof HTMLElement) {
120
+ return custom;
121
+ }
122
+ if (typeof custom === 'object' && custom !== null) {
123
+ if ('elementRef' in custom && custom.elementRef instanceof ElementRef) {
124
+ return custom.elementRef;
125
+ }
126
+ if ('nativeElement' in custom && custom.nativeElement instanceof HTMLElement) {
127
+ return custom.nativeElement;
128
+ }
129
+ }
130
+ return this.elementRef;
131
+ }
132
+ get targetOriginElement() {
133
+ const origin = this.targetOrigin;
134
+ if (origin instanceof ElementRef) {
135
+ return origin.nativeElement;
136
+ }
137
+ return origin;
138
+ }
139
+ handleClick(event) {
140
+ if (this.disabled())
141
+ return;
142
+ if (this.triggerOn() === 'click' || this.triggerOn() === 'both') {
143
+ event.preventDefault();
144
+ this.toggle();
145
+ }
146
+ }
147
+ handleMouseEnter() {
148
+ if (this.disabled())
149
+ return;
150
+ if (this.triggerOn() === 'hover' || this.triggerOn() === 'both') {
151
+ this.cancelHoverClose();
152
+ this.open();
153
+ }
154
+ }
155
+ handleMouseLeave() {
156
+ if (this.disabled())
157
+ return;
158
+ if (this.triggerOn() === 'hover' || this.triggerOn() === 'both') {
159
+ this.scheduleHoverClose();
160
+ }
161
+ }
162
+ handleKeyDownArrowDown(event) {
163
+ if (this.disabled())
164
+ return;
165
+ event.preventDefault();
166
+ if (!this.isOpen()) {
167
+ this.open();
168
+ }
169
+ setTimeout(() => {
170
+ this.activeMenu?.focusFirstItem();
171
+ }, 10);
172
+ }
173
+ handleKeyDownEscape(event) {
174
+ if (this.isOpen()) {
175
+ event.preventDefault();
176
+ this.close();
177
+ this.elementRef.nativeElement.focus();
178
+ }
179
+ }
180
+ open() {
181
+ if (this.disabled() || this.isOpen() || !this.activeMenu) {
182
+ return;
183
+ }
184
+ const overlayRef = this.getOrCreateOverlay();
185
+ if (!this.portal) {
186
+ this.portal = new TemplatePortal(this.activeMenu.templateRef, this.vcr);
187
+ }
188
+ if (this.matchWidth()) {
189
+ const width = this.targetOriginElement.offsetWidth;
190
+ if (width > 0) {
191
+ overlayRef.updateSize({ minWidth: width });
192
+ }
193
+ }
194
+ if (!overlayRef.hasAttached()) {
195
+ overlayRef.attach(this.portal);
196
+ }
197
+ this.isOpen.set(true);
198
+ this.opened.emit();
199
+ }
200
+ close() {
201
+ if (!this.isOpen())
202
+ return;
203
+ this.clearHoverTimer();
204
+ if (this.overlayRef?.hasAttached()) {
205
+ this.overlayRef.detach();
206
+ }
207
+ this.activeMenu?.resetFocus();
208
+ this.isOpen.set(false);
209
+ this.closed.emit();
210
+ }
211
+ toggle() {
212
+ if (this.isOpen()) {
213
+ this.close();
214
+ }
215
+ else {
216
+ this.open();
217
+ }
218
+ }
219
+ scheduleHoverClose() {
220
+ this.clearHoverTimer();
221
+ this.hoverTimer = setTimeout(() => {
222
+ this.close();
223
+ }, this.hoverDelay());
224
+ }
225
+ cancelHoverClose() {
226
+ this.clearHoverTimer();
227
+ }
228
+ clearHoverTimer() {
229
+ if (this.hoverTimer) {
230
+ clearTimeout(this.hoverTimer);
231
+ this.hoverTimer = null;
232
+ }
233
+ }
234
+ getOrCreateOverlay() {
235
+ if (this.overlayRef) {
236
+ return this.overlayRef;
237
+ }
238
+ const positionStrategy = this.createPositionStrategy();
239
+ this.overlayRef = this.overlay.create({
240
+ positionStrategy,
241
+ scrollStrategy: this.overlay.scrollStrategies.reposition(),
242
+ hasBackdrop: false,
243
+ minWidth: this.matchWidth() ? this.targetOriginElement.offsetWidth : undefined
244
+ });
245
+ // Close when clicking outside of both the trigger element and the overlay
246
+ this.overlayRef
247
+ .outsidePointerEvents()
248
+ .pipe(filter(event => !this.elementRef.nativeElement.contains(event.target)))
249
+ .subscribe(() => {
250
+ this.close();
251
+ });
252
+ return this.overlayRef;
253
+ }
254
+ createPositionStrategy() {
255
+ const chosenPlacement = this.placement() || this.activeMenu?.placement() || 'bottom-start';
256
+ const offsetY = this.offsetY();
257
+ const offsetX = this.offsetX();
258
+ const positions = this.getPositionsForPlacement(chosenPlacement, offsetX, offsetY);
259
+ return this.overlay
260
+ .position()
261
+ .flexibleConnectedTo(this.targetOrigin)
262
+ .withPositions(positions)
263
+ .withPush(true)
264
+ .withFlexibleDimensions(false);
265
+ }
266
+ getPositionsForPlacement(placement, offsetX, offsetY) {
267
+ const bottomStart = {
268
+ originX: 'start',
269
+ originY: 'bottom',
270
+ overlayX: 'start',
271
+ overlayY: 'top',
272
+ offsetX,
273
+ offsetY
274
+ };
275
+ const bottomEnd = {
276
+ originX: 'end',
277
+ originY: 'bottom',
278
+ overlayX: 'end',
279
+ overlayY: 'top',
280
+ offsetX,
281
+ offsetY
282
+ };
283
+ const bottomCenter = {
284
+ originX: 'center',
285
+ originY: 'bottom',
286
+ overlayX: 'center',
287
+ overlayY: 'top',
288
+ offsetX,
289
+ offsetY
290
+ };
291
+ const topStart = {
292
+ originX: 'start',
293
+ originY: 'top',
294
+ overlayX: 'start',
295
+ overlayY: 'bottom',
296
+ offsetX,
297
+ offsetY: -offsetY
298
+ };
299
+ const topEnd = {
300
+ originX: 'end',
301
+ originY: 'top',
302
+ overlayX: 'end',
303
+ overlayY: 'bottom',
304
+ offsetX,
305
+ offsetY: -offsetY
306
+ };
307
+ const topCenter = {
308
+ originX: 'center',
309
+ originY: 'top',
310
+ overlayX: 'center',
311
+ overlayY: 'bottom',
312
+ offsetX,
313
+ offsetY: -offsetY
314
+ };
315
+ const rightStart = {
316
+ originX: 'end',
317
+ originY: 'top',
318
+ overlayX: 'start',
319
+ overlayY: 'top',
320
+ offsetX: offsetY,
321
+ offsetY: offsetX
322
+ };
323
+ const leftStart = {
324
+ originX: 'start',
325
+ originY: 'top',
326
+ overlayX: 'end',
327
+ overlayY: 'top',
328
+ offsetX: -offsetY,
329
+ offsetY: offsetX
330
+ };
331
+ switch (placement) {
332
+ case 'bottom-end':
333
+ return [bottomEnd, topEnd, bottomStart, topStart];
334
+ case 'bottom':
335
+ return [bottomCenter, topCenter, bottomStart, bottomEnd];
336
+ case 'top-start':
337
+ return [topStart, bottomStart, topEnd, bottomEnd];
338
+ case 'top-end':
339
+ return [topEnd, bottomEnd, topStart, bottomStart];
340
+ case 'top':
341
+ return [topCenter, bottomCenter, topStart, topEnd];
342
+ case 'right-start':
343
+ case 'right':
344
+ return [rightStart, leftStart, bottomStart, topStart];
345
+ case 'left-start':
346
+ case 'left':
347
+ return [leftStart, rightStart, bottomStart, topStart];
348
+ case 'bottom-start':
349
+ default:
350
+ return [bottomStart, topStart, bottomEnd, topEnd];
351
+ }
352
+ }
353
+ disposeOverlay() {
354
+ if (this.overlayRef) {
355
+ this.overlayRef.dispose();
356
+ this.overlayRef = null;
357
+ this.portal = null;
358
+ }
359
+ }
360
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDropdownTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
361
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.1", type: TalosDropdownTriggerDirective, isStandalone: true, selector: "[talosDropdownTrigger], [talosDropdown]", inputs: { menu: { classPropertyName: "menu", publicName: "talosDropdownTrigger", isSignal: true, isRequired: false, transformFunction: null }, menuAlt: { classPropertyName: "menuAlt", publicName: "talosDropdown", isSignal: true, isRequired: false, transformFunction: null }, triggerOn: { classPropertyName: "triggerOn", publicName: "triggerOn", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, connectedTo: { classPropertyName: "connectedTo", publicName: "connectedTo", isSignal: true, isRequired: false, transformFunction: null }, origin: { classPropertyName: "origin", publicName: "origin", isSignal: true, isRequired: false, transformFunction: null }, matchWidth: { classPropertyName: "matchWidth", publicName: "matchWidth", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hoverDelay: { classPropertyName: "hoverDelay", publicName: "hoverDelay", isSignal: true, isRequired: false, transformFunction: null }, offsetY: { classPropertyName: "offsetY", publicName: "offsetY", isSignal: true, isRequired: false, transformFunction: null }, offsetX: { classPropertyName: "offsetX", publicName: "offsetX", isSignal: true, isRequired: false, transformFunction: null }, closeOnItemClick: { classPropertyName: "closeOnItemClick", publicName: "closeOnItemClick", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { opened: "opened", closed: "closed" }, host: { listeners: { "click": "handleClick($event)", "mouseenter": "handleMouseEnter()", "mouseleave": "handleMouseLeave()", "keydown.arrowdown": "handleKeyDownArrowDown($event)", "keydown.escape": "handleKeyDownEscape($event)" }, properties: { "attr.aria-haspopup": "\"menu\"", "attr.aria-expanded": "isOpen()", "class.talos-dropdown-open": "isOpen()" } }, exportAs: ["talosDropdownTrigger"], ngImport: i0 });
362
+ }
363
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDropdownTriggerDirective, decorators: [{
364
+ type: Directive,
365
+ args: [{
366
+ selector: '[talosDropdownTrigger], [talosDropdown]',
367
+ exportAs: 'talosDropdownTrigger',
368
+ host: {
369
+ '[attr.aria-haspopup]': '"menu"',
370
+ '[attr.aria-expanded]': 'isOpen()',
371
+ '[class.talos-dropdown-open]': 'isOpen()',
372
+ '(click)': 'handleClick($event)',
373
+ '(mouseenter)': 'handleMouseEnter()',
374
+ '(mouseleave)': 'handleMouseLeave()',
375
+ '(keydown.arrowdown)': 'handleKeyDownArrowDown($event)',
376
+ '(keydown.escape)': 'handleKeyDownEscape($event)'
377
+ }
378
+ }]
379
+ }], ctorParameters: () => [], propDecorators: { menu: [{ type: i0.Input, args: [{ isSignal: true, alias: "talosDropdownTrigger", required: false }] }], menuAlt: [{ type: i0.Input, args: [{ isSignal: true, alias: "talosDropdown", required: false }] }], triggerOn: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerOn", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], connectedTo: [{ type: i0.Input, args: [{ isSignal: true, alias: "connectedTo", required: false }] }], origin: [{ type: i0.Input, args: [{ isSignal: true, alias: "origin", required: false }] }], matchWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "matchWidth", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], hoverDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverDelay", required: false }] }], offsetY: [{ type: i0.Input, args: [{ isSignal: true, alias: "offsetY", required: false }] }], offsetX: [{ type: i0.Input, args: [{ isSignal: true, alias: "offsetX", required: false }] }], closeOnItemClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnItemClick", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
380
+
381
+ class TalosDropdownItemComponent {
382
+ elementRef = inject(ElementRef);
383
+ overlay = inject(Overlay);
384
+ vcr = inject(ViewContainerRef);
385
+ destroyRef = inject(DestroyRef);
386
+ /** Optional plain text label (if not using content projection) */
387
+ label = input('', /* @ts-ignore */
388
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
389
+ /** Optional icon component type */
390
+ icon = input(null, /* @ts-ignore */
391
+ ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
392
+ /** Optional external link URL */
393
+ href = input('', /* @ts-ignore */
394
+ ...(ngDevMode ? [{ debugName: "href" }] : /* istanbul ignore next */ []));
395
+ /** Target for external link (default '_blank' when href is present) */
396
+ target = input('_blank', /* @ts-ignore */
397
+ ...(ngDevMode ? [{ debugName: "target" }] : /* istanbul ignore next */ []));
398
+ /** Visual variant: default, danger, primary, success, warning */
399
+ variant = input('default', /* @ts-ignore */
400
+ ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
401
+ /** Quick flag for destructive danger styling */
402
+ danger = input(false, /* @ts-ignore */
403
+ ...(ngDevMode ? [{ debugName: "danger" }] : /* istanbul ignore next */ []));
404
+ /** Disabled state */
405
+ disabled = input(false, /* @ts-ignore */
406
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
407
+ /** Keyboard shortcut hint text (e.g. '⌘K', 'Ctrl+S') */
408
+ shortcut = input('', /* @ts-ignore */
409
+ ...(ngDevMode ? [{ debugName: "shortcut" }] : /* istanbul ignore next */ []));
410
+ /** Checkable / selectable state */
411
+ checked = input(undefined, /* @ts-ignore */
412
+ ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
413
+ /** Optional badge text or number */
414
+ badge = input(null, /* @ts-ignore */
415
+ ...(ngDevMode ? [{ debugName: "badge" }] : /* istanbul ignore next */ []));
416
+ /** Badge visual variant */
417
+ badgeVariant = input('primary', /* @ts-ignore */
418
+ ...(ngDevMode ? [{ debugName: "badgeVariant" }] : /* istanbul ignore next */ []));
419
+ /** Child Sub-menu to fly out when hovering/clicking */
420
+ subMenu = input(null, /* @ts-ignore */
421
+ ...(ngDevMode ? [{ debugName: "subMenu" }] : /* istanbul ignore next */ []));
422
+ /** Emitted when the item is activated */
423
+ itemClick = output();
424
+ /** Whether this item has an attached sub-menu */
425
+ hasSubMenu = computed(() => !!this.subMenu(), /* @ts-ignore */
426
+ ...(ngDevMode ? [{ debugName: "hasSubMenu" }] : /* istanbul ignore next */ []));
427
+ /** Whether the sub-menu is currently opened */
428
+ isSubMenuOpen = signal(false, /* @ts-ignore */
429
+ ...(ngDevMode ? [{ debugName: "isSubMenuOpen" }] : /* istanbul ignore next */ []));
430
+ /** Internal callback set by parent menu container to notify on click */
431
+ _onActivate;
432
+ /** Internal callback set by parent menu container to notify on item hover */
433
+ _onHover;
434
+ overlayRef = null;
435
+ portal = null;
436
+ hoverTimer = null;
437
+ constructor() {
438
+ // Listen to sub-menu mouse & item activation events
439
+ effect(() => {
440
+ const childMenu = this.subMenu();
441
+ if (!childMenu)
442
+ return;
443
+ childMenu.panelMouseEnter.subscribe(() => {
444
+ this.cancelHoverClose();
445
+ });
446
+ childMenu.panelMouseLeave.subscribe(() => {
447
+ this.scheduleHoverClose();
448
+ });
449
+ childMenu.itemActivated.subscribe((e) => {
450
+ if (this._onActivate) {
451
+ this._onActivate(e);
452
+ }
453
+ });
454
+ });
455
+ this.destroyRef.onDestroy(() => {
456
+ this.clearHoverTimer();
457
+ this.disposeOverlay();
458
+ });
459
+ }
460
+ handleClick(event) {
461
+ if (this.disabled()) {
462
+ event.preventDefault();
463
+ event.stopPropagation();
464
+ return;
465
+ }
466
+ if (this.hasSubMenu()) {
467
+ event.preventDefault();
468
+ event.stopPropagation();
469
+ this.toggleSubMenu();
470
+ return;
471
+ }
472
+ this.itemClick.emit(event);
473
+ if (this._onActivate) {
474
+ this._onActivate(event);
475
+ }
476
+ }
477
+ handleMouseEnter() {
478
+ if (this.disabled())
479
+ return;
480
+ if (this._onHover) {
481
+ this._onHover(this);
482
+ }
483
+ if (this.hasSubMenu()) {
484
+ this.cancelHoverClose();
485
+ this.hoverTimer = setTimeout(() => {
486
+ this.openSubMenu();
487
+ }, 60);
488
+ }
489
+ }
490
+ handleMouseLeave() {
491
+ if (this.disabled())
492
+ return;
493
+ if (this.hasSubMenu()) {
494
+ this.scheduleHoverClose();
495
+ }
496
+ }
497
+ openSubMenu() {
498
+ if (this.disabled() || this.isSubMenuOpen() || !this.subMenu()) {
499
+ return;
500
+ }
501
+ const overlayRef = this.getOrCreateOverlay();
502
+ if (!this.portal && this.subMenu()) {
503
+ this.portal = new TemplatePortal(this.subMenu().templateRef, this.vcr);
504
+ }
505
+ if (!overlayRef.hasAttached() && this.portal) {
506
+ overlayRef.attach(this.portal);
507
+ }
508
+ this.isSubMenuOpen.set(true);
509
+ }
510
+ closeSubMenu() {
511
+ if (!this.isSubMenuOpen())
512
+ return;
513
+ this.clearHoverTimer();
514
+ if (this.overlayRef?.hasAttached()) {
515
+ this.overlayRef.detach();
516
+ }
517
+ this.subMenu()?.resetFocus();
518
+ this.isSubMenuOpen.set(false);
519
+ }
520
+ toggleSubMenu() {
521
+ if (this.isSubMenuOpen()) {
522
+ this.closeSubMenu();
523
+ }
524
+ else {
525
+ this.openSubMenu();
526
+ }
527
+ }
528
+ scheduleHoverClose() {
529
+ this.clearHoverTimer();
530
+ this.hoverTimer = setTimeout(() => {
531
+ this.closeSubMenu();
532
+ }, 180);
533
+ }
534
+ cancelHoverClose() {
535
+ this.clearHoverTimer();
536
+ }
537
+ clearHoverTimer() {
538
+ if (this.hoverTimer) {
539
+ clearTimeout(this.hoverTimer);
540
+ this.hoverTimer = null;
541
+ }
542
+ }
543
+ getOrCreateOverlay() {
544
+ if (this.overlayRef) {
545
+ return this.overlayRef;
546
+ }
547
+ const positionStrategy = this.createSubMenuPositionStrategy();
548
+ this.overlayRef = this.overlay.create({
549
+ positionStrategy,
550
+ scrollStrategy: this.overlay.scrollStrategies.reposition(),
551
+ hasBackdrop: false
552
+ });
553
+ return this.overlayRef;
554
+ }
555
+ createSubMenuPositionStrategy() {
556
+ const positions = [
557
+ // Standard right-start flyout (offset by 4px)
558
+ {
559
+ originX: 'end',
560
+ originY: 'top',
561
+ overlayX: 'start',
562
+ overlayY: 'top',
563
+ offsetX: 4,
564
+ offsetY: -4
565
+ },
566
+ // Flip left-start if right edge of viewport is reached
567
+ {
568
+ originX: 'start',
569
+ originY: 'top',
570
+ overlayX: 'end',
571
+ overlayY: 'top',
572
+ offsetX: -4,
573
+ offsetY: -4
574
+ },
575
+ // Flip bottom aligned if bottom edge is reached
576
+ {
577
+ originX: 'end',
578
+ originY: 'bottom',
579
+ overlayX: 'start',
580
+ overlayY: 'bottom',
581
+ offsetX: 4,
582
+ offsetY: 4
583
+ },
584
+ {
585
+ originX: 'start',
586
+ originY: 'bottom',
587
+ overlayX: 'end',
588
+ overlayY: 'bottom',
589
+ offsetX: -4,
590
+ offsetY: 4
591
+ }
592
+ ];
593
+ return this.overlay
594
+ .position()
595
+ .flexibleConnectedTo(this.elementRef)
596
+ .withPositions(positions)
597
+ .withPush(true)
598
+ .withFlexibleDimensions(false);
599
+ }
600
+ disposeOverlay() {
601
+ if (this.overlayRef) {
602
+ this.overlayRef.dispose();
603
+ this.overlayRef = null;
604
+ this.portal = null;
605
+ }
606
+ }
607
+ focus() {
608
+ const focusable = this.elementRef.nativeElement.querySelector('button, a');
609
+ focusable?.focus();
610
+ }
611
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDropdownItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
612
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", type: TalosDropdownItemComponent, isStandalone: true, selector: "talos-dropdown-item, button[talosDropdownItem], a[talosDropdownItem]", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: false, transformFunction: null }, target: { classPropertyName: "target", publicName: "target", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, danger: { classPropertyName: "danger", publicName: "danger", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, shortcut: { classPropertyName: "shortcut", publicName: "shortcut", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, badgeVariant: { classPropertyName: "badgeVariant", publicName: "badgeVariant", isSignal: true, isRequired: false, transformFunction: null }, subMenu: { classPropertyName: "subMenu", publicName: "subMenu", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick" }, host: { attributes: { "role": "none" }, listeners: { "mouseenter": "handleMouseEnter()", "mouseleave": "handleMouseLeave()" }, properties: { "class.is-disabled": "disabled()", "class.is-danger": "danger() || variant() === \"danger\"", "class.is-primary": "variant() === \"primary\"", "class.is-success": "variant() === \"success\"", "class.has-submenu": "hasSubMenu()", "class.is-submenu-open": "isSubMenuOpen()", "class.is-checked": "checked() === true" }, classAttribute: "talos-dropdown-item-host" }, ngImport: i0, template: `
613
+ @if (href()) {
614
+ <a
615
+ class="talos-dropdown-item-link"
616
+ [href]="href()"
617
+ [target]="target()"
618
+ [rel]="target() === '_blank' ? 'noopener noreferrer' : null"
619
+ [attr.tabindex]="disabled() ? -1 : 0"
620
+ (click)="handleClick($event)"
621
+ >
622
+ <ng-container *ngTemplateOutlet="itemBody"></ng-container>
623
+ </a>
624
+ } @else {
625
+ <button
626
+ type="button"
627
+ class="talos-dropdown-item-btn"
628
+ [disabled]="disabled()"
629
+ [attr.tabindex]="disabled() ? -1 : 0"
630
+ [attr.aria-haspopup]="hasSubMenu() ? 'menu' : null"
631
+ [attr.aria-expanded]="hasSubMenu() ? isSubMenuOpen() : null"
632
+ (click)="handleClick($event)"
633
+ >
634
+ <ng-container *ngTemplateOutlet="itemBody"></ng-container>
635
+ </button>
636
+ }
637
+
638
+ <ng-template #itemBody>
639
+ <!-- Checkmark for checkable items -->
640
+ @if (checked() !== null && checked() !== undefined) {
641
+ <span class="talos-dropdown-item-check" [class.is-checked]="checked()">
642
+ @if (checked()) {
643
+ <svg lucideCheck [size]="13"></svg>
644
+ }
645
+ </span>
646
+ }
647
+
648
+ <!-- Custom Prefix Icon -->
649
+ @if (icon(); as itemIcon) {
650
+ <span class="talos-dropdown-item-icon">
651
+ <ng-container *ngComponentOutlet="itemIcon" />
652
+ </span>
653
+ }
654
+
655
+ <!-- Item Label / Content -->
656
+ <span class="talos-dropdown-item-label">
657
+ @if (label()) {
658
+ {{ label() }}
659
+ } @else {
660
+ <ng-content />
661
+ }
662
+ </span>
663
+
664
+ <!-- Optional Status Badge -->
665
+ @if (badge() !== null && badge() !== undefined && badge() !== '') {
666
+ <span class="talos-dropdown-item-badge" [class]="'badge-' + (badgeVariant() || 'primary')">
667
+ {{ badge() }}
668
+ </span>
669
+ }
670
+
671
+ <!-- Keyboard Shortcut Key Hint -->
672
+ @if (shortcut()) {
673
+ <kbd class="talos-dropdown-item-shortcut">{{ shortcut() }}</kbd>
674
+ }
675
+
676
+ <!-- Right Chevron for Sub-menus -->
677
+ @if (hasSubMenu()) {
678
+ <span class="talos-dropdown-item-submenu-arrow">
679
+ <svg lucideChevronRight [size]="13"></svg>
680
+ </span>
681
+ }
682
+ </ng-template>
683
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "component", type: LucideCheck, selector: "svg[lucideCheck]" }] });
684
+ }
685
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDropdownItemComponent, decorators: [{
686
+ type: Component,
687
+ args: [{
688
+ selector: 'talos-dropdown-item, button[talosDropdownItem], a[talosDropdownItem]',
689
+ imports: [CommonModule, LucideChevronRight, LucideCheck],
690
+ template: `
691
+ @if (href()) {
692
+ <a
693
+ class="talos-dropdown-item-link"
694
+ [href]="href()"
695
+ [target]="target()"
696
+ [rel]="target() === '_blank' ? 'noopener noreferrer' : null"
697
+ [attr.tabindex]="disabled() ? -1 : 0"
698
+ (click)="handleClick($event)"
699
+ >
700
+ <ng-container *ngTemplateOutlet="itemBody"></ng-container>
701
+ </a>
702
+ } @else {
703
+ <button
704
+ type="button"
705
+ class="talos-dropdown-item-btn"
706
+ [disabled]="disabled()"
707
+ [attr.tabindex]="disabled() ? -1 : 0"
708
+ [attr.aria-haspopup]="hasSubMenu() ? 'menu' : null"
709
+ [attr.aria-expanded]="hasSubMenu() ? isSubMenuOpen() : null"
710
+ (click)="handleClick($event)"
711
+ >
712
+ <ng-container *ngTemplateOutlet="itemBody"></ng-container>
713
+ </button>
714
+ }
715
+
716
+ <ng-template #itemBody>
717
+ <!-- Checkmark for checkable items -->
718
+ @if (checked() !== null && checked() !== undefined) {
719
+ <span class="talos-dropdown-item-check" [class.is-checked]="checked()">
720
+ @if (checked()) {
721
+ <svg lucideCheck [size]="13"></svg>
722
+ }
723
+ </span>
724
+ }
725
+
726
+ <!-- Custom Prefix Icon -->
727
+ @if (icon(); as itemIcon) {
728
+ <span class="talos-dropdown-item-icon">
729
+ <ng-container *ngComponentOutlet="itemIcon" />
730
+ </span>
731
+ }
732
+
733
+ <!-- Item Label / Content -->
734
+ <span class="talos-dropdown-item-label">
735
+ @if (label()) {
736
+ {{ label() }}
737
+ } @else {
738
+ <ng-content />
739
+ }
740
+ </span>
741
+
742
+ <!-- Optional Status Badge -->
743
+ @if (badge() !== null && badge() !== undefined && badge() !== '') {
744
+ <span class="talos-dropdown-item-badge" [class]="'badge-' + (badgeVariant() || 'primary')">
745
+ {{ badge() }}
746
+ </span>
747
+ }
748
+
749
+ <!-- Keyboard Shortcut Key Hint -->
750
+ @if (shortcut()) {
751
+ <kbd class="talos-dropdown-item-shortcut">{{ shortcut() }}</kbd>
752
+ }
753
+
754
+ <!-- Right Chevron for Sub-menus -->
755
+ @if (hasSubMenu()) {
756
+ <span class="talos-dropdown-item-submenu-arrow">
757
+ <svg lucideChevronRight [size]="13"></svg>
758
+ </span>
759
+ }
760
+ </ng-template>
761
+ `,
762
+ host: {
763
+ 'class': 'talos-dropdown-item-host',
764
+ 'role': 'none',
765
+ '[class.is-disabled]': 'disabled()',
766
+ '[class.is-danger]': 'danger() || variant() === "danger"',
767
+ '[class.is-primary]': 'variant() === "primary"',
768
+ '[class.is-success]': 'variant() === "success"',
769
+ '[class.has-submenu]': 'hasSubMenu()',
770
+ '[class.is-submenu-open]': 'isSubMenuOpen()',
771
+ '[class.is-checked]': 'checked() === true',
772
+ '(mouseenter)': 'handleMouseEnter()',
773
+ '(mouseleave)': 'handleMouseLeave()'
774
+ }
775
+ }]
776
+ }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], href: [{ type: i0.Input, args: [{ isSignal: true, alias: "href", required: false }] }], target: [{ type: i0.Input, args: [{ isSignal: true, alias: "target", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], danger: [{ type: i0.Input, args: [{ isSignal: true, alias: "danger", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], shortcut: [{ type: i0.Input, args: [{ isSignal: true, alias: "shortcut", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }], badgeVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "badgeVariant", required: false }] }], subMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "subMenu", required: false }] }], itemClick: [{ type: i0.Output, args: ["itemClick"] }] } });
777
+
778
+ class TalosDropdownMenuComponent {
779
+ templateRef;
780
+ panelEl;
781
+ /** Optional custom CSS class applied to the dropdown panel */
782
+ customClass = input('', /* @ts-ignore */
783
+ ...(ngDevMode ? [{ debugName: "customClass" }] : /* istanbul ignore next */ []));
784
+ /** Minimum width of the dropdown menu */
785
+ minWidth = input('180px', /* @ts-ignore */
786
+ ...(ngDevMode ? [{ debugName: "minWidth" }] : /* istanbul ignore next */ []));
787
+ /** Maximum width of the dropdown menu */
788
+ maxWidth = input('360px', /* @ts-ignore */
789
+ ...(ngDevMode ? [{ debugName: "maxWidth" }] : /* istanbul ignore next */ []));
790
+ /** Preferred placement of the dropdown menu */
791
+ placement = input('bottom-start', /* @ts-ignore */
792
+ ...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
793
+ /** Whether clicking an item should automatically close the dropdown */
794
+ autoClose = input(true, /* @ts-ignore */
795
+ ...(ngDevMode ? [{ debugName: "autoClose" }] : /* istanbul ignore next */ []));
796
+ /** Emitted when mouse enters the floating menu panel */
797
+ panelMouseEnter = output();
798
+ /** Emitted when mouse leaves the floating menu panel */
799
+ panelMouseLeave = output();
800
+ /** Emitted when an item inside this menu is activated */
801
+ itemActivated = output();
802
+ /** Query all menu items inside */
803
+ items = contentChildren(TalosDropdownItemComponent, { ...(ngDevMode ? { debugName: "items" } : /* istanbul ignore next */ {}), descendants: true });
804
+ focusedItemIndex = signal(-1, /* @ts-ignore */
805
+ ...(ngDevMode ? [{ debugName: "focusedItemIndex" }] : /* istanbul ignore next */ []));
806
+ constructor() {
807
+ // Coordinate items: activation & closing sibling submenus on hover
808
+ effect(() => {
809
+ const itemList = this.items();
810
+ for (const item of itemList) {
811
+ item._onActivate = (e) => {
812
+ this.closeAllSubMenus();
813
+ this.itemActivated.emit(e);
814
+ };
815
+ item._onHover = (hoveredItem) => {
816
+ // Close submenus on all other sibling items
817
+ for (const other of this.items()) {
818
+ if (other !== hoveredItem && other.hasSubMenu()) {
819
+ other.closeSubMenu();
820
+ }
821
+ }
822
+ };
823
+ }
824
+ });
825
+ }
826
+ handlePanelMouseEnter() {
827
+ this.panelMouseEnter.emit();
828
+ }
829
+ handlePanelMouseLeave() {
830
+ this.panelMouseLeave.emit();
831
+ }
832
+ closeAllSubMenus() {
833
+ for (const item of this.items()) {
834
+ if (item.hasSubMenu()) {
835
+ item.closeSubMenu();
836
+ }
837
+ }
838
+ }
839
+ handleKeyDown(event) {
840
+ const itemList = this.items().filter(item => !item.disabled());
841
+ if (itemList.length === 0)
842
+ return;
843
+ switch (event.key) {
844
+ case 'ArrowDown': {
845
+ event.preventDefault();
846
+ const nextIndex = (this.focusedItemIndex() + 1) % itemList.length;
847
+ this.focusedItemIndex.set(nextIndex);
848
+ itemList[nextIndex]?.focus();
849
+ break;
850
+ }
851
+ case 'ArrowUp': {
852
+ event.preventDefault();
853
+ const prevIndex = (this.focusedItemIndex() - 1 + itemList.length) % itemList.length;
854
+ this.focusedItemIndex.set(prevIndex);
855
+ itemList[prevIndex]?.focus();
856
+ break;
857
+ }
858
+ case 'ArrowRight': {
859
+ const currentItem = itemList[this.focusedItemIndex()];
860
+ if (currentItem && currentItem.hasSubMenu()) {
861
+ event.preventDefault();
862
+ currentItem.openSubMenu();
863
+ setTimeout(() => {
864
+ currentItem.subMenu()?.focusFirstItem();
865
+ }, 20);
866
+ }
867
+ break;
868
+ }
869
+ case 'Home': {
870
+ event.preventDefault();
871
+ this.focusedItemIndex.set(0);
872
+ itemList[0]?.focus();
873
+ break;
874
+ }
875
+ case 'End': {
876
+ event.preventDefault();
877
+ const lastIndex = itemList.length - 1;
878
+ this.focusedItemIndex.set(lastIndex);
879
+ itemList[lastIndex]?.focus();
880
+ break;
881
+ }
882
+ default:
883
+ break;
884
+ }
885
+ }
886
+ focusFirstItem() {
887
+ const availableItems = this.items().filter(item => !item.disabled());
888
+ if (availableItems.length > 0) {
889
+ this.focusedItemIndex.set(0);
890
+ availableItems[0]?.focus();
891
+ }
892
+ }
893
+ resetFocus() {
894
+ this.focusedItemIndex.set(-1);
895
+ this.closeAllSubMenus();
896
+ }
897
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDropdownMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
898
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.1", type: TalosDropdownMenuComponent, isStandalone: true, selector: "talos-dropdown-menu", inputs: { customClass: { classPropertyName: "customClass", publicName: "customClass", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, autoClose: { classPropertyName: "autoClose", publicName: "autoClose", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { panelMouseEnter: "panelMouseEnter", panelMouseLeave: "panelMouseLeave", itemActivated: "itemActivated" }, host: { styleAttribute: "display: none;" }, queries: [{ propertyName: "items", predicate: TalosDropdownItemComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "templateRef", first: true, predicate: ["templateRef"], descendants: true, static: true }, { propertyName: "panelEl", first: true, predicate: ["panelEl"], descendants: true }], exportAs: ["talosDropdownMenu"], ngImport: i0, template: `
899
+ <ng-template #templateRef>
900
+ <div
901
+ #panelEl
902
+ class="talos-dropdown-panel"
903
+ [class]="customClass()"
904
+ [style.min-width]="minWidth()"
905
+ [style.max-width]="maxWidth()"
906
+ role="menu"
907
+ tabindex="-1"
908
+ (mouseenter)="handlePanelMouseEnter()"
909
+ (mouseleave)="handlePanelMouseLeave()"
910
+ (keydown)="handleKeyDown($event)"
911
+ >
912
+ <ng-content />
913
+ </div>
914
+ </ng-template>
915
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] });
916
+ }
917
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDropdownMenuComponent, decorators: [{
918
+ type: Component,
919
+ args: [{
920
+ selector: 'talos-dropdown-menu',
921
+ exportAs: 'talosDropdownMenu',
922
+ imports: [CommonModule],
923
+ template: `
924
+ <ng-template #templateRef>
925
+ <div
926
+ #panelEl
927
+ class="talos-dropdown-panel"
928
+ [class]="customClass()"
929
+ [style.min-width]="minWidth()"
930
+ [style.max-width]="maxWidth()"
931
+ role="menu"
932
+ tabindex="-1"
933
+ (mouseenter)="handlePanelMouseEnter()"
934
+ (mouseleave)="handlePanelMouseLeave()"
935
+ (keydown)="handleKeyDown($event)"
936
+ >
937
+ <ng-content />
938
+ </div>
939
+ </ng-template>
940
+ `,
941
+ host: {
942
+ 'style': 'display: none;'
943
+ }
944
+ }]
945
+ }], ctorParameters: () => [], propDecorators: { templateRef: [{
946
+ type: ViewChild,
947
+ args: ['templateRef', { static: true }]
948
+ }], panelEl: [{
949
+ type: ViewChild,
950
+ args: ['panelEl']
951
+ }], customClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "customClass", required: false }] }], minWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minWidth", required: false }] }], maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], autoClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoClose", required: false }] }], panelMouseEnter: [{ type: i0.Output, args: ["panelMouseEnter"] }], panelMouseLeave: [{ type: i0.Output, args: ["panelMouseLeave"] }], itemActivated: [{ type: i0.Output, args: ["itemActivated"] }], items: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TalosDropdownItemComponent), { ...{ descendants: true }, isSignal: true }] }] } });
952
+
953
+ class TalosDropdownDividerComponent {
954
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDropdownDividerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
955
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.1", type: TalosDropdownDividerComponent, isStandalone: true, selector: "talos-dropdown-divider, [talosDropdownDivider]", host: { attributes: { "role": "separator", "aria-orientation": "horizontal" }, classAttribute: "talos-dropdown-divider" }, ngImport: i0, template: '', isInline: true });
956
+ }
957
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDropdownDividerComponent, decorators: [{
958
+ type: Component,
959
+ args: [{
960
+ selector: 'talos-dropdown-divider, [talosDropdownDivider]',
961
+ template: '',
962
+ host: {
963
+ 'class': 'talos-dropdown-divider',
964
+ 'role': 'separator',
965
+ 'aria-orientation': 'horizontal'
966
+ }
967
+ }]
968
+ }] });
969
+
970
+ class TalosDropdownHeaderComponent {
971
+ /** Optional header title string */
972
+ title = input('', /* @ts-ignore */
973
+ ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
974
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDropdownHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
975
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", type: TalosDropdownHeaderComponent, isStandalone: true, selector: "talos-dropdown-header, [talosDropdownHeader]", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "presentation" }, classAttribute: "talos-dropdown-header" }, ngImport: i0, template: `
976
+ <span class="talos-dropdown-header-text">
977
+ @if (title()) {
978
+ {{ title() }}
979
+ } @else {
980
+ <ng-content />
981
+ }
982
+ </span>
983
+ `, isInline: true });
984
+ }
985
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDropdownHeaderComponent, decorators: [{
986
+ type: Component,
987
+ args: [{
988
+ selector: 'talos-dropdown-header, [talosDropdownHeader]',
989
+ template: `
990
+ <span class="talos-dropdown-header-text">
991
+ @if (title()) {
992
+ {{ title() }}
993
+ } @else {
994
+ <ng-content />
995
+ }
996
+ </span>
997
+ `,
998
+ host: {
999
+ 'class': 'talos-dropdown-header',
1000
+ 'role': 'presentation'
1001
+ }
1002
+ }]
1003
+ }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }] } });
1004
+
1005
+ const DROPDOWN_DECLARATIONS = [
1006
+ TalosDropdownTriggerDirective,
1007
+ TalosDropdownMenuComponent,
1008
+ TalosDropdownItemComponent,
1009
+ TalosDropdownDividerComponent,
1010
+ TalosDropdownHeaderComponent
1011
+ ];
1012
+ class TalosDropdownModule {
1013
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDropdownModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1014
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.1", ngImport: i0, type: TalosDropdownModule, imports: [TalosDropdownTriggerDirective,
1015
+ TalosDropdownMenuComponent,
1016
+ TalosDropdownItemComponent,
1017
+ TalosDropdownDividerComponent,
1018
+ TalosDropdownHeaderComponent], exports: [TalosDropdownTriggerDirective,
1019
+ TalosDropdownMenuComponent,
1020
+ TalosDropdownItemComponent,
1021
+ TalosDropdownDividerComponent,
1022
+ TalosDropdownHeaderComponent] });
1023
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDropdownModule, imports: [TalosDropdownMenuComponent,
1024
+ TalosDropdownItemComponent] });
1025
+ }
1026
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosDropdownModule, decorators: [{
1027
+ type: NgModule,
1028
+ args: [{
1029
+ imports: [...DROPDOWN_DECLARATIONS],
1030
+ exports: [...DROPDOWN_DECLARATIONS]
1031
+ }]
1032
+ }] });
1033
+
1034
+ /**
1035
+ * Generated bundle index. Do not edit.
1036
+ */
1037
+
1038
+ export { TalosDropdownDividerComponent, TalosDropdownHeaderComponent, TalosDropdownItemComponent, TalosDropdownMenuComponent, TalosDropdownModule, TalosDropdownTriggerDirective };
1039
+ //# sourceMappingURL=weeehaoooz-talos-ui-dropdown.mjs.map