@nanahoshi/mona-ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/README.md +25 -0
  2. package/fesm2022/nanahoshi-mona-ui-auto-complete.mjs +590 -0
  3. package/fesm2022/nanahoshi-mona-ui-avatar.mjs +168 -0
  4. package/fesm2022/nanahoshi-mona-ui-breadcrumb.mjs +220 -0
  5. package/fesm2022/nanahoshi-mona-ui-button-group.mjs +225 -0
  6. package/fesm2022/nanahoshi-mona-ui-button.mjs +497 -0
  7. package/fesm2022/nanahoshi-mona-ui-calendar.mjs +1569 -0
  8. package/fesm2022/nanahoshi-mona-ui-check-box.mjs +339 -0
  9. package/fesm2022/nanahoshi-mona-ui-chip.mjs +453 -0
  10. package/fesm2022/nanahoshi-mona-ui-circular-progress-bar.mjs +200 -0
  11. package/fesm2022/nanahoshi-mona-ui-color-gradient.mjs +853 -0
  12. package/fesm2022/nanahoshi-mona-ui-color-palette.mjs +923 -0
  13. package/fesm2022/nanahoshi-mona-ui-color-picker.mjs +495 -0
  14. package/fesm2022/nanahoshi-mona-ui-combo-box.mjs +686 -0
  15. package/fesm2022/nanahoshi-mona-ui-common.mjs +642 -0
  16. package/fesm2022/nanahoshi-mona-ui-contextmenu.mjs +485 -0
  17. package/fesm2022/nanahoshi-mona-ui-date-input.mjs +132 -0
  18. package/fesm2022/nanahoshi-mona-ui-date-picker.mjs +460 -0
  19. package/fesm2022/nanahoshi-mona-ui-datetime-picker.mjs +659 -0
  20. package/fesm2022/nanahoshi-mona-ui-dialog.mjs +828 -0
  21. package/fesm2022/nanahoshi-mona-ui-dropdown-button.mjs +523 -0
  22. package/fesm2022/nanahoshi-mona-ui-dropdown-list.mjs +615 -0
  23. package/fesm2022/nanahoshi-mona-ui-dropdowns.mjs +701 -0
  24. package/fesm2022/nanahoshi-mona-ui-editor.mjs +1400 -0
  25. package/fesm2022/nanahoshi-mona-ui-expansion-panel.mjs +245 -0
  26. package/fesm2022/nanahoshi-mona-ui-fieldset.mjs +170 -0
  27. package/fesm2022/nanahoshi-mona-ui-filter.mjs +680 -0
  28. package/fesm2022/nanahoshi-mona-ui-grid-grid-footer-cell.component-B9SQH5N-.mjs +105 -0
  29. package/fesm2022/nanahoshi-mona-ui-grid-grid-footer-table-cell.directive-DlLwcCFT.mjs +42 -0
  30. package/fesm2022/nanahoshi-mona-ui-grid-grid-list.component-Dgea-O0X.mjs +130 -0
  31. package/fesm2022/nanahoshi-mona-ui-grid-grid-toggle.component-DIUutx9s.mjs +773 -0
  32. package/fesm2022/nanahoshi-mona-ui-grid-grid-virtual-list.component-DRHycGIh.mjs +240 -0
  33. package/fesm2022/nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-C3eZIaJK.mjs +5374 -0
  34. package/fesm2022/nanahoshi-mona-ui-grid.mjs +2 -0
  35. package/fesm2022/nanahoshi-mona-ui-internal-filter-input.mjs +87 -0
  36. package/fesm2022/nanahoshi-mona-ui-internal-indicator-icon.mjs +154 -0
  37. package/fesm2022/nanahoshi-mona-ui-internal-list.mjs +1356 -0
  38. package/fesm2022/nanahoshi-mona-ui-internal-tree.mjs +2263 -0
  39. package/fesm2022/nanahoshi-mona-ui-internal.mjs +379 -0
  40. package/fesm2022/nanahoshi-mona-ui-list-box.mjs +630 -0
  41. package/fesm2022/nanahoshi-mona-ui-list-view.mjs +527 -0
  42. package/fesm2022/nanahoshi-mona-ui-list.mjs +4 -0
  43. package/fesm2022/nanahoshi-mona-ui-menubar.mjs +966 -0
  44. package/fesm2022/nanahoshi-mona-ui-multi-select.mjs +641 -0
  45. package/fesm2022/nanahoshi-mona-ui-notification.mjs +536 -0
  46. package/fesm2022/nanahoshi-mona-ui-numeric-text-box.mjs +597 -0
  47. package/fesm2022/nanahoshi-mona-ui-pager.mjs +790 -0
  48. package/fesm2022/nanahoshi-mona-ui-placeholder.mjs +83 -0
  49. package/fesm2022/nanahoshi-mona-ui-popover.mjs +325 -0
  50. package/fesm2022/nanahoshi-mona-ui-popup-menu.mjs +1559 -0
  51. package/fesm2022/nanahoshi-mona-ui-popup.mjs +1321 -0
  52. package/fesm2022/nanahoshi-mona-ui-progress-bar.mjs +294 -0
  53. package/fesm2022/nanahoshi-mona-ui-query.mjs +175 -0
  54. package/fesm2022/nanahoshi-mona-ui-radio-button.mjs +339 -0
  55. package/fesm2022/nanahoshi-mona-ui-scroll-view.mjs +565 -0
  56. package/fesm2022/nanahoshi-mona-ui-slider.mjs +1049 -0
  57. package/fesm2022/nanahoshi-mona-ui-split-button.mjs +636 -0
  58. package/fesm2022/nanahoshi-mona-ui-splitter.mjs +843 -0
  59. package/fesm2022/nanahoshi-mona-ui-stepper.mjs +537 -0
  60. package/fesm2022/nanahoshi-mona-ui-switch.mjs +308 -0
  61. package/fesm2022/nanahoshi-mona-ui-tabs.mjs +664 -0
  62. package/fesm2022/nanahoshi-mona-ui-text-area.mjs +111 -0
  63. package/fesm2022/nanahoshi-mona-ui-text-box.mjs +369 -0
  64. package/fesm2022/nanahoshi-mona-ui-theme.mjs +314 -0
  65. package/fesm2022/nanahoshi-mona-ui-time-picker.mjs +450 -0
  66. package/fesm2022/nanahoshi-mona-ui-time-selector.mjs +723 -0
  67. package/fesm2022/nanahoshi-mona-ui-tooltip.mjs +716 -0
  68. package/fesm2022/nanahoshi-mona-ui-tree-view.mjs +733 -0
  69. package/fesm2022/nanahoshi-mona-ui-window.mjs +1329 -0
  70. package/fesm2022/nanahoshi-mona-ui.mjs +9 -0
  71. package/package.json +289 -0
  72. package/types/nanahoshi-mona-ui-auto-complete.d.ts +223 -0
  73. package/types/nanahoshi-mona-ui-avatar.d.ts +642 -0
  74. package/types/nanahoshi-mona-ui-breadcrumb.d.ts +70 -0
  75. package/types/nanahoshi-mona-ui-button-group.d.ts +77 -0
  76. package/types/nanahoshi-mona-ui-button.d.ts +111 -0
  77. package/types/nanahoshi-mona-ui-calendar.d.ts +262 -0
  78. package/types/nanahoshi-mona-ui-check-box.d.ts +133 -0
  79. package/types/nanahoshi-mona-ui-chip.d.ts +130 -0
  80. package/types/nanahoshi-mona-ui-circular-progress-bar.d.ts +113 -0
  81. package/types/nanahoshi-mona-ui-color-gradient.d.ts +201 -0
  82. package/types/nanahoshi-mona-ui-color-palette.d.ts +102 -0
  83. package/types/nanahoshi-mona-ui-color-picker.d.ts +156 -0
  84. package/types/nanahoshi-mona-ui-combo-box.d.ts +232 -0
  85. package/types/nanahoshi-mona-ui-common.d.ts +386 -0
  86. package/types/nanahoshi-mona-ui-contextmenu.d.ts +129 -0
  87. package/types/nanahoshi-mona-ui-date-input.d.ts +60 -0
  88. package/types/nanahoshi-mona-ui-date-picker.d.ts +177 -0
  89. package/types/nanahoshi-mona-ui-datetime-picker.d.ts +199 -0
  90. package/types/nanahoshi-mona-ui-dialog.d.ts +261 -0
  91. package/types/nanahoshi-mona-ui-dropdown-button.d.ts +159 -0
  92. package/types/nanahoshi-mona-ui-dropdown-list.d.ts +219 -0
  93. package/types/nanahoshi-mona-ui-dropdowns.d.ts +176 -0
  94. package/types/nanahoshi-mona-ui-editor.d.ts +113 -0
  95. package/types/nanahoshi-mona-ui-expansion-panel.d.ts +87 -0
  96. package/types/nanahoshi-mona-ui-fieldset.d.ts +68 -0
  97. package/types/nanahoshi-mona-ui-filter.d.ts +115 -0
  98. package/types/nanahoshi-mona-ui-grid.d.ts +1114 -0
  99. package/types/nanahoshi-mona-ui-internal-filter-input.d.ts +25 -0
  100. package/types/nanahoshi-mona-ui-internal-indicator-icon.d.ts +28 -0
  101. package/types/nanahoshi-mona-ui-internal-list.d.ts +269 -0
  102. package/types/nanahoshi-mona-ui-internal-tree.d.ts +391 -0
  103. package/types/nanahoshi-mona-ui-internal.d.ts +136 -0
  104. package/types/nanahoshi-mona-ui-list-box.d.ts +225 -0
  105. package/types/nanahoshi-mona-ui-list-view.d.ts +188 -0
  106. package/types/nanahoshi-mona-ui-list.d.ts +1 -0
  107. package/types/nanahoshi-mona-ui-menubar.d.ts +198 -0
  108. package/types/nanahoshi-mona-ui-multi-select.d.ts +247 -0
  109. package/types/nanahoshi-mona-ui-notification.d.ts +106 -0
  110. package/types/nanahoshi-mona-ui-numeric-text-box.d.ts +161 -0
  111. package/types/nanahoshi-mona-ui-pager.d.ts +238 -0
  112. package/types/nanahoshi-mona-ui-placeholder.d.ts +35 -0
  113. package/types/nanahoshi-mona-ui-popover.d.ts +130 -0
  114. package/types/nanahoshi-mona-ui-popup-menu.d.ts +412 -0
  115. package/types/nanahoshi-mona-ui-popup.d.ts +485 -0
  116. package/types/nanahoshi-mona-ui-progress-bar.d.ts +139 -0
  117. package/types/nanahoshi-mona-ui-query.d.ts +89 -0
  118. package/types/nanahoshi-mona-ui-radio-button.d.ts +128 -0
  119. package/types/nanahoshi-mona-ui-scroll-view.d.ts +166 -0
  120. package/types/nanahoshi-mona-ui-slider.d.ts +305 -0
  121. package/types/nanahoshi-mona-ui-split-button.d.ts +182 -0
  122. package/types/nanahoshi-mona-ui-splitter.d.ts +70 -0
  123. package/types/nanahoshi-mona-ui-stepper.d.ts +173 -0
  124. package/types/nanahoshi-mona-ui-switch.d.ts +125 -0
  125. package/types/nanahoshi-mona-ui-tabs.d.ts +158 -0
  126. package/types/nanahoshi-mona-ui-text-area.d.ts +42 -0
  127. package/types/nanahoshi-mona-ui-text-box.d.ts +164 -0
  128. package/types/nanahoshi-mona-ui-theme.d.ts +23 -0
  129. package/types/nanahoshi-mona-ui-time-picker.d.ts +184 -0
  130. package/types/nanahoshi-mona-ui-time-selector.d.ts +143 -0
  131. package/types/nanahoshi-mona-ui-tooltip.d.ts +130 -0
  132. package/types/nanahoshi-mona-ui-tree-view.d.ts +274 -0
  133. package/types/nanahoshi-mona-ui-window.d.ts +295 -0
  134. package/types/nanahoshi-mona-ui.d.ts +2 -0
@@ -0,0 +1,664 @@
1
+ import { PreventableEvent } from '@nanahoshi/mona-ui/common';
2
+ import * as i0 from '@angular/core';
3
+ import { Directive, inject, computed, input, DestroyRef, signal, viewChild, viewChildren, ElementRef, model, output, afterRenderEffect, untracked, afterNextRender, ChangeDetectionStrategy, Component, contentChild, TemplateRef, contentChildren, linkedSignal } from '@angular/core';
4
+ import { NgTemplateOutlet } from '@angular/common';
5
+ import { ThemeService } from '@nanahoshi/mona-ui/theme';
6
+ import { firstOrDefault, select } from '@mirei/ts-collections';
7
+ import { cva } from 'class-variance-authority';
8
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
9
+ import { FaIconComponent } from '@fortawesome/angular-fontawesome';
10
+ import { faChevronLeft, faChevronRight, faXmark } from '@fortawesome/free-solid-svg-icons';
11
+ import { ButtonDirective } from '@nanahoshi/mona-ui/button';
12
+ import { Subject, switchMap, EMPTY, timer, interval, tap, asapScheduler } from 'rxjs';
13
+ import { twMerge } from 'tailwind-merge';
14
+ import { createElementControlId } from '@nanahoshi/mona-ui/internal';
15
+
16
+ class TabCloseEvent extends PreventableEvent {
17
+ #index;
18
+ #selected;
19
+ constructor(index, selected, originalEvent) {
20
+ super("tabClose", originalEvent);
21
+ this.#index = index;
22
+ this.#selected = selected;
23
+ }
24
+ get index() {
25
+ return this.#index;
26
+ }
27
+ get selected() {
28
+ return this.#selected;
29
+ }
30
+ }
31
+
32
+ class TabSelectEvent extends PreventableEvent {
33
+ #index;
34
+ constructor(index, originalEvent) {
35
+ super("tabSelect", originalEvent);
36
+ this.#index = index;
37
+ }
38
+ get index() {
39
+ return this.#index;
40
+ }
41
+ }
42
+
43
+ class TabContentTemplateDirective {
44
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabContentTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
45
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: TabContentTemplateDirective, isStandalone: true, selector: "ng-template[monaTabContentTemplate]", ngImport: i0 }); }
46
+ }
47
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabContentTemplateDirective, decorators: [{
48
+ type: Directive,
49
+ args: [{
50
+ selector: "ng-template[monaTabContentTemplate]",
51
+ standalone: true
52
+ }]
53
+ }] });
54
+
55
+ class TabTitleTemplateDirective {
56
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabTitleTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
57
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: TabTitleTemplateDirective, isStandalone: true, selector: "ng-template[monaTabTitleTemplate]", ngImport: i0 }); }
58
+ }
59
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabTitleTemplateDirective, decorators: [{
60
+ type: Directive,
61
+ args: [{
62
+ selector: "ng-template[monaTabTitleTemplate]",
63
+ standalone: true
64
+ }]
65
+ }] });
66
+
67
+ const tabListBaseVariants = cva(`
68
+ w-fit max-w-full
69
+ flex overflow-hidden
70
+ bg-accent
71
+ font-medium text-sm
72
+ `, {
73
+ variants: {
74
+ rounded: {
75
+ small: "rounded-sm",
76
+ medium: "rounded-md",
77
+ large: "rounded-lg",
78
+ full: "rounded-full",
79
+ none: "rounded-none"
80
+ },
81
+ size: {
82
+ small: "h-8",
83
+ medium: "h-9",
84
+ large: "h-10"
85
+ }
86
+ }
87
+ });
88
+ const tabListListWrapperVariants = cva(`w-full h-full overflow-hidden`);
89
+ const tabListListVariants = cva(`
90
+ flex h-full w-full overflow-hidden
91
+ list-none cursor-default
92
+ select-none whitespace-nowrap
93
+ p-[3px]
94
+ transition-colors duration-300 ease-out
95
+ `);
96
+ const tabListListItemVariants = cva(`
97
+ flex items-center justify-center
98
+ cursor-pointer
99
+ px-2 outline-none
100
+ focus-visible:ring-2 focus-visible:ring-primary/40
101
+ `, {
102
+ variants: {
103
+ active: {
104
+ true: "bg-background-dark text-foreground shadow-sm",
105
+ false: ""
106
+ },
107
+ disabled: {
108
+ true: "pointer-events-none cursor-not-allowed opacity-50 select-none",
109
+ false: ""
110
+ },
111
+ rounded: {
112
+ small: "rounded-sm",
113
+ medium: "rounded-md",
114
+ large: "rounded-lg",
115
+ full: "rounded-full",
116
+ none: "rounded-none"
117
+ }
118
+ },
119
+ defaultVariants: {
120
+ rounded: "medium"
121
+ }
122
+ });
123
+ const tabListScrollButtonVariants = cva(`
124
+ flex items-center justify-center
125
+ h-full px-2
126
+ `);
127
+ const tabContentVariants = cva(`
128
+ w-full overflow-auto flex-1
129
+ border border-border shadow-sm
130
+ bg-background
131
+ `, {
132
+ variants: {
133
+ rounded: {
134
+ small: "rounded-sm",
135
+ medium: "rounded-md",
136
+ large: "rounded-lg",
137
+ full: "rounded-full",
138
+ none: "rounded-none"
139
+ }
140
+ },
141
+ defaultVariants: {
142
+ rounded: "medium"
143
+ }
144
+ });
145
+ const tabsBaseVariants = cva(`
146
+ max-w-full
147
+ flex flex-col gap-2
148
+ `);
149
+
150
+ const tabListBaseThemeVariants = (theme) => {
151
+ switch (theme) {
152
+ case "mona":
153
+ return tabListBaseVariants;
154
+ default:
155
+ return tabListBaseVariants;
156
+ }
157
+ };
158
+ const tabListListWrapperThemeVariants = (theme) => {
159
+ switch (theme) {
160
+ case "mona":
161
+ return tabListListWrapperVariants;
162
+ default:
163
+ return tabListListWrapperVariants;
164
+ }
165
+ };
166
+ const tabListListThemeVariants = (theme) => {
167
+ switch (theme) {
168
+ case "mona":
169
+ return tabListListVariants;
170
+ default:
171
+ return tabListListVariants;
172
+ }
173
+ };
174
+ const tabListListItemThemeVariants = (theme) => {
175
+ switch (theme) {
176
+ case "mona":
177
+ return tabListListItemVariants;
178
+ default:
179
+ return tabListListItemVariants;
180
+ }
181
+ };
182
+ const tabListScrollButtonThemeVariants = (theme) => {
183
+ switch (theme) {
184
+ case "mona":
185
+ return tabListScrollButtonVariants;
186
+ default:
187
+ return tabListScrollButtonVariants;
188
+ }
189
+ };
190
+ const tabContentThemeVariants = (theme) => {
191
+ switch (theme) {
192
+ case "mona":
193
+ return tabContentVariants;
194
+ default:
195
+ return tabContentVariants;
196
+ }
197
+ };
198
+ const tabsBaseThemeVariants = (theme) => {
199
+ switch (theme) {
200
+ case "mona":
201
+ return tabsBaseVariants;
202
+ default:
203
+ return tabsBaseVariants;
204
+ }
205
+ };
206
+
207
+ class TabListItemDirective {
208
+ constructor() {
209
+ this.#themeService = inject(ThemeService);
210
+ this.listItemClass = computed(() => {
211
+ const theme = this.#themeService.theme();
212
+ const active = this.active();
213
+ const disabled = this.disabled();
214
+ const rounded = this.rounded();
215
+ return tabListListItemThemeVariants(theme)({ active, disabled, rounded });
216
+ }, /* @ts-ignore */
217
+ ...(ngDevMode ? [{ debugName: "listItemClass" }] : /* istanbul ignore next */ []));
218
+ this.active = input.required(/* @ts-ignore */
219
+ ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
220
+ this.disabled = input.required(/* @ts-ignore */
221
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
222
+ this.rounded = input.required(/* @ts-ignore */
223
+ ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
224
+ }
225
+ #themeService;
226
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabListItemDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
227
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: TabListItemDirective, isStandalone: true, selector: "li[monaTabListItem]", inputs: { active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: true, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class": "listItemClass()" } }, ngImport: i0 }); }
228
+ }
229
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabListItemDirective, decorators: [{
230
+ type: Directive,
231
+ args: [{
232
+ selector: "li[monaTabListItem]",
233
+ host: {
234
+ "[class]": "listItemClass()"
235
+ }
236
+ }]
237
+ }], propDecorators: { active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: true }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: true }] }] } });
238
+
239
+ class TabListComponent {
240
+ #destroyRef;
241
+ #themeService;
242
+ #keydown$;
243
+ #resizeObserver;
244
+ #scrollIntent$;
245
+ constructor() {
246
+ this.#destroyRef = inject(DestroyRef);
247
+ this.#themeService = inject(ThemeService);
248
+ this.#keydown$ = new Subject();
249
+ this.#resizeObserver = null;
250
+ this.#scrollIntent$ = new Subject();
251
+ this.baseClass = computed(() => {
252
+ const theme = this.#themeService.theme();
253
+ const rounded = this.rounded();
254
+ const size = this.size();
255
+ return tabListBaseThemeVariants(theme)({ rounded, size });
256
+ }, /* @ts-ignore */
257
+ ...(ngDevMode ? [{ debugName: "baseClass" }] : /* istanbul ignore next */ []));
258
+ this.listClass = computed(() => {
259
+ const theme = this.#themeService.theme();
260
+ return tabListListThemeVariants(theme)();
261
+ }, /* @ts-ignore */
262
+ ...(ngDevMode ? [{ debugName: "listClass" }] : /* istanbul ignore next */ []));
263
+ this.scrollButtonClass = computed(() => {
264
+ const theme = this.#themeService.theme();
265
+ return tabListScrollButtonThemeVariants(theme)();
266
+ }, /* @ts-ignore */
267
+ ...(ngDevMode ? [{ debugName: "scrollButtonClass" }] : /* istanbul ignore next */ []));
268
+ this.scrollLeftIcon = faChevronLeft;
269
+ this.scrollRightIcon = faChevronRight;
270
+ this.scrollsVisible = signal(false, /* @ts-ignore */
271
+ ...(ngDevMode ? [{ debugName: "scrollsVisible" }] : /* istanbul ignore next */ []));
272
+ this.tabCloseIcon = faXmark;
273
+ this.tabListElement = viewChild.required("tabListElement", /* @ts-ignore */
274
+ ...(ngDevMode ? [{ debugName: "tabListElement" }] : /* istanbul ignore next */ []));
275
+ this.tabListItems = viewChildren(TabListItemDirective, { ...(ngDevMode ? { debugName: "tabListItems" } : /* istanbul ignore next */ {}), read: ElementRef });
276
+ this.closable = input(false, /* @ts-ignore */
277
+ ...(ngDevMode ? [{ debugName: "closable" }] : /* istanbul ignore next */ []));
278
+ this.disabled = input(false, /* @ts-ignore */
279
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
280
+ this.rounded = input.required(/* @ts-ignore */
281
+ ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
282
+ this.selectedTabId = model(null, /* @ts-ignore */
283
+ ...(ngDevMode ? [{ debugName: "selectedTabId" }] : /* istanbul ignore next */ []));
284
+ this.size = input.required(/* @ts-ignore */
285
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
286
+ this.tabClose = output();
287
+ this.tabSelect = output();
288
+ this.tabList = input.required(/* @ts-ignore */
289
+ ...(ngDevMode ? [{ debugName: "tabList" }] : /* istanbul ignore next */ []));
290
+ afterRenderEffect({
291
+ read: () => {
292
+ this.tabList();
293
+ untracked(() => {
294
+ this.updateScrollVisibility();
295
+ });
296
+ }
297
+ });
298
+ afterNextRender({
299
+ write: () => {
300
+ const selectedTab = firstOrDefault(this.tabList(), t => t.id === this.selectedTabId());
301
+ if (selectedTab) {
302
+ this.selectedTabId.set(selectedTab.id);
303
+ }
304
+ },
305
+ read: () => {
306
+ this.setupKeyboardNavigation();
307
+ this.setupResizeObserver();
308
+ this.setupScrolling();
309
+ }
310
+ });
311
+ inject(DestroyRef).onDestroy(() => this.#resizeObserver?.disconnect());
312
+ }
313
+ focusSelectedTab() {
314
+ const tabList = this.tabList();
315
+ const selectedTab = firstOrDefault(tabList, t => t.id === this.selectedTabId());
316
+ if (selectedTab) {
317
+ this.focusTab(selectedTab);
318
+ }
319
+ }
320
+ onKeydown(event) {
321
+ this.#keydown$.next(event);
322
+ }
323
+ onTabClick(tab, tabListElement, event) {
324
+ if (tab.id === this.selectedTabId()) {
325
+ return;
326
+ }
327
+ const selectEvent = new TabSelectEvent(tab.index, event);
328
+ this.tabSelect.emit(selectEvent);
329
+ if (selectEvent.isDefaultPrevented()) {
330
+ return;
331
+ }
332
+ this.selectTab(tab);
333
+ window.setTimeout(() => {
334
+ const listElement = tabListElement.querySelector("li[data-selected='true']");
335
+ if (listElement) {
336
+ listElement.scrollIntoView({ behavior: "auto", block: "center" });
337
+ }
338
+ });
339
+ }
340
+ onTabClose(tab, event) {
341
+ event.stopPropagation();
342
+ this.emitTabClose(tab, event);
343
+ }
344
+ startContinuousScroll(event, element, direction) {
345
+ event.currentTarget.setPointerCapture(event.pointerId);
346
+ this.startScrolling(element, direction, "continuous");
347
+ }
348
+ startScrolling(element, direction, type) {
349
+ this.#scrollIntent$.next({ element, direction, type });
350
+ }
351
+ stopScrolling() {
352
+ this.#scrollIntent$.next(null);
353
+ }
354
+ handleKeyboardEvents(event) {
355
+ const tabList = this.tabList();
356
+ const tabs = Array.from(tabList);
357
+ const selectedTab = tabs.find(t => t.id === this.selectedTabId());
358
+ if (!selectedTab) {
359
+ return;
360
+ }
361
+ if (event.key === "Tab") {
362
+ if (!event.shiftKey) {
363
+ this.handleTabKey(selectedTab, event);
364
+ }
365
+ return;
366
+ }
367
+ const listDisabled = this.disabled();
368
+ const enabledTabs = tabs.filter(t => !t.disabled && !listDisabled);
369
+ if (enabledTabs.length === 0) {
370
+ return;
371
+ }
372
+ const selectedEnabledIndex = enabledTabs.indexOf(selectedTab);
373
+ const selectedIndex = selectedEnabledIndex === -1 ? 0 : selectedEnabledIndex;
374
+ let nextIndex = selectedIndex;
375
+ switch (event.key) {
376
+ case "ArrowLeft":
377
+ nextIndex = selectedIndex === 0 ? enabledTabs.length - 1 : selectedIndex - 1;
378
+ this.activateTab(enabledTabs[nextIndex], event);
379
+ break;
380
+ case "ArrowRight":
381
+ nextIndex = selectedIndex === enabledTabs.length - 1 ? 0 : selectedIndex + 1;
382
+ this.activateTab(enabledTabs[nextIndex], event);
383
+ break;
384
+ case "Home":
385
+ this.activateTab(enabledTabs[0], event);
386
+ break;
387
+ case "End":
388
+ this.activateTab(enabledTabs[enabledTabs.length - 1], event);
389
+ break;
390
+ case "Delete":
391
+ case "Backspace":
392
+ if (!selectedTab.disabled && !listDisabled && (selectedTab.closable || this.closable())) {
393
+ this.emitTabClose(selectedTab, event);
394
+ }
395
+ break;
396
+ }
397
+ }
398
+ activateTab(tab, event) {
399
+ const prevented = this.emitTabSelect(tab, event);
400
+ if (!prevented) {
401
+ this.selectTab(tab);
402
+ this.focusSelectedTab();
403
+ }
404
+ }
405
+ emitTabClose(tabItem, event) {
406
+ const selected = tabItem.id === this.selectedTabId();
407
+ const tabCloseEvent = new TabCloseEvent(tabItem.index, selected, event);
408
+ this.tabClose.emit(tabCloseEvent);
409
+ return tabCloseEvent.isDefaultPrevented();
410
+ }
411
+ emitTabSelect(tab, event) {
412
+ const selectEvent = new TabSelectEvent(tab.index, event);
413
+ this.tabSelect.emit(selectEvent);
414
+ return selectEvent.isDefaultPrevented();
415
+ }
416
+ focusTab(tab) {
417
+ const tabListItems = this.tabListItems();
418
+ const tabListItem = tabListItems.find(t => t.nativeElement.getAttribute("data-tab-id") === tab.id);
419
+ tabListItem?.nativeElement.focus();
420
+ }
421
+ handleTabKey(tab, event) {
422
+ event.preventDefault();
423
+ const panelId = tab.id + "-panel";
424
+ const panel = document.getElementById(panelId);
425
+ if (panel) {
426
+ panel.focus();
427
+ }
428
+ }
429
+ performScroll(element, direction) {
430
+ let left = 0;
431
+ switch (direction) {
432
+ case "left":
433
+ left = Math.max(element.scrollLeft - 100, 0);
434
+ element.scrollTo({ left, behavior: "smooth" });
435
+ break;
436
+ case "right":
437
+ left = Math.min(element.scrollLeft + 100, element.scrollWidth);
438
+ element.scrollTo({ left, behavior: "smooth" });
439
+ break;
440
+ }
441
+ }
442
+ selectTab(tab) {
443
+ this.selectedTabId.set(tab.id);
444
+ }
445
+ setupKeyboardNavigation() {
446
+ this.#keydown$.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe(event => this.handleKeyboardEvents(event));
447
+ }
448
+ setupResizeObserver() {
449
+ this.#resizeObserver = new ResizeObserver(entries => {
450
+ window.requestAnimationFrame(() => {
451
+ if (!Array.isArray(entries) || !entries.length) {
452
+ return;
453
+ }
454
+ this.updateScrollVisibility();
455
+ });
456
+ });
457
+ this.#resizeObserver.observe(this.tabListElement().nativeElement);
458
+ }
459
+ setupScrolling() {
460
+ this.#scrollIntent$
461
+ .pipe(takeUntilDestroyed(this.#destroyRef), switchMap(intent => {
462
+ if (!intent) {
463
+ return EMPTY;
464
+ }
465
+ const { element, direction, type } = intent;
466
+ const timeFunction = type === "single" ? timer : interval;
467
+ return timeFunction(60).pipe(tap(() => this.performScroll(element, direction)));
468
+ }))
469
+ .subscribe();
470
+ }
471
+ updateScrollVisibility() {
472
+ asapScheduler.schedule(() => {
473
+ this.scrollsVisible.set(this.tabListElement().nativeElement.scrollWidth > this.tabListElement().nativeElement.clientWidth);
474
+ });
475
+ }
476
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
477
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: TabListComponent, isStandalone: true, selector: "mona-tab-list", inputs: { closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: true, transformFunction: null }, selectedTabId: { classPropertyName: "selectedTabId", publicName: "selectedTabId", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: true, transformFunction: null }, tabList: { classPropertyName: "tabList", publicName: "tabList", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { selectedTabId: "selectedTabIdChange", tabClose: "tabClose", tabSelect: "tabSelect" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "class": "baseClass()" } }, viewQueries: [{ propertyName: "tabListElement", first: true, predicate: ["tabListElement"], descendants: true, isSignal: true }, { propertyName: "tabListItems", predicate: TabListItemDirective, descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "@if (scrollsVisible()) {\r\n <button\r\n monaButton\r\n look=\"link\"\r\n size=\"small\"\r\n [class]=\"scrollButtonClass()\"\r\n (click)=\"startScrolling(tabListElement, 'left', 'single')\"\r\n (pointerdown)=\"startContinuousScroll($event, tabListElement, 'left')\"\r\n (pointerup)=\"stopScrolling()\"\r\n [attr.aria-hidden]=\"true\"\r\n tabindex=\"-1\">\r\n <fa-icon [icon]=\"scrollLeftIcon\"></fa-icon>\r\n </button>\r\n}\r\n<div class=\"w-full h-full overflow-hidden\">\r\n <ul [class]=\"listClass()\" #tabListElement role=\"tablist\">\r\n @for (tab of tabList(); track tab) {\r\n @let selected = tab.id === selectedTabId();\r\n @let itemDisabled = tab.disabled || disabled();\r\n <li\r\n monaTabListItem\r\n [id]=\"tab.id + '-tab'\"\r\n [active]=\"selected\"\r\n [disabled]=\"itemDisabled\"\r\n [rounded]=\"rounded()\"\r\n role=\"tab\"\r\n [tabindex]=\"selected ? 0 : -1\"\r\n [attr.aria-selected]=\"selected\"\r\n [attr.aria-disabled]=\"itemDisabled\"\r\n [attr.aria-controls]=\"tab.id + '-panel'\"\r\n [attr.data-selected]=\"selected\"\r\n [attr.data-tab-id]=\"tab.id\"\r\n (click)=\"onTabClick(tab, tabListElement, $event)\">\r\n <div>\r\n @if (tab.titleTemplate) {\r\n <ng-container [ngTemplateOutlet]=\"tab.titleTemplate\"></ng-container>\r\n } @else {\r\n <span>{{ tab.title }}</span>\r\n }\r\n </div>\r\n @if (tab.closable || closable()) {\r\n <button\r\n monaButton\r\n look=\"link\"\r\n [disabled]=\"itemDisabled\"\r\n (click)=\"onTabClose(tab, $event)\"\r\n class=\"px-0 h-fit ml-1 w-min\"\r\n tabindex=\"-1\">\r\n <fa-icon [icon]=\"tabCloseIcon\" class=\"text-xs flex\"></fa-icon>\r\n </button>\r\n }\r\n </li>\r\n }\r\n </ul>\r\n</div>\r\n@if (scrollsVisible()) {\r\n <button\r\n monaButton\r\n look=\"link\"\r\n size=\"small\"\r\n [class]=\"scrollButtonClass()\"\r\n (click)=\"startScrolling(tabListElement, 'right', 'single')\"\r\n (pointerdown)=\"startContinuousScroll($event, tabListElement, 'right')\"\r\n (pointerup)=\"stopScrolling()\"\r\n [attr.aria-hidden]=\"true\"\r\n tabindex=\"-1\">\r\n <fa-icon [icon]=\"scrollRightIcon\"></fa-icon>\r\n </button>\r\n}\r\n", dependencies: [{ kind: "directive", type: ButtonDirective, selector: "button[monaButton]", inputs: ["aria-haspopup", "disabled", "iconOnly", "loading", "look", "rounded", "selected", "size", "tabindex", "toggleable", "class"], outputs: ["disabledChange", "loadingChange", "lookChange", "selectedChange"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"], outputs: ["iconChange", "titleChange", "animationChange", "maskChange", "flipChange", "sizeChange", "pullChange", "borderChange", "inverseChange", "symbolChange", "rotateChange", "fixedWidthChange", "transformChange", "a11yRoleChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: TabListItemDirective, selector: "li[monaTabListItem]", inputs: ["active", "disabled", "rounded"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
478
+ }
479
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabListComponent, decorators: [{
480
+ type: Component,
481
+ args: [{ selector: "mona-tab-list", imports: [ButtonDirective, FaIconComponent, NgTemplateOutlet, TabListItemDirective], changeDetection: ChangeDetectionStrategy.OnPush, host: {
482
+ "[class]": "baseClass()",
483
+ "(keydown)": "onKeydown($event)"
484
+ }, template: "@if (scrollsVisible()) {\r\n <button\r\n monaButton\r\n look=\"link\"\r\n size=\"small\"\r\n [class]=\"scrollButtonClass()\"\r\n (click)=\"startScrolling(tabListElement, 'left', 'single')\"\r\n (pointerdown)=\"startContinuousScroll($event, tabListElement, 'left')\"\r\n (pointerup)=\"stopScrolling()\"\r\n [attr.aria-hidden]=\"true\"\r\n tabindex=\"-1\">\r\n <fa-icon [icon]=\"scrollLeftIcon\"></fa-icon>\r\n </button>\r\n}\r\n<div class=\"w-full h-full overflow-hidden\">\r\n <ul [class]=\"listClass()\" #tabListElement role=\"tablist\">\r\n @for (tab of tabList(); track tab) {\r\n @let selected = tab.id === selectedTabId();\r\n @let itemDisabled = tab.disabled || disabled();\r\n <li\r\n monaTabListItem\r\n [id]=\"tab.id + '-tab'\"\r\n [active]=\"selected\"\r\n [disabled]=\"itemDisabled\"\r\n [rounded]=\"rounded()\"\r\n role=\"tab\"\r\n [tabindex]=\"selected ? 0 : -1\"\r\n [attr.aria-selected]=\"selected\"\r\n [attr.aria-disabled]=\"itemDisabled\"\r\n [attr.aria-controls]=\"tab.id + '-panel'\"\r\n [attr.data-selected]=\"selected\"\r\n [attr.data-tab-id]=\"tab.id\"\r\n (click)=\"onTabClick(tab, tabListElement, $event)\">\r\n <div>\r\n @if (tab.titleTemplate) {\r\n <ng-container [ngTemplateOutlet]=\"tab.titleTemplate\"></ng-container>\r\n } @else {\r\n <span>{{ tab.title }}</span>\r\n }\r\n </div>\r\n @if (tab.closable || closable()) {\r\n <button\r\n monaButton\r\n look=\"link\"\r\n [disabled]=\"itemDisabled\"\r\n (click)=\"onTabClose(tab, $event)\"\r\n class=\"px-0 h-fit ml-1 w-min\"\r\n tabindex=\"-1\">\r\n <fa-icon [icon]=\"tabCloseIcon\" class=\"text-xs flex\"></fa-icon>\r\n </button>\r\n }\r\n </li>\r\n }\r\n </ul>\r\n</div>\r\n@if (scrollsVisible()) {\r\n <button\r\n monaButton\r\n look=\"link\"\r\n size=\"small\"\r\n [class]=\"scrollButtonClass()\"\r\n (click)=\"startScrolling(tabListElement, 'right', 'single')\"\r\n (pointerdown)=\"startContinuousScroll($event, tabListElement, 'right')\"\r\n (pointerup)=\"stopScrolling()\"\r\n [attr.aria-hidden]=\"true\"\r\n tabindex=\"-1\">\r\n <fa-icon [icon]=\"scrollRightIcon\"></fa-icon>\r\n </button>\r\n}\r\n" }]
485
+ }], ctorParameters: () => [], propDecorators: { tabListElement: [{ type: i0.ViewChild, args: ["tabListElement", { isSignal: true }] }], tabListItems: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => TabListItemDirective), { ...{ read: ElementRef }, isSignal: true }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: true }] }], selectedTabId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedTabId", required: false }] }, { type: i0.Output, args: ["selectedTabIdChange"] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: true }] }], tabClose: [{ type: i0.Output, args: ["tabClose"] }], tabSelect: [{ type: i0.Output, args: ["tabSelect"] }], tabList: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabList", required: true }] }] } });
486
+
487
+ class TabComponent {
488
+ constructor() {
489
+ this.#id = createElementControlId();
490
+ this.#tabItem = computed(() => {
491
+ const closable = this.closable();
492
+ const contentTemplate = this.contentTemplate();
493
+ const disabled = this.disabled();
494
+ const selected = this.selected();
495
+ const titleTemplate = this.titleTemplate();
496
+ const title = this.title();
497
+ const id = this.#id;
498
+ const tabItem = {
499
+ closable,
500
+ contentTemplate,
501
+ disabled,
502
+ id,
503
+ index: 0,
504
+ selected,
505
+ title,
506
+ titleTemplate
507
+ };
508
+ return tabItem;
509
+ }, /* @ts-ignore */
510
+ ...(ngDevMode ? [{ debugName: "#tabItem" }] : /* istanbul ignore next */ []));
511
+ this.contentTemplate = contentChild(TabContentTemplateDirective, { ...(ngDevMode ? { debugName: "contentTemplate" } : /* istanbul ignore next */ {}), read: TemplateRef });
512
+ this.titleTemplate = contentChild(TabTitleTemplateDirective, { ...(ngDevMode ? { debugName: "titleTemplate" } : /* istanbul ignore next */ {}), read: TemplateRef });
513
+ /**
514
+ * @description Displays a close button on this tab. Overrides the parent `mona-tabs` component's `closable` input.
515
+ * @default false
516
+ */
517
+ this.closable = input(false, /* @ts-ignore */
518
+ ...(ngDevMode ? [{ debugName: "closable" }] : /* istanbul ignore next */ []));
519
+ /**
520
+ * @description Renders this tab with reduced visual emphasis and removes pointer and keyboard interaction.
521
+ * Overrides the parent `mona-tabs` component's `disabled` input.
522
+ * @default false
523
+ */
524
+ this.disabled = input(false, /* @ts-ignore */
525
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
526
+ /**
527
+ * @description Whether the tab is selected.
528
+ * @default false
529
+ */
530
+ this.selected = model(false, /* @ts-ignore */
531
+ ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
532
+ /**
533
+ * @description Title text displayed on the tab.
534
+ * @default ""
535
+ */
536
+ this.title = input("", /* @ts-ignore */
537
+ ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
538
+ }
539
+ #id;
540
+ #tabItem;
541
+ get tabItem() {
542
+ return this.#tabItem();
543
+ }
544
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
545
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.6", type: TabComponent, isStandalone: true, selector: "mona-tab", inputs: { closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selectedChange" }, queries: [{ propertyName: "contentTemplate", first: true, predicate: TabContentTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "titleTemplate", first: true, predicate: TabTitleTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: "", isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
546
+ }
547
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabComponent, decorators: [{
548
+ type: Component,
549
+ args: [{
550
+ selector: "mona-tab",
551
+ template: "",
552
+ changeDetection: ChangeDetectionStrategy.OnPush
553
+ }]
554
+ }], propDecorators: { contentTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TabContentTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], titleTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TabTitleTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }, { type: i0.Output, args: ["selectedChange"] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }] } });
555
+
556
+ class TabsComponent {
557
+ constructor() {
558
+ this.#themeService = inject(ThemeService);
559
+ this.tabListComponent = viewChild.required(TabListComponent, /* @ts-ignore */
560
+ ...(ngDevMode ? [{ debugName: "tabListComponent" }] : /* istanbul ignore next */ []));
561
+ this.tabs = contentChildren(TabComponent, /* @ts-ignore */
562
+ ...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
563
+ this.baseClass = computed(() => {
564
+ const theme = this.#themeService.theme();
565
+ const variantClass = tabsBaseThemeVariants(theme)();
566
+ const userClass = this.userClass();
567
+ return twMerge(variantClass, userClass);
568
+ }, /* @ts-ignore */
569
+ ...(ngDevMode ? [{ debugName: "baseClass" }] : /* istanbul ignore next */ []));
570
+ this.contentClass = computed(() => {
571
+ const theme = this.#themeService.theme();
572
+ const rounded = this.rounded() === "full" ? "large" : this.rounded();
573
+ return tabContentThemeVariants(theme)({ rounded });
574
+ }, /* @ts-ignore */
575
+ ...(ngDevMode ? [{ debugName: "contentClass" }] : /* istanbul ignore next */ []));
576
+ this.selectedTabId = linkedSignal({ ...(ngDevMode ? { debugName: "selectedTabId" } : /* istanbul ignore next */ {}), source: () => this.tabList(),
577
+ computation: (tabList, previous) => {
578
+ const previousId = previous?.value;
579
+ if (previousId && tabList.any(t => t.id === previousId)) {
580
+ return previousId;
581
+ }
582
+ return tabList.firstOrDefault()?.id ?? null;
583
+ } });
584
+ this.tabList = computed(() => {
585
+ const tabs = this.tabs();
586
+ return select(tabs, t => t.tabItem)
587
+ .tap((t, tx) => (t.index = tx))
588
+ .toImmutableSet();
589
+ }, /* @ts-ignore */
590
+ ...(ngDevMode ? [{ debugName: "tabList" }] : /* istanbul ignore next */ []));
591
+ /**
592
+ * @description Displays a close button on each tab, unless overridden per tab.
593
+ * @default false
594
+ */
595
+ this.closable = input(false, /* @ts-ignore */
596
+ ...(ngDevMode ? [{ debugName: "closable" }] : /* istanbul ignore next */ []));
597
+ /**
598
+ * @description Renders every tab with reduced visual emphasis and removes pointer and keyboard interaction.
599
+ * @default false
600
+ */
601
+ this.disabled = input(false, /* @ts-ignore */
602
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
603
+ /**
604
+ * @description Keeps a tab's content in the DOM after it is deselected instead of removing it.
605
+ * @default true
606
+ */
607
+ this.keepTabContent = input(true, /* @ts-ignore */
608
+ ...(ngDevMode ? [{ debugName: "keepTabContent" }] : /* istanbul ignore next */ []));
609
+ /**
610
+ * @description Border-radius preset applied to the tabs and the tab content area.
611
+ * @default "medium"
612
+ */
613
+ this.rounded = input("medium", /* @ts-ignore */
614
+ ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
615
+ /**
616
+ * @description Size preset controlling the tabs' dimensions.
617
+ * @default "medium"
618
+ */
619
+ this.size = input("medium", /* @ts-ignore */
620
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
621
+ /**
622
+ * @description Emitted with a {@link TabCloseEvent} when a tab is closed.
623
+ */
624
+ this.tabClose = output();
625
+ /**
626
+ * @description Emitted with a {@link TabSelectEvent} when a tab is selected. This event is preventable.
627
+ */
628
+ this.tabSelect = output();
629
+ /**
630
+ * @description Additional CSS classes merged onto the host element via `tailwind-merge`.
631
+ * @default ""
632
+ */
633
+ this.userClass = input("", { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: "class" });
634
+ }
635
+ #themeService;
636
+ handlePanelKeyDown(event) {
637
+ if (event.key === "Tab" && event.shiftKey) {
638
+ if (event.target !== event.currentTarget) {
639
+ return;
640
+ }
641
+ event.preventDefault();
642
+ this.tabListComponent().focusSelectedTab();
643
+ }
644
+ }
645
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
646
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: TabsComponent, isStandalone: true, selector: "mona-tabs", inputs: { closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, keepTabContent: { classPropertyName: "keepTabContent", publicName: "keepTabContent", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tabClose: "tabClose", tabSelect: "tabSelect" }, host: { properties: { "class": "baseClass()" } }, queries: [{ propertyName: "tabs", predicate: TabComponent, isSignal: true }], viewQueries: [{ propertyName: "tabListComponent", first: true, predicate: TabListComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<mona-tab-list\r\n [closable]=\"closable()\"\r\n [disabled]=\"disabled()\"\r\n [rounded]=\"rounded()\"\r\n [size]=\"size()\"\r\n [tabList]=\"tabList()\"\r\n [selectedTabId]=\"selectedTabId()\"\r\n (selectedTabIdChange)=\"selectedTabId.set($event)\"\r\n (tabClose)=\"tabClose.emit($event)\"\r\n (tabSelect)=\"tabSelect.emit($event)\"></mona-tab-list>\r\n<div [class]=\"contentClass()\">\r\n @for (tab of tabList(); track tab) {\r\n @let selected = tab.id === selectedTabId();\r\n @let tabLoaded = keepTabContent() || selected;\r\n @let tabHidden = keepTabContent() && !selected;\r\n @if (tabLoaded) {\r\n <div\r\n class=\"w-full h-full outline-none\"\r\n [class.hidden]=\"tabHidden\"\r\n role=\"tabpanel\"\r\n [id]=\"tab.id + '-panel'\"\r\n tabindex=\"0\"\r\n (keydown)=\"handlePanelKeyDown($event)\"\r\n [attr.aria-hidden]=\"tabHidden\"\r\n [attr.aria-labelledby]=\"tab.id + '-tab'\">\r\n <ng-container [ngTemplateOutlet]=\"tab.contentTemplate\"></ng-container>\r\n </div>\r\n }\r\n }\r\n</div>\r\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TabListComponent, selector: "mona-tab-list", inputs: ["closable", "disabled", "rounded", "selectedTabId", "size", "tabList"], outputs: ["selectedTabIdChange", "tabClose", "tabSelect"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
647
+ }
648
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabsComponent, decorators: [{
649
+ type: Component,
650
+ args: [{ selector: "mona-tabs", changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet, TabListComponent], host: {
651
+ "[class]": "baseClass()"
652
+ }, template: "<mona-tab-list\r\n [closable]=\"closable()\"\r\n [disabled]=\"disabled()\"\r\n [rounded]=\"rounded()\"\r\n [size]=\"size()\"\r\n [tabList]=\"tabList()\"\r\n [selectedTabId]=\"selectedTabId()\"\r\n (selectedTabIdChange)=\"selectedTabId.set($event)\"\r\n (tabClose)=\"tabClose.emit($event)\"\r\n (tabSelect)=\"tabSelect.emit($event)\"></mona-tab-list>\r\n<div [class]=\"contentClass()\">\r\n @for (tab of tabList(); track tab) {\r\n @let selected = tab.id === selectedTabId();\r\n @let tabLoaded = keepTabContent() || selected;\r\n @let tabHidden = keepTabContent() && !selected;\r\n @if (tabLoaded) {\r\n <div\r\n class=\"w-full h-full outline-none\"\r\n [class.hidden]=\"tabHidden\"\r\n role=\"tabpanel\"\r\n [id]=\"tab.id + '-panel'\"\r\n tabindex=\"0\"\r\n (keydown)=\"handlePanelKeyDown($event)\"\r\n [attr.aria-hidden]=\"tabHidden\"\r\n [attr.aria-labelledby]=\"tab.id + '-tab'\">\r\n <ng-container [ngTemplateOutlet]=\"tab.contentTemplate\"></ng-container>\r\n </div>\r\n }\r\n }\r\n</div>\r\n" }]
653
+ }], propDecorators: { tabListComponent: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TabListComponent), { isSignal: true }] }], tabs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TabComponent), { isSignal: true }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], keepTabContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "keepTabContent", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], tabClose: [{ type: i0.Output, args: ["tabClose"] }], tabSelect: [{ type: i0.Output, args: ["tabSelect"] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
654
+
655
+ /*
656
+ * Public API Surface of @nanahoshi/mona-ui/tabs
657
+ */
658
+
659
+ /**
660
+ * Generated bundle index. Do not edit.
661
+ */
662
+
663
+ export { TabCloseEvent, TabComponent, TabContentTemplateDirective, TabSelectEvent, TabTitleTemplateDirective, TabsComponent };
664
+ //# sourceMappingURL=nanahoshi-mona-ui-tabs.mjs.map