@salas-ds/cli 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/dist/index.js +253 -86
  2. package/package.json +4 -5
  3. package/templates/angular/accordion/accordion-content.component.ts +9 -0
  4. package/templates/angular/accordion/accordion-item.component.ts +138 -0
  5. package/templates/angular/accordion/accordion-trigger.component.ts +9 -0
  6. package/templates/angular/accordion/accordion.component.ts +120 -0
  7. package/templates/angular/accordion/accordion.module.ts +21 -0
  8. package/templates/angular/autocomplete/autocomplete.component.ts +707 -0
  9. package/templates/angular/autocomplete/autocomplete.module.ts +8 -0
  10. package/templates/angular/avatar/avatar-badge.component.ts +18 -0
  11. package/templates/angular/avatar/avatar-fallback.component.ts +39 -0
  12. package/templates/angular/avatar/avatar-group-count.component.ts +46 -0
  13. package/templates/angular/avatar/avatar-group.component.ts +33 -0
  14. package/templates/angular/avatar/avatar-image.component.ts +57 -0
  15. package/templates/angular/avatar/avatar.component.ts +73 -0
  16. package/templates/angular/avatar/avatar.module.ts +27 -0
  17. package/templates/angular/badge/badge.component.ts +84 -0
  18. package/templates/angular/badge/badge.module.ts +9 -0
  19. package/templates/angular/button/button.component.ts +24 -4
  20. package/templates/angular/card/card.component.ts +100 -0
  21. package/templates/angular/card/card.module.ts +8 -0
  22. package/templates/angular/checkbox/checkbox.component.ts +172 -0
  23. package/templates/angular/checkbox/checkbox.module.ts +8 -0
  24. package/templates/angular/datepicker/datepicker.component.ts +660 -0
  25. package/templates/angular/datepicker/datepicker.module.ts +8 -0
  26. package/templates/angular/dialog/dialog-content.component.ts +9 -0
  27. package/templates/angular/dialog/dialog-description.component.ts +17 -0
  28. package/templates/angular/dialog/dialog-footer.component.ts +17 -0
  29. package/templates/angular/dialog/dialog-header.component.ts +14 -0
  30. package/templates/angular/dialog/dialog-title.component.ts +18 -0
  31. package/templates/angular/dialog/dialog-trigger.component.ts +9 -0
  32. package/templates/angular/dialog/dialog.component.ts +212 -0
  33. package/templates/angular/dialog/dialog.module.ts +31 -0
  34. package/templates/angular/input/input.component.ts +229 -0
  35. package/templates/angular/input/input.module.ts +8 -0
  36. package/templates/angular/scroll-area/scroll-area.component.ts +72 -0
  37. package/templates/angular/scroll-area/scroll-area.module.ts +9 -0
  38. package/templates/angular/scroll-area/scroll-bar.component.ts +15 -0
  39. package/templates/angular/select/select.component.ts +292 -0
  40. package/templates/angular/select/select.module.ts +8 -0
  41. package/templates/angular/separator/separator.component.ts +63 -0
  42. package/templates/angular/separator/separator.module.ts +9 -0
  43. package/templates/angular/sheet/sheet-content.component.ts +13 -0
  44. package/templates/angular/sheet/sheet-description.component.ts +29 -0
  45. package/templates/angular/sheet/sheet-footer.component.ts +27 -0
  46. package/templates/angular/sheet/sheet-header.component.ts +26 -0
  47. package/templates/angular/sheet/sheet-title.component.ts +31 -0
  48. package/templates/angular/sheet/sheet-trigger.component.ts +11 -0
  49. package/templates/angular/sheet/sheet.component.ts +251 -0
  50. package/templates/angular/sheet/sheet.module.ts +30 -0
  51. package/templates/angular/sidebar/sidebar-content.component.ts +18 -0
  52. package/templates/angular/sidebar/sidebar-footer.component.ts +20 -0
  53. package/templates/angular/sidebar/sidebar-group-content.component.ts +16 -0
  54. package/templates/angular/sidebar/sidebar-group-label.component.ts +20 -0
  55. package/templates/angular/sidebar/sidebar-group.component.ts +14 -0
  56. package/templates/angular/sidebar/sidebar-header.component.ts +20 -0
  57. package/templates/angular/sidebar/sidebar-inset.component.ts +85 -0
  58. package/templates/angular/sidebar/sidebar-menu-button.component.ts +75 -0
  59. package/templates/angular/sidebar/sidebar-menu-item.component.ts +14 -0
  60. package/templates/angular/sidebar/sidebar-menu.component.ts +19 -0
  61. package/templates/angular/sidebar/sidebar-provider.component.ts +68 -0
  62. package/templates/angular/sidebar/sidebar-trigger.component.ts +58 -0
  63. package/templates/angular/sidebar/sidebar.component.ts +196 -0
  64. package/templates/angular/sidebar/sidebar.module.ts +48 -0
  65. package/templates/angular/sidebar/sidebar.service.ts +93 -0
  66. package/templates/angular/skeleton/skeleton.component.ts +44 -0
  67. package/templates/angular/skeleton/skeleton.module.ts +8 -0
  68. package/templates/angular/spinner/spinner.component.ts +75 -0
  69. package/templates/angular/spinner/spinner.module.ts +8 -0
  70. package/templates/angular/table/table-body.component.ts +23 -0
  71. package/templates/angular/table/table-caption.component.ts +29 -0
  72. package/templates/angular/table/table-cell.component.ts +49 -0
  73. package/templates/angular/table/table-footer.component.ts +32 -0
  74. package/templates/angular/table/table-head.component.ts +48 -0
  75. package/templates/angular/table/table-header.component.ts +28 -0
  76. package/templates/angular/table/table-row.component.ts +36 -0
  77. package/templates/angular/table/table.component.ts +35 -0
  78. package/templates/angular/table/table.module.ts +33 -0
  79. package/templates/angular/tabs/tabs-content.component.ts +71 -0
  80. package/templates/angular/tabs/tabs-list.component.ts +70 -0
  81. package/templates/angular/tabs/tabs-trigger.component.ts +149 -0
  82. package/templates/angular/tabs/tabs.component.ts +155 -0
  83. package/templates/angular/tabs/tabs.module.ts +21 -0
  84. package/templates/angular/textarea/textarea.component.ts +268 -0
  85. package/templates/angular/textarea/textarea.module.ts +8 -0
  86. package/templates/angular/toast/toast.module.ts +8 -0
  87. package/templates/angular/toast/toast.service.ts +104 -0
  88. package/templates/angular/toast/toaster.component.ts +329 -0
  89. package/templates/angular/tooltip/tooltip-content.component.ts +43 -0
  90. package/templates/angular/tooltip/tooltip-trigger.component.ts +13 -0
  91. package/templates/angular/tooltip/tooltip.component.ts +243 -0
  92. package/templates/angular/tooltip/tooltip.module.ts +10 -0
@@ -0,0 +1,48 @@
1
+ import { Component, Input, ViewEncapsulation } from '@angular/core';
2
+ import { cn } from '../utils';
3
+
4
+ @Component({
5
+ selector: 'salas-table-head',
6
+ standalone: true,
7
+ imports: [],
8
+ encapsulation: ViewEncapsulation.None,
9
+ template: `
10
+ <th [class]="headClasses" data-slot="table-head">
11
+ <ng-content></ng-content>
12
+ </th>
13
+ `,
14
+ styles: [`
15
+ salas-table-head {
16
+ display: contents;
17
+ }
18
+
19
+ .salas-table-head {
20
+ height: 2.5rem;
21
+ padding: 0 1rem;
22
+ text-align: left;
23
+ font-weight: 500;
24
+ vertical-align: middle;
25
+ color: var(--salas-gray-500, #71717a);
26
+ white-space: nowrap;
27
+ }
28
+
29
+ .salas-table-head--right {
30
+ text-align: right;
31
+ }
32
+
33
+ [data-theme='dark'] .salas-table-head {
34
+ color: var(--salas-gray-400, #a1a1aa);
35
+ }
36
+ `],
37
+ })
38
+ export class SalasTableHeadComponent {
39
+ @Input() align: 'left' | 'right' | 'center' = 'left';
40
+
41
+ get headClasses(): string {
42
+ return cn(
43
+ 'salas-table-head',
44
+ this.align === 'right' && 'salas-table-head--right',
45
+ this.align === 'center' && 'salas-table-head--center',
46
+ );
47
+ }
48
+ }
@@ -0,0 +1,28 @@
1
+ import { Component, ViewEncapsulation } from '@angular/core';
2
+
3
+ @Component({
4
+ selector: 'salas-table-header',
5
+ standalone: true,
6
+ imports: [],
7
+ encapsulation: ViewEncapsulation.None,
8
+ host: { class: 'salas-table-header-host' },
9
+ template: `
10
+ <thead class="salas-table-header">
11
+ <ng-content></ng-content>
12
+ </thead>
13
+ `,
14
+ styles: [`
15
+ salas-table-header {
16
+ display: contents;
17
+ }
18
+
19
+ .salas-table-header [data-slot="table-row"] {
20
+ border-bottom: 1px solid var(--salas-gray-200, #e4e4e7);
21
+ }
22
+
23
+ [data-theme='dark'] .salas-table-header [data-slot="table-row"] {
24
+ border-bottom-color: var(--salas-gray-800, #27272a);
25
+ }
26
+ `],
27
+ })
28
+ export class SalasTableHeaderComponent {}
@@ -0,0 +1,36 @@
1
+ import { Component, ViewEncapsulation } from '@angular/core';
2
+
3
+ @Component({
4
+ selector: 'salas-table-row',
5
+ standalone: true,
6
+ imports: [],
7
+ encapsulation: ViewEncapsulation.None,
8
+ template: `
9
+ <tr class="salas-table-row" data-slot="table-row">
10
+ <ng-content></ng-content>
11
+ </tr>
12
+ `,
13
+ styles: [`
14
+ salas-table-row {
15
+ display: contents;
16
+ }
17
+
18
+ .salas-table-row {
19
+ border-bottom: 1px solid var(--salas-gray-200, #e4e4e7);
20
+ transition: background-color 0.15s;
21
+ }
22
+
23
+ .salas-table-row:hover {
24
+ background-color: var(--salas-gray-100, #f4f4f5);
25
+ }
26
+
27
+ [data-theme='dark'] .salas-table-row {
28
+ border-bottom-color: var(--salas-gray-800, #27272a);
29
+ }
30
+
31
+ [data-theme='dark'] .salas-table-row:hover {
32
+ background-color: var(--salas-gray-800, #27272a);
33
+ }
34
+ `],
35
+ })
36
+ export class SalasTableRowComponent {}
@@ -0,0 +1,35 @@
1
+ import { Component, ViewEncapsulation } from '@angular/core';
2
+
3
+ @Component({
4
+ selector: 'salas-table',
5
+ standalone: true,
6
+ imports: [],
7
+ encapsulation: ViewEncapsulation.None,
8
+ template: `
9
+ <div class="salas-table-wrapper">
10
+ <table class="salas-table">
11
+ <ng-content></ng-content>
12
+ </table>
13
+ </div>
14
+ `,
15
+ styles: [`
16
+ .salas-table-wrapper {
17
+ position: relative;
18
+ width: 100%;
19
+ overflow: auto;
20
+ }
21
+
22
+ .salas-table {
23
+ width: 100%;
24
+ caption-side: bottom;
25
+ border-collapse: collapse;
26
+ font-size: 0.875rem;
27
+ color: var(--salas-text, #09090b);
28
+ }
29
+
30
+ [data-theme='dark'] .salas-table {
31
+ color: var(--salas-text, #fafafa);
32
+ }
33
+ `],
34
+ })
35
+ export class SalasTableComponent {}
@@ -0,0 +1,33 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { SalasTableComponent } from './table.component';
3
+ import { SalasTableHeaderComponent } from './table-header.component';
4
+ import { SalasTableBodyComponent } from './table-body.component';
5
+ import { SalasTableFooterComponent } from './table-footer.component';
6
+ import { SalasTableRowComponent } from './table-row.component';
7
+ import { SalasTableHeadComponent } from './table-head.component';
8
+ import { SalasTableCellComponent } from './table-cell.component';
9
+ import { SalasTableCaptionComponent } from './table-caption.component';
10
+
11
+ @NgModule({
12
+ imports: [
13
+ SalasTableComponent,
14
+ SalasTableHeaderComponent,
15
+ SalasTableBodyComponent,
16
+ SalasTableFooterComponent,
17
+ SalasTableRowComponent,
18
+ SalasTableHeadComponent,
19
+ SalasTableCellComponent,
20
+ SalasTableCaptionComponent,
21
+ ],
22
+ exports: [
23
+ SalasTableComponent,
24
+ SalasTableHeaderComponent,
25
+ SalasTableBodyComponent,
26
+ SalasTableFooterComponent,
27
+ SalasTableRowComponent,
28
+ SalasTableHeadComponent,
29
+ SalasTableCellComponent,
30
+ SalasTableCaptionComponent,
31
+ ],
32
+ })
33
+ export class SalasTableModule {}
@@ -0,0 +1,71 @@
1
+ import { Component, Input, ViewEncapsulation } from '@angular/core';
2
+ import { cn } from '../utils';
3
+
4
+ export type TabsOrientation = 'horizontal' | 'vertical';
5
+ export type TabsVariant = 'default' | 'line';
6
+
7
+ export interface TabsProps {
8
+ defaultValue?: string;
9
+ value?: string;
10
+ orientation?: TabsOrientation;
11
+ variant?: TabsVariant;
12
+ }
13
+
14
+ export interface TabsTriggerProps {
15
+ value: string;
16
+ disabled?: boolean;
17
+ }
18
+
19
+ export interface TabsContentProps {
20
+ value: string;
21
+ }
22
+
23
+
24
+ @Component({
25
+ selector: 'salas-tabs-content',
26
+ standalone: true,
27
+ imports: [],
28
+ encapsulation: ViewEncapsulation.None,
29
+ template: `
30
+ @if (isActive) {
31
+ <div
32
+ [class]="contentClasses"
33
+ role="tabpanel"
34
+ [attr.data-state]="isActive ? 'active' : 'inactive'"
35
+ [attr.aria-hidden]="!isActive"
36
+ >
37
+ <ng-content></ng-content>
38
+ </div>
39
+ }
40
+ `,
41
+ styles: [`
42
+ .salas-tabs-content {
43
+ margin-top: 0.5rem;
44
+ padding: 1rem;
45
+ border-radius: 0.375rem;
46
+ outline: none;
47
+ }
48
+
49
+ .salas-tabs-content:focus-visible {
50
+ outline: 2px solid var(--salas-primary-500);
51
+ outline-offset: 2px;
52
+ }
53
+
54
+ [data-theme='dark'] .salas-tabs-content {
55
+ color: var(--salas-gray-100);
56
+ }
57
+ `],
58
+ })
59
+ export class SalasTabsContentComponent implements TabsContentProps {
60
+ @Input() value!: string;
61
+
62
+ isActive = false;
63
+
64
+ get contentClasses(): string {
65
+ return cn('salas-tabs-content');
66
+ }
67
+
68
+ setActive(active: boolean): void {
69
+ this.isActive = active;
70
+ }
71
+ }
@@ -0,0 +1,70 @@
1
+ import { Component, Input, ViewEncapsulation } from '@angular/core';
2
+ import { cn } from '../utils';
3
+
4
+ export type TabsOrientation = 'horizontal' | 'vertical';
5
+ export type TabsVariant = 'default' | 'line';
6
+
7
+ export interface TabsProps {
8
+ defaultValue?: string;
9
+ value?: string;
10
+ orientation?: TabsOrientation;
11
+ variant?: TabsVariant;
12
+ }
13
+
14
+ export interface TabsTriggerProps {
15
+ value: string;
16
+ disabled?: boolean;
17
+ }
18
+
19
+ export interface TabsContentProps {
20
+ value: string;
21
+ }
22
+
23
+
24
+ @Component({
25
+ selector: 'salas-tabs-list',
26
+ standalone: true,
27
+ imports: [],
28
+ encapsulation: ViewEncapsulation.None,
29
+ template: `
30
+ <div [class]="listClasses" role="tablist">
31
+ <ng-content></ng-content>
32
+ </div>
33
+ `,
34
+ styles: [`
35
+ .salas-tabs-list {
36
+ display: inline-flex;
37
+ align-items: center;
38
+ justify-content: center;
39
+ border-radius: 0.375rem;
40
+ background-color: var(--salas-gray-100);
41
+ padding: 0.25rem;
42
+ color: var(--salas-gray-600);
43
+ }
44
+
45
+ .salas-tabs-list--vertical {
46
+ flex-direction: column;
47
+ align-items: stretch;
48
+ width: auto;
49
+ }
50
+
51
+ [data-theme='dark'] .salas-tabs-list {
52
+ background-color: var(--salas-gray-800);
53
+ color: var(--salas-gray-300);
54
+ }
55
+ `],
56
+ })
57
+ export class SalasTabsListComponent {
58
+ orientation: TabsOrientation = 'horizontal';
59
+
60
+ get listClasses(): string {
61
+ return cn(
62
+ 'salas-tabs-list',
63
+ this.orientation === 'vertical' && 'salas-tabs-list--vertical',
64
+ );
65
+ }
66
+
67
+ setOrientation(orientation: TabsOrientation): void {
68
+ this.orientation = orientation;
69
+ }
70
+ }
@@ -0,0 +1,149 @@
1
+ import { Component, Input, Output, EventEmitter, ViewEncapsulation } from '@angular/core';
2
+ import { cn } from '../utils';
3
+
4
+ export type TabsOrientation = 'horizontal' | 'vertical';
5
+ export type TabsVariant = 'default' | 'line';
6
+
7
+ export interface TabsProps {
8
+ defaultValue?: string;
9
+ value?: string;
10
+ orientation?: TabsOrientation;
11
+ variant?: TabsVariant;
12
+ }
13
+
14
+ export interface TabsTriggerProps {
15
+ value: string;
16
+ disabled?: boolean;
17
+ }
18
+
19
+ export interface TabsContentProps {
20
+ value: string;
21
+ }
22
+
23
+
24
+ @Component({
25
+ selector: 'salas-tabs-trigger',
26
+ standalone: true,
27
+ imports: [],
28
+ encapsulation: ViewEncapsulation.None,
29
+ template: `
30
+ <button
31
+ type="button"
32
+ [class]="triggerClasses"
33
+ [disabled]="disabled"
34
+ (click)="onClick()"
35
+ [attr.aria-selected]="isActive"
36
+ role="tab"
37
+ [attr.data-state]="isActive ? 'active' : 'inactive'"
38
+ >
39
+ <ng-content></ng-content>
40
+ </button>
41
+ `,
42
+ styles: [`
43
+ .salas-tabs-trigger {
44
+ display: inline-flex;
45
+ align-items: center;
46
+ justify-content: center;
47
+ white-space: nowrap;
48
+ border-radius: 0.25rem;
49
+ padding: 0.5rem 1rem;
50
+ font-size: 0.875rem;
51
+ font-weight: 500;
52
+ transition: all 0.2s;
53
+ cursor: pointer;
54
+ border: none;
55
+ background: transparent;
56
+ outline: none;
57
+ color: var(--salas-gray-600);
58
+ }
59
+
60
+ .salas-tabs-trigger:hover:not(:disabled) {
61
+ color: var(--salas-gray-900);
62
+ background-color: var(--salas-gray-50);
63
+ }
64
+
65
+ .salas-tabs-trigger:focus-visible {
66
+ outline: 2px solid var(--salas-primary-500);
67
+ outline-offset: 2px;
68
+ }
69
+
70
+ .salas-tabs-trigger:disabled {
71
+ opacity: 0.5;
72
+ cursor: not-allowed;
73
+ }
74
+
75
+ .salas-tabs-trigger--active {
76
+ background-color: white;
77
+ color: var(--salas-gray-900);
78
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
79
+ }
80
+
81
+ .salas-tabs-trigger--line {
82
+ border-radius: 0;
83
+ background: transparent;
84
+ border-bottom: 2px solid transparent;
85
+ box-shadow: none;
86
+ }
87
+
88
+ .salas-tabs-trigger--line.salas-tabs-trigger--active {
89
+ border-bottom-color: var(--salas-primary-500);
90
+ background: transparent;
91
+ box-shadow: none;
92
+ }
93
+
94
+ .salas-tabs-trigger--vertical {
95
+ justify-content: flex-start;
96
+ width: 100%;
97
+ }
98
+
99
+ [data-theme='dark'] .salas-tabs-trigger {
100
+ color: var(--salas-gray-300);
101
+ }
102
+
103
+ [data-theme='dark'] .salas-tabs-trigger:hover:not(:disabled) {
104
+ color: var(--salas-gray-100);
105
+ background-color: var(--salas-gray-800);
106
+ }
107
+
108
+ [data-theme='dark'] .salas-tabs-trigger--active {
109
+ background-color: var(--salas-gray-900);
110
+ color: var(--salas-gray-100);
111
+ }
112
+ `],
113
+ })
114
+ export class SalasTabsTriggerComponent implements TabsTriggerProps {
115
+ @Input() value!: string;
116
+ @Input() disabled = false;
117
+
118
+ @Output() activated = new EventEmitter<string>();
119
+
120
+ isActive = false;
121
+ orientation: TabsOrientation = 'horizontal';
122
+ variant: TabsVariant = 'default';
123
+
124
+ get triggerClasses(): string {
125
+ return cn(
126
+ 'salas-tabs-trigger',
127
+ this.isActive && 'salas-tabs-trigger--active',
128
+ this.variant === 'line' && 'salas-tabs-trigger--line',
129
+ this.orientation === 'vertical' && 'salas-tabs-trigger--vertical',
130
+ );
131
+ }
132
+
133
+ setActive(active: boolean): void {
134
+ this.isActive = active;
135
+ }
136
+
137
+ setOrientation(orientation: TabsOrientation): void {
138
+ this.orientation = orientation;
139
+ }
140
+
141
+ setVariant(variant: TabsVariant): void {
142
+ this.variant = variant;
143
+ }
144
+
145
+ onClick(): void {
146
+ if (this.disabled) return;
147
+ this.activated.emit(this.value);
148
+ }
149
+ }
@@ -0,0 +1,155 @@
1
+ import {
2
+ Component,
3
+ Input,
4
+ Output,
5
+ EventEmitter,
6
+ ContentChildren,
7
+ QueryList,
8
+ AfterContentInit,
9
+ OnDestroy,
10
+ OnChanges,
11
+ SimpleChanges,
12
+ ViewEncapsulation,
13
+ } from '@angular/core';
14
+ import { cn } from '../utils';
15
+ import { SalasTabsTriggerComponent } from './tabs-trigger.component';
16
+ import { SalasTabsContentComponent } from './tabs-content.component';
17
+ import { SalasTabsListComponent } from './tabs-list.component';
18
+
19
+ export type TabsOrientation = 'horizontal' | 'vertical';
20
+ export type TabsVariant = 'default' | 'line';
21
+
22
+ export interface TabsProps {
23
+ defaultValue?: string;
24
+ value?: string;
25
+ orientation?: TabsOrientation;
26
+ variant?: TabsVariant;
27
+ }
28
+
29
+ export interface TabsTriggerProps {
30
+ value: string;
31
+ disabled?: boolean;
32
+ }
33
+
34
+ export interface TabsContentProps {
35
+ value: string;
36
+ }
37
+
38
+
39
+ @Component({
40
+ selector: 'salas-tabs',
41
+ standalone: true,
42
+ imports: [],
43
+ encapsulation: ViewEncapsulation.None,
44
+ template: `
45
+ <div [class]="tabsClasses">
46
+ <ng-content></ng-content>
47
+ </div>
48
+ `,
49
+ styles: [`
50
+ .salas-tabs {
51
+ width: 100%;
52
+ }
53
+
54
+ .salas-tabs--vertical {
55
+ display: flex;
56
+ flex-direction: row;
57
+ gap: 1rem;
58
+ }
59
+ `],
60
+ })
61
+ export class SalasTabsComponent implements TabsProps, AfterContentInit, OnChanges, OnDestroy {
62
+ @Input() defaultValue?: string;
63
+ @Input() value?: string;
64
+ @Input() orientation: TabsOrientation = 'horizontal';
65
+ @Input() variant: TabsVariant = 'default';
66
+
67
+ @Output() valueChange = new EventEmitter<string>();
68
+
69
+ @ContentChildren(SalasTabsListComponent) lists!: QueryList<SalasTabsListComponent>;
70
+ @ContentChildren(SalasTabsTriggerComponent, { descendants: true }) triggers!: QueryList<SalasTabsTriggerComponent>;
71
+ @ContentChildren(SalasTabsContentComponent, { descendants: true }) contents!: QueryList<SalasTabsContentComponent>;
72
+
73
+ private _activeValue: string = '';
74
+ private unsubscribes: Array<() => void> = [];
75
+
76
+ ngOnChanges(changes: SimpleChanges): void {
77
+ if (changes['value'] && this.value !== undefined) {
78
+ this._activeValue = this.value;
79
+ this.updateTabs();
80
+ }
81
+ }
82
+
83
+ ngAfterContentInit(): void {
84
+ if (!this._activeValue) {
85
+ this._activeValue = this.value || this.defaultValue || '';
86
+ }
87
+ this.updateTabs();
88
+
89
+ this.triggers.changes.subscribe(() => {
90
+ this.clearSubscriptions();
91
+ this.setupTriggers();
92
+ this.updateTabs();
93
+ });
94
+
95
+ this.contents.changes.subscribe(() => {
96
+ this.updateTabs();
97
+ });
98
+
99
+ this.setupTriggers();
100
+ }
101
+
102
+ ngOnDestroy(): void {
103
+ this.clearSubscriptions();
104
+ }
105
+
106
+ private setupTriggers(): void {
107
+ this.triggers.forEach((trigger) => {
108
+ const sub = trigger.activated.subscribe((value) => {
109
+ this.setActiveValue(value);
110
+ });
111
+ this.unsubscribes.push(() => sub.unsubscribe());
112
+ });
113
+ }
114
+
115
+ private clearSubscriptions(): void {
116
+ this.unsubscribes.forEach((unsub) => unsub());
117
+ this.unsubscribes = [];
118
+ }
119
+
120
+ get tabsClasses(): string {
121
+ return cn('salas-tabs', this.orientation === 'vertical' && 'salas-tabs--vertical');
122
+ }
123
+
124
+ get activeValue(): string {
125
+ return this._activeValue;
126
+ }
127
+
128
+ setActiveValue(value: string): void {
129
+ if (this._activeValue === value) return;
130
+ this._activeValue = value;
131
+ if (!this.value) {
132
+ // Only emit if not controlled
133
+ this.valueChange.emit(value);
134
+ }
135
+ this.updateTabs();
136
+ }
137
+
138
+ private updateTabs(): void {
139
+ const activeValue = this._activeValue || this.defaultValue || '';
140
+
141
+ this.triggers.forEach((trigger) => {
142
+ trigger.setActive(trigger.value === activeValue);
143
+ trigger.setOrientation(this.orientation);
144
+ trigger.setVariant(this.variant);
145
+ });
146
+
147
+ this.contents.forEach((content) => {
148
+ content.setActive(content.value === activeValue);
149
+ });
150
+
151
+ this.lists.forEach((list) => {
152
+ list.setOrientation(this.orientation);
153
+ });
154
+ }
155
+ }
@@ -0,0 +1,21 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { SalasTabsComponent } from './tabs.component';
3
+ import { SalasTabsListComponent } from './tabs-list.component';
4
+ import { SalasTabsTriggerComponent } from './tabs-trigger.component';
5
+ import { SalasTabsContentComponent } from './tabs-content.component';
6
+
7
+ @NgModule({
8
+ imports: [
9
+ SalasTabsComponent,
10
+ SalasTabsListComponent,
11
+ SalasTabsTriggerComponent,
12
+ SalasTabsContentComponent,
13
+ ],
14
+ exports: [
15
+ SalasTabsComponent,
16
+ SalasTabsListComponent,
17
+ SalasTabsTriggerComponent,
18
+ SalasTabsContentComponent,
19
+ ],
20
+ })
21
+ export class SalasTabsModule {}