@devstroupe/devkit-cli 1.0.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 (170) hide show
  1. package/README.md +40 -0
  2. package/dist/boilerplates/angular-template/.dockerignore +4 -0
  3. package/dist/boilerplates/angular-template/.postcssrc.json +5 -0
  4. package/dist/boilerplates/angular-template/Dockerfile +14 -0
  5. package/dist/boilerplates/angular-template/angular.json +85 -0
  6. package/dist/boilerplates/angular-template/components.json +5 -0
  7. package/dist/boilerplates/angular-template/framework.code-workspace +7 -0
  8. package/dist/boilerplates/angular-template/nginx.conf +23 -0
  9. package/dist/boilerplates/angular-template/node_modules/.bin/browserslist +21 -0
  10. package/dist/boilerplates/angular-template/node_modules/.bin/jiti +21 -0
  11. package/dist/boilerplates/angular-template/node_modules/.bin/lessc +21 -0
  12. package/dist/boilerplates/angular-template/node_modules/.bin/ng +21 -0
  13. package/dist/boilerplates/angular-template/node_modules/.bin/ng-xi18n +21 -0
  14. package/dist/boilerplates/angular-template/node_modules/.bin/ngc +21 -0
  15. package/dist/boilerplates/angular-template/node_modules/.bin/sass +21 -0
  16. package/dist/boilerplates/angular-template/node_modules/.bin/terser +21 -0
  17. package/dist/boilerplates/angular-template/node_modules/.bin/tsc +21 -0
  18. package/dist/boilerplates/angular-template/node_modules/.bin/tsserver +21 -0
  19. package/dist/boilerplates/angular-template/node_modules/.bin/vite +21 -0
  20. package/dist/boilerplates/angular-template/node_modules/.bin/vitest +21 -0
  21. package/dist/boilerplates/angular-template/node_modules/.bin/yaml +21 -0
  22. package/dist/boilerplates/angular-template/package.json +47 -0
  23. package/dist/boilerplates/angular-template/postcss.config.js +5 -0
  24. package/dist/boilerplates/angular-template/proxy.conf.json +7 -0
  25. package/dist/boilerplates/angular-template/src/app/app.component.html +3 -0
  26. package/dist/boilerplates/angular-template/src/app/app.component.ts +12 -0
  27. package/dist/boilerplates/angular-template/src/app/app.config.ts +59 -0
  28. package/dist/boilerplates/angular-template/src/app/app.entity-routes.ts +4 -0
  29. package/dist/boilerplates/angular-template/src/app/app.routes.ts +25 -0
  30. package/dist/boilerplates/angular-template/src/app/core/guards/auth.guard.ts +16 -0
  31. package/dist/boilerplates/angular-template/src/app/core/services/auth.service.ts +98 -0
  32. package/dist/boilerplates/angular-template/src/app/modules/auth/login/login.component.html +51 -0
  33. package/dist/boilerplates/angular-template/src/app/modules/auth/login/login.component.ts +47 -0
  34. package/dist/boilerplates/angular-template/src/app/modules/auth/register/register.component.html +59 -0
  35. package/dist/boilerplates/angular-template/src/app/modules/auth/register/register.component.ts +47 -0
  36. package/dist/boilerplates/angular-template/src/app/modules/dashboard/dashboard.component.html +14 -0
  37. package/dist/boilerplates/angular-template/src/app/modules/dashboard/dashboard.component.ts +23 -0
  38. package/dist/boilerplates/angular-template/src/app/shared/interceptors/tenant.interceptor.ts +25 -0
  39. package/dist/boilerplates/angular-template/src/index.html +64 -0
  40. package/dist/boilerplates/angular-template/src/main.ts +6 -0
  41. package/dist/boilerplates/angular-template/src/styles.css +9 -0
  42. package/dist/boilerplates/angular-template/tsconfig.json +36 -0
  43. package/dist/boilerplates/nest-template/Dockerfile +16 -0
  44. package/dist/boilerplates/nest-template/node_modules/.bin/acorn +21 -0
  45. package/dist/boilerplates/nest-template/node_modules/.bin/nest +21 -0
  46. package/dist/boilerplates/nest-template/node_modules/.bin/prettier +21 -0
  47. package/dist/boilerplates/nest-template/node_modules/.bin/tsc +21 -0
  48. package/dist/boilerplates/nest-template/node_modules/.bin/tsserver +21 -0
  49. package/dist/boilerplates/nest-template/node_modules/.bin/typeorm +21 -0
  50. package/dist/boilerplates/nest-template/node_modules/.bin/typeorm-ts-node-commonjs +21 -0
  51. package/dist/boilerplates/nest-template/node_modules/.bin/typeorm-ts-node-esm +21 -0
  52. package/dist/boilerplates/nest-template/node_modules/.bin/webpack +21 -0
  53. package/dist/boilerplates/nest-template/package.json +43 -0
  54. package/dist/boilerplates/nest-template/src/app.module.ts +24 -0
  55. package/dist/boilerplates/nest-template/src/database/data-source.ts +16 -0
  56. package/dist/boilerplates/nest-template/src/database/migrations/1700000000000-create-users.ts +26 -0
  57. package/dist/boilerplates/nest-template/src/main.ts +46 -0
  58. package/dist/boilerplates/nest-template/src/modules/auth/auth.controller.ts +34 -0
  59. package/dist/boilerplates/nest-template/src/modules/auth/auth.module.ts +22 -0
  60. package/dist/boilerplates/nest-template/src/modules/auth/auth.service.ts +57 -0
  61. package/dist/boilerplates/nest-template/src/modules/auth/current-user.decorator.ts +8 -0
  62. package/dist/boilerplates/nest-template/src/modules/auth/jwt-auth.guard.ts +31 -0
  63. package/dist/boilerplates/nest-template/src/modules/auth/roles.decorator.ts +4 -0
  64. package/dist/boilerplates/nest-template/src/modules/auth/roles.guard.ts +24 -0
  65. package/dist/boilerplates/nest-template/src/modules/user/database-seed.service.ts +47 -0
  66. package/dist/boilerplates/nest-template/src/modules/user/domain/user.repository.ts +9 -0
  67. package/dist/boilerplates/nest-template/src/modules/user/domain/user.ts +9 -0
  68. package/dist/boilerplates/nest-template/src/modules/user/infra/database/user.orm-entity.ts +31 -0
  69. package/dist/boilerplates/nest-template/src/modules/user/infra/database/user.repository.adapter.ts +53 -0
  70. package/dist/boilerplates/nest-template/src/modules/user/service/user.service.ts +44 -0
  71. package/dist/boilerplates/nest-template/src/modules/user/user.module.ts +20 -0
  72. package/dist/boilerplates/nest-template/tsconfig.build.json +4 -0
  73. package/dist/boilerplates/nest-template/tsconfig.json +21 -0
  74. package/dist/index.d.ts +2 -0
  75. package/dist/index.js +1967 -0
  76. package/dist/migrations/sort-entities.d.ts +2 -0
  77. package/dist/migrations/sort-entities.js +30 -0
  78. package/dist/rules/linter-rules.d.ts +12 -0
  79. package/dist/rules/linter-rules.js +338 -0
  80. package/dist/rules/linter-rules.test.d.ts +1 -0
  81. package/dist/rules/linter-rules.test.js +214 -0
  82. package/dist/templates/angular/dialog-handler.template.d.ts +2 -0
  83. package/dist/templates/angular/dialog-handler.template.js +49 -0
  84. package/dist/templates/angular/form.template.d.ts +3 -0
  85. package/dist/templates/angular/form.template.js +453 -0
  86. package/dist/templates/angular/index.d.ts +4 -0
  87. package/dist/templates/angular/index.js +20 -0
  88. package/dist/templates/angular/list.template.d.ts +3 -0
  89. package/dist/templates/angular/list.template.js +213 -0
  90. package/dist/templates/angular/service.template.d.ts +1 -0
  91. package/dist/templates/angular/service.template.js +20 -0
  92. package/dist/templates/cli-templates.d.ts +2 -0
  93. package/dist/templates/cli-templates.js +18 -0
  94. package/dist/templates/nest/crud.templates.d.ts +9 -0
  95. package/dist/templates/nest/crud.templates.js +362 -0
  96. package/dist/templates/nest/index.d.ts +3 -0
  97. package/dist/templates/nest/index.js +19 -0
  98. package/dist/templates/nest/microservice.templates.d.ts +4 -0
  99. package/dist/templates/nest/microservice.templates.js +157 -0
  100. package/dist/templates/nest/migration.template.d.ts +3 -0
  101. package/dist/templates/nest/migration.template.js +127 -0
  102. package/dist/templates/relationship-templates.test.d.ts +1 -0
  103. package/dist/templates/relationship-templates.test.js +181 -0
  104. package/dist/templates/shared/names.d.ts +3 -0
  105. package/dist/templates/shared/names.js +14 -0
  106. package/dist/templates/shared/relationships.d.ts +27 -0
  107. package/dist/templates/shared/relationships.js +96 -0
  108. package/dist/templates/ui/components/avatar.template.d.ts +3 -0
  109. package/dist/templates/ui/components/avatar.template.js +66 -0
  110. package/dist/templates/ui/components/badge.template.d.ts +3 -0
  111. package/dist/templates/ui/components/badge.template.js +27 -0
  112. package/dist/templates/ui/components/button.template.d.ts +5 -0
  113. package/dist/templates/ui/components/button.template.js +64 -0
  114. package/dist/templates/ui/components/card-list.template.d.ts +5 -0
  115. package/dist/templates/ui/components/card-list.template.js +79 -0
  116. package/dist/templates/ui/components/dialog.template.d.ts +5 -0
  117. package/dist/templates/ui/components/dialog.template.js +51 -0
  118. package/dist/templates/ui/components/filter.template.d.ts +4 -0
  119. package/dist/templates/ui/components/filter.template.js +218 -0
  120. package/dist/templates/ui/components/index.d.ts +10 -0
  121. package/dist/templates/ui/components/index.js +26 -0
  122. package/dist/templates/ui/components/input.template.d.ts +4 -0
  123. package/dist/templates/ui/components/input.template.js +76 -0
  124. package/dist/templates/ui/components/select.template.d.ts +4 -0
  125. package/dist/templates/ui/components/select.template.js +176 -0
  126. package/dist/templates/ui/components/simple-list.template.d.ts +5 -0
  127. package/dist/templates/ui/components/simple-list.template.js +89 -0
  128. package/dist/templates/ui/components/table.template.d.ts +5 -0
  129. package/dist/templates/ui/components/table.template.js +112 -0
  130. package/dist/templates/ui/index.d.ts +9 -0
  131. package/dist/templates/ui/index.js +25 -0
  132. package/dist/templates/ui/layout/header.template.d.ts +5 -0
  133. package/dist/templates/ui/layout/header.template.js +236 -0
  134. package/dist/templates/ui/layout/index.d.ts +4 -0
  135. package/dist/templates/ui/layout/index.js +20 -0
  136. package/dist/templates/ui/layout/main-layout.template.d.ts +5 -0
  137. package/dist/templates/ui/layout/main-layout.template.js +126 -0
  138. package/dist/templates/ui/layout/shell.template.d.ts +5 -0
  139. package/dist/templates/ui/layout/shell.template.js +76 -0
  140. package/dist/templates/ui/layout/sidebar.template.d.ts +5 -0
  141. package/dist/templates/ui/layout/sidebar.template.js +412 -0
  142. package/dist/templates/ui/playground.template.d.ts +5 -0
  143. package/dist/templates/ui/playground.template.js +570 -0
  144. package/dist/templates/ui/readme.template.d.ts +1 -0
  145. package/dist/templates/ui/readme.template.js +23 -0
  146. package/dist/templates/ui/shared/colors.d.ts +1 -0
  147. package/dist/templates/ui/shared/colors.js +31 -0
  148. package/dist/templates/ui/shared/profile-component.template.d.ts +5 -0
  149. package/dist/templates/ui/shared/profile-component.template.js +403 -0
  150. package/dist/templates/ui/shared/profile-service.template.d.ts +1 -0
  151. package/dist/templates/ui/shared/profile-service.template.js +44 -0
  152. package/dist/templates/ui/shared/theme-service.template.d.ts +1 -0
  153. package/dist/templates/ui/shared/theme-service.template.js +47 -0
  154. package/dist/templates/ui/spartan/badge-directive.template.d.ts +3 -0
  155. package/dist/templates/ui/spartan/badge-directive.template.js +50 -0
  156. package/dist/templates/ui/spartan/button-directive.template.d.ts +3 -0
  157. package/dist/templates/ui/spartan/button-directive.template.js +82 -0
  158. package/dist/templates/ui/spartan/button-token.template.d.ts +3 -0
  159. package/dist/templates/ui/spartan/button-token.template.js +31 -0
  160. package/dist/templates/ui/spartan/hlm-core.template.d.ts +3 -0
  161. package/dist/templates/ui/spartan/hlm-core.template.js +322 -0
  162. package/dist/templates/ui/spartan/index.d.ts +5 -0
  163. package/dist/templates/ui/spartan/index.js +21 -0
  164. package/dist/templates/ui/spartan/input-directive.template.d.ts +3 -0
  165. package/dist/templates/ui/spartan/input-directive.template.js +31 -0
  166. package/dist/templates/ui/theme-css.template.d.ts +7 -0
  167. package/dist/templates/ui/theme-css.template.js +210 -0
  168. package/dist/templates/ui-templates.d.ts +1 -0
  169. package/dist/templates/ui-templates.js +17 -0
  170. package/package.json +50 -0
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./shell.template"), exports);
18
+ __exportStar(require("./sidebar.template"), exports);
19
+ __exportStar(require("./header.template"), exports);
20
+ __exportStar(require("./main-layout.template"), exports);
@@ -0,0 +1,5 @@
1
+ export declare function devkitMainLayoutTemplate(projectName: string, brandLogo?: string, brandLogoCollapsed?: string): {
2
+ ts: string;
3
+ html: string;
4
+ css: string;
5
+ };
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.devkitMainLayoutTemplate = devkitMainLayoutTemplate;
4
+ function devkitMainLayoutTemplate(projectName, brandLogo = '', brandLogoCollapsed = '') {
5
+ return {
6
+ ts: `import { Component, OnInit } from '@angular/core';
7
+ import { CommonModule } from '@angular/common';
8
+ import { RouterModule, Router } from '@angular/router';
9
+ import { DevkitShellComponent } from '../../components/devkit/shell/shell.component';
10
+ import { DevkitSidebarComponent, INavigationItem } from '../../components/devkit/sidebar/sidebar.component';
11
+ import { DevkitHeaderComponent } from '../../components/devkit/header/header.component';
12
+ import { APP_NAVIGATION } from '../../../app.navigation';
13
+ import { AuthService } from '../../../core/services/auth.service';
14
+ import { ThemeService } from '../../../core/services/theme.service';
15
+
16
+ @Component({
17
+ selector: 'app-main-layout',
18
+ standalone: true,
19
+ imports: [
20
+ CommonModule,
21
+ RouterModule,
22
+ DevkitShellComponent,
23
+ DevkitSidebarComponent,
24
+ DevkitHeaderComponent
25
+ ],
26
+ templateUrl: './main-layout.component.html',
27
+ styleUrls: ['./main-layout.component.css']
28
+ })
29
+ export class MainLayoutComponent implements OnInit {
30
+ isCollapsed = typeof window !== 'undefined' && window.innerWidth <= 768;
31
+
32
+ menuItems: INavigationItem[] = APP_NAVIGATION;
33
+ currentUser$ = this.authService.currentUser$;
34
+ isDark$ = this.themeService.isDark$;
35
+
36
+ brandLogo = '${brandLogo}';
37
+ brandLogoCollapsed = '${brandLogoCollapsed}';
38
+
39
+ constructor(
40
+ private router: Router,
41
+ private authService: AuthService,
42
+ private themeService: ThemeService
43
+ ) {}
44
+
45
+ ngOnInit(): void {}
46
+
47
+ onLogout(): void {
48
+ this.authService.logout();
49
+ this.router.navigate(['/login']);
50
+ }
51
+
52
+ onToggleTheme(): void {
53
+ this.themeService.toggle();
54
+ }
55
+
56
+ onOpenProfile(): void {
57
+ this.router.navigate(['/profile']);
58
+ }
59
+ }
60
+ `,
61
+ html: `<devkit-shell [isCollapsed]="isCollapsed">
62
+ <button
63
+ *ngIf="!isCollapsed"
64
+ type="button"
65
+ class="dt-mobile-sidebar-backdrop"
66
+ aria-label="Fechar menu"
67
+ (click)="isCollapsed = true"
68
+ ></button>
69
+
70
+ <!-- Sidebar -->
71
+ <devkit-sidebar
72
+ [items]="menuItems"
73
+ brandName="${projectName}"
74
+ [brandLogo]="brandLogo"
75
+ [brandLogoCollapsed]="brandLogoCollapsed"
76
+ [isCollapsed]="isCollapsed"
77
+ (closeSidebar)="isCollapsed = true"
78
+ >
79
+ <!-- Slot personalizado no rodapé -->
80
+ <div devkit-sidebar-footer class="text-[10px] text-center text-muted-foreground">
81
+ DevsTroupe DevKit v1.0.0
82
+ </div>
83
+ </devkit-sidebar>
84
+
85
+ <!-- Header / Topbar -->
86
+ <devkit-header
87
+ [user]="currentUser$ | async"
88
+ [isSidebarCollapsed]="isCollapsed"
89
+ [isDarkMode]="(isDark$ | async) ?? false"
90
+ (toggleSidebar)="isCollapsed = !isCollapsed"
91
+ (logout)="onLogout()"
92
+ (toggleTheme)="onToggleTheme()"
93
+ (openProfile)="onOpenProfile()"
94
+ ></devkit-header>
95
+
96
+ <!-- Área de Roteamento Filho -->
97
+ <router-outlet></router-outlet>
98
+
99
+ </devkit-shell>
100
+ `,
101
+ css: `:host {
102
+ display: block;
103
+ width: 100%;
104
+ height: 100vh;
105
+ }
106
+
107
+ .dt-mobile-sidebar-backdrop {
108
+ display: none;
109
+ }
110
+
111
+ @media (max-width: 768px) {
112
+ .dt-mobile-sidebar-backdrop {
113
+ display: block;
114
+ position: fixed;
115
+ inset: 0;
116
+ z-index: 55;
117
+ border: 0;
118
+ background: rgb(0 0 0 / 0.45);
119
+ cursor: default;
120
+ }
121
+ }
122
+ `
123
+ };
124
+ }
125
+ // 15. Template do arquivo hlm.ts local do Spartan Core
126
+ // 15. Template do arquivo hlm.ts local do Spartan Core (hlm.ts oficial v1.0.4)
@@ -0,0 +1,5 @@
1
+ export declare function devkitShellTemplate(): {
2
+ ts: string;
3
+ html: string;
4
+ css: string;
5
+ };
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.devkitShellTemplate = devkitShellTemplate;
4
+ function devkitShellTemplate() {
5
+ return {
6
+ ts: `import { Component, Input } from '@angular/core';
7
+ import { CommonModule } from '@angular/common';
8
+
9
+ @Component({
10
+ selector: 'devkit-shell',
11
+ standalone: true,
12
+ imports: [CommonModule],
13
+ templateUrl: './shell.component.html',
14
+ styleUrls: ['./shell.component.css']
15
+ })
16
+ export class DevkitShellComponent {
17
+ @Input() layoutType: 'sidebar-left' | 'top-nav' = 'sidebar-left';
18
+ @Input() isCollapsed = false;
19
+ }
20
+ `,
21
+ html: `<div class="dt-shell-container">
22
+ <!-- Projeção da Sidebar -->
23
+ <ng-content select="devkit-sidebar"></ng-content>
24
+
25
+ <div class="dt-shell-main">
26
+ <!-- Projeção do Header -->
27
+ <ng-content select="devkit-header"></ng-content>
28
+
29
+ <!-- Área de Conteúdo Principal -->
30
+ <main class="dt-shell-content">
31
+ <ng-content></ng-content>
32
+ </main>
33
+ </div>
34
+ </div>
35
+ `,
36
+ css: `:host {
37
+ display: block;
38
+ height: 100vh;
39
+ width: 100%;
40
+ overflow: hidden;
41
+ }
42
+
43
+ .dt-shell-container {
44
+ display: flex;
45
+ height: 100vh;
46
+ width: 100%;
47
+ background-color: var(--background);
48
+ color: var(--foreground);
49
+ overflow: hidden;
50
+ }
51
+
52
+ .dt-shell-main {
53
+ display: flex;
54
+ flex-direction: column;
55
+ flex: 1;
56
+ min-width: 0;
57
+ height: 100vh;
58
+ overflow: hidden;
59
+ }
60
+
61
+ .dt-shell-content {
62
+ flex: 1;
63
+ padding: 16px;
64
+ overflow-y: auto;
65
+ }
66
+
67
+ /* Responsividade mobile */
68
+ @media (max-width: 768px) {
69
+ .dt-shell-content {
70
+ padding: 12px;
71
+ }
72
+ }
73
+ `
74
+ };
75
+ }
76
+ // 11. Template do devkit-sidebar
@@ -0,0 +1,5 @@
1
+ export declare function devkitSidebarTemplate(): {
2
+ ts: string;
3
+ html: string;
4
+ css: string;
5
+ };
@@ -0,0 +1,412 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.devkitSidebarTemplate = devkitSidebarTemplate;
4
+ function devkitSidebarTemplate() {
5
+ return {
6
+ ts: `import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
7
+ import { CommonModule } from '@angular/common';
8
+ import { RouterModule, Router, NavigationEnd } from '@angular/router';
9
+ import { NgIconComponent } from '@ng-icons/core';
10
+ import { filter } from 'rxjs/operators';
11
+
12
+ export interface INavigationItem {
13
+ label: string;
14
+ route?: string;
15
+ icon?: string;
16
+ badge?: string;
17
+ roles?: string[];
18
+ children?: INavigationItem[];
19
+ }
20
+
21
+ @Component({
22
+ selector: 'devkit-sidebar',
23
+ standalone: true,
24
+ imports: [CommonModule, RouterModule, NgIconComponent],
25
+ templateUrl: './sidebar.component.html',
26
+ styleUrls: ['./sidebar.component.css']
27
+ })
28
+ export class DevkitSidebarComponent implements OnInit {
29
+ @Input() items: INavigationItem[] = [];
30
+ @Input() brandLogo = '';
31
+ @Input() brandLogoCollapsed = '';
32
+ @Input() brandName = '';
33
+ @Input() isCollapsed = false;
34
+ @Output() closeSidebar = new EventEmitter<void>();
35
+
36
+ expandedItems = new Set<string>();
37
+ currentUrl = '';
38
+
39
+ constructor(private router: Router) {}
40
+
41
+ ngOnInit(): void {
42
+ this.currentUrl = this.router.url;
43
+ this.router.events
44
+ .pipe(filter(event => event instanceof NavigationEnd))
45
+ .subscribe((event: any) => {
46
+ this.currentUrl = event.urlAfterRedirects || event.url;
47
+ });
48
+ }
49
+
50
+ toggleExpand(label: string): void {
51
+ if (this.expandedItems.has(label)) {
52
+ this.expandedItems.delete(label);
53
+ } else {
54
+ this.expandedItems.add(label);
55
+ }
56
+ }
57
+
58
+ isExpanded(label: string): boolean {
59
+ return this.expandedItems.has(label);
60
+ }
61
+
62
+ isActive(route?: string): boolean {
63
+ if (!route) return false;
64
+ return this.currentUrl.startsWith(route);
65
+ }
66
+
67
+ isAnyChildActive(item: INavigationItem): boolean {
68
+ if (!item.children) return false;
69
+ return item.children.some(child => this.isActive(child.route));
70
+ }
71
+
72
+ getIconName(icon?: string): string {
73
+ if (!icon) return '';
74
+ if (icon.startsWith('lucide')) return icon;
75
+ return 'lucide' + icon.charAt(0).toUpperCase() + icon.slice(1);
76
+ }
77
+ }
78
+ `,
79
+ html: `<aside [class.dt-sidebar-collapsed]="isCollapsed" class="dt-sidebar">
80
+ <!-- Topo / Header da Sidebar -->
81
+ <div class="dt-sidebar-brand">
82
+ <div class="flex items-center space-x-3 w-full overflow-hidden">
83
+
84
+ <!-- Estado EXPANDIDO: logo grande + nome -->
85
+ <ng-container *ngIf="!isCollapsed">
86
+ <img *ngIf="brandLogo" [src]="brandLogo" [alt]="brandName" class="w-8 h-8 rounded object-contain flex-shrink-0" />
87
+ <span class="font-bold text-lg tracking-tight truncate text-foreground">{{ brandName }}</span>
88
+ </ng-container>
89
+
90
+ <!-- Estado COLAPSADO: logo pequena (brandLogoCollapsed) ou logo padrão ou iniciais -->
91
+ <ng-container *ngIf="isCollapsed">
92
+ <img
93
+ *ngIf="brandLogoCollapsed; else collapsedLogoFallback"
94
+ [src]="brandLogoCollapsed"
95
+ [alt]="brandName"
96
+ class="w-8 h-8 rounded object-contain flex-shrink-0 mx-auto"
97
+ />
98
+ <ng-template #collapsedLogoFallback>
99
+ <img *ngIf="brandLogo; else collapsedInitialsFallback" [src]="brandLogo" [alt]="brandName" class="w-8 h-8 rounded object-contain flex-shrink-0 mx-auto" />
100
+ <ng-template #collapsedInitialsFallback>
101
+ <div class="w-8 h-8 rounded flex items-center justify-center font-bold text-xs bg-primary text-primary-foreground mx-auto flex-shrink-0">
102
+ {{ brandName.slice(0, 2).toUpperCase() }}
103
+ </div>
104
+ </ng-template>
105
+ </ng-template>
106
+ </ng-container>
107
+
108
+ </div>
109
+ <button type="button" class="dt-sidebar-close" (click)="closeSidebar.emit()" aria-label="Fechar menu">×</button>
110
+ <!-- Slot customizado no topo -->
111
+ <ng-content select="[devkit-sidebar-header]"></ng-content>
112
+ </div>
113
+
114
+ <!-- Slot customizado antes do menu -->
115
+ <div class="dt-sidebar-content-before">
116
+ <ng-content select="[devkit-sidebar-content-before]"></ng-content>
117
+ </div>
118
+
119
+ <!-- Menu / Navegação -->
120
+ <nav class="dt-sidebar-nav">
121
+ <ul class="dt-sidebar-list">
122
+ <li *ngFor="let item of items">
123
+
124
+ <!-- Link Simples (Sem Filhos) -->
125
+ <a
126
+ *ngIf="!item.children || item.children.length === 0"
127
+ [routerLink]="item.route"
128
+ [class.dt-sidebar-item-active]="isActive(item.route)"
129
+ class="dt-sidebar-item"
130
+ [title]="item.label"
131
+ >
132
+ <ng-icon *ngIf="item.icon" [name]="getIconName(item.icon)" class="dt-sidebar-icon size-5 text-muted-foreground"></ng-icon>
133
+ <span *ngIf="!isCollapsed" class="dt-sidebar-label">{{ item.label }}</span>
134
+ <span *ngIf="item.badge && !isCollapsed" class="dt-sidebar-badge">{{ item.badge }}</span>
135
+ </a>
136
+
137
+ <!-- Grupo com Filhos (Submenu Colapsável) -->
138
+ <div *ngIf="item.children && item.children.length > 0" class="flex flex-col">
139
+ <button
140
+ (click)="toggleExpand(item.label)"
141
+ class="dt-sidebar-item"
142
+ [class.dt-sidebar-item-active]="isActive(item.route) || isAnyChildActive(item)"
143
+ [title]="item.label"
144
+ >
145
+ <ng-icon *ngIf="item.icon" [name]="getIconName(item.icon)" class="dt-sidebar-icon size-5 text-muted-foreground"></ng-icon>
146
+ <span *ngIf="!isCollapsed" class="dt-sidebar-label">{{ item.label }}</span>
147
+ <ng-icon *ngIf="!isCollapsed" name="lucideChevronRight" class="ml-auto size-4 text-muted-foreground transform transition-transform duration-200" [class.rotate-90]="isExpanded(item.label)"></ng-icon>
148
+ </button>
149
+
150
+ <!-- Sub-itens -->
151
+ <ul
152
+ *ngIf="isExpanded(item.label) && !isCollapsed"
153
+ class="dt-sidebar-sublist"
154
+ >
155
+ <li *ngFor="let child of item.children">
156
+ <a
157
+ [routerLink]="child.route"
158
+ [class.dt-sidebar-item-active]="isActive(child.route)"
159
+ class="dt-sidebar-subitem"
160
+ >
161
+ <ng-icon *ngIf="child.icon" [name]="getIconName(child.icon)" class="dt-sidebar-icon size-4 text-muted-foreground mr-2"></ng-icon>
162
+ <span class="dt-sidebar-label text-sm">{{ child.label }}</span>
163
+ </a>
164
+ </li>
165
+ </ul>
166
+ </div>
167
+
168
+ </li>
169
+ </ul>
170
+ </nav>
171
+
172
+ <!-- Slot customizado depois do menu -->
173
+ <div class="dt-sidebar-content-after">
174
+ <ng-content select="[devkit-sidebar-content-after]"></ng-content>
175
+ </div>
176
+
177
+ <!-- Rodapé da Sidebar -->
178
+ <div class="dt-sidebar-footer">
179
+ <ng-content select="[devkit-sidebar-footer]"></ng-content>
180
+ </div>
181
+ </aside>
182
+ `,
183
+ css: `:host {
184
+ display: block;
185
+ z-index: 50;
186
+ }
187
+
188
+ .dt-sidebar {
189
+ display: flex;
190
+ flex-direction: column;
191
+ width: 260px;
192
+ height: 100vh;
193
+ background-color: var(--card);
194
+ color: var(--card-foreground);
195
+ border-right: 1px solid var(--border);
196
+ transition: width 0.2s cubic-bezier(0.4, 0, 0.2, 1);
197
+ overflow-x: hidden;
198
+ }
199
+
200
+ .dt-sidebar-collapsed {
201
+ width: 76px;
202
+ }
203
+
204
+ .dt-sidebar-brand {
205
+ display: flex;
206
+ align-items: center;
207
+ padding: 20px 24px;
208
+ min-height: 64px;
209
+ border-bottom: 1px solid color-mix(in srgb, var(--border) 50%, transparent);
210
+ }
211
+
212
+ .dt-sidebar-collapsed .dt-sidebar-brand {
213
+ padding: 20px 16px;
214
+ justify-content: center;
215
+ }
216
+
217
+ .dt-sidebar-close {
218
+ display: none;
219
+ }
220
+
221
+ .dt-sidebar-content-before,
222
+ .dt-sidebar-content-after {
223
+ display: block;
224
+ }
225
+
226
+ .dt-sidebar-nav {
227
+ flex: 1;
228
+ overflow-y: auto;
229
+ overflow-x: hidden;
230
+ padding: 16px 12px;
231
+ }
232
+
233
+ .dt-sidebar-list {
234
+ display: flex;
235
+ flex-direction: column;
236
+ gap: 4px;
237
+ padding: 0;
238
+ margin: 0;
239
+ list-style: none;
240
+ }
241
+
242
+ .dt-sidebar-item {
243
+ position: relative;
244
+ display: flex;
245
+ align-items: center;
246
+ width: 100%;
247
+ padding: 10px 16px;
248
+ color: var(--muted-foreground);
249
+ background: transparent;
250
+ border: none;
251
+ border-radius: var(--radius);
252
+ cursor: pointer;
253
+ text-decoration: none;
254
+ font-family: var(--font-family);
255
+ font-weight: 500;
256
+ font-size: 14px;
257
+ transition: all 0.2s ease-in-out;
258
+ text-align: left;
259
+ outline: none;
260
+ }
261
+
262
+ .dt-sidebar-item:hover {
263
+ background-color: var(--muted);
264
+ color: var(--foreground);
265
+ }
266
+
267
+ .dt-sidebar-item:hover .dt-sidebar-icon {
268
+ color: var(--foreground);
269
+ }
270
+
271
+ .dt-sidebar-item-active {
272
+ background-color: color-mix(in srgb, var(--primary) 12%, transparent) !important;
273
+ color: var(--primary) !important;
274
+ font-weight: 600;
275
+ }
276
+
277
+ .dt-sidebar-item-active .dt-sidebar-icon {
278
+ color: var(--primary) !important;
279
+ }
280
+
281
+ .dt-sidebar-sublist {
282
+ position: relative;
283
+ margin: 4px 0 4px 28px;
284
+ padding-left: 12px;
285
+ border-left: 1px dashed color-mix(in srgb, var(--border) 70%, transparent);
286
+ display: flex;
287
+ flex-direction: column;
288
+ gap: 2px;
289
+ list-style: none;
290
+ }
291
+
292
+ .dt-sidebar-subitem {
293
+ display: flex;
294
+ align-items: center;
295
+ padding: 8px 12px;
296
+ color: var(--muted-foreground);
297
+ text-decoration: none;
298
+ border-radius: var(--radius);
299
+ font-family: var(--font-family);
300
+ font-weight: 450;
301
+ font-size: 13px;
302
+ transition: all 0.2s ease-in-out;
303
+ }
304
+
305
+ .dt-sidebar-subitem:hover {
306
+ color: var(--foreground);
307
+ background-color: var(--muted);
308
+ }
309
+
310
+ .dt-sidebar-subitem.dt-sidebar-item-active {
311
+ background-color: transparent !important;
312
+ color: var(--primary) !important;
313
+ font-weight: 600;
314
+ }
315
+
316
+ .dt-sidebar-icon {
317
+ display: inline-flex;
318
+ align-items: center;
319
+ justify-content: center;
320
+ width: 20px;
321
+ height: 20px;
322
+ font-size: 18px;
323
+ margin-right: 12px;
324
+ flex-shrink: 0;
325
+ color: var(--muted-foreground);
326
+ transition: color 0.2s ease-in-out;
327
+ }
328
+
329
+ .dt-sidebar-collapsed .dt-sidebar-icon {
330
+ margin-right: 0;
331
+ }
332
+
333
+ .dt-sidebar-label {
334
+ white-space: nowrap;
335
+ overflow: hidden;
336
+ text-overflow: ellipsis;
337
+ }
338
+
339
+ .dt-sidebar-badge {
340
+ display: inline-flex;
341
+ align-items: center;
342
+ justify-content: center;
343
+ padding: 2px 6px;
344
+ font-size: 10px;
345
+ font-weight: 600;
346
+ border-radius: 9999px;
347
+ background-color: var(--destructive);
348
+ color: var(--destructive-foreground);
349
+ margin-left: auto;
350
+ }
351
+
352
+ .dt-sidebar-footer {
353
+ padding: 16px;
354
+ border-top: 1px solid color-mix(in srgb, var(--border) 50%, transparent);
355
+ margin-top: auto;
356
+ }
357
+
358
+ .dt-sidebar-nav::-webkit-scrollbar {
359
+ width: 4px;
360
+ }
361
+ .dt-sidebar-nav::-webkit-scrollbar-track {
362
+ background: transparent;
363
+ }
364
+ .dt-sidebar-nav::-webkit-scrollbar-thumb {
365
+ background: var(--border);
366
+ border-radius: var(--radius-sm);
367
+ }
368
+
369
+ @media (max-width: 768px) {
370
+ :host {
371
+ position: fixed;
372
+ inset: 0 auto 0 0;
373
+ width: 260px;
374
+ height: 100dvh;
375
+ z-index: 60;
376
+ pointer-events: none;
377
+ }
378
+
379
+ .dt-sidebar {
380
+ width: 260px;
381
+ height: 100dvh;
382
+ transform: translateX(0);
383
+ transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
384
+ box-shadow: 12px 0 32px rgb(0 0 0 / 0.24);
385
+ pointer-events: auto;
386
+ }
387
+
388
+ .dt-sidebar-collapsed {
389
+ width: 260px;
390
+ transform: translateX(-100%);
391
+ }
392
+
393
+
394
+ .dt-sidebar-close {
395
+ display: inline-flex;
396
+ align-items: center;
397
+ justify-content: center;
398
+ width: 36px;
399
+ height: 36px;
400
+ flex: 0 0 36px;
401
+ border: 0;
402
+ border-radius: var(--radius);
403
+ background: transparent;
404
+ color: var(--foreground);
405
+ font-size: 28px;
406
+ line-height: 1;
407
+ cursor: pointer;
408
+ }
409
+ }
410
+ `
411
+ };
412
+ }
@@ -0,0 +1,5 @@
1
+ export declare function devkitPlaygroundComponentTemplate(spartanPrimitives?: string[]): {
2
+ ts: string;
3
+ html: string;
4
+ css: string;
5
+ };