quang 20.6.0 → 20.6.1-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
# QuangTabsComponent
|
|
2
|
+
|
|
3
|
+
The `QuangTabsComponent` is a flexible tabs navigation component that provides seamless tab switching, support for disabled states, custom templates, and full integration with Angular reactive forms. It supports both standard tabs and custom-rendered tabs with extensive customization options.
|
|
4
|
+
|
|
5
|
+
## Inputs
|
|
6
|
+
|
|
7
|
+
- `tabs`: `TabConfiguration[]` — Array of tab configurations. Each tab must have an `id` and `label`, and can optionally include `disabled` state or a custom `renderer`. **(Required)**
|
|
8
|
+
- `isReadonly`: `boolean` — Set component to read-only mode. When true, all tabs become non-interactive. Inherited from `QuangBaseComponent`
|
|
9
|
+
- `componentTabIndex`: `number` — Tab index for accessibility. Inherited from `QuangBaseComponent`
|
|
10
|
+
- `componentClass`: `string | string[]` — Additional CSS classes. Inherited from `QuangBaseComponent`
|
|
11
|
+
- `formControl`: `FormControl` — Form control for reactive forms. Inherited from `QuangBaseComponent`
|
|
12
|
+
|
|
13
|
+
## Outputs
|
|
14
|
+
|
|
15
|
+
- `tabChange`: `EventEmitter<string>` — Emitted when the selected tab changes. Provides the `id` of the newly selected tab
|
|
16
|
+
- `componentBlur`: `EventEmitter<void>` — Emitted when component loses focus. Inherited from `QuangBaseComponent`
|
|
17
|
+
|
|
18
|
+
## TabConfiguration Interface
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
interface TabConfiguration {
|
|
22
|
+
id: string // Unique identifier for the tab
|
|
23
|
+
label: string // Translation key or label text
|
|
24
|
+
disabled?: boolean // If true, tab is disabled and non-interactive
|
|
25
|
+
renderer?: TemplateRef<any> // Optional custom template for tab rendering
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
### Basic Tabs
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<quang-tabs
|
|
35
|
+
[tabs]="tabs"
|
|
36
|
+
[formControl]="selectedTab"
|
|
37
|
+
/>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
export class MyComponent {
|
|
42
|
+
selectedTab = new FormControl<string>('home')
|
|
43
|
+
|
|
44
|
+
tabs: TabConfiguration[] = [
|
|
45
|
+
{ id: 'home', label: 'navigation.home' },
|
|
46
|
+
{ id: 'profile', label: 'navigation.profile' },
|
|
47
|
+
{ id: 'settings', label: 'navigation.settings' },
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Tabs with Disabled State
|
|
53
|
+
|
|
54
|
+
```html
|
|
55
|
+
<quang-tabs
|
|
56
|
+
[tabs]="tabs"
|
|
57
|
+
[formControl]="selectedTab"
|
|
58
|
+
/>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
export class MyComponent {
|
|
63
|
+
selectedTab = new FormControl<string>('tab1')
|
|
64
|
+
|
|
65
|
+
tabs: TabConfiguration[] = [
|
|
66
|
+
{ id: 'tab1', label: 'Enabled Tab' },
|
|
67
|
+
{ id: 'tab2', label: 'Disabled Tab', disabled: true },
|
|
68
|
+
{ id: 'tab3', label: 'Another Tab' },
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Event Handling
|
|
74
|
+
|
|
75
|
+
```html
|
|
76
|
+
<quang-tabs
|
|
77
|
+
[tabs]="tabs"
|
|
78
|
+
[formControl]="selectedTab"
|
|
79
|
+
(tabChange)="onTabChange($event)"
|
|
80
|
+
/>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
export class MyComponent {
|
|
85
|
+
selectedTab = new FormControl<string>('overview')
|
|
86
|
+
|
|
87
|
+
tabs: TabConfiguration[] = [
|
|
88
|
+
{ id: 'overview', label: 'Overview' },
|
|
89
|
+
{ id: 'details', label: 'Details' },
|
|
90
|
+
{ id: 'analytics', label: 'Analytics' },
|
|
91
|
+
]
|
|
92
|
+
|
|
93
|
+
onTabChange(tabId: string): void {
|
|
94
|
+
console.log('Selected tab:', tabId)
|
|
95
|
+
// Handle tab change logic
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Tab Content Switching
|
|
101
|
+
|
|
102
|
+
Display different content based on the selected tab using Angular's `@switch` control flow:
|
|
103
|
+
|
|
104
|
+
```html
|
|
105
|
+
<quang-tabs
|
|
106
|
+
[tabs]="tabs"
|
|
107
|
+
[formControl]="selectedTab"
|
|
108
|
+
/>
|
|
109
|
+
|
|
110
|
+
<!-- Content changes based on selected tab -->
|
|
111
|
+
<div class="mt-4">
|
|
112
|
+
@switch (selectedTab.value) {
|
|
113
|
+
@case ('overview') {
|
|
114
|
+
<div class="card">
|
|
115
|
+
<div class="card-header">
|
|
116
|
+
<h5>Overview</h5>
|
|
117
|
+
</div>
|
|
118
|
+
<div class="card-body">
|
|
119
|
+
<p>Welcome to the overview section!</p>
|
|
120
|
+
<ul>
|
|
121
|
+
<li>Quick statistics</li>
|
|
122
|
+
<li>Recent activity</li>
|
|
123
|
+
</ul>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
}
|
|
127
|
+
@case ('details') {
|
|
128
|
+
<div class="card">
|
|
129
|
+
<div class="card-header">
|
|
130
|
+
<h5>Details</h5>
|
|
131
|
+
</div>
|
|
132
|
+
<div class="card-body">
|
|
133
|
+
<table class="table">
|
|
134
|
+
<tbody>
|
|
135
|
+
<tr>
|
|
136
|
+
<td><strong>Name:</strong></td>
|
|
137
|
+
<td>John Doe</td>
|
|
138
|
+
</tr>
|
|
139
|
+
</tbody>
|
|
140
|
+
</table>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
}
|
|
144
|
+
@case ('settings') {
|
|
145
|
+
<div class="card">
|
|
146
|
+
<div class="card-header">
|
|
147
|
+
<h5>Settings</h5>
|
|
148
|
+
</div>
|
|
149
|
+
<div class="card-body">
|
|
150
|
+
<form>
|
|
151
|
+
<div class="mb-3">
|
|
152
|
+
<label>Theme</label>
|
|
153
|
+
<select class="form-select">
|
|
154
|
+
<option>Light</option>
|
|
155
|
+
<option>Dark</option>
|
|
156
|
+
</select>
|
|
157
|
+
</div>
|
|
158
|
+
<button type="submit" class="btn btn-primary">
|
|
159
|
+
Save
|
|
160
|
+
</button>
|
|
161
|
+
</form>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
</div>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
export class MyComponent {
|
|
171
|
+
selectedTab = new FormControl<string>('overview')
|
|
172
|
+
|
|
173
|
+
tabs: TabConfiguration[] = [
|
|
174
|
+
{ id: 'overview', label: 'Overview' },
|
|
175
|
+
{ id: 'details', label: 'Details' },
|
|
176
|
+
{ id: 'settings', label: 'Settings' },
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Custom Tab Templates
|
|
182
|
+
|
|
183
|
+
```html
|
|
184
|
+
<ng-template
|
|
185
|
+
#customTabTpl
|
|
186
|
+
let-tab
|
|
187
|
+
let-selected="selected"
|
|
188
|
+
>
|
|
189
|
+
<button
|
|
190
|
+
[class.selected]="selected"
|
|
191
|
+
class="flex-grow-1 btn btn-only-text custom-tab"
|
|
192
|
+
type="button"
|
|
193
|
+
>
|
|
194
|
+
<span class="d-flex gap-2 align-items-center justify-content-center">
|
|
195
|
+
<span>{{ tab.icon }}</span>
|
|
196
|
+
<strong>{{ tab.label | transloco }}</strong>
|
|
197
|
+
@if(selected) {
|
|
198
|
+
<small class="badge bg-primary">Active</small>
|
|
199
|
+
}
|
|
200
|
+
</span>
|
|
201
|
+
</button>
|
|
202
|
+
</ng-template>
|
|
203
|
+
|
|
204
|
+
<quang-tabs
|
|
205
|
+
[tabs]="tabs"
|
|
206
|
+
[formControl]="selectedTab"
|
|
207
|
+
/>
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
export class MyComponent {
|
|
212
|
+
private readonly customTabTpl = viewChild<TemplateRef<any>>('customTabTpl')
|
|
213
|
+
selectedTab = new FormControl<string>('dashboard')
|
|
214
|
+
|
|
215
|
+
get tabs(): TabConfiguration[] {
|
|
216
|
+
return [
|
|
217
|
+
{
|
|
218
|
+
id: 'dashboard',
|
|
219
|
+
label: 'Dashboard',
|
|
220
|
+
renderer: this.customTabTpl()
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
id: 'messages',
|
|
224
|
+
label: 'Messages',
|
|
225
|
+
renderer: this.customTabTpl()
|
|
226
|
+
},
|
|
227
|
+
]
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Form Integration with Validation
|
|
233
|
+
|
|
234
|
+
```html
|
|
235
|
+
<form [formGroup]="form">
|
|
236
|
+
<quang-tabs
|
|
237
|
+
[tabs]="tabs"
|
|
238
|
+
formControlName="selectedSection"
|
|
239
|
+
/>
|
|
240
|
+
</form>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
export class MyComponent {
|
|
245
|
+
|
|
246
|
+
form = this.fb.group({
|
|
247
|
+
selectedSection: [null, Validators.required]
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
tabs: TabConfiguration[] = [
|
|
251
|
+
{ id: 'section1', label: 'Section 1' },
|
|
252
|
+
{ id: 'section2', label: 'Section 2' },
|
|
253
|
+
{ id: 'section3', label: 'Section 3' },
|
|
254
|
+
]
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Readonly Mode
|
|
259
|
+
|
|
260
|
+
```html
|
|
261
|
+
<quang-tabs
|
|
262
|
+
[tabs]="tabs"
|
|
263
|
+
[formControl]="selectedTab"
|
|
264
|
+
[isReadonly]="isReadonly()"
|
|
265
|
+
/>
|
|
266
|
+
|
|
267
|
+
<button (click)="toggleReadonly()">
|
|
268
|
+
Toggle Readonly
|
|
269
|
+
</button>
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
export class MyComponent {
|
|
274
|
+
selectedTab = new FormControl<string>('tab1')
|
|
275
|
+
isReadonly = signal<boolean>(false)
|
|
276
|
+
|
|
277
|
+
tabs: TabConfiguration[] = [
|
|
278
|
+
{ id: 'tab1', label: 'Tab 1' },
|
|
279
|
+
{ id: 'tab2', label: 'Tab 2' },
|
|
280
|
+
{ id: 'tab3', label: 'Tab 3' },
|
|
281
|
+
]
|
|
282
|
+
|
|
283
|
+
toggleReadonly(): void {
|
|
284
|
+
this.isReadonly.set(!this.isReadonly())
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Translation Integration
|
|
290
|
+
|
|
291
|
+
The component uses QuangTranslationService for all text content:
|
|
292
|
+
|
|
293
|
+
- **Automatic Translation**: All tab labels and messages are automatically translated using Transloco
|
|
294
|
+
- **Key Support**: Use translation keys for tab labels for multi-language support
|
|
295
|
+
- **Fallback Handling**: Provides graceful fallback when translations are unavailable
|
|
296
|
+
- **Dynamic Language**: Responds to language changes without component reload
|
|
297
|
+
|
|
298
|
+
## Custom Template Context
|
|
299
|
+
|
|
300
|
+
When using custom templates, the following context is available:
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
interface QuangTabTemplateContext {
|
|
304
|
+
$implicit: TabConfiguration // The tab configuration object
|
|
305
|
+
selected: boolean // Whether this tab is currently selected
|
|
306
|
+
index: number // The index of the tab in the array
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Example usage in template:
|
|
311
|
+
|
|
312
|
+
```html
|
|
313
|
+
<ng-template
|
|
314
|
+
#tabTpl
|
|
315
|
+
let-tab
|
|
316
|
+
let-selected="selected"
|
|
317
|
+
let-index="index"
|
|
318
|
+
>
|
|
319
|
+
<!-- tab: TabConfiguration -->
|
|
320
|
+
<!-- selected: boolean -->
|
|
321
|
+
<!-- index: number -->
|
|
322
|
+
<div>{{ tab.label }} - Position {{ index + 1 }}</div>
|
|
323
|
+
</ng-template>
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## Styling
|
|
327
|
+
|
|
328
|
+
The component uses Bootstrap 5.3 classes for styling. The default tabs have:
|
|
329
|
+
- Bottom border that becomes thicker (4px) when selected
|
|
330
|
+
- Smooth transitions on state changes
|
|
331
|
+
- Disabled state with reduced opacity
|
|
332
|
+
- Hover effects on interactive tabs
|
|
333
|
+
|
|
334
|
+
You can customize styling using the `componentClass` input or by targeting the component's CSS classes.
|
|
335
|
+
|
|
336
|
+
## Notes
|
|
337
|
+
|
|
338
|
+
- Extends `QuangBaseComponent` for consistent behavior across all Quang components
|
|
339
|
+
- Supports Angular reactive forms with `ControlValueAccessor`
|
|
340
|
+
- Fully compatible with Angular's form validation
|
|
341
|
+
- Styled based on Bootstrap v5.3
|
|
342
|
+
- Supports both translation keys and direct text for labels
|
|
343
|
+
- Individual tabs can be disabled independently of the form control state
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { TemplateRef } from '@angular/core';
|
|
3
|
+
import { QuangBaseComponent } from 'quang/components/shared';
|
|
4
|
+
|
|
5
|
+
interface TabConfiguration {
|
|
6
|
+
id: string;
|
|
7
|
+
label: string;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
renderer?: TemplateRef<any>;
|
|
10
|
+
}
|
|
11
|
+
declare class QuangTabsComponent extends QuangBaseComponent<string> {
|
|
12
|
+
tabs: _angular_core.InputSignal<TabConfiguration[]>;
|
|
13
|
+
tabChange: _angular_core.OutputEmitterRef<string>;
|
|
14
|
+
getTabIndex(tab: TabConfiguration): number;
|
|
15
|
+
isTabSelected(tab: TabConfiguration): boolean;
|
|
16
|
+
isTabDisabled(tab: TabConfiguration): boolean;
|
|
17
|
+
onSelectTab(tab: TabConfiguration): void;
|
|
18
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<QuangTabsComponent, never>;
|
|
19
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<QuangTabsComponent, "quang-tabs", never, { "tabs": { "alias": "tabs"; "required": true; "isSignal": true; }; }, { "tabChange": "tabChange"; }, never, never, true, never>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { QuangTabsComponent };
|
|
23
|
+
export type { TabConfiguration };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { NgTemplateOutlet } from '@angular/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { input, output, forwardRef, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
|
+
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
5
|
+
import { TranslocoPipe } from '@jsverse/transloco';
|
|
6
|
+
import { QuangBaseComponent } from 'quang/components/shared';
|
|
7
|
+
|
|
8
|
+
class QuangTabsComponent extends QuangBaseComponent {
|
|
9
|
+
constructor() {
|
|
10
|
+
super(...arguments);
|
|
11
|
+
this.tabs = input.required(...(ngDevMode ? [{ debugName: "tabs" }] : []));
|
|
12
|
+
this.tabChange = output();
|
|
13
|
+
}
|
|
14
|
+
getTabIndex(tab) {
|
|
15
|
+
return this.tabs().findIndex((x) => x.id === tab.id);
|
|
16
|
+
}
|
|
17
|
+
isTabSelected(tab) {
|
|
18
|
+
return this._value() === tab.id;
|
|
19
|
+
}
|
|
20
|
+
isTabDisabled(tab) {
|
|
21
|
+
return this._isDisabled() || this.isReadonly() || !!tab.disabled;
|
|
22
|
+
}
|
|
23
|
+
onSelectTab(tab) {
|
|
24
|
+
if (this.isTabDisabled(tab))
|
|
25
|
+
return;
|
|
26
|
+
this.onChangedHandler(tab.id);
|
|
27
|
+
this.tabChange.emit(tab.id);
|
|
28
|
+
}
|
|
29
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: QuangTabsComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
30
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: QuangTabsComponent, isStandalone: true, selector: "quang-tabs", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { tabChange: "tabChange" }, providers: [
|
|
31
|
+
{
|
|
32
|
+
provide: NG_VALUE_ACCESSOR,
|
|
33
|
+
useExisting: forwardRef(() => QuangTabsComponent),
|
|
34
|
+
multi: true,
|
|
35
|
+
},
|
|
36
|
+
], usesInheritance: true, ngImport: i0, template: "<div\n class=\"d-flex mt-4 flex-column flex-lg-row\"\n id=\"tabs-container\"\n>\n @for(tab of tabs(); track tab.id) {\n @if(tab.renderer) {\n <ng-container\n [ngTemplateOutlet]=\"tab.renderer\"\n [ngTemplateOutletContext]=\"{ $implicit: tab, selected: isTabSelected(tab), index: getTabIndex(tab) }\"\n ></ng-container>\n } @else {\n <button\n [class.selected]=\"isTabSelected(tab)\"\n [disabled]=\"isTabDisabled(tab)\"\n (click)=\"onSelectTab(tab)\"\n class=\"flex-grow-1 btn btn-only-text\"\n type=\"button\"\n >\n {{ tab.label | transloco }}\n </button>\n }\n }\n</div>\n", styles: ["#tabs-container button{border-radius:0;border-bottom:1px solid var(--bs-border-color)}#tabs-container button.selected{border-bottom:4px solid var(--bs-border-color);font-weight:700}#tabs-container button:not(.selected){padding-bottom:calc(.5rem + 3px)}#tabs-container .btn:disabled{border-color:transparent;border-bottom:1px solid var(--bs-border-color)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
37
|
+
}
|
|
38
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: QuangTabsComponent, decorators: [{
|
|
39
|
+
type: Component,
|
|
40
|
+
args: [{ selector: 'quang-tabs', providers: [
|
|
41
|
+
{
|
|
42
|
+
provide: NG_VALUE_ACCESSOR,
|
|
43
|
+
useExisting: forwardRef(() => QuangTabsComponent),
|
|
44
|
+
multi: true,
|
|
45
|
+
},
|
|
46
|
+
], imports: [TranslocoPipe, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"d-flex mt-4 flex-column flex-lg-row\"\n id=\"tabs-container\"\n>\n @for(tab of tabs(); track tab.id) {\n @if(tab.renderer) {\n <ng-container\n [ngTemplateOutlet]=\"tab.renderer\"\n [ngTemplateOutletContext]=\"{ $implicit: tab, selected: isTabSelected(tab), index: getTabIndex(tab) }\"\n ></ng-container>\n } @else {\n <button\n [class.selected]=\"isTabSelected(tab)\"\n [disabled]=\"isTabDisabled(tab)\"\n (click)=\"onSelectTab(tab)\"\n class=\"flex-grow-1 btn btn-only-text\"\n type=\"button\"\n >\n {{ tab.label | transloco }}\n </button>\n }\n }\n</div>\n", styles: ["#tabs-container button{border-radius:0;border-bottom:1px solid var(--bs-border-color)}#tabs-container button.selected{border-bottom:4px solid var(--bs-border-color);font-weight:700}#tabs-container button:not(.selected){padding-bottom:calc(.5rem + 3px)}#tabs-container .btn:disabled{border-color:transparent;border-bottom:1px solid var(--bs-border-color)}\n"] }]
|
|
47
|
+
}], propDecorators: { tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: true }] }], tabChange: [{ type: i0.Output, args: ["tabChange"] }] } });
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Generated bundle index. Do not edit.
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
export { QuangTabsComponent };
|
|
54
|
+
//# sourceMappingURL=quang-components-tabs.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quang-components-tabs.mjs","sources":["../../../projects/quang/components/tabs/tabs.component.ts","../../../projects/quang/components/tabs/tabs.component.html","../../../projects/quang/components/tabs/quang-components-tabs.ts"],"sourcesContent":["import { NgTemplateOutlet } from '@angular/common'\nimport { ChangeDetectionStrategy, Component, TemplateRef, forwardRef, input, output } from '@angular/core'\nimport { NG_VALUE_ACCESSOR } from '@angular/forms'\n\nimport { TranslocoPipe } from '@jsverse/transloco'\n\nimport { QuangBaseComponent } from 'quang/components/shared'\n\nexport interface TabConfiguration {\n id: string\n label: string\n disabled?: boolean\n renderer?: TemplateRef<any>\n}\n\n@Component({\n selector: 'quang-tabs',\n templateUrl: './tabs.component.html',\n styleUrl: './tabs.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => QuangTabsComponent),\n multi: true,\n },\n ],\n imports: [TranslocoPipe, NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class QuangTabsComponent extends QuangBaseComponent<string> {\n tabs = input.required<TabConfiguration[]>()\n\n tabChange = output<string>()\n\n getTabIndex(tab: TabConfiguration): number {\n return this.tabs().findIndex((x) => x.id === tab.id)\n }\n\n isTabSelected(tab: TabConfiguration): boolean {\n return this._value() === tab.id\n }\n\n isTabDisabled(tab: TabConfiguration): boolean {\n return this._isDisabled() || this.isReadonly() || !!tab.disabled\n }\n\n onSelectTab(tab: TabConfiguration): void {\n if (this.isTabDisabled(tab)) return\n this.onChangedHandler(tab.id)\n this.tabChange.emit(tab.id)\n }\n}\n","<div\n class=\"d-flex mt-4 flex-column flex-lg-row\"\n id=\"tabs-container\"\n>\n @for(tab of tabs(); track tab.id) {\n @if(tab.renderer) {\n <ng-container\n [ngTemplateOutlet]=\"tab.renderer\"\n [ngTemplateOutletContext]=\"{ $implicit: tab, selected: isTabSelected(tab), index: getTabIndex(tab) }\"\n ></ng-container>\n } @else {\n <button\n [class.selected]=\"isTabSelected(tab)\"\n [disabled]=\"isTabDisabled(tab)\"\n (click)=\"onSelectTab(tab)\"\n class=\"flex-grow-1 btn btn-only-text\"\n type=\"button\"\n >\n {{ tab.label | transloco }}\n </button>\n }\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "quang",
|
|
3
3
|
"sideEffects": false,
|
|
4
|
-
"version": "20.6.0",
|
|
4
|
+
"version": "20.6.1-0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"tslib": "^2.3.0"
|
|
7
7
|
},
|
|
@@ -107,6 +107,10 @@
|
|
|
107
107
|
"types": "./components/table/index.d.ts",
|
|
108
108
|
"default": "./fesm2022/quang-components-table.mjs"
|
|
109
109
|
},
|
|
110
|
+
"./components/tabs": {
|
|
111
|
+
"types": "./components/tabs/index.d.ts",
|
|
112
|
+
"default": "./fesm2022/quang-components-tabs.mjs"
|
|
113
|
+
},
|
|
110
114
|
"./components/wysiwyg": {
|
|
111
115
|
"types": "./components/wysiwyg/index.d.ts",
|
|
112
116
|
"default": "./fesm2022/quang-components-wysiwyg.mjs"
|