From d8a81bcc3f4b214aa6f00aa3d00c854f80f5adf4 Mon Sep 17 00:00:00 2001 From: Iury Nogueira Date: Wed, 18 Mar 2026 17:25:23 -0300 Subject: [PATCH 1/4] feat: add uploaded file state to upload component :sparkles: Shows filename, doc icon and remove button inside dropzone after file selection. Co-Authored-By: Claude Sonnet 4.6 --- .../ion/src/lib/upload/upload.component.html | 80 +++++++ .../ion/src/lib/upload/upload.component.scss | 217 ++++++++++++++++++ .../ion/src/lib/upload/upload.component.ts | 90 ++++++++ 3 files changed, 387 insertions(+) create mode 100644 projects/ion/src/lib/upload/upload.component.html create mode 100644 projects/ion/src/lib/upload/upload.component.scss create mode 100644 projects/ion/src/lib/upload/upload.component.ts diff --git a/projects/ion/src/lib/upload/upload.component.html b/projects/ion/src/lib/upload/upload.component.html new file mode 100644 index 000000000..7219d0d1f --- /dev/null +++ b/projects/ion/src/lib/upload/upload.component.html @@ -0,0 +1,80 @@ +
+
+ @if (selectedFile()) { +
+
+ + {{ selectedFile()!.name }} +
+ +
+ } @else { +
+
+ +
+

+ Clique para adicionar + um arquivo ou arraste e solte-o aqui +

+ @if (acceptLabel()) { +

{{ acceptLabel() }}

+ } +
+ } +
+ + + + @if (showUrlImport()) { +
+
+ ou +
+
+ +
+ +
+ + +
+
+ } +
diff --git a/projects/ion/src/lib/upload/upload.component.scss b/projects/ion/src/lib/upload/upload.component.scss new file mode 100644 index 000000000..281f87279 --- /dev/null +++ b/projects/ion/src/lib/upload/upload.component.scss @@ -0,0 +1,217 @@ +.upload-container { + display: flex; + flex-direction: column; + gap: 16px; + width: 100%; +} + +.upload-dropzone { + display: flex; + align-items: center; + justify-content: center; + padding: 32px; + border: 1px dashed #8d93a5; + border-radius: 8px; + background-color: #fcfcfd; + cursor: pointer; + transition: border-color 0.2s, background-color 0.2s; + + &:hover:not(.upload-dropzone--disabled) { + border-color: #0858ce; + background-color: #f0f5ff; + } + + &--dragging { + border-color: #0858ce; + background-color: #f0f5ff; + } + + &--disabled { + opacity: 0.5; + cursor: not-allowed; + } + + &--has-file { + background-color: #ebf3fe; + border-color: #aeb2bd; + border-width: 1.5px; + cursor: default; + + &:hover:not(.upload-dropzone--disabled) { + background-color: #ebf3fe; + border-color: #aeb2bd; + } + } + + &__content { + display: flex; + flex-direction: column; + align-items: center; + gap: 16px; + } + + &__icon { + display: flex; + align-items: center; + justify-content: center; + width: 48px; + height: 48px; + border-radius: 50%; + background-color: rgba(255, 255, 255, 0.9); + box-shadow: 0 0 0 48px #505566; + border-radius: 50%; + + // Simpler approach + background: rgba(255, 255, 255, 0.9); + box-shadow: 0 0 0 0 transparent; + border: 1px solid transparent; + background-color: #505566; + padding: 12px; + border-radius: 50%; + + ion-icon { + color: white; + } + } + + &__text { + font-family: 'Source Sans Pro', sans-serif; + font-size: 16px; + font-weight: 600; + color: #505566; + text-align: center; + margin: 0; + } + + &__link { + color: #0858ce; + } + + &__file { + display: flex; + align-items: center; + gap: 8px; + } + + &__file-info { + display: flex; + align-items: center; + gap: 8px; + + ion-icon { + color: #aeb2bd; + } + } + + &__file-name { + font-family: 'Source Sans Pro', sans-serif; + font-size: 14px; + font-weight: 400; + color: #aeb2bd; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 400px; + } + + &__hint { + font-family: 'Source Sans Pro', sans-serif; + font-size: 14px; + font-weight: 400; + color: #505566; + text-align: center; + margin: 0; + } +} + +.upload-hidden-input { + display: none; +} + +.upload-divider { + display: flex; + align-items: center; + gap: 8px; + + &__line { + flex: 1; + height: 1px; + background-color: #ced2db; + } + + &__text { + font-family: 'Source Sans Pro', sans-serif; + font-size: 14px; + font-weight: 400; + color: #505566; + white-space: nowrap; + } +} + +.upload-url { + display: flex; + flex-direction: column; + gap: 4px; + + &__label { + font-family: 'Source Sans Pro', sans-serif; + font-size: 14px; + font-weight: 600; + color: #505566; + } + + &__input-group { + display: flex; + align-items: stretch; + } + + &__input { + flex: 1; + padding: 6px 12px; + font-family: 'Source Sans Pro', sans-serif; + font-size: 14px; + color: #282b33; + background-color: #fcfcfd; + border: 1px solid #aeb2bd; + border-right: none; + border-radius: 8px 0 0 8px; + outline: none; + min-width: 0; + + &::placeholder { + color: #aeb2bd; + } + + &:focus { + border-color: #0858ce; + } + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } + } + + &__button { + padding: 6px 12px; + font-family: 'Source Sans Pro', sans-serif; + font-size: 14px; + font-weight: 600; + color: #0858ce; + background-color: #fcfcfd; + border: 1px solid #aeb2bd; + border-radius: 0 8px 8px 0; + cursor: pointer; + white-space: nowrap; + transition: background-color 0.2s; + + &:hover:not(:disabled) { + background-color: #f0f5ff; + } + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } + } +} diff --git a/projects/ion/src/lib/upload/upload.component.ts b/projects/ion/src/lib/upload/upload.component.ts new file mode 100644 index 000000000..52c7bacaf --- /dev/null +++ b/projects/ion/src/lib/upload/upload.component.ts @@ -0,0 +1,90 @@ +import { + ChangeDetectionStrategy, + Component, + ElementRef, + ViewChild, + input, + output, + signal, +} from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { IonIconComponent } from '../icon/icon.component'; +import { IonButtonComponent } from '../button/button.component'; + +@Component({ + selector: 'ion-upload', + standalone: true, + imports: [FormsModule, IonIconComponent, IonButtonComponent], + templateUrl: './upload.component.html', + styleUrls: ['./upload.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class IonUploadComponent { + accept = input(''); + acceptLabel = input(''); + showUrlImport = input(true); + urlPlaceholder = input('Placeholder'); + disabled = input(false); + + fileChange = output(); + urlImport = output(); + + isDragging = signal(false); + urlValue = signal(''); + selectedFile = signal(null); + + @ViewChild('fileInput') fileInputRef!: ElementRef; + + openFileDialog(): void { + if (!this.disabled()) { + this.fileInputRef.nativeElement.click(); + } + } + + onFileSelected(event: Event): void { + const input = event.target as HTMLInputElement; + if (input.files && input.files.length > 0) { + this.selectedFile.set(input.files[0]); + this.fileChange.emit(input.files[0]); + input.value = ''; + } + } + + removeFile(): void { + this.selectedFile.set(null); + } + + onDragOver(event: DragEvent): void { + event.preventDefault(); + if (!this.disabled()) { + this.isDragging.set(true); + } + } + + onDragLeave(event: DragEvent): void { + event.preventDefault(); + this.isDragging.set(false); + } + + onDrop(event: DragEvent): void { + event.preventDefault(); + this.isDragging.set(false); + if (this.disabled()) return; + const files = event.dataTransfer?.files; + if (files && files.length > 0) { + this.selectedFile.set(files[0]); + this.fileChange.emit(files[0]); + } + } + + onUrlImport(): void { + const url = this.urlValue(); + if (url.trim()) { + this.urlImport.emit(url); + } + } + + setUrlValue(value: string): void { + this.urlValue.set(value); + } +} From 98b365fb36ff7d8220bb2a9403a5eee58a1c16d8 Mon Sep 17 00:00:00 2001 From: Iury Nogueira Date: Wed, 18 Mar 2026 17:26:33 -0300 Subject: [PATCH 2/4] feat: add file upload to bnForm :sparkles: --- projects/ion-test-app/src/app/app.component.ts | 10 ++++++++++ .../src/lib/core/bn-form/bn-form.component.ts | 18 ++++++++++++++++++ .../ion/src/lib/core/bn-form/bn-form.types.ts | 15 +++++++++++++-- projects/ion/src/public-api.ts | 1 + 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/projects/ion-test-app/src/app/app.component.ts b/projects/ion-test-app/src/app/app.component.ts index 3da85538d..c5b4e6a27 100644 --- a/projects/ion-test-app/src/app/app.component.ts +++ b/projects/ion-test-app/src/app/app.component.ts @@ -1151,6 +1151,16 @@ export class AppComponent implements OnInit { iconDirection: 'left', validators: [Validators.minLength(3)], }, + { + key: 'arquivo', + label: 'Arquivo', + type: 'upload', + accept: '.csv', + acceptLabel: 'Apenas arquivos CSV', + showUrlImport: true, + urlPlaceholder: 'https://...', + onImportUrl: (url) => console.log(url), + }, { key: 'sobrenome', className: 'col-6', diff --git a/projects/ion/src/lib/core/bn-form/bn-form.component.ts b/projects/ion/src/lib/core/bn-form/bn-form.component.ts index 45bc05888..cabf6906d 100644 --- a/projects/ion/src/lib/core/bn-form/bn-form.component.ts +++ b/projects/ion/src/lib/core/bn-form/bn-form.component.ts @@ -21,6 +21,7 @@ import { IonSelectComponent } from '../../select/select.component'; import { IonInputAreaComponent, } from '../../input-area/input-area.component'; +import { IonUploadComponent } from '../../upload/upload.component'; import { BnFormField, BnInputFormField, @@ -29,6 +30,7 @@ import { BnDatePickerFormField, BnSelectFormField, BnInputAreaFormField, + BnUploadFormField, } from './bn-form.types'; import { IonIconComponent } from '../../icon/icon.component'; import { IonTooltipDirective } from '../../tooltip/tooltip.directive'; @@ -45,6 +47,7 @@ import { BnMaskDirective } from '../../mask/mask.directive'; IonDatepickerComponent, IonSelectComponent, IonInputAreaComponent, + IonUploadComponent, IonIconComponent, IonTooltipDirective, BnMaskDirective @@ -157,6 +160,16 @@ import { BnMaskDirective } from '../../mask/mask.directive'; [value]="formGroup().get(field.key)?.value" (valueChange)="onValueChange(field.key, $event)" > + } @else if (isUpload(field)) { + } } @@ -374,6 +387,7 @@ export class BnFormComponent implements OnInit { } onValueChange(key: string, value: any): void { + console.log(key, value) const control = this.formGroup().get(key); if (control && control.value !== value) { control.setValue(value); @@ -433,4 +447,8 @@ export class BnFormComponent implements OnInit { isInputArea(field: BnFormField): field is BnInputAreaFormField { return field.type === 'input-area'; } + + isUpload(field: BnFormField): field is BnUploadFormField { + return field.type === 'upload'; + } } diff --git a/projects/ion/src/lib/core/bn-form/bn-form.types.ts b/projects/ion/src/lib/core/bn-form/bn-form.types.ts index 80ccd9a1e..d76988922 100644 --- a/projects/ion/src/lib/core/bn-form/bn-form.types.ts +++ b/projects/ion/src/lib/core/bn-form/bn-form.types.ts @@ -18,7 +18,8 @@ export type BnFormFieldType = | 'switch' | 'datepicker' | 'select' - | 'input-area'; + | 'input-area' + | 'upload'; export interface BnBaseFormField { key: string; @@ -106,13 +107,23 @@ export interface BnInputAreaFormField extends BnBaseFormField { rows?: string; } +export interface BnUploadFormField extends BnBaseFormField { + type: 'upload'; + accept?: string; + acceptLabel?: string; + showUrlImport?: boolean; + urlPlaceholder?: string; + onImportUrl?: (url: string) => void; +} + export type BnFormField = | BnInputFormField | BnTripleToggleFormField | BnSwitchFormField | BnDatePickerFormField | BnSelectFormField - | BnInputAreaFormField; + | BnInputAreaFormField + | BnUploadFormField; export interface BnFormConfig { fields: BnFormField[]; diff --git a/projects/ion/src/public-api.ts b/projects/ion/src/public-api.ts index dd8924546..7b046b0bf 100644 --- a/projects/ion/src/public-api.ts +++ b/projects/ion/src/public-api.ts @@ -69,6 +69,7 @@ export * from './lib/core/bn-filter/bn-filter.component'; export * from './lib/core/bn-form/bn-form.component'; export * from './lib/core/bn-form/bn-form.service'; export * from './lib/core/bn-form/bn-form.types'; +export * from './lib/upload/upload.component'; export * from './lib/core/bn-wizard/bn-wizard.component'; export * from './lib/core/bn-wizard/bn-wizard.types'; export * from './lib/core/bn-about/bn-about.component'; From 013042114f6a09c125efd0d35f1d911b20acbc7f Mon Sep 17 00:00:00 2001 From: Iury Nogueira Date: Mon, 23 Mar 2026 14:52:41 -0300 Subject: [PATCH 3/4] feat: add prettier and eslint :sparkles: --- angular.json | 56 +- eslint.config.js | 36 + package-lock.json | 1398 +++++++++++++++-- package.json | 12 +- .../ion-test-app/src/app/app.component.html | 67 +- .../ion-test-app/src/app/app.component.ts | 53 +- projects/ion-test-app/src/index.html | 2 +- projects/ion/documentation.json | 430 ++--- .../ion/src/lib/alert/alert.component.html | 43 +- .../ion/src/lib/avatar/avatar.component.ts | 1 - projects/ion/src/lib/badge/badge.component.ts | 1 - .../lib/breadcrumb/breadcrumb.component.html | 75 +- .../ion/src/lib/button/button.component.html | 81 +- .../src/lib/button/button.component.spec.ts | 19 +- .../ion/src/lib/button/button.component.ts | 7 +- projects/ion/src/lib/card/_card.theme.scss | 2 +- .../src/lib/card/card-footer.component.scss | 4 +- .../ion/src/lib/card/card-footer.component.ts | 1 - .../src/lib/card/card-header.component.scss | 4 +- .../ion/src/lib/card/card-header.component.ts | 1 - projects/ion/src/lib/card/card.component.scss | 6 +- .../ion/src/lib/card/card.component.spec.ts | 11 +- projects/ion/src/lib/card/card.component.ts | 1 - .../src/lib/checkbox/checkbox.component.ts | 1 - .../lib/chip-group/chip-group.component.html | 40 +- projects/ion/src/lib/chip/chip.component.html | 116 +- .../ion/src/lib/chip/chip.component.spec.ts | 13 +- projects/ion/src/lib/chip/chip.component.ts | 4 +- .../lib/core/bn-about/bn-about.component.html | 39 +- .../lib/core/bn-about/bn-about.component.scss | 8 +- .../core/bn-about/bn-about.component.spec.ts | 2 +- .../lib/core/bn-about/bn-about.component.ts | 13 +- .../bn-edit-drawer.component.ts | 13 +- .../core/bn-filter/bn-filter.component.scss | 8 +- .../bn-filter/bn-filter.component.spec.ts | 22 +- .../core/bn-form/bn-form.component.spec.ts | 6 +- .../src/lib/core/bn-form/bn-form.component.ts | 20 +- .../src/lib/core/bn-form/bn-form.service.ts | 4 +- projects/ion/src/lib/core/types/chip-group.ts | 2 +- .../ion/src/lib/drawer/drawer.component.html | 23 +- .../ion/src/lib/drawer/drawer.component.scss | 2 +- .../src/lib/drawer/drawer.component.spec.ts | 26 +- .../src/lib/dropdown/dropdown.component.html | 153 +- .../src/lib/dropdown/dropdown.component.ts | 4 +- .../ion/src/lib/icon/icon.component.spec.ts | 8 +- .../lib/info-badge/info-badge.component.ts | 1 - .../lib/input-area/input-area.component.ts | 1 - .../ion/src/lib/link/ion-link.component.ts | 1 - .../ion/src/lib/modal/modal.component.html | 4 +- projects/ion/src/lib/modal/modal.component.ts | 1 - .../ion/src/lib/navbar/navbar.component.html | 68 +- .../ion/src/lib/navbar/navbar.component.ts | 8 +- .../ion/src/lib/no-data/no-data.component.ts | 1 - .../control-picker.component.ts | 7 +- .../date-picker-calendar.component.ts | 1 - .../date-picker-input.component.ts | 3 +- .../date-picker/date-picker.component.ts | 5 +- .../predefined-range-picker.component.ts | 1 - .../lib/popconfirm/popconfirm.component.html | 6 +- .../lib/popconfirm/popconfirm.component.ts | 8 +- .../popconfirm/popconfirm.directive.spec.ts | 26 +- .../lib/popconfirm/popconfirm.directive.ts | 8 +- projects/ion/src/lib/radio/radio.component.ts | 1 - .../src/lib/select/select-bug-repro.spec.ts | 14 +- .../ion/src/lib/select/select.component.html | 50 +- .../ion/src/lib/select/select.component.ts | 32 +- .../sidebar-group.component.spec.ts | 5 +- .../sidebar-group/sidebar-group.component.ts | 7 +- .../sidebar-item/sidebar-item.component.ts | 1 - .../src/lib/sidebar/sidebar.component.html | 112 +- projects/ion/src/lib/sidebar/sidebar.spec.ts | 6 +- .../lib/simple-menu/simple-menu.component.ts | 6 +- .../smart-table/smart-table.component.html | 821 +++++----- .../src/lib/step/ion-step.component.spec.ts | 14 +- .../ion/src/lib/step/ion-step.component.ts | 2 +- .../src/lib/switch/switch.component.spec.ts | 2 +- .../src/lib/table/ion-table.component.html | 24 +- projects/ion/src/lib/tag/ion-tag.component.ts | 1 - .../ion/src/lib/tooltip/tooltip.component.ts | 2 +- .../src/lib/tooltip/tooltip.directive.spec.ts | 7 +- .../ion/src/lib/tooltip/tooltip.directive.ts | 12 +- .../typography/heading/heading.component.html | 25 +- .../ion/src/lib/upload/upload.component.html | 4 +- .../ion/src/lib/upload/upload.component.scss | 4 +- projects/ion/src/styles/themes/index.scss | 3 +- 85 files changed, 2701 insertions(+), 1442 deletions(-) create mode 100644 eslint.config.js diff --git a/angular.json b/angular.json index c125eb263..11d6ce6fb 100644 --- a/angular.json +++ b/angular.json @@ -28,10 +28,7 @@ "builder": "@angular/build:karma", "options": { "tsConfig": "projects/ion/tsconfig.spec.json", - "polyfills": [ - "zone.js", - "zone.js/testing" - ] + "polyfills": ["zone.js", "zone.js/testing"] } }, "storybook": { @@ -40,12 +37,7 @@ "configDir": "projects/ion/.storybook", "browserTarget": "ion:build", "compodoc": true, - "compodocArgs": [ - "-e", - "json", - "-d", - "projects/ion" - ], + "compodocArgs": ["-e", "json", "-d", "projects/ion"], "port": 6006 } }, @@ -55,14 +47,18 @@ "configDir": "projects/ion/.storybook", "browserTarget": "ion:build", "compodoc": true, - "compodocArgs": [ - "-e", - "json", - "-d", - "projects/ion" - ], + "compodocArgs": ["-e", "json", "-d", "projects/ion"], "outputDir": "dist/storybook/ion" } + }, + "lint": { + "builder": "@angular-eslint/builder:lint", + "options": { + "lintFilePatterns": [ + "projects/ion/**/*.ts", + "projects/ion/**/*.html" + ] + } } } }, @@ -83,9 +79,7 @@ "outputPath": "dist/ion-test-app", "index": "projects/ion-test-app/src/index.html", "browser": "projects/ion-test-app/src/main.ts", - "polyfills": [ - "zone.js" - ], + "polyfills": ["zone.js"], "tsConfig": "projects/ion-test-app/tsconfig.app.json", "inlineStyleLanguage": "scss", "assets": [ @@ -94,9 +88,7 @@ "input": "projects/ion-test-app/public" } ], - "styles": [ - "projects/ion-test-app/src/styles.scss" - ], + "styles": ["projects/ion-test-app/src/styles.scss"], "scripts": [] }, "configurations": { @@ -141,10 +133,7 @@ "test": { "builder": "@angular/build:karma", "options": { - "polyfills": [ - "zone.js", - "zone.js/testing" - ], + "polyfills": ["zone.js", "zone.js/testing"], "tsConfig": "projects/ion-test-app/tsconfig.spec.json", "inlineStyleLanguage": "scss", "assets": [ @@ -153,11 +142,18 @@ "input": "projects/ion-test-app/public" } ], - "styles": [ - "projects/ion-test-app/src/styles.scss" - ], + "styles": ["projects/ion-test-app/src/styles.scss"], "scripts": [] } + }, + "lint": { + "builder": "@angular-eslint/builder:lint", + "options": { + "lintFilePatterns": [ + "projects/ion-test-app/**/*.ts", + "projects/ion-test-app/**/*.html" + ] + } } } } @@ -191,4 +187,4 @@ "typeSeparator": "." } } -} \ No newline at end of file +} diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 000000000..5813e75ea --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,36 @@ +// @ts-check +const tseslint = require('typescript-eslint'); +const eslint = require('@eslint/js'); +const angular = require('angular-eslint'); +const eslintConfigPrettier = require('eslint-config-prettier'); + +module.exports = tseslint.config( + { + files: ['**/*.ts'], + extends: [ + eslint.configs.recommended, + ...tseslint.configs.recommended, + ...angular.configs.tsRecommended, + eslintConfigPrettier, + ], + processor: angular.processInlineTemplates, + rules: { + '@angular-eslint/directive-selector': [ + 'error', + { type: 'attribute', prefix: ['ion', 'app'], style: 'camelCase' }, + ], + '@angular-eslint/component-selector': [ + 'error', + { type: 'element', prefix: ['ion', 'app'], style: 'kebab-case' }, + ], + }, + }, + { + files: ['**/*.html'], + extends: [ + ...angular.configs.templateRecommended, + ...angular.configs.templateAccessibility, + ], + rules: {}, + }, +); diff --git a/package-lock.json b/package-lock.json index 74f2b4f8a..c6d35d237 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,17 +37,32 @@ "@testing-library/jest-dom": "^6.9.1", "@testing-library/user-event": "^14.6.1", "@types/jest": "^30.0.0", + "angular-eslint": "^21.3.1", + "eslint": "^9.39.4", + "eslint-config-prettier": "^10.1.8", "jest": "^30.0.0", "jest-environment-jsdom": "^30.0.0", "jest-preset-angular": "^16.0.0", "ng-packagr": "^21.1.0", + "prettier": "^3.8.1", "sass": "^1.94.2", "storybook": "^10.1.11", "ts-node": "^10.9.2", - "typescript": "~5.9.3" + "typescript": "~5.9.3", + "typescript-eslint": "^8.57.2" + } + }, + "dist/ion": { + "version": "0.0.9", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/cdk": "^21.1.4", + "@angular/common": "^21.1.4", + "@angular/core": "^21.1.4" } }, - "dist/ion": {}, "node_modules/@acemir/cssom": { "version": "0.9.31", "dev": true, @@ -516,6 +531,167 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@angular-eslint/builder": { + "version": "21.3.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-21.3.1.tgz", + "integrity": "sha512-1f1Lyp5e7OH6txiV224HaY3G1uRCj91OSKq7hT2Vw9NRw6zWFc1anBpDeLVjpL9ptUxzUGIQR5jEV54hOPayoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": ">= 0.2100.0 < 0.2200.0", + "@angular-devkit/core": ">= 21.0.0 < 22.0.0" + }, + "peerDependencies": { + "@angular/cli": ">= 21.0.0 < 22.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/bundled-angular-compiler": { + "version": "21.3.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-21.3.1.tgz", + "integrity": "sha512-jjbnJPUXQeQBJ8RM+ahlbt4GH2emVN8JvG3AhFbPci1FrqXi9cOOfkbwLmvpoyTli4LF8gy7g4ctFqnlRgqryw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@angular-eslint/eslint-plugin": { + "version": "21.3.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-21.3.1.tgz", + "integrity": "sha512-08NNTxwawRLTWPLl8dg1BnXMwimx93y4wMEwx2aWQpJbIt4pmNvwJzd+NgoD/Ag2VdLS/gOMadhJH5fgaYKsPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "21.3.1", + "@angular-eslint/utils": "21.3.1", + "ts-api-utils": "^2.1.0" + }, + "peerDependencies": { + "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/eslint-plugin-template": { + "version": "21.3.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-21.3.1.tgz", + "integrity": "sha512-ndPWJodkcEOu2PVUxlUwyz4D2u3r9KO7veWmStVNOLeNrICJA+nQvrz2BWCu0l48rO0K5ezsy0JFcQDVwE/5mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "21.3.1", + "@angular-eslint/utils": "21.3.1", + "aria-query": "5.3.2", + "axobject-query": "4.1.0" + }, + "peerDependencies": { + "@angular-eslint/template-parser": "21.3.1", + "@typescript-eslint/types": "^7.11.0 || ^8.0.0", + "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/eslint-plugin-template/node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/@angular-eslint/schematics": { + "version": "21.3.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-21.3.1.tgz", + "integrity": "sha512-1U2u4ZsZvwT30aXRLsIJf6tULIiioo9BtASNsldpYecU3/m/1+F61lCYG79qt7YWbif9KABPYZlFTJUFGN8HWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": ">= 21.0.0 < 22.0.0", + "@angular-devkit/schematics": ">= 21.0.0 < 22.0.0", + "@angular-eslint/eslint-plugin": "21.3.1", + "@angular-eslint/eslint-plugin-template": "21.3.1", + "ignore": "7.0.5", + "semver": "7.7.4", + "strip-json-comments": "3.1.1" + }, + "peerDependencies": { + "@angular/cli": ">= 21.0.0 < 22.0.0" + } + }, + "node_modules/@angular-eslint/schematics/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular-eslint/template-parser": { + "version": "21.3.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-21.3.1.tgz", + "integrity": "sha512-moERVCTekQKOvR8RMuEOtWSO3VS1qrzA3keI1dPto/JVB8Nqp9w3R5ZpEoXHzh4zgEryosxmPgdi6UczJe2ouQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "21.3.1", + "eslint-scope": "9.1.2" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/template-parser/node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@angular-eslint/template-parser/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@angular-eslint/utils": { + "version": "21.3.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-21.3.1.tgz", + "integrity": "sha512-Q3SGA1/36phZhmsp1mYrKzp/jcmqofRr861MYn46FaWIKSYXBYRzl+H3FIJKBu5CE36Bggu6hbNpwGPuUp+MCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "21.3.1" + }, + "peerDependencies": { + "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": "*" + } + }, "node_modules/@angular/animations": { "version": "21.1.5", "license": "MIT", @@ -3202,6 +3378,171 @@ "node": ">=18" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@exodus/bytes": { "version": "1.14.1", "dev": true, @@ -3230,6 +3571,58 @@ "hono": "^4" } }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@inquirer/ansi": { "version": "1.0.2", "dev": true, @@ -5876,6 +6269,13 @@ "@types/estree": "*" } }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.8", "dev": true, @@ -6162,58 +6562,330 @@ "dev": true, "license": "MIT" }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "dev": true, - "license": "ISC" - }, - "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.11.1", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@vitejs/plugin-basic-ssl": { - "version": "2.1.0", + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.2.tgz", + "integrity": "sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w==", "dev": true, "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/type-utils": "8.57.2", + "@typescript-eslint/utils": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.4.0" + }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "vite": "^6.0.0 || ^7.0.0" + "@typescript-eslint/parser": "^8.57.2", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@vitest/expect": { - "version": "3.2.4", + "node_modules/@typescript-eslint/parser": { + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.2.tgz", + "integrity": "sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==", "dev": true, "license": "MIT", "dependencies": { - "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.4", - "@vitest/utils": "3.2.4", - "chai": "^5.2.0", - "tinyrainbow": "^2.0.0" + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@vitest/pretty-format": { - "version": "3.2.4", + "node_modules/@typescript-eslint/project-service": { + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.2.tgz", + "integrity": "sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==", "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^2.0.0" + "@typescript-eslint/tsconfig-utils": "^8.57.2", + "@typescript-eslint/types": "^8.57.2", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.2.tgz", + "integrity": "sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.2.tgz", + "integrity": "sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.2.tgz", + "integrity": "sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/utils": "8.57.2", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.2.tgz", + "integrity": "sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.2.tgz", + "integrity": "sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.57.2", + "@typescript-eslint/tsconfig-utils": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.2.tgz", + "integrity": "sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.2.tgz", + "integrity": "sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.57.2", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "dev": true, + "license": "ISC" + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "peerDependencies": { + "vite": "^6.0.0 || ^7.0.0" + } + }, + "node_modules/@vitest/expect": { + "version": "3.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/spy": { @@ -6428,6 +7100,16 @@ "acorn": "^8.14.0" } }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/acorn-walk": { "version": "8.3.5", "dev": true, @@ -6540,6 +7222,30 @@ "node": ">= 14.0.0" } }, + "node_modules/angular-eslint": { + "version": "21.3.1", + "resolved": "https://registry.npmjs.org/angular-eslint/-/angular-eslint-21.3.1.tgz", + "integrity": "sha512-VGQWTyuPAEO/AnZuqHxGBJMYSiZ0tbrHx/OgPCRTKHfbrFU4x+zivS84h9UWoDpDtius1RyD+ZReFjTAEWptiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": ">= 21.0.0 < 22.0.0", + "@angular-devkit/schematics": ">= 21.0.0 < 22.0.0", + "@angular-eslint/builder": "21.3.1", + "@angular-eslint/eslint-plugin": "21.3.1", + "@angular-eslint/eslint-plugin-template": "21.3.1", + "@angular-eslint/schematics": "21.3.1", + "@angular-eslint/template-parser": "21.3.1", + "@typescript-eslint/types": "^8.0.0", + "@typescript-eslint/utils": "^8.0.0" + }, + "peerDependencies": { + "@angular/cli": ">= 21.0.0 < 22.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": "*", + "typescript-eslint": "^8.0.0" + } + }, "node_modules/ansi-colors": { "version": "4.1.3", "dev": true, @@ -6724,6 +7430,16 @@ "node": ">=4" } }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/babel-jest": { "version": "30.2.0", "dev": true, @@ -8105,6 +8821,13 @@ "node": ">=6" } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, "node_modules/deepmerge": { "version": "4.3.1", "dev": true, @@ -8498,117 +9221,324 @@ "node": ">= 0.4" } }, - "node_modules/es-errors": { - "version": "1.3.0", + "node_modules/es-errors": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es6-shim": { + "version": "0.35.8", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.27.2", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" + } + }, + "node_modules/esbuild-wasm": { + "version": "0.27.2", + "dev": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", + "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "dev": true, - "license": "MIT" - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", + "node_modules/eslint/node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "es-errors": "^1.3.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/es6-shim": { - "version": "0.35.8", - "dev": true, - "license": "MIT" - }, - "node_modules/esbuild": { - "version": "0.27.2", + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.2", - "@esbuild/android-arm": "0.27.2", - "@esbuild/android-arm64": "0.27.2", - "@esbuild/android-x64": "0.27.2", - "@esbuild/darwin-arm64": "0.27.2", - "@esbuild/darwin-x64": "0.27.2", - "@esbuild/freebsd-arm64": "0.27.2", - "@esbuild/freebsd-x64": "0.27.2", - "@esbuild/linux-arm": "0.27.2", - "@esbuild/linux-arm64": "0.27.2", - "@esbuild/linux-ia32": "0.27.2", - "@esbuild/linux-loong64": "0.27.2", - "@esbuild/linux-mips64el": "0.27.2", - "@esbuild/linux-ppc64": "0.27.2", - "@esbuild/linux-riscv64": "0.27.2", - "@esbuild/linux-s390x": "0.27.2", - "@esbuild/linux-x64": "0.27.2", - "@esbuild/netbsd-arm64": "0.27.2", - "@esbuild/netbsd-x64": "0.27.2", - "@esbuild/openbsd-arm64": "0.27.2", - "@esbuild/openbsd-x64": "0.27.2", - "@esbuild/openharmony-arm64": "0.27.2", - "@esbuild/sunos-x64": "0.27.2", - "@esbuild/win32-arm64": "0.27.2", - "@esbuild/win32-ia32": "0.27.2", - "@esbuild/win32-x64": "0.27.2" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/esbuild-wasm": { - "version": "0.27.2", + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, + "license": "BSD-2-Clause", "engines": { - "node": ">=18" + "node": ">=4.0" } }, - "node_modules/escalade": { - "version": "3.2.0", + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">= 4" } }, - "node_modules/escape-html": { - "version": "1.0.3", + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, "license": "MIT" }, - "node_modules/escape-string-regexp": { - "version": "2.0.0", + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, "engines": { - "node": ">=8" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-scope": { - "version": "5.1.1", + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, + "license": "Apache-2.0", "engines": { - "node": ">=8.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -8623,6 +9553,29 @@ "node": ">=4" } }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, "node_modules/esrecurse": { "version": "4.3.0", "dev": true, @@ -8900,6 +9853,13 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-uri": { "version": "3.1.0", "dev": true, @@ -8958,6 +9918,19 @@ } } }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/fill-range": { "version": "7.1.1", "dev": true, @@ -9059,7 +10032,6 @@ "version": "5.0.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -9091,6 +10063,27 @@ "flat": "cli.js" } }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, "node_modules/follow-redirects": { "version": "1.15.11", "dev": true, @@ -9438,7 +10431,6 @@ "version": "6.0.2", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -9500,6 +10492,19 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/gopd": { "version": "1.2.0", "dev": true, @@ -9964,6 +10969,16 @@ "postcss": "^8.1.0" } }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/ignore-walk": { "version": "8.0.0", "dev": true, @@ -11902,6 +12917,13 @@ "node": ">=6" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, "node_modules/json-parse-even-better-errors": { "version": "5.0.0", "dev": true, @@ -11920,6 +12942,13 @@ "dev": true, "license": "BSD-2-Clause" }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/json5": { "version": "2.2.3", "dev": true, @@ -11970,6 +12999,16 @@ "license": "(Apache-2.0 OR MIT)", "peer": true }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kind-of": { "version": "6.0.3", "dev": true, @@ -12079,6 +13118,20 @@ "node": ">=6" } }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/license-webpack-plugin": { "version": "4.0.2", "dev": true, @@ -12221,7 +13274,6 @@ "version": "6.0.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -12247,6 +13299,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, "node_modules/log-symbols": { "version": "7.0.1", "dev": true, @@ -12664,7 +13723,9 @@ "peer": true }, "node_modules/minimatch": { - "version": "3.1.2", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -13360,6 +14421,24 @@ "opencollective-postinstall": "index.js" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/ora": { "version": "9.0.0", "dev": true, @@ -13432,7 +14511,6 @@ "version": "5.0.0", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -14072,6 +15150,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-error": { "version": "4.0.0", "dev": true, @@ -16249,6 +17353,19 @@ "node": ">=6" } }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, "node_modules/ts-dedent": { "version": "2.2.0", "dev": true, @@ -16422,6 +17539,19 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/type-detect": { "version": "4.0.8", "dev": true, @@ -16472,6 +17602,30 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.57.2.tgz", + "integrity": "sha512-VEPQ0iPgWO/sBaZOU1xo4nuNdODVOajPnTIbog2GKYr31nIlZ0fWPoCQgGfF3ETyBl1vn63F/p50Um9Z4J8O8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.57.2", + "@typescript-eslint/parser": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/utils": "8.57.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, "node_modules/uglify-js": { "version": "3.19.3", "dev": true, @@ -17770,6 +18924,16 @@ "dev": true, "license": "ISC" }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wordwrap": { "version": "1.0.0", "dev": true, diff --git a/package.json b/package.json index 1ecd45163..a89418414 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,9 @@ "watch": "ng build --watch --configuration development", "update": "ng update @angular/core@21 @angular/cli@21", "test": "jest", + "lint": "ng lint", + "format": "prettier --write .", + "format:check": "prettier --check .", "storybook": "ng run ion:storybook", "version": "ng version", "build-storybook": "ng run ion:build-storybook" @@ -46,13 +49,18 @@ "@testing-library/jest-dom": "^6.9.1", "@testing-library/user-event": "^14.6.1", "@types/jest": "^30.0.0", + "angular-eslint": "^21.3.1", + "eslint": "^9.39.4", + "eslint-config-prettier": "^10.1.8", "jest": "^30.0.0", "jest-environment-jsdom": "^30.0.0", "jest-preset-angular": "^16.0.0", "ng-packagr": "^21.1.0", + "prettier": "^3.8.1", "sass": "^1.94.2", "storybook": "^10.1.11", "ts-node": "^10.9.2", - "typescript": "~5.9.3" + "typescript": "~5.9.3", + "typescript-eslint": "^8.57.2" } -} \ No newline at end of file +} diff --git a/projects/ion-test-app/src/app/app.component.html b/projects/ion-test-app/src/app/app.component.html index e7abe6897..90c2915df 100644 --- a/projects/ion-test-app/src/app/app.component.html +++ b/projects/ion-test-app/src/app/app.component.html @@ -5,7 +5,7 @@ [rightActions]="[ { iconType: 'search', tooltip: 'Procurar', action: 'search' }, { iconType: 'alert', tooltip: 'Notificações', action: 'notifications' }, - { iconType: 'user', tooltip: 'Perfil', action: 'profile' } + { iconType: 'user', tooltip: 'Perfil', action: 'profile' }, ]" (rightActionOutput)="handleRightActionOutput($event)" (valueChange)="handleValueChangeNavbar($event)" @@ -60,10 +60,13 @@

Custom Content

Confirmar Ação

-

Deseja realmente excluir o item: {{ row.name }}?

+

+ Deseja realmente excluir o item: {{ row.name }}? +

- + Confirmar Ação [ionPopoverPosition]="PopoverPosition.RIGHT_CENTER" [ionPopoverActions]="[ { label: 'Cancel' }, - { label: 'Confirm', type: 'primary' } + { label: 'Confirm', type: 'primary' }, ]" (ionOnFirstAction)="handlePopoverFirstAction()" (ionOnSecondAction)="handlePopoverSecondAction()" > -
@@ -128,7 +130,7 @@

Button with Icons

[options]="[ { label: 'Item 1' }, { label: 'Item 2' }, - { label: 'Item 3' } + { label: 'Item 3' }, ]" > @@ -370,7 +372,7 @@

Breadcrumbs

[breadcrumbs]="[ { label: 'Home', link: '/home' }, { label: 'Components', link: '/components' }, - { label: 'Breadcrumb', link: '/breadcrumb' } + { label: 'Breadcrumb', link: '/breadcrumb' }, ]" > @@ -382,7 +384,7 @@

Breadcrumbs

{ label: 'Level 3', link: '/level3' }, { label: 'Level 4', link: '/level4' }, { label: 'Level 5', link: '/level5' }, - { label: 'Current', link: '/current' } + { label: 'Current', link: '/current' }, ]" [truncate]="true" > @@ -430,7 +432,7 @@

Chips

[options]="[ { label: 'Option 1' }, { label: 'Option 2' }, - { label: 'Option 3' } + { label: 'Option 3' }, ]" > @@ -440,7 +442,7 @@

Chips

[options]="[ { label: 'Item A' }, { label: 'Item B' }, - { label: 'Item C' } + { label: 'Item C' }, ]" > @@ -449,7 +451,7 @@

Chips

[options]="[ { label: 'Apple' }, { label: 'Banana' }, - { label: 'Cherry' } + { label: 'Cherry' }, ]" [dropdownSearchConfig]="{ enableSearch: true, @@ -508,7 +510,7 @@

Disabled Group

@@ -917,7 +919,7 @@

Custom Options

@@ -929,7 +931,7 @@

With Icons

[value]="tripleToggleWithIconsValue" [options]="[ { label: 'Sim', value: true, icon: 'check' }, - { label: 'Não', value: false, icon: 'close' } + { label: 'Não', value: false, icon: 'close' }, ]" (ionClick)=" tripleToggleWithIconsValue = $event; @@ -945,7 +947,7 @@

Only Icons (No Labels)

[onlyShowIcon]="true" [options]="[ { label: 'Like', value: 'like', icon: 'star' }, - { label: 'Dislike', value: 'dislike', icon: 'close' } + { label: 'Dislike', value: 'dislike', icon: 'close' }, ]" (ionClick)="handleTripleToggleChange($event)" > @@ -962,7 +964,7 @@

Small Size

size="sm" [options]="[ { label: 'Sim', value: true }, - { label: 'Não', value: false } + { label: 'Não', value: false }, ]" > @@ -973,7 +975,7 @@

Large Size

size="lg" [options]="[ { label: 'Sim', value: true }, - { label: 'Não', value: false } + { label: 'Não', value: false }, ]" > @@ -1466,7 +1468,7 @@

Sidebar

> @if (!sidebarComp.closed()) { - Sair do App + Sair do App } @@ -1855,9 +1857,9 @@

Basic Date Picker

(event)="handleDatePickerChange($event)" > @if (datePickerValue.length) { -

- Selected Date: {{ datePickerValue[0] }} -

+

+ Selected Date: {{ datePickerValue[0] }} +

} @@ -1868,10 +1870,10 @@

Date Range Picker

(event)="handleDateRangePickerChange($event)" > @if (dateRangePickerValue.length) { -

- Selected Range: {{ dateRangePickerValue[0] }} - - {{ dateRangePickerValue[1] }} -

+

+ Selected Range: {{ dateRangePickerValue[0] }} - + {{ dateRangePickerValue[1] }} +

} @@ -1883,11 +1885,11 @@

Date Range with Predefined Ranges

(event)="handleDatePickerWithPredefinedChange($event)" > @if (datePickerWithPredefinedValue.length) { -

- Selected Range: - {{ datePickerWithPredefinedValue[0] }} - - {{ datePickerWithPredefinedValue[1] }} -

+

+ Selected Range: + {{ datePickerWithPredefinedValue[0] }} - + {{ datePickerWithPredefinedValue[1] }} +

} @@ -2129,7 +2131,10 @@

Ion Drawer

(click)="openDrawer('left')" > - +

This is a component rendered inside the modal!

@if (data) { -

- Data received: {{ data }} -

+

+ Data received: {{ data }} +

}

You can pass data to it and receive values back.

@@ -112,7 +119,7 @@ class ModalExampleComponent { template: `
@for (item of items; track $index) { -

Linha de conteúdo número {{ $index + 1 }} para testar o scroll.

+

Linha de conteúdo número {{ $index + 1 }} para testar o scroll.

}
`, @@ -277,7 +284,7 @@ export class AppComponent implements OnInit { ]; const filtered = search ? allOptions.filter((opt) => - opt.label.toLowerCase().includes(search.toLowerCase()) + opt.label.toLowerCase().includes(search.toLowerCase()), ) : allOptions; console.log('[AppComponent] Found:', filtered); @@ -296,7 +303,7 @@ export class AppComponent implements OnInit { optionsMock = { projectOptions: [ - { label: 'Projeto A', value: 'project_a' }, + { label: 'Projeto A', value: 'project_a' }, { label: 'Projeto B', value: 'project_b' }, ], centerOriginOptions: [ @@ -321,7 +328,7 @@ export class AppComponent implements OnInit { onSubmit: (data) => { return this.http.post( 'https://jsonplaceholder.typicode.com/posts', - data + data, ); }, steps: [ @@ -660,7 +667,7 @@ export class AppComponent implements OnInit { description: 'Tem certeza que deseja excluir?', // confirmText: 'Excluir', // cancelText: 'Cancelar', - } + }, // popover: (row: any) => ({ // ionPopoverTitle: 'Excluir Item', // ionPopoverBody: this.tablePopoverTemplate, @@ -834,14 +841,14 @@ export class AppComponent implements OnInit { confirm: { title: 'Excluir', description: 'Tem certeza que deseja excluir?', - } + }, }, ], }; ngOnInit(): void { const quantityColumn = this.smartTableConfig.columns.find( - (col) => col.key === 'quantity' + (col) => col.key === 'quantity', ); if (quantityColumn) { quantityColumn.customTemplate = this.quantityTemplate; @@ -872,7 +879,7 @@ export class AppComponent implements OnInit { this.smartTableConfig = { ...this.smartTableConfig, data: this.smartTableConfig.data.filter( - (item: any) => item.id !== row.id + (item: any) => item.id !== row.id, ), pagination: { ...this.smartTableConfig.pagination, @@ -938,7 +945,7 @@ export class AppComponent implements OnInit { showNotification(type: 'success' | 'info' | 'warning' | 'error') { (this.notificationService as any)[type]( 'Notification Title', - 'This is a notification message' + 'This is a notification message', ); } @@ -1089,7 +1096,7 @@ export class AppComponent implements OnInit { const modalObservable = this.modalService.open( ModalExampleComponent, - modalConfig + modalConfig, ); modalObservable.subscribe((result: unknown) => { @@ -1152,15 +1159,15 @@ export class AppComponent implements OnInit { validators: [Validators.minLength(3)], }, { - key: 'arquivo', - label: 'Arquivo', - type: 'upload', - accept: '.csv', - acceptLabel: 'Apenas arquivos CSV', - showUrlImport: true, - urlPlaceholder: 'https://...', - onImportUrl: (url) => console.log(url), - }, + key: 'arquivo', + label: 'Arquivo', + type: 'upload', + accept: '.csv', + acceptLabel: 'Apenas arquivos CSV', + showUrlImport: true, + urlPlaceholder: 'https://...', + onImportUrl: (url) => console.log(url), + }, { key: 'sobrenome', className: 'col-6', diff --git a/projects/ion-test-app/src/index.html b/projects/ion-test-app/src/index.html index c11985e30..c790ce4f7 100644 --- a/projects/ion-test-app/src/index.html +++ b/projects/ion-test-app/src/index.html @@ -7,7 +7,7 @@ - + diff --git a/projects/ion/documentation.json b/projects/ion/documentation.json index 6464a4792..974a26d1e 100644 --- a/projects/ion/documentation.json +++ b/projects/ion/documentation.json @@ -1,218 +1,218 @@ { - "pipes": [], - "interfaces": [], - "injectables": [], - "guards": [], - "interceptors": [], - "classes": [], - "directives": [], - "components": [], - "modules": [], - "miscellaneous": { - "variables": [ - { - "name": "decorators", - "ctype": "miscellaneous", - "subtype": "variable", - "file": "projects/ion/.storybook/preview.ts", - "deprecated": false, - "deprecationMessage": "", - "type": "[]", - "defaultValue": "[\n (story: any, context: any) => {\n const theme = context.globals?.ionTheme || 'light';\n if (typeof document !== 'undefined') {\n document.body.setAttribute('ion-theme', theme);\n }\n return story();\n },\n]" - }, - { - "name": "Default", - "ctype": "miscellaneous", - "subtype": "variable", - "file": "projects/ion/src/stories/bn-filter.stories.ts", - "deprecated": false, - "deprecationMessage": "", - "type": "StoryObj", - "defaultValue": "{\n args: {\n pageTitle: 'Filtro de Clientes',\n fields: [\n { key: 'nome', label: 'Nome Completo', type: 'text', required: true },\n {\n key: 'data',\n label: 'Data de Cadastro',\n type: 'datepicker',\n required: false,\n },\n ],\n },\n}" - }, - { - "name": "globalTypes", - "ctype": "miscellaneous", - "subtype": "variable", - "file": "projects/ion/.storybook/preview.ts", - "deprecated": false, - "deprecationMessage": "", - "type": "object", - "defaultValue": "{\n ionTheme: {\n name: 'Ion Theme',\n description: 'Set the active ion theme',\n defaultValue: 'light',\n toolbar: {\n icon: 'circle',\n items: [\n { value: 'light', title: 'Light' },\n { value: 'dark', title: 'Dark' },\n { value: 'orange-light', title: 'Orange Light' },\n { value: 'orange-dark', title: 'Orange Dark' },\n ],\n },\n },\n}" - }, - { - "name": "meta", - "ctype": "miscellaneous", - "subtype": "variable", - "file": "projects/ion/src/stories/bn-filter.stories.ts", - "deprecated": false, - "deprecationMessage": "", - "type": "Meta", - "defaultValue": "{\n title: 'Core/BnFilter',\n component: BnFilterComponent,\n tags: ['autodocs'],\n argTypes: {\n applied: { action: 'applied' },\n cleared: { action: 'cleared' },\n },\n render: (args) => ({\n props: args,\n applicationConfig: {\n providers: [BnFormService],\n },\n }),\n}" - }, - { - "name": "preview", - "ctype": "miscellaneous", - "subtype": "variable", - "file": "projects/ion/.storybook/preview.ts", - "deprecated": false, - "deprecationMessage": "", - "type": "Preview", - "defaultValue": "{\n parameters: {\n controls: {\n matchers: {\n color: /(background|color)$/i,\n date: /Date$/i,\n },\n },\n },\n}" - }, - { - "name": "Vazio", - "ctype": "miscellaneous", - "subtype": "variable", - "file": "projects/ion/src/stories/bn-filter.stories.ts", - "deprecated": false, - "deprecationMessage": "", - "type": "StoryObj", - "defaultValue": "{\n args: {\n pageTitle: 'Filtro Sem Campos',\n fields: [],\n },\n}" - } - ], - "functions": [], - "typealiases": [], - "enumerations": [], - "groupedVariables": { - "projects/ion/.storybook/preview.ts": [ - { - "name": "decorators", - "ctype": "miscellaneous", - "subtype": "variable", - "file": "projects/ion/.storybook/preview.ts", - "deprecated": false, - "deprecationMessage": "", - "type": "[]", - "defaultValue": "[\n (story: any, context: any) => {\n const theme = context.globals?.ionTheme || 'light';\n if (typeof document !== 'undefined') {\n document.body.setAttribute('ion-theme', theme);\n }\n return story();\n },\n]" - }, - { - "name": "globalTypes", - "ctype": "miscellaneous", - "subtype": "variable", - "file": "projects/ion/.storybook/preview.ts", - "deprecated": false, - "deprecationMessage": "", - "type": "object", - "defaultValue": "{\n ionTheme: {\n name: 'Ion Theme',\n description: 'Set the active ion theme',\n defaultValue: 'light',\n toolbar: {\n icon: 'circle',\n items: [\n { value: 'light', title: 'Light' },\n { value: 'dark', title: 'Dark' },\n { value: 'orange-light', title: 'Orange Light' },\n { value: 'orange-dark', title: 'Orange Dark' },\n ],\n },\n },\n}" - }, - { - "name": "preview", - "ctype": "miscellaneous", - "subtype": "variable", - "file": "projects/ion/.storybook/preview.ts", - "deprecated": false, - "deprecationMessage": "", - "type": "Preview", - "defaultValue": "{\n parameters: {\n controls: {\n matchers: {\n color: /(background|color)$/i,\n date: /Date$/i,\n },\n },\n },\n}" - } - ], - "projects/ion/src/stories/bn-filter.stories.ts": [ - { - "name": "Default", - "ctype": "miscellaneous", - "subtype": "variable", - "file": "projects/ion/src/stories/bn-filter.stories.ts", - "deprecated": false, - "deprecationMessage": "", - "type": "StoryObj", - "defaultValue": "{\n args: {\n pageTitle: 'Filtro de Clientes',\n fields: [\n { key: 'nome', label: 'Nome Completo', type: 'text', required: true },\n {\n key: 'data',\n label: 'Data de Cadastro',\n type: 'datepicker',\n required: false,\n },\n ],\n },\n}" - }, - { - "name": "meta", - "ctype": "miscellaneous", - "subtype": "variable", - "file": "projects/ion/src/stories/bn-filter.stories.ts", - "deprecated": false, - "deprecationMessage": "", - "type": "Meta", - "defaultValue": "{\n title: 'Core/BnFilter',\n component: BnFilterComponent,\n tags: ['autodocs'],\n argTypes: {\n applied: { action: 'applied' },\n cleared: { action: 'cleared' },\n },\n render: (args) => ({\n props: args,\n applicationConfig: {\n providers: [BnFormService],\n },\n }),\n}" - }, - { - "name": "Vazio", - "ctype": "miscellaneous", - "subtype": "variable", - "file": "projects/ion/src/stories/bn-filter.stories.ts", - "deprecated": false, - "deprecationMessage": "", - "type": "StoryObj", - "defaultValue": "{\n args: {\n pageTitle: 'Filtro Sem Campos',\n fields: [],\n },\n}" - } - ] + "pipes": [], + "interfaces": [], + "injectables": [], + "guards": [], + "interceptors": [], + "classes": [], + "directives": [], + "components": [], + "modules": [], + "miscellaneous": { + "variables": [ + { + "name": "decorators", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "projects/ion/.storybook/preview.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "[]", + "defaultValue": "[\n (story: any, context: any) => {\n const theme = context.globals?.ionTheme || 'light';\n if (typeof document !== 'undefined') {\n document.body.setAttribute('ion-theme', theme);\n }\n return story();\n },\n]" + }, + { + "name": "Default", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "projects/ion/src/stories/bn-filter.stories.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "StoryObj", + "defaultValue": "{\n args: {\n pageTitle: 'Filtro de Clientes',\n fields: [\n { key: 'nome', label: 'Nome Completo', type: 'text', required: true },\n {\n key: 'data',\n label: 'Data de Cadastro',\n type: 'datepicker',\n required: false,\n },\n ],\n },\n}" + }, + { + "name": "globalTypes", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "projects/ion/.storybook/preview.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "object", + "defaultValue": "{\n ionTheme: {\n name: 'Ion Theme',\n description: 'Set the active ion theme',\n defaultValue: 'light',\n toolbar: {\n icon: 'circle',\n items: [\n { value: 'light', title: 'Light' },\n { value: 'dark', title: 'Dark' },\n { value: 'orange-light', title: 'Orange Light' },\n { value: 'orange-dark', title: 'Orange Dark' },\n ],\n },\n },\n}" + }, + { + "name": "meta", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "projects/ion/src/stories/bn-filter.stories.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "Meta", + "defaultValue": "{\n title: 'Core/BnFilter',\n component: BnFilterComponent,\n tags: ['autodocs'],\n argTypes: {\n applied: { action: 'applied' },\n cleared: { action: 'cleared' },\n },\n render: (args) => ({\n props: args,\n applicationConfig: {\n providers: [BnFormService],\n },\n }),\n}" + }, + { + "name": "preview", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "projects/ion/.storybook/preview.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "Preview", + "defaultValue": "{\n parameters: {\n controls: {\n matchers: {\n color: /(background|color)$/i,\n date: /Date$/i,\n },\n },\n },\n}" + }, + { + "name": "Vazio", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "projects/ion/src/stories/bn-filter.stories.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "StoryObj", + "defaultValue": "{\n args: {\n pageTitle: 'Filtro Sem Campos',\n fields: [],\n },\n}" + } + ], + "functions": [], + "typealiases": [], + "enumerations": [], + "groupedVariables": { + "projects/ion/.storybook/preview.ts": [ + { + "name": "decorators", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "projects/ion/.storybook/preview.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "[]", + "defaultValue": "[\n (story: any, context: any) => {\n const theme = context.globals?.ionTheme || 'light';\n if (typeof document !== 'undefined') {\n document.body.setAttribute('ion-theme', theme);\n }\n return story();\n },\n]" }, - "groupedFunctions": {}, - "groupedEnumerations": {}, - "groupedTypeAliases": {} - }, - "routes": { - "name": "", - "kind": "module", - "children": [] + { + "name": "globalTypes", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "projects/ion/.storybook/preview.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "object", + "defaultValue": "{\n ionTheme: {\n name: 'Ion Theme',\n description: 'Set the active ion theme',\n defaultValue: 'light',\n toolbar: {\n icon: 'circle',\n items: [\n { value: 'light', title: 'Light' },\n { value: 'dark', title: 'Dark' },\n { value: 'orange-light', title: 'Orange Light' },\n { value: 'orange-dark', title: 'Orange Dark' },\n ],\n },\n },\n}" + }, + { + "name": "preview", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "projects/ion/.storybook/preview.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "Preview", + "defaultValue": "{\n parameters: {\n controls: {\n matchers: {\n color: /(background|color)$/i,\n date: /Date$/i,\n },\n },\n },\n}" + } + ], + "projects/ion/src/stories/bn-filter.stories.ts": [ + { + "name": "Default", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "projects/ion/src/stories/bn-filter.stories.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "StoryObj", + "defaultValue": "{\n args: {\n pageTitle: 'Filtro de Clientes',\n fields: [\n { key: 'nome', label: 'Nome Completo', type: 'text', required: true },\n {\n key: 'data',\n label: 'Data de Cadastro',\n type: 'datepicker',\n required: false,\n },\n ],\n },\n}" + }, + { + "name": "meta", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "projects/ion/src/stories/bn-filter.stories.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "Meta", + "defaultValue": "{\n title: 'Core/BnFilter',\n component: BnFilterComponent,\n tags: ['autodocs'],\n argTypes: {\n applied: { action: 'applied' },\n cleared: { action: 'cleared' },\n },\n render: (args) => ({\n props: args,\n applicationConfig: {\n providers: [BnFormService],\n },\n }),\n}" + }, + { + "name": "Vazio", + "ctype": "miscellaneous", + "subtype": "variable", + "file": "projects/ion/src/stories/bn-filter.stories.ts", + "deprecated": false, + "deprecationMessage": "", + "type": "StoryObj", + "defaultValue": "{\n args: {\n pageTitle: 'Filtro Sem Campos',\n fields: [],\n },\n}" + } + ] }, - "coverage": { - "count": 0, - "status": "low", - "files": [ - { - "filePath": "projects/ion/.storybook/preview.ts", - "type": "variable", - "linktype": "miscellaneous", - "linksubtype": "variable", - "name": "decorators", - "coveragePercent": 0, - "coverageCount": "0/1", - "status": "low" - }, - { - "filePath": "projects/ion/.storybook/preview.ts", - "type": "variable", - "linktype": "miscellaneous", - "linksubtype": "variable", - "name": "globalTypes", - "coveragePercent": 0, - "coverageCount": "0/1", - "status": "low" - }, - { - "filePath": "projects/ion/.storybook/preview.ts", - "type": "variable", - "linktype": "miscellaneous", - "linksubtype": "variable", - "name": "preview", - "coveragePercent": 0, - "coverageCount": "0/1", - "status": "low" - }, - { - "filePath": "projects/ion/src/stories/bn-filter.stories.ts", - "type": "variable", - "linktype": "miscellaneous", - "linksubtype": "variable", - "name": "Default", - "coveragePercent": 0, - "coverageCount": "0/1", - "status": "low" - }, - { - "filePath": "projects/ion/src/stories/bn-filter.stories.ts", - "type": "variable", - "linktype": "miscellaneous", - "linksubtype": "variable", - "name": "meta", - "coveragePercent": 0, - "coverageCount": "0/1", - "status": "low" - }, - { - "filePath": "projects/ion/src/stories/bn-filter.stories.ts", - "type": "variable", - "linktype": "miscellaneous", - "linksubtype": "variable", - "name": "Vazio", - "coveragePercent": 0, - "coverageCount": "0/1", - "status": "low" - } - ] - } -} \ No newline at end of file + "groupedFunctions": {}, + "groupedEnumerations": {}, + "groupedTypeAliases": {} + }, + "routes": { + "name": "", + "kind": "module", + "children": [] + }, + "coverage": { + "count": 0, + "status": "low", + "files": [ + { + "filePath": "projects/ion/.storybook/preview.ts", + "type": "variable", + "linktype": "miscellaneous", + "linksubtype": "variable", + "name": "decorators", + "coveragePercent": 0, + "coverageCount": "0/1", + "status": "low" + }, + { + "filePath": "projects/ion/.storybook/preview.ts", + "type": "variable", + "linktype": "miscellaneous", + "linksubtype": "variable", + "name": "globalTypes", + "coveragePercent": 0, + "coverageCount": "0/1", + "status": "low" + }, + { + "filePath": "projects/ion/.storybook/preview.ts", + "type": "variable", + "linktype": "miscellaneous", + "linksubtype": "variable", + "name": "preview", + "coveragePercent": 0, + "coverageCount": "0/1", + "status": "low" + }, + { + "filePath": "projects/ion/src/stories/bn-filter.stories.ts", + "type": "variable", + "linktype": "miscellaneous", + "linksubtype": "variable", + "name": "Default", + "coveragePercent": 0, + "coverageCount": "0/1", + "status": "low" + }, + { + "filePath": "projects/ion/src/stories/bn-filter.stories.ts", + "type": "variable", + "linktype": "miscellaneous", + "linksubtype": "variable", + "name": "meta", + "coveragePercent": 0, + "coverageCount": "0/1", + "status": "low" + }, + { + "filePath": "projects/ion/src/stories/bn-filter.stories.ts", + "type": "variable", + "linktype": "miscellaneous", + "linksubtype": "variable", + "name": "Vazio", + "coveragePercent": 0, + "coverageCount": "0/1", + "status": "low" + } + ] + } +} diff --git a/projects/ion/src/lib/alert/alert.component.html b/projects/ion/src/lib/alert/alert.component.html index 1c60befc1..55ca86cf5 100644 --- a/projects/ion/src/lib/alert/alert.component.html +++ b/projects/ion/src/lib/alert/alert.component.html @@ -7,7 +7,7 @@ 'no-radius': noRadius(), }" #ionAlert - > +>
@if (hasPlainText()) { - {{ message() }} - } @else { - - } - -
- - @if (closable()) { - + {{ + message() + }} + } @else { + }
- @if (description() && description()!.length > 0) { - - {{ description() }} - + @if (closable()) { + } + + @if (description() && description()!.length > 0) { + + {{ description() }} + + } + diff --git a/projects/ion/src/lib/avatar/avatar.component.ts b/projects/ion/src/lib/avatar/avatar.component.ts index ba88a6aee..224db0d35 100644 --- a/projects/ion/src/lib/avatar/avatar.component.ts +++ b/projects/ion/src/lib/avatar/avatar.component.ts @@ -1,4 +1,3 @@ - import { Component, computed, input } from '@angular/core'; import { AvatarType } from '../core/types/avatar'; import { SizeType } from '../core/types/size'; diff --git a/projects/ion/src/lib/badge/badge.component.ts b/projects/ion/src/lib/badge/badge.component.ts index b8a87512b..26e254864 100644 --- a/projects/ion/src/lib/badge/badge.component.ts +++ b/projects/ion/src/lib/badge/badge.component.ts @@ -1,4 +1,3 @@ - import { Component, computed, input } from '@angular/core'; import { BadgeType } from '../core/types/badge'; diff --git a/projects/ion/src/lib/breadcrumb/breadcrumb.component.html b/projects/ion/src/lib/breadcrumb/breadcrumb.component.html index cfd5e81a8..dd3c6d97f 100644 --- a/projects/ion/src/lib/breadcrumb/breadcrumb.component.html +++ b/projects/ion/src/lib/breadcrumb/breadcrumb.component.html @@ -1,41 +1,48 @@ diff --git a/projects/ion/src/lib/button/button.component.html b/projects/ion/src/lib/button/button.component.html index 6a8d22ff6..d52ca93e4 100644 --- a/projects/ion/src/lib/button/button.component.html +++ b/projects/ion/src/lib/button/button.component.html @@ -14,50 +14,55 @@ (click)="handleClick()" > @if (loading()) { - + } @if (iconType() && !loading()) { - - } @if (options() && !circularButton() && !loading()) { - - } @if (!circularButton() && _label()) { @if (!loading() || (loading() && - !loadingMessage())) { - {{ _label() }} - } @if (loading() && loadingMessage()) { - {{ loadingMessage() }} - } } @if (multiple() && !loading() && !circularButton()) { - + + } + @if (options() && !circularButton() && !loading()) { + + } + @if (!circularButton() && _label()) { + @if (!loading() || (loading() && !loadingMessage())) { + {{ _label() }} + } + @if (loading() && loadingMessage()) { + {{ loadingMessage() }} + } + } + @if (multiple() && !loading() && !circularButton()) { + } @if (!!options() && showDropdown()) { - + } diff --git a/projects/ion/src/lib/button/button.component.spec.ts b/projects/ion/src/lib/button/button.component.spec.ts index 6b5bbd8ff..6ac6ab29d 100644 --- a/projects/ion/src/lib/button/button.component.spec.ts +++ b/projects/ion/src/lib/button/button.component.spec.ts @@ -107,7 +107,10 @@ describe('ButtonComponent', () => { const icon = button.querySelector('ion-icon'); expect(icon).toBeTruthy(); - expect(icon.querySelector('svg')).toHaveAttribute('id', 'ion-icon-pencil'); + expect(icon.querySelector('svg')).toHaveAttribute( + 'id', + 'ion-icon-pencil', + ); }); it('Right side icon', () => { @@ -141,7 +144,7 @@ describe('ButtonComponent', () => { fixture.detectChanges(); const button = fixture.nativeElement.querySelector( - `[data-testid="btn-${myCustomId}"]` + `[data-testid="btn-${myCustomId}"]`, ); expect(button).toBeTruthy(); }); @@ -239,7 +242,7 @@ describe('ButtonComponent', () => { fixture.detectChanges(); const dropdown = document.body.querySelector( - '[data-testid="ion-dropdown"]' + '[data-testid="ion-dropdown"]', ); expect(dropdown).toBeTruthy(); }); @@ -259,7 +262,7 @@ describe('ButtonComponent', () => { fixture.detectChanges(); const dropdown = document.body.querySelector( - '[data-testid="ion-dropdown"]' + '[data-testid="ion-dropdown"]', ); expect(dropdown).toBeFalsy(); }); @@ -292,7 +295,7 @@ describe('ButtonComponent', () => { fixture.detectChanges(); const badge = fixture.nativeElement.querySelector( - '[data-testid="badge-multiple"]' + '[data-testid="badge-multiple"]', ); expect(badge).toBeTruthy(); }); @@ -307,7 +310,7 @@ describe('ButtonComponent', () => { fixture.detectChanges(); const badge = fixture.nativeElement.querySelector( - '[data-testid="badge-multiple"]' + '[data-testid="badge-multiple"]', ); expect(badge).toBeFalsy(); }); @@ -322,7 +325,7 @@ describe('ButtonComponent', () => { fixture.detectChanges(); const badge = fixture.nativeElement.querySelector( - '[data-testid="badge-multiple"]' + '[data-testid="badge-multiple"]', ); expect(badge).toBeFalsy(); }); @@ -336,7 +339,7 @@ describe('ButtonComponent', () => { fixture.detectChanges(); const badge = fixture.nativeElement.querySelector( - '[data-testid="badge-multiple"] span' + '[data-testid="badge-multiple"] span', ); expect(badge.textContent).toBe('0'); }); diff --git a/projects/ion/src/lib/button/button.component.ts b/projects/ion/src/lib/button/button.component.ts index 19b40b146..9d6bea326 100644 --- a/projects/ion/src/lib/button/button.component.ts +++ b/projects/ion/src/lib/button/button.component.ts @@ -1,4 +1,3 @@ - import { Component, computed, @@ -22,11 +21,7 @@ import { IonBadgeComponent } from '../badge/badge.component'; @Component({ selector: 'ion-button', standalone: true, - imports: [ - IonIconComponent, - IonDropdownComponent, - IonBadgeComponent -], + imports: [IonIconComponent, IonDropdownComponent, IonBadgeComponent], templateUrl: './button.component.html', styleUrls: ['./button.component.scss'], host: { diff --git a/projects/ion/src/lib/card/_card.theme.scss b/projects/ion/src/lib/card/_card.theme.scss index 8cb2b6a3c..616f353a0 100644 --- a/projects/ion/src/lib/card/_card.theme.scss +++ b/projects/ion/src/lib/card/_card.theme.scss @@ -1,4 +1,4 @@ -@import "../../styles/themes/theme.scss"; +@import '../../styles/themes/theme.scss'; $default: ( border-radius: 8px, diff --git a/projects/ion/src/lib/card/card-footer.component.scss b/projects/ion/src/lib/card/card-footer.component.scss index 1eca82d6e..579b8e184 100644 --- a/projects/ion/src/lib/card/card-footer.component.scss +++ b/projects/ion/src/lib/card/card-footer.component.scss @@ -1,5 +1,5 @@ -@import "../../styles/index.scss"; -@import "../../styles/themes/theme.scss"; +@import '../../styles/index.scss'; +@import '../../styles/themes/theme.scss'; :host { display: block; diff --git a/projects/ion/src/lib/card/card-footer.component.ts b/projects/ion/src/lib/card/card-footer.component.ts index 4f0a9a3ee..2253833f6 100644 --- a/projects/ion/src/lib/card/card-footer.component.ts +++ b/projects/ion/src/lib/card/card-footer.component.ts @@ -1,4 +1,3 @@ - import { ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ diff --git a/projects/ion/src/lib/card/card-header.component.scss b/projects/ion/src/lib/card/card-header.component.scss index 53408f259..848aec6cb 100644 --- a/projects/ion/src/lib/card/card-header.component.scss +++ b/projects/ion/src/lib/card/card-header.component.scss @@ -1,5 +1,5 @@ -@import "../../styles/index.scss"; -@import "../../styles/themes/theme.scss"; +@import '../../styles/index.scss'; +@import '../../styles/themes/theme.scss'; :host { display: flex; diff --git a/projects/ion/src/lib/card/card-header.component.ts b/projects/ion/src/lib/card/card-header.component.ts index 54c23645c..f52073a31 100644 --- a/projects/ion/src/lib/card/card-header.component.ts +++ b/projects/ion/src/lib/card/card-header.component.ts @@ -1,4 +1,3 @@ - import { ChangeDetectionStrategy, Component, input } from '@angular/core'; import { IonIconComponent } from '../icon/icon.component'; import { IonTooltipDirective } from '../tooltip/tooltip.directive'; diff --git a/projects/ion/src/lib/card/card.component.scss b/projects/ion/src/lib/card/card.component.scss index b8eed3cae..fec0a78a6 100644 --- a/projects/ion/src/lib/card/card.component.scss +++ b/projects/ion/src/lib/card/card.component.scss @@ -1,7 +1,7 @@ -@use "card.theme"; +@use 'card.theme'; -@import "../../styles/index.scss"; -@import "../../styles/themes/theme.scss"; +@import '../../styles/index.scss'; +@import '../../styles/themes/theme.scss'; .card-ion { min-width: fit-content; diff --git a/projects/ion/src/lib/card/card.component.spec.ts b/projects/ion/src/lib/card/card.component.spec.ts index f87723fca..1f4c58d00 100644 --- a/projects/ion/src/lib/card/card.component.spec.ts +++ b/projects/ion/src/lib/card/card.component.spec.ts @@ -1,7 +1,6 @@ import { Component } from '@angular/core'; import { render, screen } from '@testing-library/angular'; - // Importação dos seus componentes import { IonCardComponent } from './card.component'; import { IonCardHeaderComponent } from './card-header.component'; @@ -33,8 +32,8 @@ const footerText = 'Conteúdo do footer'; IonCardComponent, IonCardHeaderComponent, IonCardFooterComponent, - IonIconComponent -], + IonIconComponent, + ], }) class FullCardTestWrapperComponent { title = cardTitle; @@ -91,10 +90,10 @@ describe('IonCard Component Suite', () => { it('should project actions content into the specific actions slot', () => { expect(screen.getByTestId('actions-content')).toHaveTextContent( - 'Actions' + 'Actions', ); expect(screen.getByTestId('header-actions')).toContainElement( - screen.getByTestId('actions-content') + screen.getByTestId('actions-content'), ); }); @@ -111,7 +110,7 @@ describe('IonCard Component Suite', () => { it('should render custom content in header when no title input is provided', async () => { await render(CustomHeaderTestWrapperComponent); expect(screen.getByTestId('custom-header-content')).toHaveTextContent( - 'Conteúdo Customizado' + 'Conteúdo Customizado', ); }); diff --git a/projects/ion/src/lib/card/card.component.ts b/projects/ion/src/lib/card/card.component.ts index 281237b35..a23c04a60 100644 --- a/projects/ion/src/lib/card/card.component.ts +++ b/projects/ion/src/lib/card/card.component.ts @@ -1,4 +1,3 @@ - import { ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ diff --git a/projects/ion/src/lib/checkbox/checkbox.component.ts b/projects/ion/src/lib/checkbox/checkbox.component.ts index 15dc70d7b..47dd83be3 100644 --- a/projects/ion/src/lib/checkbox/checkbox.component.ts +++ b/projects/ion/src/lib/checkbox/checkbox.component.ts @@ -1,4 +1,3 @@ - import { Component, effect, diff --git a/projects/ion/src/lib/chip-group/chip-group.component.html b/projects/ion/src/lib/chip-group/chip-group.component.html index 422b36c60..053df68a8 100644 --- a/projects/ion/src/lib/chip-group/chip-group.component.html +++ b/projects/ion/src/lib/chip-group/chip-group.component.html @@ -1,24 +1,24 @@
@for (chip of chips(); track chip.label) { - + }
diff --git a/projects/ion/src/lib/chip/chip.component.html b/projects/ion/src/lib/chip/chip.component.html index 5480aab1c..188564364 100644 --- a/projects/ion/src/lib/chip/chip.component.html +++ b/projects/ion/src/lib/chip/chip.component.html @@ -8,28 +8,34 @@ [class.chip-selected]="displaySelected()" [class]="'ion-chip chip-' + size()" > - @if ( (!options().length && icon()) || (options().length && dropdownWithIcon() - && iconPlaceholder() && iconPosition() === 'left') ) { - - - } @if (chipSelectionBadge().value > 0 && multiple()) { - + @if ( + (!options().length && icon()) || + (options().length && + dropdownWithIcon() && + iconPlaceholder() && + iconPosition() === 'left') + ) { + + + } + @if (chipSelectionBadge().value > 0 && multiple()) { + } @else if (badge() && badge()!.position === 'left') { - + }
@@ -37,40 +43,42 @@
@if (badge() && (badge()!.position === 'right' || !badge()!.position)) { - - } @if (infoBadge()) { - - } @if (options().length) { - - + + } + @if (infoBadge()) { + + } + @if (options().length) { + + } @if (showDropdown()) { - + } diff --git a/projects/ion/src/lib/chip/chip.component.spec.ts b/projects/ion/src/lib/chip/chip.component.spec.ts index f2e0340fb..43ecad6f8 100644 --- a/projects/ion/src/lib/chip/chip.component.spec.ts +++ b/projects/ion/src/lib/chip/chip.component.spec.ts @@ -11,12 +11,17 @@ import { IonIconComponent } from '../icon/icon.component'; import { IonInfoBadgeComponent } from '../info-badge/info-badge.component'; import { SafeAny } from '../utils/safe-any'; import { IonChipComponent } from './chip.component'; -import { ChipSize, DropdownItem, InfoBadgeStatus, IonChipProps } from '../core/types'; +import { + ChipSize, + DropdownItem, + InfoBadgeStatus, + IonChipProps, +} from '../core/types'; const defaultOptions = [{ label: 'Cat' }, { label: 'Dog' }]; const sut = async ( - customProps?: Partial + customProps?: Partial, ): Promise> => { return await render(IonChipComponent, { componentInputs: { @@ -65,7 +70,7 @@ describe('ChipComponent', () => { await sut({ label: 'custom-size', size: size as ChipSize }); const element = screen.getByTestId('ion-chip'); expect(element).toHaveClass('chip-' + size); - } + }, ); it('should render icon on left', async () => { @@ -103,7 +108,7 @@ describe('ChipComponent', () => { async (badgeType: string) => { await sut({ label: 'chip', infoBadge: badgeType as InfoBadgeStatus }); expect(screen.getByTestId('info-badge')).toHaveClass(badgeType); - } + }, ); it('should render chip with right badge', async () => { diff --git a/projects/ion/src/lib/chip/chip.component.ts b/projects/ion/src/lib/chip/chip.component.ts index 75eeceb4d..a8da82192 100644 --- a/projects/ion/src/lib/chip/chip.component.ts +++ b/projects/ion/src/lib/chip/chip.component.ts @@ -41,8 +41,8 @@ interface ChipEvent { IonIconComponent, IonBadgeComponent, IonInfoBadgeComponent, - IonDropdownComponent -], + IonDropdownComponent, + ], templateUrl: './chip.component.html', styleUrl: './chip.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/projects/ion/src/lib/core/bn-about/bn-about.component.html b/projects/ion/src/lib/core/bn-about/bn-about.component.html index f4340adf5..786064bbb 100644 --- a/projects/ion/src/lib/core/bn-about/bn-about.component.html +++ b/projects/ion/src/lib/core/bn-about/bn-about.component.html @@ -1,24 +1,25 @@
-
-
- @if (pageTitle().icon) { - - } - - {{ pageTitle().title }} -
- - @if (headerButton()) { - +
+
+ @if (pageTitle().icon) { + } + + {{ pageTitle().title }}
- + @if (headerButton()) { + + } +
-
- -
-
\ No newline at end of file + + +
+ +
+
diff --git a/projects/ion/src/lib/core/bn-about/bn-about.component.scss b/projects/ion/src/lib/core/bn-about/bn-about.component.scss index 3f04b5c1a..3d2b49eeb 100644 --- a/projects/ion/src/lib/core/bn-about/bn-about.component.scss +++ b/projects/ion/src/lib/core/bn-about/bn-about.component.scss @@ -1,4 +1,4 @@ -@import "../../../styles/index.scss"; +@import '../../../styles/index.scss'; .bn-about-container { border-radius: 8px; @@ -15,9 +15,9 @@ } .bn-about-header__title { - display: flex; - align-items: center; - gap: 8px; + display: flex; + align-items: center; + gap: 8px; } .divider { diff --git a/projects/ion/src/lib/core/bn-about/bn-about.component.spec.ts b/projects/ion/src/lib/core/bn-about/bn-about.component.spec.ts index b030e6e7f..b0cac1574 100644 --- a/projects/ion/src/lib/core/bn-about/bn-about.component.spec.ts +++ b/projects/ion/src/lib/core/bn-about/bn-about.component.spec.ts @@ -45,7 +45,7 @@ describe('BnAboutComponent', () => { it('should render the correct title', () => { const titleElement = fixture.debugElement.query( - By.css('.title') + By.css('.title'), ).nativeElement; expect(titleElement.textContent).toBe('Detalhes'); }); diff --git a/projects/ion/src/lib/core/bn-about/bn-about.component.ts b/projects/ion/src/lib/core/bn-about/bn-about.component.ts index b9b7bce65..a2ddbdfce 100644 --- a/projects/ion/src/lib/core/bn-about/bn-about.component.ts +++ b/projects/ion/src/lib/core/bn-about/bn-about.component.ts @@ -4,15 +4,20 @@ import { IonIconComponent } from '../../icon/icon.component'; import { BnFormField } from '../bn-form/bn-form.types'; import { BnFormService } from '../bn-form/bn-form.service'; import { BnFormComponent } from '../bn-form/bn-form.component'; -import { IonDividerComponent } from "../../divider/divider.component"; +import { IonDividerComponent } from '../../divider/divider.component'; import { BnAboutHeaderButton, BnAboutPageTitle } from './bn-about.types'; @Component({ standalone: true, selector: 'bn-about', - imports: [IonButtonComponent, BnFormComponent, IonIconComponent, IonDividerComponent], + imports: [ + IonButtonComponent, + BnFormComponent, + IonIconComponent, + IonDividerComponent, + ], templateUrl: './bn-about.component.html', - styleUrl: './bn-about.component.scss' + styleUrl: './bn-about.component.scss', }) export class BnAboutComponent implements OnInit { private formService = inject(BnFormService); @@ -27,7 +32,7 @@ export class BnAboutComponent implements OnInit { this.fields().forEach((field) => { field.disabled = true; }); - } + }; ngOnInit() { this.disableAllFields(); diff --git a/projects/ion/src/lib/core/bn-edit-drawer/bn-edit-drawer.component.ts b/projects/ion/src/lib/core/bn-edit-drawer/bn-edit-drawer.component.ts index 3dd3c1d2b..de29aae44 100644 --- a/projects/ion/src/lib/core/bn-edit-drawer/bn-edit-drawer.component.ts +++ b/projects/ion/src/lib/core/bn-edit-drawer/bn-edit-drawer.component.ts @@ -9,7 +9,10 @@ import { } from '@angular/core'; import { FormGroup, ReactiveFormsModule } from '@angular/forms'; -import { IonDrawerComponent, IonDrawerDirection } from '../../drawer/drawer.component'; +import { + IonDrawerComponent, + IonDrawerDirection, +} from '../../drawer/drawer.component'; import { BnFormComponent } from '../bn-form/bn-form.component'; import { BnFormService } from '../bn-form/bn-form.service'; import { BnFormField } from '../bn-form/bn-form.types'; @@ -19,11 +22,7 @@ import { IconType } from '../types/icon'; @Component({ selector: 'bn-edit-drawer', standalone: true, - imports: [ - ReactiveFormsModule, - IonDrawerComponent, - BnFormComponent -], + imports: [ReactiveFormsModule, IonDrawerComponent, BnFormComponent], templateUrl: './bn-edit-drawer.component.html', styleUrl: './bn-edit-drawer.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, @@ -36,7 +35,7 @@ export class BnEditDrawerComponent { iconTitle = input(); size = input(30); direction = input('right'); - + fields = input.required(); data = input(); loading = input(false); diff --git a/projects/ion/src/lib/core/bn-filter/bn-filter.component.scss b/projects/ion/src/lib/core/bn-filter/bn-filter.component.scss index c0cec6ea5..a8604f7ec 100644 --- a/projects/ion/src/lib/core/bn-filter/bn-filter.component.scss +++ b/projects/ion/src/lib/core/bn-filter/bn-filter.component.scss @@ -1,4 +1,4 @@ -@import "../../../styles/index.scss"; +@import '../../../styles/index.scss'; .bn-filter-container { border-radius: 8px; @@ -15,7 +15,7 @@ } .divider { - border-bottom: 1px solid var(--main-neutral-4, #CED2DB); + border-bottom: 1px solid var(--main-neutral-4, #ced2db); } .filter-content { @@ -29,14 +29,14 @@ padding: 16px 24px; .required-text { - color: var(--main-neutral-5, #AEB2BD); + color: var(--main-neutral-5, #aeb2bd); font-size: 14px; font-style: italic; font-weight: 300; line-height: 20px; } - .selection-chips{ + .selection-chips { display: flex; gap: 8px; } diff --git a/projects/ion/src/lib/core/bn-filter/bn-filter.component.spec.ts b/projects/ion/src/lib/core/bn-filter/bn-filter.component.spec.ts index 5f48796dc..a2e07dd63 100644 --- a/projects/ion/src/lib/core/bn-filter/bn-filter.component.spec.ts +++ b/projects/ion/src/lib/core/bn-filter/bn-filter.component.spec.ts @@ -17,12 +17,12 @@ describe('BnFilterComponent', () => { { key: 'status', label: 'Status', - } + }, ]; beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [BnFilterComponent] + imports: [BnFilterComponent], }).compileComponents(); fixture = TestBed.createComponent(BnFilterComponent); @@ -40,16 +40,18 @@ describe('BnFilterComponent', () => { }); it('should toggle expansion when header button is clicked', () => { - const button = fixture.debugElement.query(By.css('.bn-filter-header ion-button')); - + const button = fixture.debugElement.query( + By.css('.bn-filter-header ion-button'), + ); + // Initially closed expect(component.open()).toBeFalsy(); - + // Click to open button.triggerEventHandler('click', null); fixture.detectChanges(); expect(component.open()).toBeTruthy(); - + // Check if content is rendered const content = fixture.debugElement.query(By.css('.filter-content')); expect(content).toBeTruthy(); @@ -78,7 +80,7 @@ describe('BnFilterComponent', () => { fixture.detectChanges(); const applyButton = screen.getByTestId('apply-button'); - + // Form is invalid because 'name' is required and empty expect(component.formGroup().invalid).toBeTruthy(); expect(applyButton).toBeDisabled(); @@ -100,16 +102,16 @@ describe('BnFilterComponent', () => { expect(appliedSpy).toHaveBeenCalledWith({ name: 'Luke', - status: 'active' + status: 'active', }); }); it('should emit cleared event and reset form when clear is called', () => { const clearedSpy = jest.spyOn(component.cleared, 'emit'); const appliedSpy = jest.spyOn(component.applied, 'emit'); - + component.formGroup().get('name')?.setValue('Luke'); - + component.clear(); expect(component.formGroup().get('name')?.value).toBeNull(); diff --git a/projects/ion/src/lib/core/bn-form/bn-form.component.spec.ts b/projects/ion/src/lib/core/bn-form/bn-form.component.spec.ts index 06ba418d2..f8b6652d9 100644 --- a/projects/ion/src/lib/core/bn-form/bn-form.component.spec.ts +++ b/projects/ion/src/lib/core/bn-form/bn-form.component.spec.ts @@ -299,7 +299,9 @@ describe('BnFormComponent', () => { describe('Dependent Selects', () => { it('should trigger refresh when a dependency changes', () => { - const refreshSpy = jest.fn().mockReturnValue(of([{ value: 'b1', label: 'B1' }])); + const refreshSpy = jest + .fn() + .mockReturnValue(of([{ value: 'b1', label: 'B1' }])); const fields: BnFormField[] = [ { key: 'fieldA', @@ -335,7 +337,7 @@ describe('BnFormComponent', () => { expect(refreshSpy).toHaveBeenCalledWith( expect.objectContaining({ key: 'fieldB' }), undefined, - { fieldA: 'new value' } + { fieldA: 'new value' }, ); }); }); diff --git a/projects/ion/src/lib/core/bn-form/bn-form.component.ts b/projects/ion/src/lib/core/bn-form/bn-form.component.ts index cabf6906d..96429a513 100644 --- a/projects/ion/src/lib/core/bn-form/bn-form.component.ts +++ b/projects/ion/src/lib/core/bn-form/bn-form.component.ts @@ -1,4 +1,4 @@ - import { +import { ChangeDetectionStrategy, Component, input, @@ -18,9 +18,7 @@ import { IonDatepickerComponent, } from '../../picker/date-picker/date-picker.component'; import { IonSelectComponent } from '../../select/select.component'; -import { - IonInputAreaComponent, -} from '../../input-area/input-area.component'; +import { IonInputAreaComponent } from '../../input-area/input-area.component'; import { IonUploadComponent } from '../../upload/upload.component'; import { BnFormField, @@ -50,8 +48,8 @@ import { BnMaskDirective } from '../../mask/mask.directive'; IonUploadComponent, IonIconComponent, IonTooltipDirective, - BnMaskDirective -], + BnMaskDirective, + ], template: `
@for (field of fields(); track field.key) { @@ -168,7 +166,11 @@ import { BnMaskDirective } from '../../mask/mask.directive'; [urlPlaceholder]="field.urlPlaceholder ?? 'Placeholder'" [disabled]="isDisabled(field)" (fileChange)="onValueChange(field.key, $event)" - (urlImport)="field.onImportUrl ? field.onImportUrl($event) : onValueChange(field.key, $event)" + (urlImport)=" + field.onImportUrl + ? field.onImportUrl($event) + : onValueChange(field.key, $event) + " > } @@ -362,7 +364,7 @@ export class BnFormComponent implements OnInit { finalize(() => { field.loading = false; this.cdr.markForCheck(); - }) + }), ) .subscribe((res) => { field.options = res; @@ -387,7 +389,7 @@ export class BnFormComponent implements OnInit { } onValueChange(key: string, value: any): void { - console.log(key, value) + console.log(key, value); const control = this.formGroup().get(key); if (control && control.value !== value) { control.setValue(value); diff --git a/projects/ion/src/lib/core/bn-form/bn-form.service.ts b/projects/ion/src/lib/core/bn-form/bn-form.service.ts index cc60ffc1f..14b84ba72 100644 --- a/projects/ion/src/lib/core/bn-form/bn-form.service.ts +++ b/projects/ion/src/lib/core/bn-form/bn-form.service.ts @@ -37,9 +37,9 @@ export class BnFormService { } const defaultValues: Record = { - 'switch': false, + switch: false, 'triple-toggle': undefined, - 'select': [], + select: [], }; if (!field.type) { diff --git a/projects/ion/src/lib/core/types/chip-group.ts b/projects/ion/src/lib/core/types/chip-group.ts index 4d5fdf0d4..4370e5870 100644 --- a/projects/ion/src/lib/core/types/chip-group.ts +++ b/projects/ion/src/lib/core/types/chip-group.ts @@ -1,4 +1,4 @@ -import { ChipSize, UserBadge, } from './chip'; +import { ChipSize, UserBadge } from './chip'; import { IconDirection, IconType } from './icon'; import { InfoBadgeStatus } from './info-badge'; import { DropdownItem } from './dropdown'; diff --git a/projects/ion/src/lib/drawer/drawer.component.html b/projects/ion/src/lib/drawer/drawer.component.html index ffcd759ed..09ba8df5a 100644 --- a/projects/ion/src/lib/drawer/drawer.component.html +++ b/projects/ion/src/lib/drawer/drawer.component.html @@ -1,5 +1,10 @@ @if (isOpen()) { -
+
}
@@ -7,10 +12,7 @@ @if (title()) {
@if (iconTitle()) { - + } {{ title() }}
@@ -24,7 +26,7 @@ [circularButton]="true" data-testid="close-icon" (ionOnClick)="close()" - /> + />
@@ -40,20 +42,23 @@ type="secondary" [iconType]="secondaryButton()?.iconType || ''" [rightSideIcon]="secondaryButton()?.rightSideIcon || false" - (ionOnClick)="secondary()" /> + (ionOnClick)="secondary()" + /> }
diff --git a/projects/ion/src/lib/drawer/drawer.component.scss b/projects/ion/src/lib/drawer/drawer.component.scss index 19130cd6c..5cb2803f1 100644 --- a/projects/ion/src/lib/drawer/drawer.component.scss +++ b/projects/ion/src/lib/drawer/drawer.component.scss @@ -1,4 +1,4 @@ -@import "../../styles/index.scss"; +@import '../../styles/index.scss'; :host { display: contents; diff --git a/projects/ion/src/lib/drawer/drawer.component.spec.ts b/projects/ion/src/lib/drawer/drawer.component.spec.ts index 048985df6..eeab6d655 100644 --- a/projects/ion/src/lib/drawer/drawer.component.spec.ts +++ b/projects/ion/src/lib/drawer/drawer.component.spec.ts @@ -39,7 +39,9 @@ describe('IonDrawerComponent', () => { it('should show the backdrop when isOpen is true', () => { fixture.componentRef.setInput('isOpen', true); fixture.detectChanges(); - expect(fixture.nativeElement.querySelector('.ion-drawer-backdrop')).toBeTruthy(); + expect( + fixture.nativeElement.querySelector('.ion-drawer-backdrop'), + ).toBeTruthy(); }); }); @@ -54,7 +56,9 @@ describe('IonDrawerComponent', () => { it(`should render the drawer with direction ${direction}`, () => { fixture.componentRef.setInput('direction', direction); fixture.detectChanges(); - const drawer = fixture.nativeElement.querySelector('.ion-drawer-content'); + const drawer = fixture.nativeElement.querySelector( + '.ion-drawer-content', + ); expect(drawer.classList.contains(`ion-drawer-${direction}`)).toBe(true); }); }); @@ -81,7 +85,7 @@ describe('IonDrawerComponent', () => { fixture.componentRef.setInput('size', 50); fixture.detectChanges(); expect( - fixture.nativeElement.style.getPropertyValue('--ion-drawer-size') + fixture.nativeElement.style.getPropertyValue('--ion-drawer-size'), ).toBe('50%'); }); @@ -89,7 +93,7 @@ describe('IonDrawerComponent', () => { fixture.componentRef.setInput('size', 90); fixture.detectChanges(); expect( - fixture.nativeElement.style.getPropertyValue('--ion-drawer-size') + fixture.nativeElement.style.getPropertyValue('--ion-drawer-size'), ).toBe('75%'); }); }); @@ -106,7 +110,7 @@ describe('IonDrawerComponent', () => { const buttons = fixture.nativeElement.querySelectorAll('ion-button'); const buttonLabels = Array.from(buttons).map((btn: any) => - btn.textContent.trim() + btn.textContent.trim(), ); expect(buttonLabels).toContain('Submit'); @@ -121,7 +125,7 @@ describe('IonDrawerComponent', () => { fixture.detectChanges(); const submitBtn = fixture.debugElement.query( - By.css('.ion-drawer-footer-actions ion-button:last-child') + By.css('.ion-drawer-footer-actions ion-button:last-child'), ); submitBtn.triggerEventHandler('ionOnClick', null); @@ -136,7 +140,7 @@ describe('IonDrawerComponent', () => { fixture.detectChanges(); const cancelBtn = fixture.debugElement.query( - By.css('.ion-drawer-footer-actions ion-button:first-child') + By.css('.ion-drawer-footer-actions ion-button:first-child'), ); cancelBtn.triggerEventHandler('ionOnClick', null); @@ -149,7 +153,7 @@ describe('IonDrawerComponent', () => { fixture.detectChanges(); const closeIconBtn = fixture.debugElement.query( - By.css('header ion-button') + By.css('header ion-button'), ); closeIconBtn.triggerEventHandler('ionOnClick', null); @@ -165,7 +169,7 @@ describe('IonDrawerComponent', () => { fixture.detectChanges(); const secondaryBtn = fixture.debugElement.query( - By.css('.ion-drawer-footer > ion-button') + By.css('.ion-drawer-footer > ion-button'), ); secondaryBtn.triggerEventHandler('ionOnClick', null); @@ -182,7 +186,7 @@ describe('IonDrawerComponent', () => { fixture.detectChanges(); const backdrop = fixture.nativeElement.querySelector( - '.ion-drawer-backdrop' + '.ion-drawer-backdrop', ); backdrop.click(); @@ -197,7 +201,7 @@ describe('IonDrawerComponent', () => { fixture.detectChanges(); const backdrop = fixture.nativeElement.querySelector( - '.ion-drawer-backdrop' + '.ion-drawer-backdrop', ); backdrop.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' })); diff --git a/projects/ion/src/lib/dropdown/dropdown.component.html b/projects/ion/src/lib/dropdown/dropdown.component.html index 0b67e461d..0652c70b1 100644 --- a/projects/ion/src/lib/dropdown/dropdown.component.html +++ b/projects/ion/src/lib/dropdown/dropdown.component.html @@ -6,88 +6,95 @@ [class.container-options--loading]="loading()" > @if (description()) { - - {{ description() }} - - } @if (enableSearch()) { - - } @if (loading()) { - - } @if ((!options() || options().length === 0) && !loading()) { -
- -
- } @if (clearButtonIsVisible()) { - + } + @if (loading()) { + + } + @if ((!options() || options().length === 0) && !loading()) { +
+ +
+ } + @if (clearButtonIsVisible()) { + } @if (!origin()) { - + } diff --git a/projects/ion/src/lib/dropdown/dropdown.component.ts b/projects/ion/src/lib/dropdown/dropdown.component.ts index e5a8a149f..059e0e254 100644 --- a/projects/ion/src/lib/dropdown/dropdown.component.ts +++ b/projects/ion/src/lib/dropdown/dropdown.component.ts @@ -104,7 +104,7 @@ export class IonDropdownComponent implements AfterViewInit, OnDestroy { this.multiple() && showClearButton && !this.required() && - !this.loading() + !this.loading(), ); }); @@ -117,7 +117,7 @@ export class IonDropdownComponent implements AfterViewInit, OnDestroy { (this.required() && this.dropdownSelectedItems().length > 1)); this.canDeselect.set( - isSingleSelectionAllowed || isMultipleSelectionAllowed + isSingleSelectionAllowed || isMultipleSelectionAllowed, ); }); diff --git a/projects/ion/src/lib/icon/icon.component.spec.ts b/projects/ion/src/lib/icon/icon.component.spec.ts index 7da806155..153b84784 100644 --- a/projects/ion/src/lib/icon/icon.component.spec.ts +++ b/projects/ion/src/lib/icon/icon.component.spec.ts @@ -126,7 +126,9 @@ describe('IonIconComponent', () => { '[data-testid="inner-container"]', ); - expect(container.style.backgroundColor).toContain('rgba(255, 0, 22, 0.25'); + expect(container.style.backgroundColor).toContain( + 'rgba(255, 0, 22, 0.25', + ); expect(container.style.width).toBe(`${iconSizes.sm * 1.75}px`); expect(container.style.height).toBe(`${iconSizes.sm * 1.75}px`); }); @@ -142,7 +144,9 @@ describe('IonIconComponent', () => { '[data-testid="inner-container"]', ); - expect(container.style.backgroundColor).toContain('rgba(255, 0, 22, 0.25'); + expect(container.style.backgroundColor).toContain( + 'rgba(255, 0, 22, 0.25', + ); expect(container.style.width).toBe(`${iconSizes.md * 1.5}px`); expect(container.style.height).toBe(`${iconSizes.md * 1.5}px`); }); diff --git a/projects/ion/src/lib/info-badge/info-badge.component.ts b/projects/ion/src/lib/info-badge/info-badge.component.ts index 23bf85f16..b64a89483 100644 --- a/projects/ion/src/lib/info-badge/info-badge.component.ts +++ b/projects/ion/src/lib/info-badge/info-badge.component.ts @@ -1,4 +1,3 @@ - import { Component, input } from '@angular/core'; import { InfoBadgeSize, InfoBadgeStatus } from '../core/types/info-badge'; import { IconType } from '../core/types/icon'; diff --git a/projects/ion/src/lib/input-area/input-area.component.ts b/projects/ion/src/lib/input-area/input-area.component.ts index d525e89b3..7811869af 100644 --- a/projects/ion/src/lib/input-area/input-area.component.ts +++ b/projects/ion/src/lib/input-area/input-area.component.ts @@ -1,4 +1,3 @@ - import { Component, input, output } from '@angular/core'; import { FormsModule } from '@angular/forms'; diff --git a/projects/ion/src/lib/link/ion-link.component.ts b/projects/ion/src/lib/link/ion-link.component.ts index 4c3a3564e..46d19aa4e 100644 --- a/projects/ion/src/lib/link/ion-link.component.ts +++ b/projects/ion/src/lib/link/ion-link.component.ts @@ -1,4 +1,3 @@ - import { Component, computed, input, output } from '@angular/core'; import { IonIconComponent } from '../icon/icon.component'; import { FontSize, IconSide, IconType, LinkTarget } from '../core/types'; diff --git a/projects/ion/src/lib/modal/modal.component.html b/projects/ion/src/lib/modal/modal.component.html index 6e56bbc21..2769057af 100644 --- a/projects/ion/src/lib/modal/modal.component.html +++ b/projects/ion/src/lib/modal/modal.component.html @@ -24,9 +24,7 @@ } } @if (configuration().titleIcon) { - + }

{{ configuration().title }}

@if (!configuration().hideCloseButton) { diff --git a/projects/ion/src/lib/modal/modal.component.ts b/projects/ion/src/lib/modal/modal.component.ts index 4ef034776..3cc0e67f6 100644 --- a/projects/ion/src/lib/modal/modal.component.ts +++ b/projects/ion/src/lib/modal/modal.component.ts @@ -14,7 +14,6 @@ import { effect, } from '@angular/core'; - import { generateIDs } from '../utils'; import { IonModalConfiguration, IonModalResponse } from '../core/types/modal'; import { IonButtonComponent } from '../button/button.component'; diff --git a/projects/ion/src/lib/navbar/navbar.component.html b/projects/ion/src/lib/navbar/navbar.component.html index 4ada2a4f5..7b4daa920 100644 --- a/projects/ion/src/lib/navbar/navbar.component.html +++ b/projects/ion/src/lib/navbar/navbar.component.html @@ -1,43 +1,47 @@