@shival99/z-ui 2.1.32 → 2.1.33

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.
@@ -0,0 +1,507 @@
1
+ import { NgTemplateOutlet } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { input, inject, TemplateRef, Directive, contentChildren, viewChild, viewChildren, model, output, signal, computed, effect, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
4
+ import { TranslatePipe } from '@ngx-translate/core';
5
+ import { ZButtonComponent } from '@shival99/z-ui/components/z-button';
6
+ import { ZIconComponent } from '@shival99/z-ui/components/z-icon';
7
+ import { ZPopoverDirective } from '@shival99/z-ui/components/z-popover';
8
+ import { ZTooltipDirective } from '@shival99/z-ui/components/z-tooltip';
9
+ import { ZCacheService } from '@shival99/z-ui/services';
10
+ import { zMergeClasses } from '@shival99/z-ui/utils';
11
+ import { NgScrollbar } from 'ngx-scrollbar';
12
+ import { cva } from 'class-variance-authority';
13
+
14
+ class ZTabPanelDirective {
15
+ zTabPanel = input.required(...(ngDevMode ? [{ debugName: "zTabPanel" }] : []));
16
+ template = inject((TemplateRef));
17
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZTabPanelDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
18
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.9", type: ZTabPanelDirective, isStandalone: true, selector: "[z-tab-panel], [zTabPanel]", inputs: { zTabPanel: { classPropertyName: "zTabPanel", publicName: "zTabPanel", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["zTabPanel"], ngImport: i0 });
19
+ }
20
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZTabPanelDirective, decorators: [{
21
+ type: Directive,
22
+ args: [{
23
+ selector: '[z-tab-panel], [zTabPanel]',
24
+ standalone: true,
25
+ exportAs: 'zTabPanel',
26
+ }]
27
+ }], propDecorators: { zTabPanel: [{ type: i0.Input, args: [{ isSignal: true, alias: "zTabPanel", required: true }] }] } });
28
+
29
+ const zTabsVariants = cva('z-tabs flex min-w-0', {
30
+ variants: {
31
+ zType: {
32
+ line: 'gap-0',
33
+ soft: 'gap-1 bg-background p-0 dark:bg-transparent',
34
+ segment: 'gap-1 rounded-lg bg-muted/60 p-1 dark:bg-muted/35',
35
+ 'segment-solid': 'gap-1 rounded-lg bg-muted/60 p-1 dark:bg-muted/35',
36
+ folder: 'isolate gap-0 bg-background p-0 dark:bg-transparent',
37
+ 'folder-soft': 'isolate gap-0 bg-background p-0 dark:bg-transparent',
38
+ 'folder-solid': 'isolate gap-0 bg-background p-0 dark:bg-transparent',
39
+ underline: 'gap-0',
40
+ underlined: 'gap-0 rounded-none bg-background p-0 dark:bg-transparent',
41
+ badge: 'gap-0 rounded-none bg-background p-0 dark:bg-transparent',
42
+ sharp: 'gap-1 rounded-none bg-background p-0 dark:bg-transparent',
43
+ 'sharp-line': 'gap-0 rounded-none bg-background p-0 dark:bg-transparent',
44
+ 'sharp-line-filled': 'gap-0 rounded-none bg-background p-0 dark:bg-transparent',
45
+ 'vertical-sharp': 'gap-1 rounded-none bg-background p-0 dark:bg-transparent',
46
+ 'code-line': 'h-10 w-full justify-start gap-0 rounded-none bg-background p-0 dark:bg-transparent',
47
+ },
48
+ zOrientation: {
49
+ horizontal: 'w-max flex-row items-center',
50
+ vertical: 'w-full flex-col items-stretch gap-1 border-b-0',
51
+ },
52
+ },
53
+ defaultVariants: {
54
+ zType: 'line',
55
+ zOrientation: 'horizontal',
56
+ },
57
+ compoundVariants: [
58
+ {
59
+ zType: 'vertical-sharp',
60
+ zOrientation: 'vertical',
61
+ class: 'border-r-0 pr-0',
62
+ },
63
+ {
64
+ zType: 'sharp-line',
65
+ zOrientation: 'vertical',
66
+ class: 'gap-0',
67
+ },
68
+ {
69
+ zType: 'sharp-line-filled',
70
+ zOrientation: 'vertical',
71
+ class: 'gap-0',
72
+ },
73
+ ],
74
+ });
75
+ const zTabItemVariants = cva('z-tab-item relative inline-flex min-h-10 select-none items-center justify-center gap-2 whitespace-nowrap font-medium text-sm leading-none text-muted-foreground transition-[color,background-color,border-color,box-shadow,transform] duration-200 outline-none focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 cursor-pointer disabled:opacity-45 disabled:cursor-not-allowed', {
76
+ variants: {
77
+ zType: {
78
+ line: 'rounded-none border-0 hover:text-foreground data-[active=true]:text-primary after:pointer-events-none after:absolute after:inset-x-0 after:bottom-[-1px] after:h-1 after:bg-primary after:origin-center after:scale-x-0 after:transition-transform after:duration-200 data-[active=true]:after:scale-x-100',
79
+ soft: 'rounded-md border-0 text-muted-foreground hover:text-foreground data-[active=true]:bg-primary/10 data-[active=true]:text-primary data-[active=true]:shadow-xs! dark:data-[active=true]:bg-primary/15',
80
+ segment: 'rounded-md border border-transparent! text-muted-foreground hover:text-foreground data-[active=true]:bg-background data-[active=true]:text-primary data-[active=true]:shadow-sm dark:data-[active=true]:border-border!',
81
+ 'segment-solid': 'rounded-md border-0 text-muted-foreground hover:text-foreground data-[active=true]:bg-primary data-[active=true]:text-primary-foreground data-[active=true]:shadow-sm',
82
+ folder: 'rounded-t-md border-0 bg-transparent text-muted-foreground shadow-[inset_0_-1px_0_var(--border)] hover:text-foreground focus-visible:ring-0 focus-visible:ring-offset-0 data-[active=true]:z-[2] data-[active=true]:bg-background data-[active=true]:text-primary data-[active=true]:shadow-[inset_1px_0_0_var(--border),inset_-1px_0_0_var(--border),inset_0_1px_0_var(--border)]',
83
+ 'folder-soft': 'rounded-t-md border-0 bg-transparent text-muted-foreground shadow-[inset_0_-1px_0_var(--border)] hover:text-foreground focus-visible:ring-0 focus-visible:ring-offset-0 data-[active=true]:z-[2] data-[active=true]:bg-primary/10 data-[active=true]:text-primary data-[active=true]:shadow-[inset_1px_0_0_var(--border),inset_-1px_0_0_var(--border),inset_0_1px_0_var(--border)] dark:data-[active=true]:bg-primary/15',
84
+ 'folder-solid': 'rounded-t-md border-0 bg-transparent text-muted-foreground shadow-[inset_0_-1px_0_var(--border)] hover:text-foreground focus-visible:ring-0 focus-visible:ring-offset-0 data-[active=true]:z-[2] data-[active=true]:bg-primary data-[active=true]:text-primary-foreground data-[active=true]:shadow-[inset_1px_0_0_var(--primary),inset_-1px_0_0_var(--primary),inset_0_1px_0_var(--primary)]',
85
+ underline: 'hover:text-foreground data-[active=true]:text-primary after:pointer-events-none after:absolute after:inset-x-1 after:bottom-[-1px] after:h-[0.1875rem] after:bg-primary after:origin-center after:scale-x-0 after:transition-transform after:duration-200 data-[active=true]:after:scale-x-100',
86
+ underlined: 'rounded-none border-0 border-b-2 border-b-transparent! bg-background text-foreground/60 hover:text-foreground data-[active=true]:border-b-primary! data-[active=true]:bg-primary/10 data-[active=true]:text-primary data-[active=true]:shadow-sm!',
87
+ badge: 'rounded-none border-0 border-b-2 border-b-transparent! bg-background text-foreground/60 hover:text-foreground data-[active=true]:border-b-primary! data-[active=true]:bg-primary/10 data-[active=true]:text-primary data-[active=true]:shadow-none',
88
+ sharp: 'rounded-none border border-border/45 border-b-[3px] bg-background text-foreground/60 hover:text-foreground data-[active=true]:border-primary! data-[active=true]:border-b-primary! data-[active=true]:text-primary',
89
+ 'sharp-line': 'rounded-none border border-border/45 border-b-[3px] bg-background text-foreground/60 hover:text-foreground data-[active=true]:border-primary! data-[active=true]:border-b-primary! data-[active=true]:text-primary',
90
+ 'sharp-line-filled': 'rounded-none border border-border/45 border-b-[3px] bg-background text-foreground/60 hover:text-foreground data-[active=true]:border-primary! data-[active=true]:border-b-primary! data-[active=true]:bg-primary/30 data-[active=true]:text-primary',
91
+ 'vertical-sharp': 'rounded-none border border-transparent border-b-[3px] bg-background text-foreground/60 hover:text-foreground data-[active=true]:border-primary data-[active=true]:bg-primary/10 data-[active=true]:text-primary data-[active=true]:shadow-none',
92
+ 'code-line': 'relative inline-flex h-full min-h-8 flex-1 items-center justify-center gap-1.5 whitespace-nowrap rounded-none border border-border/45 border-b-2 bg-background px-4 py-1.5 font-medium text-foreground/60 transition-all hover:text-foreground data-[active=true]:relative data-[active=true]:z-[1] data-[active=true]:-mb-px data-[active=true]:border-x-primary/70! data-[active=true]:border-t-primary/70! data-[active=true]:border-b-primary! data-[active=true]:bg-primary/30 data-[active=true]:text-primary data-[active=true]:shadow-none [&_span.z-tab-item-label]:font-mono [&_span.z-tab-item-label]:text-[13px]',
93
+ },
94
+ zSize: {
95
+ xs: 'min-h-8 px-2.5 py-1 text-xs',
96
+ sm: 'min-h-9 px-3 py-1.5 text-sm',
97
+ default: 'min-h-10 px-4 py-2 text-sm',
98
+ lg: 'min-h-[2.625rem] px-4.5 py-2.25 text-sm',
99
+ },
100
+ zOrientation: {
101
+ horizontal: '',
102
+ vertical: 'justify-start px-3 py-2',
103
+ },
104
+ },
105
+ compoundVariants: [
106
+ {
107
+ zType: 'line',
108
+ zOrientation: 'vertical',
109
+ class: 'w-full justify-start rounded-sm data-[active=true]:shadow-xs',
110
+ },
111
+ {
112
+ zType: 'soft',
113
+ zOrientation: 'vertical',
114
+ class: 'w-full justify-start rounded-md data-[active=true]:bg-primary/10 data-[active=true]:shadow-xs dark:data-[active=true]:bg-primary/15',
115
+ },
116
+ {
117
+ zType: 'segment',
118
+ zOrientation: 'vertical',
119
+ class: 'w-full justify-start rounded-md data-[active=true]:bg-background data-[active=true]:shadow-xs dark:data-[active=true]:border-border!',
120
+ },
121
+ {
122
+ zType: 'segment-solid',
123
+ zOrientation: 'vertical',
124
+ class: 'w-full justify-start rounded-md data-[active=true]:bg-primary data-[active=true]:text-primary-foreground data-[active=true]:shadow-xs',
125
+ },
126
+ {
127
+ zType: 'folder',
128
+ zOrientation: 'vertical',
129
+ class: 'w-full justify-start rounded-sm data-[active=true]:shadow-xs',
130
+ },
131
+ {
132
+ zType: 'folder-soft',
133
+ zOrientation: 'vertical',
134
+ class: 'w-full justify-start rounded-sm data-[active=true]:shadow-xs',
135
+ },
136
+ {
137
+ zType: 'folder-solid',
138
+ zOrientation: 'vertical',
139
+ class: 'w-full justify-start rounded-sm data-[active=true]:shadow-xs',
140
+ },
141
+ {
142
+ zType: 'underline',
143
+ zOrientation: 'vertical',
144
+ class: 'w-full justify-start rounded-sm data-[active=true]:shadow-xs',
145
+ },
146
+ {
147
+ zType: 'underlined',
148
+ zOrientation: 'vertical',
149
+ class: 'w-full justify-start rounded-none data-[active=true]:shadow-xs',
150
+ },
151
+ {
152
+ zType: 'badge',
153
+ zOrientation: 'vertical',
154
+ class: 'w-full justify-start rounded-none data-[active=true]:shadow-xs',
155
+ },
156
+ {
157
+ zType: 'sharp',
158
+ zOrientation: 'vertical',
159
+ class: 'w-full justify-start rounded-none data-[active=true]:shadow-xs',
160
+ },
161
+ {
162
+ zType: 'sharp-line',
163
+ zOrientation: 'vertical',
164
+ class: 'w-full justify-start rounded-none data-[active=true]:shadow-xs',
165
+ },
166
+ {
167
+ zType: 'sharp-line-filled',
168
+ zOrientation: 'vertical',
169
+ class: 'w-full justify-start rounded-none data-[active=true]:shadow-xs',
170
+ },
171
+ {
172
+ zType: 'vertical-sharp',
173
+ zOrientation: 'vertical',
174
+ class: 'w-full justify-start rounded-none border border-transparent border-b-[3px] px-3 py-1.5 data-[active=true]:border-primary data-[active=true]:shadow-xs',
175
+ },
176
+ {
177
+ zType: 'code-line',
178
+ zSize: 'xs',
179
+ zOrientation: 'horizontal',
180
+ class: 'min-h-7 px-3 py-1 text-xs [&_span.z-tab-item-label]:text-xs',
181
+ },
182
+ {
183
+ zType: 'code-line',
184
+ zSize: 'sm',
185
+ zOrientation: 'horizontal',
186
+ class: 'min-h-8 px-3.5 py-1.5 text-sm',
187
+ },
188
+ {
189
+ zType: 'code-line',
190
+ zSize: 'default',
191
+ zOrientation: 'horizontal',
192
+ class: 'min-h-8 px-4 py-1.5 text-sm',
193
+ },
194
+ {
195
+ zType: 'code-line',
196
+ zSize: 'lg',
197
+ zOrientation: 'horizontal',
198
+ class: 'min-h-9 px-4.5 py-2 text-sm',
199
+ },
200
+ {
201
+ zType: 'code-line',
202
+ zOrientation: 'vertical',
203
+ class: 'h-auto w-full flex-none justify-start rounded-none px-3 py-2 data-[active=true]:shadow-xs',
204
+ },
205
+ ],
206
+ defaultVariants: {
207
+ zType: 'line',
208
+ zSize: 'default',
209
+ zOrientation: 'horizontal',
210
+ },
211
+ });
212
+
213
+ let zTabsInstanceId = 0;
214
+ const Z_TABS_SCROLL_TOLERANCE = 4;
215
+ class ZTabsComponent {
216
+ tabPanels = contentChildren(ZTabPanelDirective, ...(ngDevMode ? [{ debugName: "tabPanels" }] : []));
217
+ tabsListContainer = viewChild('tabsListContainer', ...(ngDevMode ? [{ debugName: "tabsListContainer" }] : []));
218
+ tabButtons = viewChildren('tabButton', ...(ngDevMode ? [{ debugName: "tabButtons" }] : []));
219
+ class = input('', ...(ngDevMode ? [{ debugName: "class" }] : []));
220
+ zTabs = input.required(...(ngDevMode ? [{ debugName: "zTabs" }] : []));
221
+ zType = input('line', ...(ngDevMode ? [{ debugName: "zType" }] : []));
222
+ zSize = input('default', ...(ngDevMode ? [{ debugName: "zSize" }] : []));
223
+ zOrientation = input('horizontal', ...(ngDevMode ? [{ debugName: "zOrientation" }] : []));
224
+ zContentFit = input('none', ...(ngDevMode ? [{ debugName: "zContentFit" }] : []));
225
+ zLazy = input(false, ...(ngDevMode ? [{ debugName: "zLazy" }] : []));
226
+ zDestroyInactive = input(false, ...(ngDevMode ? [{ debugName: "zDestroyInactive" }] : []));
227
+ zTabsOnly = input(false, ...(ngDevMode ? [{ debugName: "zTabsOnly" }] : []));
228
+ zShowContentWrapper = input(true, ...(ngDevMode ? [{ debugName: "zShowContentWrapper" }] : []));
229
+ zReloadable = input(true, ...(ngDevMode ? [{ debugName: "zReloadable" }] : []));
230
+ zEmitOnActiveClick = input(true, ...(ngDevMode ? [{ debugName: "zEmitOnActiveClick" }] : []));
231
+ zCache = input(true, ...(ngDevMode ? [{ debugName: "zCache" }] : []));
232
+ zCacheKey = input('', ...(ngDevMode ? [{ debugName: "zCacheKey" }] : []));
233
+ activeTab = model('', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
234
+ zTabChange = output();
235
+ loadedTabs = signal(new Set(), ...(ngDevMode ? [{ debugName: "loadedTabs" }] : []));
236
+ canScrollLeft = signal(false, ...(ngDevMode ? [{ debugName: "canScrollLeft" }] : []));
237
+ canScrollRight = signal(false, ...(ngDevMode ? [{ debugName: "canScrollRight" }] : []));
238
+ panelRenderStates = computed(() => new Map(this.tabPanels().map(panel => {
239
+ const tabValue = panel.zTabPanel();
240
+ if (this.zDestroyInactive()) {
241
+ return [tabValue, this.activeTab() === tabValue];
242
+ }
243
+ if (!this.zLazy()) {
244
+ return [tabValue, true];
245
+ }
246
+ return [tabValue, this.loadedTabs().has(tabValue) || this.activeTab() === tabValue];
247
+ })), ...(ngDevMode ? [{ debugName: "panelRenderStates" }] : []));
248
+ _resizeObserver;
249
+ _cacheInstanceId = ++zTabsInstanceId;
250
+ constructor() {
251
+ effect(() => {
252
+ this.zTabs();
253
+ requestAnimationFrame(() => this.checkScroll());
254
+ });
255
+ }
256
+ ngOnInit() {
257
+ this._restoreActiveTabFromCache();
258
+ }
259
+ ngAfterViewInit() {
260
+ this.checkScroll();
261
+ this._setupResizeObserver();
262
+ }
263
+ ngOnDestroy() {
264
+ this._resizeObserver?.disconnect();
265
+ }
266
+ tabsClasses = computed(() => zMergeClasses(zTabsVariants({
267
+ zType: this.zType(),
268
+ zOrientation: this.zOrientation(),
269
+ }), this.class()), ...(ngDevMode ? [{ debugName: "tabsClasses" }] : []));
270
+ contentWrapperFramed = computed(() => {
271
+ if (!this.zShowContentWrapper()) {
272
+ return false;
273
+ }
274
+ if (this.zOrientation() === 'vertical') {
275
+ return false;
276
+ }
277
+ const type = this.zType();
278
+ return (type === 'folder' ||
279
+ type === 'folder-soft' ||
280
+ type === 'folder-solid' ||
281
+ type === 'sharp' ||
282
+ type === 'sharp-line' ||
283
+ type === 'sharp-line-filled' ||
284
+ type === 'code-line');
285
+ }, ...(ngDevMode ? [{ debugName: "contentWrapperFramed" }] : []));
286
+ tabsListHasBottomPadding = computed(() => {
287
+ if (this.zOrientation() !== 'horizontal') {
288
+ return false;
289
+ }
290
+ const type = this.zType();
291
+ return (type !== 'folder' &&
292
+ type !== 'folder-soft' &&
293
+ type !== 'folder-solid' &&
294
+ type !== 'segment' &&
295
+ type !== 'segment-solid' &&
296
+ type !== 'sharp' &&
297
+ type !== 'sharp-line' &&
298
+ type !== 'sharp-line-filled' &&
299
+ type !== 'code-line');
300
+ }, ...(ngDevMode ? [{ debugName: "tabsListHasBottomPadding" }] : []));
301
+ verticalTabsScrollable = computed(() => this.zOrientation() === 'vertical' && this.zTabs().length > 8, ...(ngDevMode ? [{ debugName: "verticalTabsScrollable" }] : []));
302
+ getTabItemClasses(_tab) {
303
+ return zMergeClasses(zTabItemVariants({
304
+ zType: this.zType(),
305
+ zSize: this.zSize(),
306
+ zOrientation: this.zOrientation(),
307
+ }));
308
+ }
309
+ selectTab(tab, scrollToView = false) {
310
+ if (tab.disabled) {
311
+ return;
312
+ }
313
+ const isAlreadyActive = this.activeTab() === tab.value;
314
+ if (isAlreadyActive && !this.zReloadable()) {
315
+ return;
316
+ }
317
+ this.activeTab.set(tab.value);
318
+ this._saveActiveTabToCache(tab.value);
319
+ if (!isAlreadyActive || this.zEmitOnActiveClick()) {
320
+ this.zTabChange.emit(tab.value);
321
+ }
322
+ if (this.zLazy()) {
323
+ this.loadedTabs.update(tabs => {
324
+ const newTabs = new Set(tabs);
325
+ newTabs.add(tab.value);
326
+ return newTabs;
327
+ });
328
+ }
329
+ if (scrollToView && this.zOrientation() === 'horizontal') {
330
+ requestAnimationFrame(() => {
331
+ const tabIndex = this.zTabs().findIndex(t => t.value === tab.value);
332
+ const tabButtonsList = this.tabButtons();
333
+ const tabButton = tabButtonsList[tabIndex];
334
+ if (tabButton) {
335
+ tabButton.nativeElement.scrollIntoView({
336
+ behavior: 'smooth',
337
+ block: 'nearest',
338
+ inline: 'center',
339
+ });
340
+ }
341
+ });
342
+ }
343
+ }
344
+ isTabActive(tab) {
345
+ return this.activeTab() === tab.value;
346
+ }
347
+ onTabKeydown(event, currentIndex) {
348
+ const tabs = this.zTabs().filter(t => !t.disabled);
349
+ const currentTab = tabs[currentIndex];
350
+ if (!currentTab) {
351
+ return;
352
+ }
353
+ const isHorizontal = this.zOrientation() === 'horizontal';
354
+ const nextKey = isHorizontal ? 'ArrowRight' : 'ArrowDown';
355
+ const prevKey = isHorizontal ? 'ArrowLeft' : 'ArrowUp';
356
+ if (event.key === nextKey) {
357
+ event.preventDefault();
358
+ const nextIndex = (currentIndex + 1) % tabs.length;
359
+ this.selectTab(tabs[nextIndex]);
360
+ return;
361
+ }
362
+ if (event.key === prevKey) {
363
+ event.preventDefault();
364
+ const prevIndex = (currentIndex - 1 + tabs.length) % tabs.length;
365
+ this.selectTab(tabs[prevIndex]);
366
+ return;
367
+ }
368
+ if (event.key === 'Home') {
369
+ event.preventDefault();
370
+ this.selectTab(tabs[0]);
371
+ return;
372
+ }
373
+ if (event.key === 'End') {
374
+ event.preventDefault();
375
+ this.selectTab(tabs[tabs.length - 1]);
376
+ }
377
+ }
378
+ checkScroll() {
379
+ const container = this.tabsListContainer()?.nativeElement;
380
+ if (!container || this.zOrientation() !== 'horizontal') {
381
+ this.canScrollLeft.set(false);
382
+ this.canScrollRight.set(false);
383
+ return;
384
+ }
385
+ const { scrollLeft, scrollWidth, clientWidth } = container;
386
+ const maxScrollLeft = scrollWidth - clientWidth;
387
+ if (maxScrollLeft <= Z_TABS_SCROLL_TOLERANCE) {
388
+ container.scrollLeft = 0;
389
+ this.canScrollLeft.set(false);
390
+ this.canScrollRight.set(false);
391
+ return;
392
+ }
393
+ this.canScrollLeft.set(scrollLeft > Z_TABS_SCROLL_TOLERANCE);
394
+ this.canScrollRight.set(maxScrollLeft - scrollLeft > Z_TABS_SCROLL_TOLERANCE);
395
+ }
396
+ scrollLeft() {
397
+ const container = this.tabsListContainer()?.nativeElement;
398
+ if (!container) {
399
+ return;
400
+ }
401
+ container.scrollBy({ left: -200, behavior: 'smooth' });
402
+ setTimeout(() => this.checkScroll(), 300);
403
+ }
404
+ scrollRight() {
405
+ const container = this.tabsListContainer()?.nativeElement;
406
+ if (!container) {
407
+ return;
408
+ }
409
+ container.scrollBy({ left: 200, behavior: 'smooth' });
410
+ setTimeout(() => this.checkScroll(), 300);
411
+ }
412
+ onTabsScroll() {
413
+ this.checkScroll();
414
+ }
415
+ _setupResizeObserver() {
416
+ const container = this.tabsListContainer()?.nativeElement;
417
+ if (!container) {
418
+ return;
419
+ }
420
+ this._resizeObserver = new ResizeObserver(() => {
421
+ this.checkScroll();
422
+ });
423
+ this._resizeObserver.observe(container);
424
+ }
425
+ _restoreActiveTabFromCache() {
426
+ if (!this.zCache()) {
427
+ return;
428
+ }
429
+ const cacheKey = this._getCacheKey();
430
+ const cachedTab = ZCacheService.get(cacheKey);
431
+ if (!cachedTab) {
432
+ return;
433
+ }
434
+ const tab = this.zTabs().find(item => item.value === cachedTab && !item.disabled);
435
+ if (!tab) {
436
+ return;
437
+ }
438
+ this.activeTab.set(tab.value);
439
+ if (this.zLazy()) {
440
+ this.loadedTabs.update(tabs => {
441
+ const newTabs = new Set(tabs);
442
+ newTabs.add(tab.value);
443
+ return newTabs;
444
+ });
445
+ }
446
+ }
447
+ _saveActiveTabToCache(value) {
448
+ if (!this.zCache()) {
449
+ return;
450
+ }
451
+ ZCacheService.set(this._getCacheKey(), value);
452
+ }
453
+ _getCacheKey() {
454
+ const customKey = this.zCacheKey().trim();
455
+ if (customKey) {
456
+ return customKey;
457
+ }
458
+ const path = typeof window === 'undefined' ? 'ssr' : window.location.pathname;
459
+ return `z-tabs:${path}:${this._cacheInstanceId}`;
460
+ }
461
+ scrollToActiveDropdownItem() {
462
+ setTimeout(() => {
463
+ const activeIndex = this.zTabs().findIndex(tab => tab.value === this.activeTab());
464
+ if (activeIndex === -1) {
465
+ return;
466
+ }
467
+ const dropdownMenu = document.querySelector('.z-tabs-dropdown-menu');
468
+ if (!dropdownMenu) {
469
+ return;
470
+ }
471
+ const dropdownItems = Array.from(dropdownMenu.querySelectorAll('button'));
472
+ const activeItem = dropdownItems[activeIndex];
473
+ if (activeItem && dropdownMenu) {
474
+ const menuRect = dropdownMenu.getBoundingClientRect();
475
+ const itemRect = activeItem.getBoundingClientRect();
476
+ const scrollTop = activeItem.offsetTop - menuRect.height / 2 + itemRect.height / 2;
477
+ dropdownMenu.scrollTo({
478
+ top: scrollTop,
479
+ behavior: 'smooth',
480
+ });
481
+ }
482
+ }, 150);
483
+ }
484
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZTabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
485
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.9", type: ZTabsComponent, isStandalone: true, selector: "z-tabs", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, zTabs: { classPropertyName: "zTabs", publicName: "zTabs", isSignal: true, isRequired: true, transformFunction: null }, zType: { classPropertyName: "zType", publicName: "zType", isSignal: true, isRequired: false, transformFunction: null }, zSize: { classPropertyName: "zSize", publicName: "zSize", isSignal: true, isRequired: false, transformFunction: null }, zOrientation: { classPropertyName: "zOrientation", publicName: "zOrientation", isSignal: true, isRequired: false, transformFunction: null }, zContentFit: { classPropertyName: "zContentFit", publicName: "zContentFit", isSignal: true, isRequired: false, transformFunction: null }, zLazy: { classPropertyName: "zLazy", publicName: "zLazy", isSignal: true, isRequired: false, transformFunction: null }, zDestroyInactive: { classPropertyName: "zDestroyInactive", publicName: "zDestroyInactive", isSignal: true, isRequired: false, transformFunction: null }, zTabsOnly: { classPropertyName: "zTabsOnly", publicName: "zTabsOnly", isSignal: true, isRequired: false, transformFunction: null }, zShowContentWrapper: { classPropertyName: "zShowContentWrapper", publicName: "zShowContentWrapper", isSignal: true, isRequired: false, transformFunction: null }, zReloadable: { classPropertyName: "zReloadable", publicName: "zReloadable", isSignal: true, isRequired: false, transformFunction: null }, zEmitOnActiveClick: { classPropertyName: "zEmitOnActiveClick", publicName: "zEmitOnActiveClick", isSignal: true, isRequired: false, transformFunction: null }, zCache: { classPropertyName: "zCache", publicName: "zCache", isSignal: true, isRequired: false, transformFunction: null }, zCacheKey: { classPropertyName: "zCacheKey", publicName: "zCacheKey", isSignal: true, isRequired: false, transformFunction: null }, activeTab: { classPropertyName: "activeTab", publicName: "activeTab", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeTab: "activeTabChange", zTabChange: "zTabChange" }, host: { classAttribute: "z-tabs-wrapper block" }, queries: [{ propertyName: "tabPanels", predicate: ZTabPanelDirective, isSignal: true }], viewQueries: [{ propertyName: "tabsListContainer", first: true, predicate: ["tabsListContainer"], descendants: true, isSignal: true }, { propertyName: "tabButtons", predicate: ["tabButton"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"z-tabs-container flex gap-1\"\n [attr.data-type]=\"zType()\"\n [attr.data-orientation]=\"zOrientation()\"\n [attr.data-content-fit]=\"zContentFit()\"\n [class.flex-col]=\"!zTabsOnly()\"\n [class.flex-row]=\"zOrientation() === 'vertical'\"\n [class.gap-4]=\"zOrientation() === 'vertical'\">\n <!-- Tabs Navigation (Left/Scroll/Tabs/Right/Dropdown) -->\n <div\n class=\"z-tabs-nav flex items-center gap-1.5\"\n [class.w-full]=\"zOrientation() === 'horizontal'\"\n [class.w-auto]=\"zOrientation() === 'vertical'\"\n [class.shrink-0]=\"zOrientation() === 'vertical'\">\n <!-- Scroll Left Button -->\n @if (canScrollLeft() && zOrientation() === 'horizontal') {\n <z-button\n zType=\"ghost\"\n zSize=\"sm\"\n zIconOnly=\"true\"\n [zWave]=\"false\"\n class=\"z-tabs-nav-control shrink-0\"\n (click)=\"scrollLeft()\"\n aria-label=\"Scroll left\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"16\" />\n </z-button>\n }\n\n <!-- Tabs List Container with Scroll + Fade -->\n <div class=\"z-tabs-scroll-container relative min-w-0 flex-1\" [attr.data-type]=\"zType()\">\n @if (zOrientation() === 'vertical') {\n <ng-scrollbar\n class=\"z-tabs-scroll-wrapper z-tabs-scrollbar vertical\"\n [class.z-tabs-scroll-wrapper-limited]=\"verticalTabsScrollable()\"\n track=\"vertical\"\n orientation=\"vertical\"\n appearance=\"compact\"\n visibility=\"hover\">\n <ng-container *ngTemplateOutlet=\"tabsListTpl\" />\n </ng-scrollbar>\n } @else {\n <div\n #tabsListContainer\n class=\"z-tabs-scroll-wrapper\"\n [class.z-tabs-scroll-wrapper-scrollable]=\"canScrollLeft() || canScrollRight()\"\n (scroll)=\"onTabsScroll()\">\n <ng-container *ngTemplateOutlet=\"tabsListTpl\" />\n </div>\n }\n\n <!-- Fade overlays (outside scroll container) -->\n @if (canScrollLeft() && zOrientation() === 'horizontal') {\n <div class=\"z-tabs-fade-left\"></div>\n }\n @if (canScrollRight() && zOrientation() === 'horizontal') {\n <div class=\"z-tabs-fade-right\"></div>\n }\n </div>\n\n <!-- Scroll Right Button -->\n @if (canScrollRight() && zOrientation() === 'horizontal') {\n <z-button\n zType=\"ghost\"\n zSize=\"sm\"\n zIconOnly=\"true\"\n class=\"z-tabs-nav-control shrink-0\"\n (click)=\"scrollRight()\"\n [zWave]=\"false\"\n aria-label=\"Scroll right\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"16\" />\n </z-button>\n }\n\n <!-- Dropdown Button (Mobile or Overflow) -->\n @if (zOrientation() === 'horizontal' && (canScrollLeft() || canScrollRight())) {\n <z-button\n zType=\"ghost\"\n zSize=\"sm\"\n zIconOnly=\"true\"\n class=\"z-tabs-nav-control shrink-0\"\n z-popover\n [zPopoverContent]=\"dropdownTpl\"\n zPosition=\"bottom-right\"\n [zWave]=\"false\"\n zClass=\"min-w-[6.25rem] max-w-[12.5rem]\"\n (zShow)=\"scrollToActiveDropdownItem()\"\n aria-label=\"Select tab\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"16\" />\n </z-button>\n }\n </div>\n\n <ng-template #tabsListTpl>\n <!-- Tab List -->\n <div\n [class]=\"tabsClasses()\"\n [class.pb-0.5]=\"tabsListHasBottomPadding()\"\n role=\"tablist\"\n [attr.aria-orientation]=\"zOrientation()\"\n [attr.data-type]=\"zType()\">\n @for (tab of zTabs(); track tab.value; let idx = $index; let last = $last) {\n <button\n #tabButton\n type=\"button\"\n role=\"tab\"\n [class]=\"getTabItemClasses(tab)\"\n [attr.data-active]=\"isTabActive(tab)\"\n [attr.data-state]=\"isTabActive(tab) ? 'active' : 'inactive'\"\n [attr.data-type]=\"zType()\"\n [attr.data-orientation]=\"zOrientation()\"\n [attr.data-last]=\"last\"\n [attr.aria-selected]=\"isTabActive(tab)\"\n [attr.aria-controls]=\"'panel-' + tab.value\"\n [disabled]=\"tab.disabled\"\n [tabindex]=\"isTabActive(tab) ? 0 : -1\"\n z-tooltip\n [zContent]=\"zOrientation() === 'vertical' ? (tab.label | translate) : ''\"\n zPosition=\"top\"\n [zHideDelay]=\"0\"\n [zOffset]=\"5\"\n [zArrow]=\"false\"\n (click)=\"selectTab(tab)\"\n (keydown)=\"onTabKeydown($event, idx)\">\n @if (tab.icon) {\n <z-icon [zType]=\"tab.icon\" zSize=\"16\" class=\"shrink-0\" />\n }\n <span class=\"z-tab-item-label min-w-0 flex-1 truncate text-left\">{{ tab.label | translate }}</span>\n @if (tab.badge) {\n <span\n class=\"ring-background ml-1.5 inline-flex h-5 min-w-5 items-center justify-center rounded-full px-1.5 text-xs font-semibold ring-2\"\n [class.bg-primary]=\"zType() !== 'badge'\"\n [class.text-primary-foreground]=\"zType() !== 'badge'\"\n [class.bg-primary!]=\"zType() === 'badge'\"\n [class.text-primary-foreground!]=\"zType() === 'badge'\">\n {{ tab.badge }}\n </span>\n }\n </button>\n }\n </div>\n </ng-template>\n\n <!-- Tab Panels -->\n @if (!zTabsOnly()) {\n <div\n class=\"z-tabs-panels min-h-0\"\n [class.flex-1]=\"zOrientation() === 'vertical'\"\n [class.shadow-xs]=\"contentWrapperFramed()\"\n [class.z-tabs-panels-unwrapped]=\"!contentWrapperFramed()\">\n @for (panel of tabPanels(); track panel.zTabPanel()) {\n @if (panelRenderStates().get(panel.zTabPanel())) {\n <div\n role=\"tabpanel\"\n [id]=\"'panel-' + panel.zTabPanel()\"\n [attr.aria-labelledby]=\"panel.zTabPanel()\"\n [hidden]=\"activeTab() !== panel.zTabPanel()\">\n <ng-container *ngTemplateOutlet=\"panel.template\" />\n </div>\n }\n }\n </div>\n }\n</div>\n\n<!-- Dropdown Menu Template -->\n<ng-template #dropdownTpl let-close=\"close\">\n <div\n class=\"z-tabs-dropdown-menu flex max-h-[18.75rem] max-w-[12.5rem] min-w-[6.25rem] flex-col gap-0.5 overflow-y-auto p-1\">\n @for (tab of zTabs(); track tab.value) {\n <button\n #dropdownItem\n type=\"button\"\n class=\"flex w-full cursor-pointer items-center justify-start gap-2 rounded-sm px-2 py-1.5 text-left text-sm font-medium transition-colors outline-none disabled:pointer-events-none disabled:opacity-50\"\n [class.hover:text-foreground]=\"!isTabActive(tab)\"\n [class.focus:bg-primary/10]=\"!isTabActive(tab)\"\n [class.bg-primary/15]=\"isTabActive(tab)\"\n [class.text-primary]=\"isTabActive(tab)\"\n [disabled]=\"tab.disabled\"\n (click)=\"selectTab(tab, true); close()\">\n @if (tab.icon) {\n <z-icon [zType]=\"tab.icon\" zSize=\"16\" class=\"text-muted-foreground shrink-0\" />\n }\n <span\n class=\"min-w-0 flex-1 truncate\"\n z-tooltip\n [zContent]=\"tab.label | translate\"\n zPosition=\"top\"\n [zHideDelay]=\"0\"\n [zOffset]=\"5\"\n [zArrow]=\"false\"\n [zTriggerElement]=\"dropdownItem\">\n {{ tab.label | translate }}\n </span>\n @if (tab.badge) {\n <span\n class=\"bg-primary text-primary-foreground inline-flex h-5 min-w-5 items-center justify-center rounded-full px-1.5 text-xs font-semibold\">\n {{ tab.badge }}\n </span>\n }\n @if (isTabActive(tab)) {\n <z-icon zType=\"lucideCheck\" zSize=\"16\" class=\"text-primary shink-0\" />\n }\n </button>\n }\n </div>\n</ng-template>\n", styles: [".z-tabs-scroll-wrapper{overflow-x:clip;overflow-y:visible;scrollbar-width:none;-ms-overflow-style:none;scroll-behavior:smooth}.z-tabs-scroll-wrapper::-webkit-scrollbar{display:none}.z-tabs-scroll-wrapper.vertical{max-height:var(--z-tabs-vertical-max-height, min(22rem, 60vh));overflow:hidden auto}.z-tabs-scroll-wrapper.vertical.z-tabs-scroll-wrapper-limited{height:var(--z-tabs-vertical-max-height, min(22rem, 60vh));overflow:hidden auto}.z-tabs-scroll-wrapper.z-tabs-scroll-wrapper-scrollable{overflow-x:auto}.z-tabs-scrollbar{--scrollbar-padding: .125rem;--z-tabs-scrollbar-gutter: .75rem;--scrollbar-track-color: transparent;--scrollbar-thumb-color: color-mix(in oklab, var(--muted-foreground) 35%, transparent);--scrollbar-thumb-hover-color: color-mix(in oklab, var(--muted-foreground) 55%, transparent);--scrollbar-size: .375rem;display:block}.z-tabs-scrollbar .ng-scroll-viewport,.z-tabs-scrollbar .ng-scroll-content{max-width:100%}.z-tabs-scrollbar.z-tabs-scroll-wrapper-limited .ng-scroll-viewport{height:100%;max-height:100%}.z-tabs-scrollbar .ng-scroll-content{box-sizing:border-box;padding-right:var(--z-tabs-scrollbar-gutter)}.z-tabs-scroll-container{isolation:isolate;--z-tabs-fade-width: 2rem}.z-tabs-fade-left{content:\"\";position:absolute;left:0;top:.0625rem;bottom:.0625rem;width:var(--z-tabs-fade-width);background:linear-gradient(to right,var(--background) 0%,oklch(from var(--background) l c h/.86) 28%,oklch(from var(--background) l c h/.48) 60%,oklch(from var(--background) l c h/0) 100%);pointer-events:none;z-index:5}.z-tabs-fade-right{content:\"\";position:absolute;right:0;top:.0625rem;bottom:.0625rem;width:var(--z-tabs-fade-width);background:linear-gradient(to left,var(--background) 0%,oklch(from var(--background) l c h/.86) 28%,oklch(from var(--background) l c h/.48) 60%,oklch(from var(--background) l c h/0) 100%);pointer-events:none;z-index:5}.z-tabs{align-items:stretch;min-height:2.5rem}.z-tabs.flex-col{width:100%}.z-tabs.flex-col.border-r{border-right:.0625rem solid hsl(var(--border));padding-right:.5rem}.z-tabs-nav-control{transition:color .2s ease,background-color .2s ease,border-color .2s ease}.z-tab-item{-webkit-tap-highlight-color:transparent;position:relative}.z-tab-item[data-active=true]{position:relative}.z-tab-item:disabled{pointer-events:none}.z-tabs-panels{border:.0625rem solid var(--border);border-radius:var(--radius-xs);padding:1rem}.z-tabs-panels [role=tabpanel]{animation:z-tabs-fade-in .2s ease-in-out}.z-tabs-panels [role=tabpanel][hidden]{display:none}.z-tabs-panels-unwrapped{border:0;border-radius:0;padding:0}.z-tabs-wrapper .z-tabs.flex-row+.z-tabs-panels{margin-top:.875rem}.z-tabs-wrapper .z-tabs.flex-col+.z-tabs-panels{margin-top:0;margin-left:0}.z-tabs-container[data-orientation=horizontal]{gap:0}.z-tabs-container[data-orientation=horizontal] .z-tabs-scroll-container{z-index:1}.z-tabs-container[data-orientation=horizontal] .z-tabs-panels{margin-top:0}.z-tabs-container[data-content-fit=screen]{height:var(--z-tabs-screen-height, calc(100dvh - var(--z-tabs-screen-offset, 0rem)));max-height:var(--z-tabs-screen-height, calc(100dvh - var(--z-tabs-screen-offset, 0rem)));min-height:0;overflow:hidden}.z-tabs-container[data-content-fit=screen] .z-tabs-nav{flex:none;min-height:0}.z-tabs-container[data-content-fit=screen] .z-tabs-panels{flex:1 1 auto;min-height:0;overflow:auto}.z-tabs-container[data-content-fit=screen] [role=tabpanel]{min-height:0}.z-tabs-container[data-type=line][data-orientation=horizontal] .z-tabs-nav{position:relative}.z-tabs-container[data-type=line][data-orientation=horizontal] .z-tabs-nav:after{content:\"\";position:absolute;right:0;bottom:0;left:0;height:.0625rem;background:color-mix(in oklab,var(--border) 80%,transparent);pointer-events:none;z-index:0}.z-tabs-container:is([data-type=outline],[data-type=soft],[data-type=segment],[data-type=folder],[data-type=folder-soft],[data-type=folder-solid],[data-type=underline],[data-type=underlined],[data-type=badge],[data-type=sharp],[data-type=sharp-line],[data-type=sharp-line-filled],[data-type=code-line])[data-orientation=horizontal] .z-tabs-scroll-wrapper{padding-inline:0}.z-tabs-container:is([data-type=outline],[data-type=soft],[data-type=segment],[data-type=folder],[data-type=folder-soft],[data-type=folder-solid],[data-type=underline],[data-type=underlined],[data-type=badge],[data-type=sharp],[data-type=sharp-line],[data-type=sharp-line-filled],[data-type=code-line])[data-orientation=horizontal] .z-tabs-panels{border-radius:0 0 var(--radius-xs) var(--radius-xs)}.z-tabs-container:is([data-type=outline],[data-type=soft],[data-type=segment],[data-type=folder],[data-type=folder-soft],[data-type=folder-solid],[data-type=underline],[data-type=underlined],[data-type=badge],[data-type=sharp],[data-type=sharp-line],[data-type=sharp-line-filled],[data-type=code-line])[data-orientation=horizontal] .z-tabs-panels-unwrapped{border:0;border-radius:0}.z-tabs-container:is([data-type=folder],[data-type=folder-soft],[data-type=folder-solid])[data-orientation=horizontal] .z-tabs-nav{position:relative}.z-tabs-container:is([data-type=folder],[data-type=folder-soft],[data-type=folder-solid])[data-orientation=horizontal] .z-tabs-nav:after{content:\"\";position:absolute;right:0;bottom:0;left:0;height:.0625rem;background:var(--border);pointer-events:none;z-index:0}.z-tabs-container:is([data-type=folder],[data-type=folder-soft],[data-type=folder-solid])[data-orientation=horizontal] .z-tabs-panels{border-top:0}.z-tabs-container[data-type=folder-solid][data-orientation=horizontal] .z-tab-item[data-active=true][data-last=true]{box-shadow:inset .0625rem 0 0 var(--primary),inset -.0625rem 0 0 var(--border),inset 0 .0625rem 0 var(--primary)}.z-tabs-container:is([data-type=segment],[data-type=segment-solid]) .z-tabs{align-items:center}.z-tabs-container[data-orientation=vertical] .z-tabs-nav{align-items:stretch}.z-tabs-container[data-orientation=vertical] .z-tabs-scroll-container{width:min(12rem,40vw);flex:none}.z-tabs-container[data-orientation=vertical] .z-tabs-panels,.z-tabs-container[data-orientation=vertical] .z-tab-item{min-width:0}@media(prefers-reduced-motion:reduce){.z-tab-item,.z-tabs-nav-control{transition:none!important}.z-tabs-scroll-wrapper{scroll-behavior:auto}.z-tabs-panels [role=tabpanel]{animation:none!important}}@keyframes z-tabs-fade-in{0%{opacity:0;transform:translateY(-.2rem)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zAnimatedType", "zAnimate", "zAnimationTrigger", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "component", type: ZButtonComponent, selector: "z-button, button[z-button], a[z-button]", inputs: ["class", "zType", "zSize", "zShape", "zLabel", "zLoading", "zDisabled", "zTypeIcon", "zAnimatedTypeIcon", "zAnimateIcon", "zAnimationTriggerIcon", "zSizeIcon", "zStrokeWidthIcon", "zWave"], exportAs: ["zButton"] }, { kind: "directive", type: ZTooltipDirective, selector: "[z-tooltip], [zTooltip]", inputs: ["zContent", "zPosition", "zTooltipPosition", "zTrigger", "zTooltipTrigger", "zTooltipType", "zTooltipSize", "zClass", "zTooltipClass", "zShowDelay", "zTooltipShowDelay", "zHideDelay", "zTooltipHideDelay", "zArrow", "zTooltipArrow", "zDisabled", "zTooltipDisabled", "zOffset", "zTooltipOffset", "zAutoDetect", "zTriggerElement", "zAlwaysShow", "zMaxWidth"], outputs: ["zShow", "zHide"], exportAs: ["zTooltip"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: ZPopoverDirective, selector: "[z-popover]", inputs: ["zPopoverContent", "zPosition", "zTrigger", "zPopoverTrigger", "zClass", "zShowDelay", "zHideDelay", "zDisabled", "zOffset", "zPopoverWidth", "zTriggerRef", "zManualClose", "zOutsideClickClose", "zScrollClose", "zSticky", "zShowArrow", "zKeyboardSafe"], outputs: ["zShow", "zHide", "zHideStart", "zControl", "zPositionChange", "zOutsideClick"], exportAs: ["zPopover"] }, { kind: "component", type: NgScrollbar, selector: "ng-scrollbar:not([externalViewport]), [ngScrollbar]", exportAs: ["ngScrollbar"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
486
+ }
487
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZTabsComponent, decorators: [{
488
+ type: Component,
489
+ args: [{ selector: 'z-tabs', imports: [
490
+ ZIconComponent,
491
+ ZButtonComponent,
492
+ ZTooltipDirective,
493
+ NgTemplateOutlet,
494
+ ZPopoverDirective,
495
+ TranslatePipe,
496
+ NgScrollbar,
497
+ ], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
498
+ class: 'z-tabs-wrapper block',
499
+ }, template: "<div\n class=\"z-tabs-container flex gap-1\"\n [attr.data-type]=\"zType()\"\n [attr.data-orientation]=\"zOrientation()\"\n [attr.data-content-fit]=\"zContentFit()\"\n [class.flex-col]=\"!zTabsOnly()\"\n [class.flex-row]=\"zOrientation() === 'vertical'\"\n [class.gap-4]=\"zOrientation() === 'vertical'\">\n <!-- Tabs Navigation (Left/Scroll/Tabs/Right/Dropdown) -->\n <div\n class=\"z-tabs-nav flex items-center gap-1.5\"\n [class.w-full]=\"zOrientation() === 'horizontal'\"\n [class.w-auto]=\"zOrientation() === 'vertical'\"\n [class.shrink-0]=\"zOrientation() === 'vertical'\">\n <!-- Scroll Left Button -->\n @if (canScrollLeft() && zOrientation() === 'horizontal') {\n <z-button\n zType=\"ghost\"\n zSize=\"sm\"\n zIconOnly=\"true\"\n [zWave]=\"false\"\n class=\"z-tabs-nav-control shrink-0\"\n (click)=\"scrollLeft()\"\n aria-label=\"Scroll left\">\n <z-icon zType=\"lucideChevronLeft\" zSize=\"16\" />\n </z-button>\n }\n\n <!-- Tabs List Container with Scroll + Fade -->\n <div class=\"z-tabs-scroll-container relative min-w-0 flex-1\" [attr.data-type]=\"zType()\">\n @if (zOrientation() === 'vertical') {\n <ng-scrollbar\n class=\"z-tabs-scroll-wrapper z-tabs-scrollbar vertical\"\n [class.z-tabs-scroll-wrapper-limited]=\"verticalTabsScrollable()\"\n track=\"vertical\"\n orientation=\"vertical\"\n appearance=\"compact\"\n visibility=\"hover\">\n <ng-container *ngTemplateOutlet=\"tabsListTpl\" />\n </ng-scrollbar>\n } @else {\n <div\n #tabsListContainer\n class=\"z-tabs-scroll-wrapper\"\n [class.z-tabs-scroll-wrapper-scrollable]=\"canScrollLeft() || canScrollRight()\"\n (scroll)=\"onTabsScroll()\">\n <ng-container *ngTemplateOutlet=\"tabsListTpl\" />\n </div>\n }\n\n <!-- Fade overlays (outside scroll container) -->\n @if (canScrollLeft() && zOrientation() === 'horizontal') {\n <div class=\"z-tabs-fade-left\"></div>\n }\n @if (canScrollRight() && zOrientation() === 'horizontal') {\n <div class=\"z-tabs-fade-right\"></div>\n }\n </div>\n\n <!-- Scroll Right Button -->\n @if (canScrollRight() && zOrientation() === 'horizontal') {\n <z-button\n zType=\"ghost\"\n zSize=\"sm\"\n zIconOnly=\"true\"\n class=\"z-tabs-nav-control shrink-0\"\n (click)=\"scrollRight()\"\n [zWave]=\"false\"\n aria-label=\"Scroll right\">\n <z-icon zType=\"lucideChevronRight\" zSize=\"16\" />\n </z-button>\n }\n\n <!-- Dropdown Button (Mobile or Overflow) -->\n @if (zOrientation() === 'horizontal' && (canScrollLeft() || canScrollRight())) {\n <z-button\n zType=\"ghost\"\n zSize=\"sm\"\n zIconOnly=\"true\"\n class=\"z-tabs-nav-control shrink-0\"\n z-popover\n [zPopoverContent]=\"dropdownTpl\"\n zPosition=\"bottom-right\"\n [zWave]=\"false\"\n zClass=\"min-w-[6.25rem] max-w-[12.5rem]\"\n (zShow)=\"scrollToActiveDropdownItem()\"\n aria-label=\"Select tab\">\n <z-icon zType=\"lucideChevronDown\" zSize=\"16\" />\n </z-button>\n }\n </div>\n\n <ng-template #tabsListTpl>\n <!-- Tab List -->\n <div\n [class]=\"tabsClasses()\"\n [class.pb-0.5]=\"tabsListHasBottomPadding()\"\n role=\"tablist\"\n [attr.aria-orientation]=\"zOrientation()\"\n [attr.data-type]=\"zType()\">\n @for (tab of zTabs(); track tab.value; let idx = $index; let last = $last) {\n <button\n #tabButton\n type=\"button\"\n role=\"tab\"\n [class]=\"getTabItemClasses(tab)\"\n [attr.data-active]=\"isTabActive(tab)\"\n [attr.data-state]=\"isTabActive(tab) ? 'active' : 'inactive'\"\n [attr.data-type]=\"zType()\"\n [attr.data-orientation]=\"zOrientation()\"\n [attr.data-last]=\"last\"\n [attr.aria-selected]=\"isTabActive(tab)\"\n [attr.aria-controls]=\"'panel-' + tab.value\"\n [disabled]=\"tab.disabled\"\n [tabindex]=\"isTabActive(tab) ? 0 : -1\"\n z-tooltip\n [zContent]=\"zOrientation() === 'vertical' ? (tab.label | translate) : ''\"\n zPosition=\"top\"\n [zHideDelay]=\"0\"\n [zOffset]=\"5\"\n [zArrow]=\"false\"\n (click)=\"selectTab(tab)\"\n (keydown)=\"onTabKeydown($event, idx)\">\n @if (tab.icon) {\n <z-icon [zType]=\"tab.icon\" zSize=\"16\" class=\"shrink-0\" />\n }\n <span class=\"z-tab-item-label min-w-0 flex-1 truncate text-left\">{{ tab.label | translate }}</span>\n @if (tab.badge) {\n <span\n class=\"ring-background ml-1.5 inline-flex h-5 min-w-5 items-center justify-center rounded-full px-1.5 text-xs font-semibold ring-2\"\n [class.bg-primary]=\"zType() !== 'badge'\"\n [class.text-primary-foreground]=\"zType() !== 'badge'\"\n [class.bg-primary!]=\"zType() === 'badge'\"\n [class.text-primary-foreground!]=\"zType() === 'badge'\">\n {{ tab.badge }}\n </span>\n }\n </button>\n }\n </div>\n </ng-template>\n\n <!-- Tab Panels -->\n @if (!zTabsOnly()) {\n <div\n class=\"z-tabs-panels min-h-0\"\n [class.flex-1]=\"zOrientation() === 'vertical'\"\n [class.shadow-xs]=\"contentWrapperFramed()\"\n [class.z-tabs-panels-unwrapped]=\"!contentWrapperFramed()\">\n @for (panel of tabPanels(); track panel.zTabPanel()) {\n @if (panelRenderStates().get(panel.zTabPanel())) {\n <div\n role=\"tabpanel\"\n [id]=\"'panel-' + panel.zTabPanel()\"\n [attr.aria-labelledby]=\"panel.zTabPanel()\"\n [hidden]=\"activeTab() !== panel.zTabPanel()\">\n <ng-container *ngTemplateOutlet=\"panel.template\" />\n </div>\n }\n }\n </div>\n }\n</div>\n\n<!-- Dropdown Menu Template -->\n<ng-template #dropdownTpl let-close=\"close\">\n <div\n class=\"z-tabs-dropdown-menu flex max-h-[18.75rem] max-w-[12.5rem] min-w-[6.25rem] flex-col gap-0.5 overflow-y-auto p-1\">\n @for (tab of zTabs(); track tab.value) {\n <button\n #dropdownItem\n type=\"button\"\n class=\"flex w-full cursor-pointer items-center justify-start gap-2 rounded-sm px-2 py-1.5 text-left text-sm font-medium transition-colors outline-none disabled:pointer-events-none disabled:opacity-50\"\n [class.hover:text-foreground]=\"!isTabActive(tab)\"\n [class.focus:bg-primary/10]=\"!isTabActive(tab)\"\n [class.bg-primary/15]=\"isTabActive(tab)\"\n [class.text-primary]=\"isTabActive(tab)\"\n [disabled]=\"tab.disabled\"\n (click)=\"selectTab(tab, true); close()\">\n @if (tab.icon) {\n <z-icon [zType]=\"tab.icon\" zSize=\"16\" class=\"text-muted-foreground shrink-0\" />\n }\n <span\n class=\"min-w-0 flex-1 truncate\"\n z-tooltip\n [zContent]=\"tab.label | translate\"\n zPosition=\"top\"\n [zHideDelay]=\"0\"\n [zOffset]=\"5\"\n [zArrow]=\"false\"\n [zTriggerElement]=\"dropdownItem\">\n {{ tab.label | translate }}\n </span>\n @if (tab.badge) {\n <span\n class=\"bg-primary text-primary-foreground inline-flex h-5 min-w-5 items-center justify-center rounded-full px-1.5 text-xs font-semibold\">\n {{ tab.badge }}\n </span>\n }\n @if (isTabActive(tab)) {\n <z-icon zType=\"lucideCheck\" zSize=\"16\" class=\"text-primary shink-0\" />\n }\n </button>\n }\n </div>\n</ng-template>\n", styles: [".z-tabs-scroll-wrapper{overflow-x:clip;overflow-y:visible;scrollbar-width:none;-ms-overflow-style:none;scroll-behavior:smooth}.z-tabs-scroll-wrapper::-webkit-scrollbar{display:none}.z-tabs-scroll-wrapper.vertical{max-height:var(--z-tabs-vertical-max-height, min(22rem, 60vh));overflow:hidden auto}.z-tabs-scroll-wrapper.vertical.z-tabs-scroll-wrapper-limited{height:var(--z-tabs-vertical-max-height, min(22rem, 60vh));overflow:hidden auto}.z-tabs-scroll-wrapper.z-tabs-scroll-wrapper-scrollable{overflow-x:auto}.z-tabs-scrollbar{--scrollbar-padding: .125rem;--z-tabs-scrollbar-gutter: .75rem;--scrollbar-track-color: transparent;--scrollbar-thumb-color: color-mix(in oklab, var(--muted-foreground) 35%, transparent);--scrollbar-thumb-hover-color: color-mix(in oklab, var(--muted-foreground) 55%, transparent);--scrollbar-size: .375rem;display:block}.z-tabs-scrollbar .ng-scroll-viewport,.z-tabs-scrollbar .ng-scroll-content{max-width:100%}.z-tabs-scrollbar.z-tabs-scroll-wrapper-limited .ng-scroll-viewport{height:100%;max-height:100%}.z-tabs-scrollbar .ng-scroll-content{box-sizing:border-box;padding-right:var(--z-tabs-scrollbar-gutter)}.z-tabs-scroll-container{isolation:isolate;--z-tabs-fade-width: 2rem}.z-tabs-fade-left{content:\"\";position:absolute;left:0;top:.0625rem;bottom:.0625rem;width:var(--z-tabs-fade-width);background:linear-gradient(to right,var(--background) 0%,oklch(from var(--background) l c h/.86) 28%,oklch(from var(--background) l c h/.48) 60%,oklch(from var(--background) l c h/0) 100%);pointer-events:none;z-index:5}.z-tabs-fade-right{content:\"\";position:absolute;right:0;top:.0625rem;bottom:.0625rem;width:var(--z-tabs-fade-width);background:linear-gradient(to left,var(--background) 0%,oklch(from var(--background) l c h/.86) 28%,oklch(from var(--background) l c h/.48) 60%,oklch(from var(--background) l c h/0) 100%);pointer-events:none;z-index:5}.z-tabs{align-items:stretch;min-height:2.5rem}.z-tabs.flex-col{width:100%}.z-tabs.flex-col.border-r{border-right:.0625rem solid hsl(var(--border));padding-right:.5rem}.z-tabs-nav-control{transition:color .2s ease,background-color .2s ease,border-color .2s ease}.z-tab-item{-webkit-tap-highlight-color:transparent;position:relative}.z-tab-item[data-active=true]{position:relative}.z-tab-item:disabled{pointer-events:none}.z-tabs-panels{border:.0625rem solid var(--border);border-radius:var(--radius-xs);padding:1rem}.z-tabs-panels [role=tabpanel]{animation:z-tabs-fade-in .2s ease-in-out}.z-tabs-panels [role=tabpanel][hidden]{display:none}.z-tabs-panels-unwrapped{border:0;border-radius:0;padding:0}.z-tabs-wrapper .z-tabs.flex-row+.z-tabs-panels{margin-top:.875rem}.z-tabs-wrapper .z-tabs.flex-col+.z-tabs-panels{margin-top:0;margin-left:0}.z-tabs-container[data-orientation=horizontal]{gap:0}.z-tabs-container[data-orientation=horizontal] .z-tabs-scroll-container{z-index:1}.z-tabs-container[data-orientation=horizontal] .z-tabs-panels{margin-top:0}.z-tabs-container[data-content-fit=screen]{height:var(--z-tabs-screen-height, calc(100dvh - var(--z-tabs-screen-offset, 0rem)));max-height:var(--z-tabs-screen-height, calc(100dvh - var(--z-tabs-screen-offset, 0rem)));min-height:0;overflow:hidden}.z-tabs-container[data-content-fit=screen] .z-tabs-nav{flex:none;min-height:0}.z-tabs-container[data-content-fit=screen] .z-tabs-panels{flex:1 1 auto;min-height:0;overflow:auto}.z-tabs-container[data-content-fit=screen] [role=tabpanel]{min-height:0}.z-tabs-container[data-type=line][data-orientation=horizontal] .z-tabs-nav{position:relative}.z-tabs-container[data-type=line][data-orientation=horizontal] .z-tabs-nav:after{content:\"\";position:absolute;right:0;bottom:0;left:0;height:.0625rem;background:color-mix(in oklab,var(--border) 80%,transparent);pointer-events:none;z-index:0}.z-tabs-container:is([data-type=outline],[data-type=soft],[data-type=segment],[data-type=folder],[data-type=folder-soft],[data-type=folder-solid],[data-type=underline],[data-type=underlined],[data-type=badge],[data-type=sharp],[data-type=sharp-line],[data-type=sharp-line-filled],[data-type=code-line])[data-orientation=horizontal] .z-tabs-scroll-wrapper{padding-inline:0}.z-tabs-container:is([data-type=outline],[data-type=soft],[data-type=segment],[data-type=folder],[data-type=folder-soft],[data-type=folder-solid],[data-type=underline],[data-type=underlined],[data-type=badge],[data-type=sharp],[data-type=sharp-line],[data-type=sharp-line-filled],[data-type=code-line])[data-orientation=horizontal] .z-tabs-panels{border-radius:0 0 var(--radius-xs) var(--radius-xs)}.z-tabs-container:is([data-type=outline],[data-type=soft],[data-type=segment],[data-type=folder],[data-type=folder-soft],[data-type=folder-solid],[data-type=underline],[data-type=underlined],[data-type=badge],[data-type=sharp],[data-type=sharp-line],[data-type=sharp-line-filled],[data-type=code-line])[data-orientation=horizontal] .z-tabs-panels-unwrapped{border:0;border-radius:0}.z-tabs-container:is([data-type=folder],[data-type=folder-soft],[data-type=folder-solid])[data-orientation=horizontal] .z-tabs-nav{position:relative}.z-tabs-container:is([data-type=folder],[data-type=folder-soft],[data-type=folder-solid])[data-orientation=horizontal] .z-tabs-nav:after{content:\"\";position:absolute;right:0;bottom:0;left:0;height:.0625rem;background:var(--border);pointer-events:none;z-index:0}.z-tabs-container:is([data-type=folder],[data-type=folder-soft],[data-type=folder-solid])[data-orientation=horizontal] .z-tabs-panels{border-top:0}.z-tabs-container[data-type=folder-solid][data-orientation=horizontal] .z-tab-item[data-active=true][data-last=true]{box-shadow:inset .0625rem 0 0 var(--primary),inset -.0625rem 0 0 var(--border),inset 0 .0625rem 0 var(--primary)}.z-tabs-container:is([data-type=segment],[data-type=segment-solid]) .z-tabs{align-items:center}.z-tabs-container[data-orientation=vertical] .z-tabs-nav{align-items:stretch}.z-tabs-container[data-orientation=vertical] .z-tabs-scroll-container{width:min(12rem,40vw);flex:none}.z-tabs-container[data-orientation=vertical] .z-tabs-panels,.z-tabs-container[data-orientation=vertical] .z-tab-item{min-width:0}@media(prefers-reduced-motion:reduce){.z-tab-item,.z-tabs-nav-control{transition:none!important}.z-tabs-scroll-wrapper{scroll-behavior:auto}.z-tabs-panels [role=tabpanel]{animation:none!important}}@keyframes z-tabs-fade-in{0%{opacity:0;transform:translateY(-.2rem)}to{opacity:1;transform:translateY(0)}}\n"] }]
500
+ }], ctorParameters: () => [], propDecorators: { tabPanels: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => ZTabPanelDirective), { isSignal: true }] }], tabsListContainer: [{ type: i0.ViewChild, args: ['tabsListContainer', { isSignal: true }] }], tabButtons: [{ type: i0.ViewChildren, args: ['tabButton', { isSignal: true }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], zTabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "zTabs", required: true }] }], zType: [{ type: i0.Input, args: [{ isSignal: true, alias: "zType", required: false }] }], zSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "zSize", required: false }] }], zOrientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "zOrientation", required: false }] }], zContentFit: [{ type: i0.Input, args: [{ isSignal: true, alias: "zContentFit", required: false }] }], zLazy: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLazy", required: false }] }], zDestroyInactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "zDestroyInactive", required: false }] }], zTabsOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "zTabsOnly", required: false }] }], zShowContentWrapper: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowContentWrapper", required: false }] }], zReloadable: [{ type: i0.Input, args: [{ isSignal: true, alias: "zReloadable", required: false }] }], zEmitOnActiveClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "zEmitOnActiveClick", required: false }] }], zCache: [{ type: i0.Input, args: [{ isSignal: true, alias: "zCache", required: false }] }], zCacheKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "zCacheKey", required: false }] }], activeTab: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeTab", required: false }] }, { type: i0.Output, args: ["activeTabChange"] }], zTabChange: [{ type: i0.Output, args: ["zTabChange"] }] } });
501
+
502
+ /**
503
+ * Generated bundle index. Do not edit.
504
+ */
505
+
506
+ export { ZTabPanelDirective, ZTabsComponent, zTabItemVariants, zTabsVariants };
507
+ //# sourceMappingURL=shival99-z-ui-components-z-tabs.mjs.map