@cute-widgets/base 20.0.1
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.
- package/CHANGELOG.md +1 -0
- package/LICENSE.md +191 -0
- package/README.md +190 -0
- package/abstract/index.d.ts +327 -0
- package/alert/index.d.ts +68 -0
- package/autocomplete/index.d.ts +442 -0
- package/badge/index.d.ts +26 -0
- package/bottom-sheet/index.d.ts +231 -0
- package/button/index.d.ts +182 -0
- package/button-toggle/index.d.ts +225 -0
- package/card/index.d.ts +163 -0
- package/checkbox/index.d.ts +174 -0
- package/chips/index.d.ts +963 -0
- package/collapse/index.d.ts +97 -0
- package/core/animation/index.d.ts +43 -0
- package/core/datetime/index.d.ts +404 -0
- package/core/directives/index.d.ts +168 -0
- package/core/error/index.d.ts +74 -0
- package/core/index.d.ts +1039 -0
- package/core/interfaces/index.d.ts +114 -0
- package/core/layout/index.d.ts +53 -0
- package/core/line/index.d.ts +37 -0
- package/core/nav/index.d.ts +321 -0
- package/core/observers/index.d.ts +124 -0
- package/core/option/index.d.ts +185 -0
- package/core/pipes/index.d.ts +53 -0
- package/core/ripple/index.d.ts +66 -0
- package/core/testing/index.d.ts +154 -0
- package/core/theming/index.d.ts +118 -0
- package/core/types/index.d.ts +53 -0
- package/core/utils/index.d.ts +129 -0
- package/cute-widgets-base-20.0.1.tgz +0 -0
- package/datepicker/index.d.ts +1817 -0
- package/dialog/index.d.ts +484 -0
- package/divider/index.d.ts +24 -0
- package/expansion/README.md +8 -0
- package/expansion/index.d.ts +308 -0
- package/fesm2022/cute-widgets-base-abstract.mjs +547 -0
- package/fesm2022/cute-widgets-base-abstract.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-alert.mjs +198 -0
- package/fesm2022/cute-widgets-base-alert.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-autocomplete.mjs +1217 -0
- package/fesm2022/cute-widgets-base-autocomplete.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-badge.mjs +75 -0
- package/fesm2022/cute-widgets-base-badge.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-bottom-sheet.mjs +416 -0
- package/fesm2022/cute-widgets-base-bottom-sheet.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-button-toggle.mjs +640 -0
- package/fesm2022/cute-widgets-base-button-toggle.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-button.mjs +546 -0
- package/fesm2022/cute-widgets-base-button.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-card.mjs +471 -0
- package/fesm2022/cute-widgets-base-card.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-checkbox.mjs +390 -0
- package/fesm2022/cute-widgets-base-checkbox.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-chips.mjs +2360 -0
- package/fesm2022/cute-widgets-base-chips.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-collapse.mjs +259 -0
- package/fesm2022/cute-widgets-base-collapse.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-animation.mjs +53 -0
- package/fesm2022/cute-widgets-base-core-animation.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-datetime.mjs +568 -0
- package/fesm2022/cute-widgets-base-core-datetime.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-directives.mjs +404 -0
- package/fesm2022/cute-widgets-base-core-directives.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-error.mjs +105 -0
- package/fesm2022/cute-widgets-base-core-error.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-interfaces.mjs +22 -0
- package/fesm2022/cute-widgets-base-core-interfaces.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-layout.mjs +74 -0
- package/fesm2022/cute-widgets-base-core-layout.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-line.mjs +87 -0
- package/fesm2022/cute-widgets-base-core-line.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-nav.mjs +863 -0
- package/fesm2022/cute-widgets-base-core-nav.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-observers.mjs +304 -0
- package/fesm2022/cute-widgets-base-core-observers.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-option.mjs +373 -0
- package/fesm2022/cute-widgets-base-core-option.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-pipes.mjs +97 -0
- package/fesm2022/cute-widgets-base-core-pipes.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-ripple.mjs +172 -0
- package/fesm2022/cute-widgets-base-core-ripple.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-testing.mjs +210 -0
- package/fesm2022/cute-widgets-base-core-testing.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-theming.mjs +314 -0
- package/fesm2022/cute-widgets-base-core-theming.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-types.mjs +22 -0
- package/fesm2022/cute-widgets-base-core-types.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core-utils.mjs +257 -0
- package/fesm2022/cute-widgets-base-core-utils.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-core.mjs +1600 -0
- package/fesm2022/cute-widgets-base-core.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-datepicker.mjs +4827 -0
- package/fesm2022/cute-widgets-base-datepicker.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-dialog.mjs +1046 -0
- package/fesm2022/cute-widgets-base-dialog.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-divider.mjs +86 -0
- package/fesm2022/cute-widgets-base-divider.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-expansion.mjs +623 -0
- package/fesm2022/cute-widgets-base-expansion.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-form-field.mjs +969 -0
- package/fesm2022/cute-widgets-base-form-field.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-grid-list.mjs +715 -0
- package/fesm2022/cute-widgets-base-grid-list.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-icon.mjs +1105 -0
- package/fesm2022/cute-widgets-base-icon.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-input.mjs +726 -0
- package/fesm2022/cute-widgets-base-input.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-layout-container.mjs +95 -0
- package/fesm2022/cute-widgets-base-layout-container.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-layout-stack.mjs +166 -0
- package/fesm2022/cute-widgets-base-layout-stack.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-layout.mjs +250 -0
- package/fesm2022/cute-widgets-base-layout.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-list.mjs +1557 -0
- package/fesm2022/cute-widgets-base-list.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-menu.mjs +1283 -0
- package/fesm2022/cute-widgets-base-menu.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-navbar.mjs +359 -0
- package/fesm2022/cute-widgets-base-navbar.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-paginator.mjs +485 -0
- package/fesm2022/cute-widgets-base-paginator.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-progress.mjs +321 -0
- package/fesm2022/cute-widgets-base-progress.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-radio.mjs +637 -0
- package/fesm2022/cute-widgets-base-radio.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-select.mjs +1208 -0
- package/fesm2022/cute-widgets-base-select.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-sidenav.mjs +1095 -0
- package/fesm2022/cute-widgets-base-sidenav.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-slider.mjs +99 -0
- package/fesm2022/cute-widgets-base-slider.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-snack-bar.mjs +897 -0
- package/fesm2022/cute-widgets-base-snack-bar.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-sort.mjs +639 -0
- package/fesm2022/cute-widgets-base-sort.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-spinner.mjs +154 -0
- package/fesm2022/cute-widgets-base-spinner.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-stepper.mjs +673 -0
- package/fesm2022/cute-widgets-base-stepper.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-table.mjs +1023 -0
- package/fesm2022/cute-widgets-base-table.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-tabs.mjs +729 -0
- package/fesm2022/cute-widgets-base-tabs.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-timepicker.mjs +965 -0
- package/fesm2022/cute-widgets-base-timepicker.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-toolbar.mjs +120 -0
- package/fesm2022/cute-widgets-base-toolbar.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-tooltip.mjs +947 -0
- package/fesm2022/cute-widgets-base-tooltip.mjs.map +1 -0
- package/fesm2022/cute-widgets-base-tree.mjs +598 -0
- package/fesm2022/cute-widgets-base-tree.mjs.map +1 -0
- package/fesm2022/cute-widgets-base.mjs +68 -0
- package/fesm2022/cute-widgets-base.mjs.map +1 -0
- package/form-field/index.d.ts +401 -0
- package/grid-list/index.d.ts +361 -0
- package/icon/index.d.ts +477 -0
- package/index.d.ts +3 -0
- package/input/index.d.ts +256 -0
- package/layout/container/index.d.ts +31 -0
- package/layout/index.d.ts +78 -0
- package/layout/stack/index.d.ts +52 -0
- package/list/index.d.ts +659 -0
- package/menu/index.d.ts +497 -0
- package/navbar/index.d.ts +91 -0
- package/package.json +279 -0
- package/paginator/index.d.ts +216 -0
- package/progress/index.d.ts +130 -0
- package/radio/index.d.ts +259 -0
- package/select/index.d.ts +426 -0
- package/sidenav/index.d.ts +369 -0
- package/slider/index.d.ts +48 -0
- package/snack-bar/index.d.ts +374 -0
- package/sort/index.d.ts +334 -0
- package/spinner/index.d.ts +70 -0
- package/stepper/index.d.ts +295 -0
- package/table/index.d.ts +395 -0
- package/tabs/index.d.ts +307 -0
- package/timepicker/index.d.ts +350 -0
- package/toolbar/index.d.ts +36 -0
- package/tooltip/index.d.ts +299 -0
- package/tree/index.d.ts +314 -0
|
@@ -0,0 +1,729 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, Directive, TemplateRef, DestroyRef, EventEmitter, ViewContainerRef, forwardRef, booleanAttribute, numberAttribute, Output, Input, ViewChild, ViewChildren, ContentChildren, ViewEncapsulation, ChangeDetectionStrategy, Component, signal, ContentChild, NgModule } from '@angular/core';
|
|
3
|
+
import { animation, state, animate, style, trigger, transition } from '@angular/animations';
|
|
4
|
+
import { NgTemplateOutlet, CommonModule } from '@angular/common';
|
|
5
|
+
import { CuteLayoutControl, CuteFocusableControl } from '@cute-widgets/base/abstract';
|
|
6
|
+
import { fromEvent, debounceTime, Subject } from 'rxjs';
|
|
7
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
8
|
+
import { moveItemInArray, CdkDropList, CdkDrag } from '@angular/cdk/drag-drop';
|
|
9
|
+
import * as i1 from '@cute-widgets/base/core/nav';
|
|
10
|
+
import { CuteNavModule, CuteNavLink } from '@cute-widgets/base/core/nav';
|
|
11
|
+
import { CuteButton } from '@cute-widgets/base/button';
|
|
12
|
+
import { CuteObserveVisibility } from '@cute-widgets/base/core/observers';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @license Apache-2.0
|
|
16
|
+
*
|
|
17
|
+
* Copyright (c) 2025 CuteWidgets Team. All Rights Reserved.
|
|
18
|
+
*
|
|
19
|
+
* You may not use this file except in compliance with the License
|
|
20
|
+
* that can be found at http://www.apache.org/licenses/LICENSE-2.0
|
|
21
|
+
*
|
|
22
|
+
* This code is a modification of the `@angular/material` original
|
|
23
|
+
* code licensed under MIT-style License (https://angular.dev/license).
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Injection token that can be used to reference instances of `CuteTabLabel`. It serves as
|
|
27
|
+
* alternative token to the actual `CuteTabLabel` class which could cause unnecessary
|
|
28
|
+
* retention of the class and its directive metadata.
|
|
29
|
+
*/
|
|
30
|
+
const CUTE_TAB_LABEL = new InjectionToken('CuteTabLabel');
|
|
31
|
+
/** Used to flag tab labels for use with the portal directive */
|
|
32
|
+
class CuteTabLabel {
|
|
33
|
+
constructor() {
|
|
34
|
+
this._closestTab = inject(CUTE_TAB, { optional: true });
|
|
35
|
+
}
|
|
36
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CuteTabLabel, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
37
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: CuteTabLabel, isStandalone: true, selector: "ng-template[cute-tab-label], ng-template[cuteTabLabel]", providers: [{ provide: CUTE_TAB_LABEL, useExisting: CuteTabLabel }], exportAs: ["cuteTabLabel"], ngImport: i0 }); }
|
|
38
|
+
}
|
|
39
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CuteTabLabel, decorators: [{
|
|
40
|
+
type: Directive,
|
|
41
|
+
args: [{
|
|
42
|
+
selector: 'ng-template[cute-tab-label], ng-template[cuteTabLabel]',
|
|
43
|
+
exportAs: 'cuteTabLabel',
|
|
44
|
+
providers: [{ provide: CUTE_TAB_LABEL, useExisting: CuteTabLabel }],
|
|
45
|
+
}]
|
|
46
|
+
}] });
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @license Apache-2.0
|
|
50
|
+
*
|
|
51
|
+
* Copyright (c) 2025 CuteWidgets Team. All Rights Reserved.
|
|
52
|
+
*
|
|
53
|
+
* You may not use this file except in compliance with the License
|
|
54
|
+
* that can be found at http://www.apache.org/licenses/LICENSE-2.0
|
|
55
|
+
*
|
|
56
|
+
* This code is a modification of the `@angular/material` original
|
|
57
|
+
* code licensed under MIT-style License (https://angular.dev/license).
|
|
58
|
+
*/
|
|
59
|
+
/**
|
|
60
|
+
* Injection token that can be used to reference instances of `CuteTabContent`. It serves as
|
|
61
|
+
* alternative token to the actual `CuteTabContent` class which could cause unnecessary
|
|
62
|
+
* retention of the class and its directive metadata.
|
|
63
|
+
*/
|
|
64
|
+
const CUTE_TAB_CONTENT = new InjectionToken('CuteTabContent');
|
|
65
|
+
/** Decorates the `ng-template` tags and reads out the template from it. */
|
|
66
|
+
class CuteTabContent {
|
|
67
|
+
constructor() {
|
|
68
|
+
this.template = inject(TemplateRef);
|
|
69
|
+
}
|
|
70
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CuteTabContent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
71
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: CuteTabContent, isStandalone: true, selector: "ng-template[cute-tab-content], ng-template[cuteTabContent]", providers: [{ provide: CUTE_TAB_CONTENT, useExisting: CuteTabContent }], ngImport: i0 }); }
|
|
72
|
+
}
|
|
73
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CuteTabContent, decorators: [{
|
|
74
|
+
type: Directive,
|
|
75
|
+
args: [{
|
|
76
|
+
selector: 'ng-template[cute-tab-content], ng-template[cuteTabContent]',
|
|
77
|
+
providers: [{ provide: CUTE_TAB_CONTENT, useExisting: CuteTabContent }],
|
|
78
|
+
}]
|
|
79
|
+
}] });
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @license Apache-2.0
|
|
83
|
+
*
|
|
84
|
+
* Copyright (c) 2025 CuteWidgets Team. All Rights Reserved.
|
|
85
|
+
*
|
|
86
|
+
* You may not use this file except in compliance with the License
|
|
87
|
+
* that can be found at http://www.apache.org/licenses/LICENSE-2.0
|
|
88
|
+
*
|
|
89
|
+
* This code is a modification of the `@angular/material` original
|
|
90
|
+
* code licensed under MIT-style License (https://angular.dev/license).
|
|
91
|
+
*/
|
|
92
|
+
const transitionAnimation = animation([
|
|
93
|
+
state('void', style({ transform: 'translateX({{offset}})', opacity: 0 })),
|
|
94
|
+
animate('300ms ease-out', style({ transform: 'translateX(0)', opacity: 1 })),
|
|
95
|
+
], { params: { offset: '30px' } });
|
|
96
|
+
let nextId$1 = 0;
|
|
97
|
+
/**
|
|
98
|
+
* Used to provide a tab group to a tab without causing a circular dependency.
|
|
99
|
+
*/
|
|
100
|
+
const CUTE_TAB_GROUP = new InjectionToken('CUTE_TAB_GROUP');
|
|
101
|
+
/** Cancelable event emitted when the `cute-tab` selection is about to change. */
|
|
102
|
+
class CuteTabChangingEvent extends Event {
|
|
103
|
+
constructor(
|
|
104
|
+
/** Index of the currently-selected tab. */
|
|
105
|
+
index,
|
|
106
|
+
/** Reference to the currently-selected tab. */
|
|
107
|
+
tab,
|
|
108
|
+
/** Index of the previously-selected tab. */
|
|
109
|
+
fromIndex,
|
|
110
|
+
/** Reference to the previously-selected tab. */
|
|
111
|
+
fromTab,
|
|
112
|
+
/** How the tab was focused. */
|
|
113
|
+
origin) {
|
|
114
|
+
super("tabChanging", { cancelable: true });
|
|
115
|
+
this.index = index;
|
|
116
|
+
this.tab = tab;
|
|
117
|
+
this.fromIndex = fromIndex;
|
|
118
|
+
this.fromTab = fromTab;
|
|
119
|
+
this.origin = origin;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/** A simple change event emitted on focus or selection changes. */
|
|
123
|
+
class CuteTabChangeEvent extends Event {
|
|
124
|
+
constructor(
|
|
125
|
+
/** Index of the currently-selected tab. */
|
|
126
|
+
index,
|
|
127
|
+
/** Reference to the currently-selected tab. */
|
|
128
|
+
tab,
|
|
129
|
+
/** Index of the previously-selected tab. */
|
|
130
|
+
fromIndex,
|
|
131
|
+
/** Reference to the previously-selected tab. */
|
|
132
|
+
fromTab,
|
|
133
|
+
/** How the tab was focused. */
|
|
134
|
+
origin) {
|
|
135
|
+
super("tabChange");
|
|
136
|
+
this.index = index;
|
|
137
|
+
this.tab = tab;
|
|
138
|
+
this.fromIndex = fromIndex;
|
|
139
|
+
this.fromTab = fromTab;
|
|
140
|
+
this.origin = origin;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* A flexible, feature-rich tab component for Angular applications with Bootstrap integration.
|
|
145
|
+
*/
|
|
146
|
+
class CuteTabGroup extends CuteLayoutControl {
|
|
147
|
+
/** The index of the active tab. */
|
|
148
|
+
get selectedIndex() { return this._selectedIndex; }
|
|
149
|
+
set selectedIndex(value) {
|
|
150
|
+
if (value !== this._selectedIndex) {
|
|
151
|
+
this._indexToChange = value;
|
|
152
|
+
Promise.resolve().then(() => this.selectTab(value));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* The style a `cute-tab`’s content extends the full available width, proportionately (**fill**) or equal-width (**justified**).
|
|
157
|
+
* The width is determined by the longest `cute-tab-label`'s content. By default, stretching of items is not used (**none**).
|
|
158
|
+
*/
|
|
159
|
+
get stretchTabs() { return this._stretchTabs; }
|
|
160
|
+
set stretchTabs(value) {
|
|
161
|
+
if (value) {
|
|
162
|
+
if (typeof value === "boolean" || value === "true" || value === "false") {
|
|
163
|
+
this._stretchTabs = Boolean(value) ? "justified" : "none";
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
this._stretchTabs = value;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
this._stretchTabs = "none";
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
constructor() {
|
|
174
|
+
super();
|
|
175
|
+
this._indexToChange = null;
|
|
176
|
+
this.showScrollButtons = false;
|
|
177
|
+
this.canScrollLeft = false;
|
|
178
|
+
this.canScrollRight = false;
|
|
179
|
+
/** Number of pixels to scroll left or right */
|
|
180
|
+
this.scrollAmount = 200;
|
|
181
|
+
this.dynamicTabs = [];
|
|
182
|
+
this.destroyRef = inject(DestroyRef);
|
|
183
|
+
/**
|
|
184
|
+
* Alignment for tabs.
|
|
185
|
+
* @default start
|
|
186
|
+
*/
|
|
187
|
+
this.alignTabs = "start";
|
|
188
|
+
this._stretchTabs = "none";
|
|
189
|
+
/** Whether the tab group will change its height to the height of the currently active tab. */
|
|
190
|
+
this.dynamicHeight = false;
|
|
191
|
+
/**
|
|
192
|
+
* Possible positions for the tab header.
|
|
193
|
+
* @default top
|
|
194
|
+
*/
|
|
195
|
+
this.headerPosition = 'top';
|
|
196
|
+
/** Use `underline` style for horizontal tabs. */
|
|
197
|
+
this.underlineTabs = false;
|
|
198
|
+
/**
|
|
199
|
+
* Whether tabs can be draggable.
|
|
200
|
+
* @default false
|
|
201
|
+
*/
|
|
202
|
+
this.dragEnabled = false;
|
|
203
|
+
/**
|
|
204
|
+
* Defines the horizontal alignment when scrolling the tabs.
|
|
205
|
+
* @default center
|
|
206
|
+
*/
|
|
207
|
+
this.tabScrollingAlignment = "center";
|
|
208
|
+
/** Output to enable support for two-way binding on `[(selectedIndex)]` */
|
|
209
|
+
this.selectedIndexChange = new EventEmitter();
|
|
210
|
+
/** Event emitted when the active tab selection is about to change. */
|
|
211
|
+
this.selectedTabChanging = new EventEmitter();
|
|
212
|
+
/** Event emitted when the tab selection has changed. */
|
|
213
|
+
this.selectedTabChange = new EventEmitter();
|
|
214
|
+
/** Event emitted when focus has changed within a tab group. */
|
|
215
|
+
this.focusChange = new EventEmitter();
|
|
216
|
+
/** Event emitted after the new tab was added. */
|
|
217
|
+
this.tabAdded = new EventEmitter();
|
|
218
|
+
/** Event emitted after the closable tab was removed. */
|
|
219
|
+
this.tabRemoved = new EventEmitter();
|
|
220
|
+
}
|
|
221
|
+
/** Whether the tab group currently has a horizontal layout */
|
|
222
|
+
get isHorizontal() {
|
|
223
|
+
return this.headerPosition === 'top' || this.headerPosition === 'bottom';
|
|
224
|
+
}
|
|
225
|
+
/** The active tab. */
|
|
226
|
+
get selectedTab() {
|
|
227
|
+
return this.tabs?.get(this.selectedIndex ?? NaN);
|
|
228
|
+
}
|
|
229
|
+
/** The number of tabs in the tab group. */
|
|
230
|
+
get tabCount() {
|
|
231
|
+
return this.tabs?.length || 0;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Returns the first element in the array of tabs that satisfies the provided testing function.
|
|
235
|
+
* Otherwise, _undefined_ is returned.
|
|
236
|
+
* @param predicate Testing function
|
|
237
|
+
* @returns `CuteTab` object or _undefined_ if there are no tabs with the specified condition.
|
|
238
|
+
*/
|
|
239
|
+
findTab(predicate) {
|
|
240
|
+
return this.tabs?.find(predicate);
|
|
241
|
+
}
|
|
242
|
+
generateId() {
|
|
243
|
+
return `cute-tab-group-${nextId$1++}`;
|
|
244
|
+
}
|
|
245
|
+
checkScrollButtons() {
|
|
246
|
+
const el = this.headerScroll.nativeElement;
|
|
247
|
+
this.showScrollButtons = el.scrollWidth > el.clientWidth;
|
|
248
|
+
this.canScrollLeft = el.scrollLeft > 0;
|
|
249
|
+
this.canScrollRight = el.scrollLeft < el.scrollWidth - el.clientWidth - 1;
|
|
250
|
+
//this._changeDetectorRef.detectChanges();
|
|
251
|
+
this.markForCheck();
|
|
252
|
+
}
|
|
253
|
+
setupScrollListener() {
|
|
254
|
+
fromEvent(this.headerScroll.nativeElement, 'scroll')
|
|
255
|
+
.pipe(debounceTime(100), takeUntilDestroyed(this.destroyRef))
|
|
256
|
+
.subscribe(() => this.checkScrollButtons());
|
|
257
|
+
this._resizeObserver = new ResizeObserver(() => {
|
|
258
|
+
this.checkScrollButtons();
|
|
259
|
+
//setTimeout(()=>this.scrollToTab( this.selectedIndex ));
|
|
260
|
+
});
|
|
261
|
+
this._resizeObserver.observe(this.headerContainer.nativeElement);
|
|
262
|
+
}
|
|
263
|
+
scrollHeader(direction) {
|
|
264
|
+
const el = this.headerScroll.nativeElement;
|
|
265
|
+
clearTimeout(this._scrollDebounce);
|
|
266
|
+
el.scrollBy({
|
|
267
|
+
left: direction * this.scrollAmount,
|
|
268
|
+
behavior: 'smooth'
|
|
269
|
+
});
|
|
270
|
+
this._scrollDebounce = setTimeout(() => {
|
|
271
|
+
this.checkScrollButtons();
|
|
272
|
+
}, 300);
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Activates tab with specified index.
|
|
276
|
+
* @param index Tab index
|
|
277
|
+
* @param origin (optional) Focus origin
|
|
278
|
+
*/
|
|
279
|
+
selectTab(index, origin = "program") {
|
|
280
|
+
if (!this.tabs)
|
|
281
|
+
return;
|
|
282
|
+
if (index < 0 || index >= this.tabs.length)
|
|
283
|
+
return;
|
|
284
|
+
if (index === this.selectedIndex)
|
|
285
|
+
return;
|
|
286
|
+
const tabsArray = this.tabs.toArray();
|
|
287
|
+
if (tabsArray[index].disabled)
|
|
288
|
+
return;
|
|
289
|
+
this._indexToChange = null;
|
|
290
|
+
this._selectedIndex = index;
|
|
291
|
+
this.tabs.forEach((tab, i) => {
|
|
292
|
+
tab.active = (i === index);
|
|
293
|
+
});
|
|
294
|
+
setTimeout(() => {
|
|
295
|
+
if (tabsArray[index].scrollNeeded) {
|
|
296
|
+
this.scrollToTab(index);
|
|
297
|
+
}
|
|
298
|
+
}, 100);
|
|
299
|
+
this.selectedIndexChange.emit(index);
|
|
300
|
+
this.markForCheck();
|
|
301
|
+
}
|
|
302
|
+
_createChangeEvent(event) {
|
|
303
|
+
const tabsArray = this.tabs?.toArray() ?? [];
|
|
304
|
+
return new CuteTabChangeEvent(event.index, tabsArray[event.index], event.fromIndex, event.fromIndex ? tabsArray[event.fromIndex] : null, event.origin);
|
|
305
|
+
}
|
|
306
|
+
_createChangingEvent(event) {
|
|
307
|
+
const tabsArray = this.tabs?.toArray() ?? [];
|
|
308
|
+
return new CuteTabChangeEvent(event.index, tabsArray[event.index], event.fromIndex, event.fromIndex ? tabsArray[event.fromIndex] : null, event.origin);
|
|
309
|
+
}
|
|
310
|
+
onNavFocusChange(event) {
|
|
311
|
+
this.focusChange.emit(this._createChangeEvent(event));
|
|
312
|
+
}
|
|
313
|
+
onNavLinkChange(event) {
|
|
314
|
+
this.selectedTabChange.emit(this._createChangeEvent(event));
|
|
315
|
+
}
|
|
316
|
+
onNavLinkChanging(event) {
|
|
317
|
+
const ev = this._createChangingEvent(event);
|
|
318
|
+
this.selectedTabChanging.emit(ev);
|
|
319
|
+
if (ev.defaultPrevented) {
|
|
320
|
+
event.preventDefault();
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
getLabelContext(tab, index) {
|
|
324
|
+
return { ...tab.getContentContext(), index };
|
|
325
|
+
}
|
|
326
|
+
/** Gets the current index of the specified tab object. */
|
|
327
|
+
getTabIndex(tab) {
|
|
328
|
+
return this.tabs?.toArray().indexOf(tab);
|
|
329
|
+
}
|
|
330
|
+
scrollToTab(index) {
|
|
331
|
+
if (index != null) {
|
|
332
|
+
const tabElement = this.tabLinks?.toArray()[index]?.element.nativeElement;
|
|
333
|
+
if (tabElement) {
|
|
334
|
+
tabElement.scrollIntoView({
|
|
335
|
+
behavior: 'smooth',
|
|
336
|
+
block: 'nearest',
|
|
337
|
+
inline: this.tabScrollingAlignment
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
/** Drop event */
|
|
343
|
+
onDrop(event) {
|
|
344
|
+
if (event.previousIndex === event.currentIndex)
|
|
345
|
+
return;
|
|
346
|
+
if (!this.tabs)
|
|
347
|
+
return;
|
|
348
|
+
const tabsArray = this.tabs.toArray();
|
|
349
|
+
moveItemInArray(tabsArray, event.previousIndex, event.currentIndex);
|
|
350
|
+
// Refresh QueryList
|
|
351
|
+
this.tabs.reset(tabsArray);
|
|
352
|
+
this._adjustActiveIndex(event.previousIndex, event.currentIndex);
|
|
353
|
+
this.tabs.notifyOnChanges();
|
|
354
|
+
}
|
|
355
|
+
/** Sets a new active index after the dragging tabs */
|
|
356
|
+
_adjustActiveIndex(prevIndex, newIndex) {
|
|
357
|
+
if (this.selectedIndex === prevIndex) {
|
|
358
|
+
this.selectedIndex = newIndex;
|
|
359
|
+
}
|
|
360
|
+
else if (this.selectedIndex !== undefined) {
|
|
361
|
+
const min = Math.min(prevIndex, newIndex);
|
|
362
|
+
const max = Math.max(prevIndex, newIndex);
|
|
363
|
+
if (this.selectedIndex >= min && this.selectedIndex <= max) {
|
|
364
|
+
this.selectedIndex += (prevIndex < newIndex ? -1 : 1);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Adds a new tab to the end of `tab-group` dynamically.
|
|
370
|
+
*
|
|
371
|
+
* @param label Tab label
|
|
372
|
+
* @param content Tab template reference
|
|
373
|
+
* @param context (optional) Template context object
|
|
374
|
+
* @param closable (optional) Whether the tab is closable. Default is _true_.
|
|
375
|
+
* @returns `ComponentRef` object of the new Tab.
|
|
376
|
+
*/
|
|
377
|
+
async addTab(label, content, context, closable) {
|
|
378
|
+
const componentRef = this.dynamicTabsContainer.createComponent(CuteTab);
|
|
379
|
+
const newTab = componentRef.instance;
|
|
380
|
+
newTab.textLabel = label || `Tab ${(this.tabs?.length ?? 0) + 1}`;
|
|
381
|
+
newTab.contentTemplate = content;
|
|
382
|
+
newTab.contentContext = context;
|
|
383
|
+
newTab.active = true; // !this.tabs || this.tabs.length === 0;
|
|
384
|
+
newTab.isDynamic = true;
|
|
385
|
+
//componentRef.setInput("closable", true);
|
|
386
|
+
newTab.closable = closable ?? true;
|
|
387
|
+
componentRef.changeDetectorRef.detectChanges();
|
|
388
|
+
this.dynamicTabs.push(componentRef);
|
|
389
|
+
const tabsArray = this.tabs?.toArray() || [];
|
|
390
|
+
tabsArray.push(newTab);
|
|
391
|
+
this.tabs?.reset(tabsArray);
|
|
392
|
+
this.tabAdded.emit();
|
|
393
|
+
if (newTab.active) {
|
|
394
|
+
this.selectTab(tabsArray.length - 1);
|
|
395
|
+
}
|
|
396
|
+
return componentRef;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Removes the tab with specified index.
|
|
400
|
+
* @param index Tab index
|
|
401
|
+
*/
|
|
402
|
+
async removeTab(index) {
|
|
403
|
+
if (!this.tabs)
|
|
404
|
+
return;
|
|
405
|
+
if (index < 0 || index >= this.tabs.length)
|
|
406
|
+
return;
|
|
407
|
+
const tab = this.tabs.get(index);
|
|
408
|
+
const wasActive = tab.active;
|
|
409
|
+
const dynIndex = this.dynamicTabs.findIndex(cref => cref.instance == tab);
|
|
410
|
+
if (dynIndex >= 0) {
|
|
411
|
+
this.dynamicTabsContainer?.remove(dynIndex);
|
|
412
|
+
this.dynamicTabs.splice(dynIndex, 1);
|
|
413
|
+
}
|
|
414
|
+
const tabsArray = this.tabs.filter((_, i) => i !== index);
|
|
415
|
+
this.tabs.reset(tabsArray);
|
|
416
|
+
this.tabs.notifyOnChanges();
|
|
417
|
+
this.tabRemoved.emit(index);
|
|
418
|
+
if (wasActive && this.tabs.length > 0) {
|
|
419
|
+
const newIndex = Math.min(index, this.tabs.length - 1);
|
|
420
|
+
if (newIndex == index) {
|
|
421
|
+
// To bypass verification
|
|
422
|
+
this._selectedIndex = undefined;
|
|
423
|
+
}
|
|
424
|
+
this.selectedIndex = newIndex;
|
|
425
|
+
this.tabs.get(newIndex)?.link?.focus();
|
|
426
|
+
}
|
|
427
|
+
//this.markForCheck();
|
|
428
|
+
}
|
|
429
|
+
ngAfterViewInit() {
|
|
430
|
+
super.ngAfterViewInit();
|
|
431
|
+
this.checkScrollButtons();
|
|
432
|
+
this.setupScrollListener();
|
|
433
|
+
}
|
|
434
|
+
ngAfterContentInit() {
|
|
435
|
+
super.ngAfterContentInit();
|
|
436
|
+
if (this.tabs) {
|
|
437
|
+
const tabsArray = this.tabs.toArray();
|
|
438
|
+
if (this._indexToChange == null) {
|
|
439
|
+
this.selectedIndex = Math.max(tabsArray.findIndex(t => !t.disabled), 0);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
ngOnDestroy() {
|
|
444
|
+
super.ngOnDestroy();
|
|
445
|
+
this._resizeObserver?.disconnect();
|
|
446
|
+
}
|
|
447
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CuteTabGroup, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
448
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: CuteTabGroup, isStandalone: true, selector: "cute-tab-group", inputs: { selectedIndex: ["selectedIndex", "selectedIndex", numberAttribute], alignTabs: ["cute-align-tabs", "alignTabs"], stretchTabs: ["cute-stretch-tabs", "stretchTabs"], preserveContent: ["preserveContent", "preserveContent", booleanAttribute], dynamicHeight: ["dynamicHeight", "dynamicHeight", booleanAttribute], headerPosition: "headerPosition", underlineTabs: ["underlineTabs", "underlineTabs", booleanAttribute], dragEnabled: ["dragEnabled", "dragEnabled", booleanAttribute], tabScrollingAlignment: "tabScrollingAlignment" }, outputs: { selectedIndexChange: "selectedIndexChange", selectedTabChanging: "selectedTabChanging", selectedTabChange: "selectedTabChange", focusChange: "focusChange", tabAdded: "tabAdded", tabRemoved: "tabRemoved" }, host: { properties: { "class.tabs-top": "headerPosition === 'top'", "class.tabs-bottom": "headerPosition === 'bottom'", "class.tabs-left": "headerPosition === 'left'", "class.tabs-right": "headerPosition === 'right'", "class.tabs-end": "headerPosition === 'end'", "class.tabs-start": "headerPosition === 'start'" }, classAttribute: "cute-tab-group" }, providers: [
|
|
449
|
+
{ provide: CUTE_TAB_GROUP, useExisting: forwardRef(() => CuteTabGroup) },
|
|
450
|
+
], queries: [{ propertyName: "tabs", predicate: CuteTab }], viewQueries: [{ propertyName: "dynamicTabsContainer", first: true, predicate: ["dynamicTabs"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "headerContainer", first: true, predicate: ["headerContainer"], descendants: true, static: true }, { propertyName: "headerScroll", first: true, predicate: ["headerScroll"], descendants: true, static: true }, { propertyName: "tabLinks", predicate: ["tabLink"], descendants: true, read: CuteNavLink }], exportAs: ["cuteTabGroup"], usesInheritance: true, ngImport: i0, template: "<div class=\"tab-header-wrapper\" #headerContainer>\r\n <div class=\"tab-header-scroll\" #headerScroll\r\n cdkDropList\r\n [cdkDropListOrientation]=\"isHorizontal ? 'horizontal' : 'vertical'\"\r\n (cdkDropListDropped)=\"onDrop($event)\">\r\n <nav [cuteNav]=\"isHorizontal ? (underlineTabs ? 'underline' : 'tabs') : 'pills'\"\r\n [selectedIndex]=\"selectedIndex\"\r\n [alignment]=\"alignTabs\"\r\n [stretchItems]=\"stretchTabs\"\r\n [preserveTabContent]=\"preserveContent\"\r\n [color]=\"color\"\r\n [class.flex-column]=\"!isHorizontal\"\r\n (selectedIndexChange)=\"selectTab($event)\"\r\n (selectedLinkChanging)=\"onNavLinkChanging($event)\"\r\n (selectedLinkChange)=\"onNavLinkChange($event)\"\r\n (focusChange)=\"onNavFocusChange($event)\">\r\n @for (tab of tabs; track tab.id; let i = $index) {\r\n <li cute-nav-item\r\n cdkDrag\r\n [cdkDragDisabled]=\"!dragEnabled || tabCount <= 1\"\r\n [cdkDragData]=\"tab\">\r\n <a href=\"#\" cute-nav-link\r\n [cuteObserveVisibility]=\"1\"\r\n [cuteObserveVisibilityRoot]=\"headerScroll\"\r\n (cuteObserveVisibility)=\"tab._visibilityChanged($event)\"\r\n [active]=\"tab.active\"\r\n [disabled]=\"tab.disabled\"\r\n [id]=\"tab.ariaLabelledby || undefined\"\r\n [attr.aria-disabled]=\"tab.disabled\"\r\n [attr.aria-controls]=\"tab.id\"\r\n [attr.tabindex]=\"tab.active && !tab.disabled ? 0 : -1\"\r\n role=\"tab\"\r\n #tabLink>\r\n\r\n @if (tab._templateLabel) {\r\n <ng-container\r\n *ngTemplateOutlet=\"tab._templateLabel; context: getLabelContext(tab, i)\">\r\n </ng-container>\r\n } @else {\r\n <!-- <ng-container>-->\r\n <!-- @if (dragEnabled && tabCount > 1) {-->\r\n <!-- <span cdkDragHandle>\u2630</span>-->\r\n <!-- }-->\r\n {{ tab.textLabel || 'Tab '+i }}\r\n <!-- </ng-container>-->\r\n }\r\n\r\n @if (tab.closable && tab.isDynamic) {\r\n <button cuteButton=\"close-button\"\r\n magnitude=\"smallest\"\r\n tabIndex=\"-1\"\r\n (click)=\"removeTab(i); $event.preventDefault();\"\r\n aria-label=\"Close tab\">\r\n </button>\r\n }\r\n\r\n </a>\r\n </li>\r\n }\r\n </nav>\r\n\r\n </div>\r\n\r\n @if (showScrollButtons) {\r\n <button cuteButton class=\"scroll-button left\"\r\n tabindex=\"-1\"\r\n magnitude=\"smallest\"\r\n visuallyHiddenLabel=\"Prev\"\r\n aria-hidden=\"true\"\r\n (click)=\"scrollHeader(-1)\"\r\n [disabled]=\"!canScrollLeft\">\r\n <!--\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"currentColor\" class=\"bi bi-chevron-left\" viewBox=\"0 0 16 16\">\r\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0\"/>\r\n </svg>\r\n -->\r\n </button>\r\n <button cuteButton class=\"scroll-button right\"\r\n tabindex=\"-1\"\r\n magnitude=\"smallest\"\r\n visuallyHiddenLabel=\"Next\"\r\n aria-hidden=\"true\"\r\n (click)=\"scrollHeader(1)\"\r\n [disabled]=\"!canScrollRight\">\r\n <!--\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"currentColor\" class=\"bi bi-chevron-right\" viewBox=\"0 0 16 16\">\r\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708\"/>\r\n </svg>\r\n -->\r\n </button>\r\n <!--\r\n <div class=\"scroll-indicator\"\r\n [class.active]=\"showScrollButtons\"\r\n [class.left-visible]=\"canScrollLeft\"\r\n [class.right-visible]=\"canScrollRight\">\r\n </div>\r\n -->\r\n }\r\n\r\n</div>\r\n\r\n<div class=\"tab-content-wrapper\">\r\n<!-- <div class=\"tab-content\">-->\r\n <ng-content></ng-content>\r\n <ng-container #dynamicTabs></ng-container>\r\n<!-- </div>-->\r\n</div>\r\n", styles: [".cute-tab-group{display:flex;flex-flow:column nowrap;width:100%}.cute-tab-group.tabs-top{flex-direction:column}.cute-tab-group.tabs-top .tab-header-wrapper{margin-bottom:.75rem}.cute-tab-group.tabs-bottom{flex-direction:column-reverse;justify-content:space-between}.cute-tab-group.tabs-bottom .tab-header-wrapper{margin-top:1rem}.cute-tab-group.tabs-bottom .nav-tabs{border:0;border-top:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.cute-tab-group.tabs-bottom .nav-tabs .nav-link{margin-top:calc(-2 * var(--bs-nav-tabs-border-width));margin-bottom:0;border-radius:0 0 var(--bs-nav-tabs-border-radius) var(--bs-nav-tabs-border-radius)}.cute-tab-group.tabs-bottom .nav-tabs .nav-link.active,.cute-tab-group.tabs-bottom .nav-tabs .nav-link:focus{border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.cute-tab-group.tabs-left,.cute-tab-group.tabs-start,[dir=rtl] .cute-tab-group.tabs-end{flex-direction:row}.cute-tab-group.tabs-left .tab-header-wrapper,.cute-tab-group.tabs-start .tab-header-wrapper,[dir=rtl] .cute-tab-group.tabs-end .tab-header-wrapper{flex-direction:row-reverse;margin-right:1rem}.cute-tab-group.tabs-right,.cute-tab-group.tabs-end,[dir=rtl] .cute-tab-group.tabs-start{flex-direction:row-reverse}.cute-tab-group.tabs-right .tab-header-wrapper,.cute-tab-group.tabs-end .tab-header-wrapper,[dir=rtl] .cute-tab-group.tabs-start .tab-header-wrapper{margin-left:1rem}.cute-tab-group .tab-header-wrapper{position:relative;overflow:hidden}.cute-tab-group .tab-header-scroll{display:flex;width:100%}.cute-tab-group.tabs-top .tab-header-wrapper .tab-header-scroll,.cute-tab-group.tabs-bottom .tab-header-wrapper .tab-header-scroll{white-space:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:none}.cute-tab-group.tabs-top .tab-header-wrapper .tab-header-scroll::-webkit-scrollbar,.cute-tab-group.tabs-bottom .tab-header-wrapper .tab-header-scroll::-webkit-scrollbar{display:none}.cute-tab-group.tabs-top .tab-header-wrapper .tab-header-scroll .cute-nav,.cute-tab-group.tabs-bottom .tab-header-wrapper .tab-header-scroll .cute-nav{flex-wrap:nowrap;white-space:nowrap;flex-basis:100%}.cute-tab-group.tabs-left .tab-header-wrapper,.cute-tab-group.tabs-right .tab-header-wrapper,.cute-tab-group.tabs-start .tab-header-wrapper,.cute-tab-group.tabs-end .tab-header-wrapper{min-width:100px;height:100%;overflow-x:hidden;overflow-y:auto}.cute-tab-group.tabs-left .tab-header-wrapper .cute-nav,.cute-tab-group.tabs-right .tab-header-wrapper .cute-nav,.cute-tab-group.tabs-start .tab-header-wrapper .cute-nav,.cute-tab-group.tabs-end .tab-header-wrapper .cute-nav{flex-wrap:nowrap;padding:.25rem;gap:.25rem;text-align:center;height:100%}.cute-tab-group.tabs-left .tab-header-wrapper .btn-add-tab,.cute-tab-group.tabs-right .tab-header-wrapper .btn-add-tab,.cute-tab-group.tabs-start .tab-header-wrapper .btn-add-tab,.cute-tab-group.tabs-end .tab-header-wrapper .btn-add-tab{position:sticky;top:0}.cute-tab-group .tab-content-wrapper{overflow:auto;height:100%;flex:1;transform:none}.cute-tab-group .cute-nav-link{display:flex;align-items:center;justify-content:center;width:100%;gap:.25rem}[dir=rtl] .cute-tab-group .cute-nav-link{flex-direction:row-reverse}.cdk-drag-preview{display:flex;opacity:.8;box-sizing:border-box;border:none;border-radius:var(--bs-nav-tabs-border-radius);box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;list-style:none;overflow:hidden;align-items:center;justify-content:center}.cdk-drag-placeholder{opacity:.2}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.scroll-button{position:absolute;top:0;bottom:0;width:1rem;font-weight:700;background:rgba(var(--bs-body-bg-rgb),.9);border:none;cursor:pointer;z-index:1;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .3s}.scroll-button:hover{opacity:1!important}.scroll-button[disabled]{opacity:0!important;cursor:default;pointer-events:none}.scroll-button.left{left:0;background:linear-gradient(to right,var(--bs-body-color) 0%,rgba(var(--bs-body-bg-rgb),0) 100%)}.scroll-button.right{right:0;background:linear-gradient(to left,var(--bs-body-color) 0%,rgba(var(--bs-body-bg-rgb),0) 100%)}.tab-header-wrapper:hover .scroll-button{opacity:.7}.scroll-indicator{position:absolute;bottom:0;left:0;right:0;height:1px;background:var(--bs-body-color)}.scroll-indicator:before,.scroll-indicator:after{content:\"\";position:absolute;bottom:0;width:30%;height:1px;background:var(--bs-primary);transform:scaleX(0);transition:transform .3s}.scroll-indicator.left-visible:before{transform:scaleX(1);left:0}.scroll-indicator.right-visible:after{transform:scaleX(1);right:0}\n"], dependencies: [{ kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: CuteNavModule }, { kind: "directive", type: i1.CuteNav, selector: "[cute-nav], [cuteNav]", inputs: ["cuteNav", "orientation", "alignment", "stretchItems", "preserveTabContent", "animation", "autoSelect", "selectedIndex"], outputs: ["selectedIndexChange", "selectedLinkChange", "selectedLinkChanging", "focusChange"], exportAs: ["cuteNav"] }, { kind: "component", type: i1.CuteNavItem, selector: "cute-nav-item, [cute-nav-item], [cuteNavItem]", inputs: ["preserveTabContent"], exportAs: ["cuteNavItem"] }, { kind: "directive", type: i1.CuteNavLink, selector: "a[cute-nav-link], a[cuteNavLink], button[cute-nav-link], button[cuteNavLink] ", inputs: ["active", "aria-controls"], exportAs: ["cuteNavLink"] }, { kind: "component", type: CuteButton, selector: "button[cuteButton], button[cute-button], a[cuteButton], a[cute-button], ", exportAs: ["cuteButton"] }, { kind: "directive", type: CuteObserveVisibility, selector: "[cuteObserveVisibility], [cute-observe-visibility]", inputs: ["cuteObserveVisibilityDisabled", "cuteObserveVisibilityDebounce", "cuteObserveVisibility", "cuteObserveVisibilityRootMargin", "cuteObserveVisibilityRoot"], outputs: ["cuteObserveVisibility"], exportAs: ["cuteObserveVisibility"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
451
|
+
}
|
|
452
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CuteTabGroup, decorators: [{
|
|
453
|
+
type: Component,
|
|
454
|
+
args: [{ selector: 'cute-tab-group', exportAs: "cuteTabGroup", host: {
|
|
455
|
+
"class": "cute-tab-group",
|
|
456
|
+
"[class.tabs-top]": "headerPosition === 'top'",
|
|
457
|
+
"[class.tabs-bottom]": "headerPosition === 'bottom'",
|
|
458
|
+
"[class.tabs-left]": "headerPosition === 'left'",
|
|
459
|
+
"[class.tabs-right]": "headerPosition === 'right'",
|
|
460
|
+
"[class.tabs-end]": "headerPosition === 'end'",
|
|
461
|
+
"[class.tabs-start]": "headerPosition === 'start'",
|
|
462
|
+
}, imports: [
|
|
463
|
+
CdkDropList,
|
|
464
|
+
CdkDrag,
|
|
465
|
+
NgTemplateOutlet,
|
|
466
|
+
CuteNavModule,
|
|
467
|
+
CuteButton,
|
|
468
|
+
CuteObserveVisibility,
|
|
469
|
+
], providers: [
|
|
470
|
+
{ provide: CUTE_TAB_GROUP, useExisting: forwardRef(() => CuteTabGroup) },
|
|
471
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"tab-header-wrapper\" #headerContainer>\r\n <div class=\"tab-header-scroll\" #headerScroll\r\n cdkDropList\r\n [cdkDropListOrientation]=\"isHorizontal ? 'horizontal' : 'vertical'\"\r\n (cdkDropListDropped)=\"onDrop($event)\">\r\n <nav [cuteNav]=\"isHorizontal ? (underlineTabs ? 'underline' : 'tabs') : 'pills'\"\r\n [selectedIndex]=\"selectedIndex\"\r\n [alignment]=\"alignTabs\"\r\n [stretchItems]=\"stretchTabs\"\r\n [preserveTabContent]=\"preserveContent\"\r\n [color]=\"color\"\r\n [class.flex-column]=\"!isHorizontal\"\r\n (selectedIndexChange)=\"selectTab($event)\"\r\n (selectedLinkChanging)=\"onNavLinkChanging($event)\"\r\n (selectedLinkChange)=\"onNavLinkChange($event)\"\r\n (focusChange)=\"onNavFocusChange($event)\">\r\n @for (tab of tabs; track tab.id; let i = $index) {\r\n <li cute-nav-item\r\n cdkDrag\r\n [cdkDragDisabled]=\"!dragEnabled || tabCount <= 1\"\r\n [cdkDragData]=\"tab\">\r\n <a href=\"#\" cute-nav-link\r\n [cuteObserveVisibility]=\"1\"\r\n [cuteObserveVisibilityRoot]=\"headerScroll\"\r\n (cuteObserveVisibility)=\"tab._visibilityChanged($event)\"\r\n [active]=\"tab.active\"\r\n [disabled]=\"tab.disabled\"\r\n [id]=\"tab.ariaLabelledby || undefined\"\r\n [attr.aria-disabled]=\"tab.disabled\"\r\n [attr.aria-controls]=\"tab.id\"\r\n [attr.tabindex]=\"tab.active && !tab.disabled ? 0 : -1\"\r\n role=\"tab\"\r\n #tabLink>\r\n\r\n @if (tab._templateLabel) {\r\n <ng-container\r\n *ngTemplateOutlet=\"tab._templateLabel; context: getLabelContext(tab, i)\">\r\n </ng-container>\r\n } @else {\r\n <!-- <ng-container>-->\r\n <!-- @if (dragEnabled && tabCount > 1) {-->\r\n <!-- <span cdkDragHandle>\u2630</span>-->\r\n <!-- }-->\r\n {{ tab.textLabel || 'Tab '+i }}\r\n <!-- </ng-container>-->\r\n }\r\n\r\n @if (tab.closable && tab.isDynamic) {\r\n <button cuteButton=\"close-button\"\r\n magnitude=\"smallest\"\r\n tabIndex=\"-1\"\r\n (click)=\"removeTab(i); $event.preventDefault();\"\r\n aria-label=\"Close tab\">\r\n </button>\r\n }\r\n\r\n </a>\r\n </li>\r\n }\r\n </nav>\r\n\r\n </div>\r\n\r\n @if (showScrollButtons) {\r\n <button cuteButton class=\"scroll-button left\"\r\n tabindex=\"-1\"\r\n magnitude=\"smallest\"\r\n visuallyHiddenLabel=\"Prev\"\r\n aria-hidden=\"true\"\r\n (click)=\"scrollHeader(-1)\"\r\n [disabled]=\"!canScrollLeft\">\r\n <!--\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"currentColor\" class=\"bi bi-chevron-left\" viewBox=\"0 0 16 16\">\r\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0\"/>\r\n </svg>\r\n -->\r\n </button>\r\n <button cuteButton class=\"scroll-button right\"\r\n tabindex=\"-1\"\r\n magnitude=\"smallest\"\r\n visuallyHiddenLabel=\"Next\"\r\n aria-hidden=\"true\"\r\n (click)=\"scrollHeader(1)\"\r\n [disabled]=\"!canScrollRight\">\r\n <!--\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"currentColor\" class=\"bi bi-chevron-right\" viewBox=\"0 0 16 16\">\r\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708\"/>\r\n </svg>\r\n -->\r\n </button>\r\n <!--\r\n <div class=\"scroll-indicator\"\r\n [class.active]=\"showScrollButtons\"\r\n [class.left-visible]=\"canScrollLeft\"\r\n [class.right-visible]=\"canScrollRight\">\r\n </div>\r\n -->\r\n }\r\n\r\n</div>\r\n\r\n<div class=\"tab-content-wrapper\">\r\n<!-- <div class=\"tab-content\">-->\r\n <ng-content></ng-content>\r\n <ng-container #dynamicTabs></ng-container>\r\n<!-- </div>-->\r\n</div>\r\n", styles: [".cute-tab-group{display:flex;flex-flow:column nowrap;width:100%}.cute-tab-group.tabs-top{flex-direction:column}.cute-tab-group.tabs-top .tab-header-wrapper{margin-bottom:.75rem}.cute-tab-group.tabs-bottom{flex-direction:column-reverse;justify-content:space-between}.cute-tab-group.tabs-bottom .tab-header-wrapper{margin-top:1rem}.cute-tab-group.tabs-bottom .nav-tabs{border:0;border-top:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.cute-tab-group.tabs-bottom .nav-tabs .nav-link{margin-top:calc(-2 * var(--bs-nav-tabs-border-width));margin-bottom:0;border-radius:0 0 var(--bs-nav-tabs-border-radius) var(--bs-nav-tabs-border-radius)}.cute-tab-group.tabs-bottom .nav-tabs .nav-link.active,.cute-tab-group.tabs-bottom .nav-tabs .nav-link:focus{border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.cute-tab-group.tabs-left,.cute-tab-group.tabs-start,[dir=rtl] .cute-tab-group.tabs-end{flex-direction:row}.cute-tab-group.tabs-left .tab-header-wrapper,.cute-tab-group.tabs-start .tab-header-wrapper,[dir=rtl] .cute-tab-group.tabs-end .tab-header-wrapper{flex-direction:row-reverse;margin-right:1rem}.cute-tab-group.tabs-right,.cute-tab-group.tabs-end,[dir=rtl] .cute-tab-group.tabs-start{flex-direction:row-reverse}.cute-tab-group.tabs-right .tab-header-wrapper,.cute-tab-group.tabs-end .tab-header-wrapper,[dir=rtl] .cute-tab-group.tabs-start .tab-header-wrapper{margin-left:1rem}.cute-tab-group .tab-header-wrapper{position:relative;overflow:hidden}.cute-tab-group .tab-header-scroll{display:flex;width:100%}.cute-tab-group.tabs-top .tab-header-wrapper .tab-header-scroll,.cute-tab-group.tabs-bottom .tab-header-wrapper .tab-header-scroll{white-space:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:none}.cute-tab-group.tabs-top .tab-header-wrapper .tab-header-scroll::-webkit-scrollbar,.cute-tab-group.tabs-bottom .tab-header-wrapper .tab-header-scroll::-webkit-scrollbar{display:none}.cute-tab-group.tabs-top .tab-header-wrapper .tab-header-scroll .cute-nav,.cute-tab-group.tabs-bottom .tab-header-wrapper .tab-header-scroll .cute-nav{flex-wrap:nowrap;white-space:nowrap;flex-basis:100%}.cute-tab-group.tabs-left .tab-header-wrapper,.cute-tab-group.tabs-right .tab-header-wrapper,.cute-tab-group.tabs-start .tab-header-wrapper,.cute-tab-group.tabs-end .tab-header-wrapper{min-width:100px;height:100%;overflow-x:hidden;overflow-y:auto}.cute-tab-group.tabs-left .tab-header-wrapper .cute-nav,.cute-tab-group.tabs-right .tab-header-wrapper .cute-nav,.cute-tab-group.tabs-start .tab-header-wrapper .cute-nav,.cute-tab-group.tabs-end .tab-header-wrapper .cute-nav{flex-wrap:nowrap;padding:.25rem;gap:.25rem;text-align:center;height:100%}.cute-tab-group.tabs-left .tab-header-wrapper .btn-add-tab,.cute-tab-group.tabs-right .tab-header-wrapper .btn-add-tab,.cute-tab-group.tabs-start .tab-header-wrapper .btn-add-tab,.cute-tab-group.tabs-end .tab-header-wrapper .btn-add-tab{position:sticky;top:0}.cute-tab-group .tab-content-wrapper{overflow:auto;height:100%;flex:1;transform:none}.cute-tab-group .cute-nav-link{display:flex;align-items:center;justify-content:center;width:100%;gap:.25rem}[dir=rtl] .cute-tab-group .cute-nav-link{flex-direction:row-reverse}.cdk-drag-preview{display:flex;opacity:.8;box-sizing:border-box;border:none;border-radius:var(--bs-nav-tabs-border-radius);box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;list-style:none;overflow:hidden;align-items:center;justify-content:center}.cdk-drag-placeholder{opacity:.2}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.scroll-button{position:absolute;top:0;bottom:0;width:1rem;font-weight:700;background:rgba(var(--bs-body-bg-rgb),.9);border:none;cursor:pointer;z-index:1;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .3s}.scroll-button:hover{opacity:1!important}.scroll-button[disabled]{opacity:0!important;cursor:default;pointer-events:none}.scroll-button.left{left:0;background:linear-gradient(to right,var(--bs-body-color) 0%,rgba(var(--bs-body-bg-rgb),0) 100%)}.scroll-button.right{right:0;background:linear-gradient(to left,var(--bs-body-color) 0%,rgba(var(--bs-body-bg-rgb),0) 100%)}.tab-header-wrapper:hover .scroll-button{opacity:.7}.scroll-indicator{position:absolute;bottom:0;left:0;right:0;height:1px;background:var(--bs-body-color)}.scroll-indicator:before,.scroll-indicator:after{content:\"\";position:absolute;bottom:0;width:30%;height:1px;background:var(--bs-primary);transform:scaleX(0);transition:transform .3s}.scroll-indicator.left-visible:before{transform:scaleX(1);left:0}.scroll-indicator.right-visible:after{transform:scaleX(1);right:0}\n"] }]
|
|
472
|
+
}], ctorParameters: () => [], propDecorators: { tabs: [{
|
|
473
|
+
type: ContentChildren,
|
|
474
|
+
args: [CuteTab]
|
|
475
|
+
}], tabLinks: [{
|
|
476
|
+
type: ViewChildren,
|
|
477
|
+
args: ['tabLink', { read: CuteNavLink }]
|
|
478
|
+
}], dynamicTabsContainer: [{
|
|
479
|
+
type: ViewChild,
|
|
480
|
+
args: ['dynamicTabs', { read: ViewContainerRef, static: true }]
|
|
481
|
+
}], headerContainer: [{
|
|
482
|
+
type: ViewChild,
|
|
483
|
+
args: ['headerContainer', { static: true }]
|
|
484
|
+
}], headerScroll: [{
|
|
485
|
+
type: ViewChild,
|
|
486
|
+
args: ['headerScroll', { static: true }]
|
|
487
|
+
}], selectedIndex: [{
|
|
488
|
+
type: Input,
|
|
489
|
+
args: [{ transform: numberAttribute }]
|
|
490
|
+
}], alignTabs: [{
|
|
491
|
+
type: Input,
|
|
492
|
+
args: [{ alias: 'cute-align-tabs' }]
|
|
493
|
+
}], stretchTabs: [{
|
|
494
|
+
type: Input,
|
|
495
|
+
args: [{ alias: 'cute-stretch-tabs' }]
|
|
496
|
+
}], preserveContent: [{
|
|
497
|
+
type: Input,
|
|
498
|
+
args: [{ transform: booleanAttribute }]
|
|
499
|
+
}], dynamicHeight: [{
|
|
500
|
+
type: Input,
|
|
501
|
+
args: [{ transform: booleanAttribute }]
|
|
502
|
+
}], headerPosition: [{
|
|
503
|
+
type: Input
|
|
504
|
+
}], underlineTabs: [{
|
|
505
|
+
type: Input,
|
|
506
|
+
args: [{ transform: booleanAttribute }]
|
|
507
|
+
}], dragEnabled: [{
|
|
508
|
+
type: Input,
|
|
509
|
+
args: [{ transform: booleanAttribute }]
|
|
510
|
+
}], tabScrollingAlignment: [{
|
|
511
|
+
type: Input
|
|
512
|
+
}], selectedIndexChange: [{
|
|
513
|
+
type: Output
|
|
514
|
+
}], selectedTabChanging: [{
|
|
515
|
+
type: Output
|
|
516
|
+
}], selectedTabChange: [{
|
|
517
|
+
type: Output
|
|
518
|
+
}], focusChange: [{
|
|
519
|
+
type: Output
|
|
520
|
+
}], tabAdded: [{
|
|
521
|
+
type: Output
|
|
522
|
+
}], tabRemoved: [{
|
|
523
|
+
type: Output
|
|
524
|
+
}] } });
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* @license Apache-2.0
|
|
528
|
+
*
|
|
529
|
+
* Copyright (c) 2025 CuteWidgets Team. All Rights Reserved.
|
|
530
|
+
*
|
|
531
|
+
* You may not use this file except in compliance with the License
|
|
532
|
+
* that can be found at http://www.apache.org/licenses/LICENSE-2.0
|
|
533
|
+
*
|
|
534
|
+
* This code is a modification of the `@angular/material` original
|
|
535
|
+
* code licensed under MIT-style License (https://angular.dev/license).
|
|
536
|
+
*/
|
|
537
|
+
/**
|
|
538
|
+
* Used to provide a tab label to a tab without causing a circular dependency.
|
|
539
|
+
* @docs-private
|
|
540
|
+
*/
|
|
541
|
+
const CUTE_TAB = new InjectionToken('CUTE_TAB');
|
|
542
|
+
let nextId = 0;
|
|
543
|
+
class CuteTab extends CuteFocusableControl {
|
|
544
|
+
/** Whether the tab is currently active. */
|
|
545
|
+
get active() { return this._active; }
|
|
546
|
+
set active(value) {
|
|
547
|
+
if (value !== this._active) {
|
|
548
|
+
this._active = value;
|
|
549
|
+
this._stateChanges.next();
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
/** Whether the tab is intersected the containing box and needs to scroll to display its full size */
|
|
553
|
+
get scrollNeeded() {
|
|
554
|
+
return this._intersectionRatio < 1;
|
|
555
|
+
}
|
|
556
|
+
isPreserveContent() {
|
|
557
|
+
return this.preserveContent ?? this._tabGroup?.preserveContent ?? false;
|
|
558
|
+
}
|
|
559
|
+
/** Tab content defined by <ng-template cute-tab-content> or directly referenced where the latter has more priority. */
|
|
560
|
+
get explicitContent() {
|
|
561
|
+
return this.contentTemplate || this._explicitContent;
|
|
562
|
+
}
|
|
563
|
+
/** Template inside the CuteTab view that contains an `<ng-content>`. */
|
|
564
|
+
// @ViewChild(TemplateRef, {static: true}) _implicitContent: TemplateRef<any> | undefined;
|
|
565
|
+
constructor() {
|
|
566
|
+
super();
|
|
567
|
+
this._tabGroup = inject(CUTE_TAB_GROUP, { optional: true });
|
|
568
|
+
this._intersectionRatio = NaN;
|
|
569
|
+
/** Plain text label for the tab, used when there is no template label. */
|
|
570
|
+
this.textLabel = "";
|
|
571
|
+
/** Lazy loading label's outlet context */
|
|
572
|
+
this.labelContext = {};
|
|
573
|
+
/** Lazy loading content's outlet context */
|
|
574
|
+
this.contentContext = {};
|
|
575
|
+
/** Whether the tab is closable. */
|
|
576
|
+
this.closable = false;
|
|
577
|
+
this._active = false;
|
|
578
|
+
/** Whether the tab was added dynamically */
|
|
579
|
+
this.isDynamic = false;
|
|
580
|
+
/** Emits whenever the internal state of the tab changes. */
|
|
581
|
+
this._stateChanges = new Subject();
|
|
582
|
+
/** Whether the tab content was loaded */
|
|
583
|
+
this.loaded = signal(false, ...(ngDevMode ? [{ debugName: "loaded" }] : []));
|
|
584
|
+
this._stateChanges.pipe(takeUntilDestroyed()).subscribe(() => {
|
|
585
|
+
this.markForCheck();
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
generateId() {
|
|
589
|
+
return `cute-tab-${nextId++}`;
|
|
590
|
+
}
|
|
591
|
+
/** Gets the content template's context object */
|
|
592
|
+
getContentContext() {
|
|
593
|
+
return { ...this.contentContext,
|
|
594
|
+
$implicit: this,
|
|
595
|
+
index: this._tabGroup?.getTabIndex(this),
|
|
596
|
+
active: this.active,
|
|
597
|
+
tab: this
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Removes this tab from the tab group.
|
|
602
|
+
*/
|
|
603
|
+
async remove() {
|
|
604
|
+
if (this._tabGroup) {
|
|
605
|
+
const index = this._tabGroup.getTabIndex(this);
|
|
606
|
+
if (index != null) {
|
|
607
|
+
return this._tabGroup.removeTab(index);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
_visibilityChanged(entries) {
|
|
613
|
+
if (entries.length) {
|
|
614
|
+
this._intersectionRatio = entries[0].intersectionRatio;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
ngOnInit() {
|
|
618
|
+
super.ngOnInit();
|
|
619
|
+
this.ariaLabelledby = this.id + "-link";
|
|
620
|
+
}
|
|
621
|
+
ngOnChanges(changes) {
|
|
622
|
+
super.ngOnChanges(changes);
|
|
623
|
+
if (changes['textLabel'] || changes['disabled'] || changes['closable']) {
|
|
624
|
+
this._stateChanges.next();
|
|
625
|
+
}
|
|
626
|
+
if (changes["active"] && changes["active"].currentValue) {
|
|
627
|
+
this.loaded.set(true);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
ngOnDestroy() {
|
|
631
|
+
super.ngOnDestroy();
|
|
632
|
+
this._stateChanges.complete();
|
|
633
|
+
}
|
|
634
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CuteTab, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
635
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: CuteTab, isStandalone: true, selector: "cute-tab", inputs: { textLabel: ["label", "textLabel"], contentTemplate: "contentTemplate", labelContext: "labelContext", contentContext: "contentContext", closable: ["closable", "closable", booleanAttribute], preserveContent: ["preserveContent", "preserveContent", booleanAttribute] }, host: { attributes: { "role": "tabpanel" }, properties: { "class.show": "active", "class.active": "active", "attr.tabindex": "active && !disabled ? 0 : -1", "attr.aria-labelledby": "ariaLabelledby || null", "attr.id": "id || null", "@contentFade": "active ? 'in' : 'out'" }, classAttribute: "cute-tab tab-pane" }, queries: [{ propertyName: "_templateLabel", first: true, predicate: CuteTabLabel, descendants: true, read: TemplateRef, static: true }, { propertyName: "_explicitContent", first: true, predicate: CuteTabContent, descendants: true, read: TemplateRef, static: true }, { propertyName: "link", first: true, predicate: CuteNavLink, descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "@if (active || isPreserveContent()) {\r\n\r\n <ng-content></ng-content>\r\n\r\n @if (explicitContent) {\r\n <ng-container [ngTemplateOutlet]=\"explicitContent\"\r\n [ngTemplateOutletContext]=\"getContentContext()\">\r\n </ng-container>\r\n }\r\n}\r\n", styles: [".cute-tab{display:block;width:100%;padding:.25rem}.cute-tab:not(.show){display:none}.cute-tab.ng-animating{overflow:hidden}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], animations: [
|
|
636
|
+
trigger('contentFade', [
|
|
637
|
+
state('in', style({ opacity: 1, height: '*' })),
|
|
638
|
+
state('out', style({ opacity: 0, height: '0px' })),
|
|
639
|
+
transition('in <=> out', animate('150ms linear'))
|
|
640
|
+
])
|
|
641
|
+
], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
642
|
+
}
|
|
643
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CuteTab, decorators: [{
|
|
644
|
+
type: Component,
|
|
645
|
+
args: [{ selector: 'cute-tab', animations: [
|
|
646
|
+
trigger('contentFade', [
|
|
647
|
+
state('in', style({ opacity: 1, height: '*' })),
|
|
648
|
+
state('out', style({ opacity: 0, height: '0px' })),
|
|
649
|
+
transition('in <=> out', animate('150ms linear'))
|
|
650
|
+
])
|
|
651
|
+
], host: {
|
|
652
|
+
"class": "cute-tab tab-pane",
|
|
653
|
+
"[class.show]": "active",
|
|
654
|
+
"[class.active]": "active",
|
|
655
|
+
// "[class.d-none]": "!active",
|
|
656
|
+
'[attr.tabindex]': 'active && !disabled ? 0 : -1',
|
|
657
|
+
'[attr.aria-labelledby]': 'ariaLabelledby || null',
|
|
658
|
+
'[attr.id]': 'id || null',
|
|
659
|
+
"role": "tabpanel",
|
|
660
|
+
"[@contentFade]": "active ? 'in' : 'out'"
|
|
661
|
+
}, imports: [
|
|
662
|
+
NgTemplateOutlet,
|
|
663
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "@if (active || isPreserveContent()) {\r\n\r\n <ng-content></ng-content>\r\n\r\n @if (explicitContent) {\r\n <ng-container [ngTemplateOutlet]=\"explicitContent\"\r\n [ngTemplateOutletContext]=\"getContentContext()\">\r\n </ng-container>\r\n }\r\n}\r\n", styles: [".cute-tab{display:block;width:100%;padding:.25rem}.cute-tab:not(.show){display:none}.cute-tab.ng-animating{overflow:hidden}\n"] }]
|
|
664
|
+
}], ctorParameters: () => [], propDecorators: { textLabel: [{
|
|
665
|
+
type: Input,
|
|
666
|
+
args: ["label"]
|
|
667
|
+
}], contentTemplate: [{
|
|
668
|
+
type: Input
|
|
669
|
+
}], labelContext: [{
|
|
670
|
+
type: Input
|
|
671
|
+
}], contentContext: [{
|
|
672
|
+
type: Input
|
|
673
|
+
}], closable: [{
|
|
674
|
+
type: Input,
|
|
675
|
+
args: [{ transform: booleanAttribute }]
|
|
676
|
+
}], preserveContent: [{
|
|
677
|
+
type: Input,
|
|
678
|
+
args: [{ transform: booleanAttribute }]
|
|
679
|
+
}], _templateLabel: [{
|
|
680
|
+
type: ContentChild,
|
|
681
|
+
args: [CuteTabLabel, { read: TemplateRef, static: true }]
|
|
682
|
+
}], _explicitContent: [{
|
|
683
|
+
type: ContentChild,
|
|
684
|
+
args: [CuteTabContent, { read: TemplateRef, static: true }]
|
|
685
|
+
}], link: [{
|
|
686
|
+
type: ContentChild,
|
|
687
|
+
args: [CuteNavLink, { descendants: true }]
|
|
688
|
+
}] } });
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* @license Apache-2.0
|
|
692
|
+
*
|
|
693
|
+
* Copyright (c) 2025 CuteWidgets Team. All Rights Reserved.
|
|
694
|
+
*
|
|
695
|
+
* You may not use this file except in compliance with the License
|
|
696
|
+
* that can be found at http://www.apache.org/licenses/LICENSE-2.0
|
|
697
|
+
*/
|
|
698
|
+
const TYPES = [
|
|
699
|
+
CuteTab,
|
|
700
|
+
CuteTabGroup,
|
|
701
|
+
CuteTabLabel,
|
|
702
|
+
CuteTabContent,
|
|
703
|
+
];
|
|
704
|
+
class CuteTabsModule {
|
|
705
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CuteTabsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
706
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: CuteTabsModule, imports: [CommonModule, CuteTab,
|
|
707
|
+
CuteTabGroup,
|
|
708
|
+
CuteTabLabel,
|
|
709
|
+
CuteTabContent], exports: [CuteTab,
|
|
710
|
+
CuteTabGroup,
|
|
711
|
+
CuteTabLabel,
|
|
712
|
+
CuteTabContent] }); }
|
|
713
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CuteTabsModule, imports: [CommonModule, CuteTabGroup] }); }
|
|
714
|
+
}
|
|
715
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: CuteTabsModule, decorators: [{
|
|
716
|
+
type: NgModule,
|
|
717
|
+
args: [{
|
|
718
|
+
imports: [CommonModule, ...TYPES],
|
|
719
|
+
exports: TYPES,
|
|
720
|
+
declarations: [],
|
|
721
|
+
}]
|
|
722
|
+
}] });
|
|
723
|
+
|
|
724
|
+
/**
|
|
725
|
+
* Generated bundle index. Do not edit.
|
|
726
|
+
*/
|
|
727
|
+
|
|
728
|
+
export { CUTE_TAB, CUTE_TAB_CONTENT, CUTE_TAB_GROUP, CUTE_TAB_LABEL, CuteTab, CuteTabChangeEvent, CuteTabChangingEvent, CuteTabContent, CuteTabGroup, CuteTabLabel, CuteTabsModule, transitionAnimation };
|
|
729
|
+
//# sourceMappingURL=cute-widgets-base-tabs.mjs.map
|