@seniorsistemas/angular-components 19.3.3 → 19.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/accordion/README.md +166 -0
  2. package/alert/README.md +92 -0
  3. package/autocomplete/README.md +162 -0
  4. package/badge/README.md +126 -0
  5. package/bignumber-input/README.md +122 -0
  6. package/breadcrumb/README.md +144 -0
  7. package/button/README.md +159 -0
  8. package/calendar-mask/README.md +89 -0
  9. package/card/README.md +133 -0
  10. package/chat/README.md +130 -0
  11. package/checkbox/README.md +108 -0
  12. package/checkbox-list/README.md +149 -0
  13. package/chips/README.md +152 -0
  14. package/code-editor/README.md +149 -0
  15. package/collapse-link/README.md +128 -0
  16. package/confirm-dialog/README.md +105 -0
  17. package/content-generator/README.md +111 -0
  18. package/control-errors/README.md +92 -0
  19. package/country-phone-picker/README.md +121 -0
  20. package/currency/README.md +90 -0
  21. package/custom-fields/README.md +142 -0
  22. package/dialog/README.md +152 -0
  23. package/dynamic-form/README.md +176 -0
  24. package/editable-overlay/README.md +98 -0
  25. package/empty-state/README.md +134 -0
  26. package/esm2022/loading-state/lib/loading-state/loading-state.component.mjs +4 -4
  27. package/fesm2022/seniorsistemas-angular-components-loading-state.mjs +3 -3
  28. package/fesm2022/seniorsistemas-angular-components-loading-state.mjs.map +1 -1
  29. package/fieldset/README.md +135 -0
  30. package/file-picker/README.md +162 -0
  31. package/file-upload/README.md +23 -7
  32. package/gantt/README.md +173 -0
  33. package/global-search/README.md +151 -0
  34. package/grid-menu/README.md +123 -0
  35. package/help-popover/README.md +134 -0
  36. package/ia-insight/README.md +24 -6
  37. package/image-cropper/README.md +140 -0
  38. package/infinite-scroll/README.md +130 -0
  39. package/info-sign/README.md +111 -0
  40. package/inline-edit/README.md +139 -0
  41. package/insights/README.md +159 -0
  42. package/interactive-content/README.md +120 -0
  43. package/kanban/README.md +184 -0
  44. package/label-value/README.md +154 -0
  45. package/loading-state/README.md +141 -0
  46. package/localized-number-input/README.md +128 -0
  47. package/mouse-events/README.md +157 -0
  48. package/navigation-button/README.md +160 -0
  49. package/numeric/README.md +147 -0
  50. package/numeric-mask/README.md +170 -0
  51. package/object-card/README.md +158 -0
  52. package/package.json +1 -1
  53. package/paginator/README.md +121 -0
  54. package/panel/README.md +147 -0
  55. package/password-strength/README.md +144 -0
  56. package/picklist/README.md +170 -0
  57. package/pin-code-field/README.md +137 -0
  58. package/product-header/README.md +33 -6
  59. package/profile-picture-picker/README.md +159 -0
  60. package/progressbar/README.md +136 -0
  61. package/radio-button/README.md +117 -0
  62. package/rating-scale/README.md +154 -0
  63. package/select/README.md +147 -0
  64. package/select-button/README.md +137 -0
  65. package/sidebar/README.md +117 -0
  66. package/slide-in-bar/README.md +122 -0
  67. package/slider/README.md +127 -0
  68. package/speech-recognition/README.md +104 -0
  69. package/split-button/README.md +126 -0
  70. package/spotlight/README.md +200 -0
  71. package/star-rating/README.md +127 -0
  72. package/stats-card/README.md +135 -0
  73. package/stepper/README.md +164 -0
  74. package/switch/README.md +125 -0
  75. package/table/README.md +185 -0
  76. package/text-area-ia/README.md +17 -6
@@ -1,7 +1,7 @@
1
1
  import * as i1$1 from '@angular/common';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { Component, Input, inject, ViewContainerRef, TemplateRef, ComponentFactoryResolver, ChangeDetectorRef, Directive, NgModule } from '@angular/core';
4
+ import { Component, ViewEncapsulation, Input, inject, ViewContainerRef, TemplateRef, ComponentFactoryResolver, ChangeDetectorRef, Directive, NgModule } from '@angular/core';
5
5
  import * as i1 from '@seniorsistemas/angular-components/common';
6
6
  import { SVGFactoryModule } from '@seniorsistemas/angular-components/common';
7
7
 
@@ -117,11 +117,11 @@ class LoadingStateComponent {
117
117
  }
118
118
  }
119
119
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LoadingStateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
120
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LoadingStateComponent, selector: "s-loading-state", inputs: { indicator: "indicator", id: "id", blockWindow: "blockWindow", loading: "loading" }, ngImport: i0, template: "<div\n [id]=\"id\"\n class=\"s-loading-state\"\n [ngClass]=\"{\n 's-loading-state--loading': loading,\n 's-loading-state--blocking': blocking,\n 's-loading-state--fullscreen': blockWindow\n }\"\n>\n <div\n [id]=\"id + '-loader'\"\n class=\"loader\"\n >\n <div\n [id]=\"id + '-spinner'\"\n class=\"spinner\"\n >\n @switch (indicator) {\n @case ('logo') {\n <s-logo-indicator></s-logo-indicator>\n }\n @case ('dots') {\n <s-dots-indicator></s-dots-indicator>\n }\n }\n </div>\n <div\n [id]=\"id + '-overlay'\"\n class=\"overlay\"\n ></div>\n </div>\n <div\n [id]=\"id + '-contents'\"\n class=\"state-contents\"\n >\n <ng-container *ngTemplateOutlet=\"contents || originalContent\"></ng-container>\n <ng-template #originalContent>\n <ng-content></ng-content>\n </ng-template>\n </div>\n</div>\n", styles: [".s-loading-state{position:relative}.s-loading-state .loader{opacity:0;position:absolute;transition:opacity .2s ease-out,display .2s ease-out;visibility:hidden;inset:1px;display:flex;justify-content:center;align-items:center}.s-loading-state .loader .overlay{background-color:#fff;height:100%;opacity:.8;transition:opacity .2s ease-out,display .2s ease-out;width:100%}.s-loading-state .loader .spinner{display:flex;position:absolute;z-index:2}.s-loading-state.s-loading-state--loading>.loader,.s-loading-state.s-loading-state--blocking>.loader{visibility:visible}.s-loading-state.s-loading-state--loading>.loader,.s-loading-state.s-loading-state--loading>.loader>.overlay,.s-loading-state.s-loading-state--blocking>.loader,.s-loading-state.s-loading-state--blocking>.loader>.overlay{cursor:wait;z-index:1}.s-loading-state.s-loading-state--loading>.state-contents,.s-loading-state.s-loading-state--blocking>.state-contents{z-index:0!important}.s-loading-state.s-loading-state--blocking.s-loading-state--loading>.loader{opacity:1}.s-loading-state.s-loading-state--fullscreen>.loader{left:0;position:fixed;top:0;z-index:1005}::ng-deep .s-loading-state-container.s-loading-state--loading.s-loading-state--blocking s-loading-state .s-loading-state-container>.loader{opacity:0;visibility:hidden}::ng-deep .s-loading-state-container.s-loading-state--loading.s-loading-state--blocking s-loading-state .s-loading-state-container>.state-contents{z-index:0!important}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: DotsIndicatorComponent, selector: "s-dots-indicator" }, { kind: "component", type: LoadingIndicatorComponent, selector: "s-logo-indicator" }] });
120
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: LoadingStateComponent, selector: "s-loading-state", inputs: { indicator: "indicator", id: "id", blockWindow: "blockWindow", loading: "loading" }, ngImport: i0, template: "<div\n [id]=\"id\"\n class=\"s-loading-state\"\n [ngClass]=\"{\n 's-loading-state--loading': loading,\n 's-loading-state--blocking': blocking,\n 's-loading-state--fullscreen': blockWindow\n }\"\n>\n <div\n [id]=\"id + '-loader'\"\n class=\"loader\"\n >\n <div\n [id]=\"id + '-spinner'\"\n class=\"spinner\"\n >\n @switch (indicator) {\n @case ('logo') {\n <s-logo-indicator></s-logo-indicator>\n }\n @case ('dots') {\n <s-dots-indicator></s-dots-indicator>\n }\n }\n </div>\n <div\n [id]=\"id + '-overlay'\"\n class=\"overlay\"\n ></div>\n </div>\n <div\n [id]=\"id + '-contents'\"\n class=\"state-contents\"\n >\n <ng-container *ngTemplateOutlet=\"contents || originalContent\"></ng-container>\n <ng-template #originalContent>\n <ng-content></ng-content>\n </ng-template>\n </div>\n</div>\n", styles: ["s-loading-state .s-loading-state{position:relative}s-loading-state .s-loading-state .loader{opacity:0;position:absolute;transition:opacity .2s ease-out,display .2s ease-out;visibility:hidden;inset:1px;display:flex;justify-content:center;align-items:center}s-loading-state .s-loading-state .loader .overlay{height:100%;opacity:.8;transition:opacity .2s ease-out,display .2s ease-out;width:100%}s-loading-state .s-loading-state .loader .spinner{display:flex;position:absolute;z-index:2}s-loading-state .s-loading-state.s-loading-state--loading>.loader,s-loading-state .s-loading-state.s-loading-state--blocking>.loader{cursor:wait;visibility:visible;z-index:2}s-loading-state .s-loading-state.s-loading-state--loading>.loader>.overlay,s-loading-state .s-loading-state.s-loading-state--blocking>.loader>.overlay{cursor:wait;z-index:1}s-loading-state .s-loading-state.s-loading-state--loading>.state-contents,s-loading-state .s-loading-state.s-loading-state--blocking>.state-contents{position:relative;z-index:0!important;opacity:.5}s-loading-state .s-loading-state.s-loading-state--fullscreen>.loader{left:0;position:fixed;top:0;z-index:1005}s-loading-state .s-loading-state.s-loading-state--blocking.s-loading-state--loading>.loader{opacity:1}s-loading-state .s-loading-state-container.s-loading-state--loading.s-loading-state--blocking s-loading-state .s-loading-state-container>.loader{opacity:0;visibility:hidden}s-loading-state .s-loading-state-container.s-loading-state--loading.s-loading-state--blocking s-loading-state .s-loading-state-container>.state-contents{z-index:0!important}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: DotsIndicatorComponent, selector: "s-dots-indicator" }, { kind: "component", type: LoadingIndicatorComponent, selector: "s-logo-indicator" }], encapsulation: i0.ViewEncapsulation.None });
121
121
  }
122
122
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LoadingStateComponent, decorators: [{
123
123
  type: Component,
124
- args: [{ selector: 's-loading-state', template: "<div\n [id]=\"id\"\n class=\"s-loading-state\"\n [ngClass]=\"{\n 's-loading-state--loading': loading,\n 's-loading-state--blocking': blocking,\n 's-loading-state--fullscreen': blockWindow\n }\"\n>\n <div\n [id]=\"id + '-loader'\"\n class=\"loader\"\n >\n <div\n [id]=\"id + '-spinner'\"\n class=\"spinner\"\n >\n @switch (indicator) {\n @case ('logo') {\n <s-logo-indicator></s-logo-indicator>\n }\n @case ('dots') {\n <s-dots-indicator></s-dots-indicator>\n }\n }\n </div>\n <div\n [id]=\"id + '-overlay'\"\n class=\"overlay\"\n ></div>\n </div>\n <div\n [id]=\"id + '-contents'\"\n class=\"state-contents\"\n >\n <ng-container *ngTemplateOutlet=\"contents || originalContent\"></ng-container>\n <ng-template #originalContent>\n <ng-content></ng-content>\n </ng-template>\n </div>\n</div>\n", styles: [".s-loading-state{position:relative}.s-loading-state .loader{opacity:0;position:absolute;transition:opacity .2s ease-out,display .2s ease-out;visibility:hidden;inset:1px;display:flex;justify-content:center;align-items:center}.s-loading-state .loader .overlay{background-color:#fff;height:100%;opacity:.8;transition:opacity .2s ease-out,display .2s ease-out;width:100%}.s-loading-state .loader .spinner{display:flex;position:absolute;z-index:2}.s-loading-state.s-loading-state--loading>.loader,.s-loading-state.s-loading-state--blocking>.loader{visibility:visible}.s-loading-state.s-loading-state--loading>.loader,.s-loading-state.s-loading-state--loading>.loader>.overlay,.s-loading-state.s-loading-state--blocking>.loader,.s-loading-state.s-loading-state--blocking>.loader>.overlay{cursor:wait;z-index:1}.s-loading-state.s-loading-state--loading>.state-contents,.s-loading-state.s-loading-state--blocking>.state-contents{z-index:0!important}.s-loading-state.s-loading-state--blocking.s-loading-state--loading>.loader{opacity:1}.s-loading-state.s-loading-state--fullscreen>.loader{left:0;position:fixed;top:0;z-index:1005}::ng-deep .s-loading-state-container.s-loading-state--loading.s-loading-state--blocking s-loading-state .s-loading-state-container>.loader{opacity:0;visibility:hidden}::ng-deep .s-loading-state-container.s-loading-state--loading.s-loading-state--blocking s-loading-state .s-loading-state-container>.state-contents{z-index:0!important}\n"] }]
124
+ args: [{ selector: 's-loading-state', encapsulation: ViewEncapsulation.None, template: "<div\n [id]=\"id\"\n class=\"s-loading-state\"\n [ngClass]=\"{\n 's-loading-state--loading': loading,\n 's-loading-state--blocking': blocking,\n 's-loading-state--fullscreen': blockWindow\n }\"\n>\n <div\n [id]=\"id + '-loader'\"\n class=\"loader\"\n >\n <div\n [id]=\"id + '-spinner'\"\n class=\"spinner\"\n >\n @switch (indicator) {\n @case ('logo') {\n <s-logo-indicator></s-logo-indicator>\n }\n @case ('dots') {\n <s-dots-indicator></s-dots-indicator>\n }\n }\n </div>\n <div\n [id]=\"id + '-overlay'\"\n class=\"overlay\"\n ></div>\n </div>\n <div\n [id]=\"id + '-contents'\"\n class=\"state-contents\"\n >\n <ng-container *ngTemplateOutlet=\"contents || originalContent\"></ng-container>\n <ng-template #originalContent>\n <ng-content></ng-content>\n </ng-template>\n </div>\n</div>\n", styles: ["s-loading-state .s-loading-state{position:relative}s-loading-state .s-loading-state .loader{opacity:0;position:absolute;transition:opacity .2s ease-out,display .2s ease-out;visibility:hidden;inset:1px;display:flex;justify-content:center;align-items:center}s-loading-state .s-loading-state .loader .overlay{height:100%;opacity:.8;transition:opacity .2s ease-out,display .2s ease-out;width:100%}s-loading-state .s-loading-state .loader .spinner{display:flex;position:absolute;z-index:2}s-loading-state .s-loading-state.s-loading-state--loading>.loader,s-loading-state .s-loading-state.s-loading-state--blocking>.loader{cursor:wait;visibility:visible;z-index:2}s-loading-state .s-loading-state.s-loading-state--loading>.loader>.overlay,s-loading-state .s-loading-state.s-loading-state--blocking>.loader>.overlay{cursor:wait;z-index:1}s-loading-state .s-loading-state.s-loading-state--loading>.state-contents,s-loading-state .s-loading-state.s-loading-state--blocking>.state-contents{position:relative;z-index:0!important;opacity:.5}s-loading-state .s-loading-state.s-loading-state--fullscreen>.loader{left:0;position:fixed;top:0;z-index:1005}s-loading-state .s-loading-state.s-loading-state--blocking.s-loading-state--loading>.loader{opacity:1}s-loading-state .s-loading-state-container.s-loading-state--loading.s-loading-state--blocking s-loading-state .s-loading-state-container>.loader{opacity:0;visibility:hidden}s-loading-state .s-loading-state-container.s-loading-state--loading.s-loading-state--blocking s-loading-state .s-loading-state-container>.state-contents{z-index:0!important}\n"] }]
125
125
  }], propDecorators: { indicator: [{
126
126
  type: Input
127
127
  }], id: [{
@@ -1 +1 @@
1
- {"version":3,"file":"seniorsistemas-angular-components-loading-state.mjs","sources":["../../projects/angular-components/loading-state/src/lib/loading-state/components/dots-indicator/dots-indicator.components.ts","../../projects/angular-components/loading-state/src/lib/loading-state/components/dots-indicator/dots-indicator.component.html","../../projects/angular-components/loading-state/src/lib/loading-state/components/logo-indicator/logo-indicator.component.ts","../../projects/angular-components/loading-state/src/lib/loading-state/components/logo-indicator/logo-indicator.component.html","../../projects/angular-components/loading-state/src/lib/loading-state/components/loading-state-indicators.ts","../../projects/angular-components/loading-state/src/lib/loading-state/loading-state.component.ts","../../projects/angular-components/loading-state/src/lib/loading-state/loading-state.component.html","../../projects/angular-components/loading-state/src/lib/loading-state/loading-state.directive.ts","../../projects/angular-components/loading-state/src/lib/loading-state/loading-state.module.ts","../../projects/angular-components/loading-state/src/seniorsistemas-angular-components-loading-state.ts"],"sourcesContent":["import { Component } from '@angular/core';\n\n@Component({\n selector: 's-dots-indicator',\n templateUrl: './dots-indicator.component.html',\n styleUrls: ['./dots-indicator.component.scss'],\n})\nexport class DotsIndicatorComponent {}\n","<div class=\"dots-indicator\">\n <div class=\"bounce bounce--1\"></div>\n <div class=\"bounce bounce--2\"></div>\n <div class=\"bounce bounce--3\"></div>\n</div>\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 's-logo-indicator',\n templateUrl: './logo-indicator.component.html',\n styleUrls: ['./logo-indicator.component.scss'],\n})\nexport class LoadingIndicatorComponent {}\n","<div class=\"logo-indicator\">\n <span *sSVGFactory=\"'senior'\"></span>\n</div>\n","export enum LoadingStateIndicators {\n Dots = 'dots',\n Logo = 'logo',\n}\n","import { Component, Input, OnDestroy, TemplateRef } from '@angular/core';\n\nimport { LoadingStateIndicators } from './components/loading-state-indicators';\n\n/**\n * @description Componente de estado de carregamento que exibe um indicador animado enquanto\n * um processo assíncrono está em andamento. Suporta bloqueio da janela inteira\n * e diferentes tipos de indicadores visuais.\n * Também pode ser usado como diretiva estrutural `[sLoadingState]`.\n *\n * @example\n * ```html\n * <s-loading-state [loading]=\"isLoading\" [blockWindow]=\"true\">\n * <p>Conteúdo carregado!</p>\n * </s-loading-state>\n * ```\n *\n * @category Feedback\n */\n@Component({\n selector: 's-loading-state',\n templateUrl: './loading-state.component.html',\n styleUrls: ['./loading-state.component.scss'],\n})\nexport class LoadingStateComponent implements OnDestroy {\n public static nextId = 0;\n\n /**\n * @description Tipo de indicador visual exibido durante o carregamento.\n * - `LoadingStateIndicators.Dots`: indicador de pontos animados (padrão).\n * - `LoadingStateIndicators.Logo`: indicador com logotipo animado.\n *\n * @default LoadingStateIndicators.Dots\n */\n @Input()\n public indicator: LoadingStateIndicators = LoadingStateIndicators.Dots;\n\n /**\n * @description Identificador único do componente. Gerado automaticamente se não informado.\n */\n @Input()\n public id = `s-loading-state-${LoadingStateComponent.nextId++}`;\n\n /**\n * @description Quando `true`, bloqueia a janela inteira durante o carregamento,\n * sobrepondo todo o conteúdo da página com o indicador.\n *\n * @default false\n */\n @Input()\n public blockWindow = false;\n\n /**\n * @description Controla o estado de carregamento do componente. Campo obrigatório.\n * Quando `true`, exibe o indicador de carregamento após um breve delay.\n * Quando `false`, remove o indicador após um breve delay (evita flash).\n */\n @Input({ required: true })\n public set loading(loading: boolean) {\n this._loading = loading;\n loading ? this.block() : this.unblock();\n }\n\n public get loading() {\n return this._loading;\n }\n\n public contents: TemplateRef<any> | null = null;\n public blocking = false;\n\n private _loading = false;\n private BLOCK_TIMEOUT_VALUE = 300;\n private UNBLOCK_TIMEOUT_VALUE = 200;\n private blockTimeoutId: any;\n private unblockTimeoutId: any;\n\n public ngOnDestroy(): void {\n if (this.blockTimeoutId) {\n clearTimeout(this.blockTimeoutId);\n }\n\n if (this.unblockTimeoutId) {\n clearTimeout(this.unblockTimeoutId);\n }\n }\n\n public block(): void {\n if (this.unblockTimeoutId) {\n clearTimeout(this.unblockTimeoutId);\n this.unblockTimeoutId = undefined;\n }\n\n if (!this.blockTimeoutId) {\n this.blockTimeoutId = setTimeout(() => {\n this.blocking = true;\n this.blockTimeoutId = undefined;\n }, this.BLOCK_TIMEOUT_VALUE);\n }\n }\n\n public unblock(): void {\n if (this.blockTimeoutId) {\n clearTimeout(this.blockTimeoutId);\n this.blockTimeoutId = undefined;\n }\n\n if (!this.unblockTimeoutId) {\n this.unblockTimeoutId = setTimeout(() => {\n this.blocking = false;\n this.unblockTimeoutId = undefined;\n }, this.UNBLOCK_TIMEOUT_VALUE);\n }\n }\n}\n\n","<div\n [id]=\"id\"\n class=\"s-loading-state\"\n [ngClass]=\"{\n 's-loading-state--loading': loading,\n 's-loading-state--blocking': blocking,\n 's-loading-state--fullscreen': blockWindow\n }\"\n>\n <div\n [id]=\"id + '-loader'\"\n class=\"loader\"\n >\n <div\n [id]=\"id + '-spinner'\"\n class=\"spinner\"\n >\n @switch (indicator) {\n @case ('logo') {\n <s-logo-indicator></s-logo-indicator>\n }\n @case ('dots') {\n <s-dots-indicator></s-dots-indicator>\n }\n }\n </div>\n <div\n [id]=\"id + '-overlay'\"\n class=\"overlay\"\n ></div>\n </div>\n <div\n [id]=\"id + '-contents'\"\n class=\"state-contents\"\n >\n <ng-container *ngTemplateOutlet=\"contents || originalContent\"></ng-container>\n <ng-template #originalContent>\n <ng-content></ng-content>\n </ng-template>\n </div>\n</div>\n","import { AfterViewInit, ChangeDetectorRef, \n// NOSONAR - 'ComponentFactoryResolver' is deprecated.\nComponentFactoryResolver, ComponentRef, Directive, Input, OnDestroy, TemplateRef, ViewContainerRef, inject } from '@angular/core';\n\nimport { LoadingStateComponent } from './loading-state.component';\nimport { LoadingStateIndicators } from './components/loading-state-indicators';\n\n/**\n * @description Diretiva estrutural que envolve o conteúdo da view com um indicador de carregamento.\n * É uma alternativa inline ao `LoadingStateComponent`, podendo ser aplicada diretamente\n * em containers existentes sem a necessidade de criar um wrapper explícito no template.\n *\n * @example\n * ```html\n * <!-- Forma simples (boolean) -->\n * <div *sLoadingState=\"isLoading\">Conteúdo</div>\n *\n * <!-- Forma com configuração -->\n * <div *sLoadingState=\"{ loading: isLoading, indicator: 'logo' }\">Conteúdo</div>\n * ```\n *\n * @category Feedback\n */\n@Directive({\n selector: '[sLoadingState]',\n})\nexport class LoadingStateDirective implements AfterViewInit, OnDestroy {\n private readonly target = inject(ViewContainerRef);\n private readonly template = inject<TemplateRef<any>>(TemplateRef);\n private readonly componentFactoryResolver = inject(ComponentFactoryResolver);\n private readonly cdr = inject(ChangeDetectorRef);\n\n /**\n * @description Controla o estado de carregamento da diretiva.\n * Aceita:\n * - `boolean`: ativa/desativa o carregamento com o indicador padrão (`dots`).\n * - `{ loading: boolean; indicator?: LoadingStateIndicators }`: permite configurar\n * o tipo de indicador junto com o estado de carregamento.\n */\n @Input()\n public set sLoadingState(value: boolean | { loading: boolean; indicator?: LoadingStateIndicators }) {\n if (typeof value === 'boolean') {\n this._loading = value;\n this.indicator = LoadingStateIndicators.Dots;\n } else if (typeof value === 'object') {\n this._loading = value.loading;\n this.indicator = value.indicator ?? LoadingStateIndicators.Dots;\n }\n\n if (this.loaderComponent) {\n this.loaderComponent.instance.loading = this._loading;\n this.loaderComponent.instance.indicator = this.indicator;\n }\n }\n\n private _loading = false;\n private indicator = LoadingStateIndicators.Dots;\n private loaderComponent: ComponentRef<LoadingStateComponent> | null = null;\n\n public ngAfterViewInit() {\n this.createComponent();\n }\n\n private createComponent() {\n const factory = this.componentFactoryResolver.resolveComponentFactory(LoadingStateComponent);\n this.loaderComponent = this.target.createComponent(factory);\n this.loaderComponent.instance.contents = this.template;\n this.loaderComponent.instance.loading = this._loading;\n this.loaderComponent.instance.indicator = this.indicator;\n this.cdr.detectChanges();\n }\n\n public ngOnDestroy() {\n if (this.loaderComponent) {\n this.loaderComponent.destroy();\n }\n }\n}\n\n","import { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\n\nimport { DotsIndicatorComponent } from './components/dots-indicator/dots-indicator.components';\nimport { LoadingIndicatorComponent } from './components/logo-indicator/logo-indicator.component';\nimport { LoadingStateComponent } from './loading-state.component';\nimport { LoadingStateDirective } from './loading-state.directive';\nimport { SVGFactoryModule } from '@seniorsistemas/angular-components/common';\n\n@NgModule({\n imports: [CommonModule, SVGFactoryModule],\n declarations: [\n LoadingStateComponent,\n LoadingStateDirective,\n DotsIndicatorComponent,\n LoadingIndicatorComponent,\n ],\n exports: [LoadingStateComponent, LoadingStateDirective],\n})\nexport class LoadingStateModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i2.DotsIndicatorComponent","i3.LoadingIndicatorComponent"],"mappings":"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"}
1
+ {"version":3,"file":"seniorsistemas-angular-components-loading-state.mjs","sources":["../../projects/angular-components/loading-state/src/lib/loading-state/components/dots-indicator/dots-indicator.components.ts","../../projects/angular-components/loading-state/src/lib/loading-state/components/dots-indicator/dots-indicator.component.html","../../projects/angular-components/loading-state/src/lib/loading-state/components/logo-indicator/logo-indicator.component.ts","../../projects/angular-components/loading-state/src/lib/loading-state/components/logo-indicator/logo-indicator.component.html","../../projects/angular-components/loading-state/src/lib/loading-state/components/loading-state-indicators.ts","../../projects/angular-components/loading-state/src/lib/loading-state/loading-state.component.ts","../../projects/angular-components/loading-state/src/lib/loading-state/loading-state.component.html","../../projects/angular-components/loading-state/src/lib/loading-state/loading-state.directive.ts","../../projects/angular-components/loading-state/src/lib/loading-state/loading-state.module.ts","../../projects/angular-components/loading-state/src/seniorsistemas-angular-components-loading-state.ts"],"sourcesContent":["import { Component } from '@angular/core';\n\n@Component({\n selector: 's-dots-indicator',\n templateUrl: './dots-indicator.component.html',\n styleUrls: ['./dots-indicator.component.scss'],\n})\nexport class DotsIndicatorComponent {}\n","<div class=\"dots-indicator\">\n <div class=\"bounce bounce--1\"></div>\n <div class=\"bounce bounce--2\"></div>\n <div class=\"bounce bounce--3\"></div>\n</div>\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 's-logo-indicator',\n templateUrl: './logo-indicator.component.html',\n styleUrls: ['./logo-indicator.component.scss'],\n})\nexport class LoadingIndicatorComponent {}\n","<div class=\"logo-indicator\">\n <span *sSVGFactory=\"'senior'\"></span>\n</div>\n","export enum LoadingStateIndicators {\n Dots = 'dots',\n Logo = 'logo',\n}\n","import { Component, Input, OnDestroy, TemplateRef, ViewEncapsulation } from '@angular/core';\n\nimport { LoadingStateIndicators } from './components/loading-state-indicators';\n\n/**\n * @description Componente de estado de carregamento que exibe um indicador animado enquanto\n * um processo assíncrono está em andamento. Suporta bloqueio da janela inteira\n * e diferentes tipos de indicadores visuais.\n * Também pode ser usado como diretiva estrutural `[sLoadingState]`.\n *\n * @example\n * ```html\n * <s-loading-state [loading]=\"isLoading\" [blockWindow]=\"true\">\n * <p>Conteúdo carregado!</p>\n * </s-loading-state>\n * ```\n *\n * @category Feedback\n */\n@Component({\n selector: 's-loading-state',\n templateUrl: './loading-state.component.html',\n styleUrls: ['./loading-state.component.scss'],\n encapsulation: ViewEncapsulation.None,\n})\nexport class LoadingStateComponent implements OnDestroy {\n public static nextId = 0;\n\n /**\n * @description Tipo de indicador visual exibido durante o carregamento.\n * - `LoadingStateIndicators.Dots`: indicador de pontos animados (padrão).\n * - `LoadingStateIndicators.Logo`: indicador com logotipo animado.\n *\n * @default LoadingStateIndicators.Dots\n */\n @Input()\n public indicator: LoadingStateIndicators = LoadingStateIndicators.Dots;\n\n /**\n * @description Identificador único do componente. Gerado automaticamente se não informado.\n */\n @Input()\n public id = `s-loading-state-${LoadingStateComponent.nextId++}`;\n\n /**\n * @description Quando `true`, bloqueia a janela inteira durante o carregamento,\n * sobrepondo todo o conteúdo da página com o indicador.\n *\n * @default false\n */\n @Input()\n public blockWindow = false;\n\n /**\n * @description Controla o estado de carregamento do componente. Campo obrigatório.\n * Quando `true`, exibe o indicador de carregamento após um breve delay.\n * Quando `false`, remove o indicador após um breve delay (evita flash).\n */\n @Input({ required: true })\n public set loading(loading: boolean) {\n this._loading = loading;\n loading ? this.block() : this.unblock();\n }\n\n public get loading() {\n return this._loading;\n }\n\n public contents: TemplateRef<any> | null = null;\n public blocking = false;\n\n private _loading = false;\n private BLOCK_TIMEOUT_VALUE = 300;\n private UNBLOCK_TIMEOUT_VALUE = 200;\n private blockTimeoutId: any;\n private unblockTimeoutId: any;\n\n public ngOnDestroy(): void {\n if (this.blockTimeoutId) {\n clearTimeout(this.blockTimeoutId);\n }\n\n if (this.unblockTimeoutId) {\n clearTimeout(this.unblockTimeoutId);\n }\n }\n\n public block(): void {\n if (this.unblockTimeoutId) {\n clearTimeout(this.unblockTimeoutId);\n this.unblockTimeoutId = undefined;\n }\n\n if (!this.blockTimeoutId) {\n this.blockTimeoutId = setTimeout(() => {\n this.blocking = true;\n this.blockTimeoutId = undefined;\n }, this.BLOCK_TIMEOUT_VALUE);\n }\n }\n\n public unblock(): void {\n if (this.blockTimeoutId) {\n clearTimeout(this.blockTimeoutId);\n this.blockTimeoutId = undefined;\n }\n\n if (!this.unblockTimeoutId) {\n this.unblockTimeoutId = setTimeout(() => {\n this.blocking = false;\n this.unblockTimeoutId = undefined;\n }, this.UNBLOCK_TIMEOUT_VALUE);\n }\n }\n}\n\n","<div\n [id]=\"id\"\n class=\"s-loading-state\"\n [ngClass]=\"{\n 's-loading-state--loading': loading,\n 's-loading-state--blocking': blocking,\n 's-loading-state--fullscreen': blockWindow\n }\"\n>\n <div\n [id]=\"id + '-loader'\"\n class=\"loader\"\n >\n <div\n [id]=\"id + '-spinner'\"\n class=\"spinner\"\n >\n @switch (indicator) {\n @case ('logo') {\n <s-logo-indicator></s-logo-indicator>\n }\n @case ('dots') {\n <s-dots-indicator></s-dots-indicator>\n }\n }\n </div>\n <div\n [id]=\"id + '-overlay'\"\n class=\"overlay\"\n ></div>\n </div>\n <div\n [id]=\"id + '-contents'\"\n class=\"state-contents\"\n >\n <ng-container *ngTemplateOutlet=\"contents || originalContent\"></ng-container>\n <ng-template #originalContent>\n <ng-content></ng-content>\n </ng-template>\n </div>\n</div>\n","import { AfterViewInit, ChangeDetectorRef, \n// NOSONAR - 'ComponentFactoryResolver' is deprecated.\nComponentFactoryResolver, ComponentRef, Directive, Input, OnDestroy, TemplateRef, ViewContainerRef, inject } from '@angular/core';\n\nimport { LoadingStateComponent } from './loading-state.component';\nimport { LoadingStateIndicators } from './components/loading-state-indicators';\n\n/**\n * @description Diretiva estrutural que envolve o conteúdo da view com um indicador de carregamento.\n * É uma alternativa inline ao `LoadingStateComponent`, podendo ser aplicada diretamente\n * em containers existentes sem a necessidade de criar um wrapper explícito no template.\n *\n * @example\n * ```html\n * <!-- Forma simples (boolean) -->\n * <div *sLoadingState=\"isLoading\">Conteúdo</div>\n *\n * <!-- Forma com configuração -->\n * <div *sLoadingState=\"{ loading: isLoading, indicator: 'logo' }\">Conteúdo</div>\n * ```\n *\n * @category Feedback\n */\n@Directive({\n selector: '[sLoadingState]',\n})\nexport class LoadingStateDirective implements AfterViewInit, OnDestroy {\n private readonly target = inject(ViewContainerRef);\n private readonly template = inject<TemplateRef<any>>(TemplateRef);\n private readonly componentFactoryResolver = inject(ComponentFactoryResolver);\n private readonly cdr = inject(ChangeDetectorRef);\n\n /**\n * @description Controla o estado de carregamento da diretiva.\n * Aceita:\n * - `boolean`: ativa/desativa o carregamento com o indicador padrão (`dots`).\n * - `{ loading: boolean; indicator?: LoadingStateIndicators }`: permite configurar\n * o tipo de indicador junto com o estado de carregamento.\n */\n @Input()\n public set sLoadingState(value: boolean | { loading: boolean; indicator?: LoadingStateIndicators }) {\n if (typeof value === 'boolean') {\n this._loading = value;\n this.indicator = LoadingStateIndicators.Dots;\n } else if (typeof value === 'object') {\n this._loading = value.loading;\n this.indicator = value.indicator ?? LoadingStateIndicators.Dots;\n }\n\n if (this.loaderComponent) {\n this.loaderComponent.instance.loading = this._loading;\n this.loaderComponent.instance.indicator = this.indicator;\n }\n }\n\n private _loading = false;\n private indicator = LoadingStateIndicators.Dots;\n private loaderComponent: ComponentRef<LoadingStateComponent> | null = null;\n\n public ngAfterViewInit() {\n this.createComponent();\n }\n\n private createComponent() {\n const factory = this.componentFactoryResolver.resolveComponentFactory(LoadingStateComponent);\n this.loaderComponent = this.target.createComponent(factory);\n this.loaderComponent.instance.contents = this.template;\n this.loaderComponent.instance.loading = this._loading;\n this.loaderComponent.instance.indicator = this.indicator;\n this.cdr.detectChanges();\n }\n\n public ngOnDestroy() {\n if (this.loaderComponent) {\n this.loaderComponent.destroy();\n }\n }\n}\n\n","import { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\n\nimport { DotsIndicatorComponent } from './components/dots-indicator/dots-indicator.components';\nimport { LoadingIndicatorComponent } from './components/logo-indicator/logo-indicator.component';\nimport { LoadingStateComponent } from './loading-state.component';\nimport { LoadingStateDirective } from './loading-state.directive';\nimport { SVGFactoryModule } from '@seniorsistemas/angular-components/common';\n\n@NgModule({\n imports: [CommonModule, SVGFactoryModule],\n declarations: [\n LoadingStateComponent,\n LoadingStateDirective,\n DotsIndicatorComponent,\n LoadingIndicatorComponent,\n ],\n exports: [LoadingStateComponent, LoadingStateDirective],\n})\nexport class LoadingStateModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i2.DotsIndicatorComponent","i3.LoadingIndicatorComponent"],"mappings":"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"}
@@ -0,0 +1,135 @@
1
+ # Fieldset
2
+
3
+ ![Status](https://img.shields.io/badge/status-stable-brightgreen)
4
+
5
+ Componente de agrupamento de campos de formulário com legenda, ícone e suporte a toggle (recolher/expandir) com animação. Aceita template customizado para o cabeçalho via `sTemplate="header"`.
6
+
7
+ ## Quando usar
8
+
9
+ - Agrupar campos relacionados em formulários longos com separação visual por título
10
+ - Seções opcionais que podem ser recolhidas para reduzir a carga visual
11
+ - Formulários com múltiplas seções que precisam de diferenciação visual
12
+
13
+ ## Quando não usar
14
+
15
+ - Agrupamentos sem necessidade de título — use `<div>` simples
16
+ - Múltiplos painéis onde apenas um pode estar aberto por vez — use [`Accordion`](../accordion/README.md)
17
+
18
+ ## Instalação
19
+
20
+ ```typescript
21
+ import { FieldsetModule } from '@seniorsistemas/angular-components/fieldset';
22
+
23
+ @Component({ standalone: true, imports: [FieldsetModule] })
24
+ export class MeuComponent {}
25
+ ```
26
+
27
+ ## Uso básico
28
+
29
+ ```html
30
+ <s-fieldset legend="Dados Pessoais">
31
+ <p>Conteúdo do fieldset</p>
32
+ </s-fieldset>
33
+ ```
34
+
35
+ ## API
36
+
37
+ ### Inputs
38
+
39
+ | Propriedade | Tipo | Padrão | Obrigatório | Descrição |
40
+ |-------------|------|--------|:-----------:|-----------|
41
+ | `legend` | `string` | `''` | — | Texto exibido como título do fieldset |
42
+ | `icon` | `string` | `''` | — | Classe de ícone exibida ao lado da legenda (ex: `'fas fa-cog'`) |
43
+ | `toggleable` | `boolean` | `false` | — | Habilita o botão +/- para recolher e expandir com animação |
44
+ | `destroyOnHide` | `boolean` | `true` | — | Remove o conteúdo do DOM ao recolher. Use `false` para preservar estado de formulários |
45
+
46
+ ### Outputs
47
+
48
+ | Evento | Tipo | Descrição |
49
+ |--------|------|-----------|
50
+ | `beforeToggle` | `EventEmitter<FieldSetToggle>` | Emitido antes da animação de toggle iniciar |
51
+ | `afterToggle` | `EventEmitter<FieldSetToggle>` | Emitido após a animação de toggle concluir |
52
+
53
+ ### Tipos
54
+
55
+ ```typescript
56
+ type FieldSetToggle = {
57
+ originalEvent: PointerEvent | KeyboardEvent;
58
+ collapsed: boolean; // true = estava aberto e vai fechar; false = estava fechado e vai abrir
59
+ };
60
+ ```
61
+
62
+ ## Exemplos
63
+
64
+ ### Fieldset básico
65
+
66
+ ```html
67
+ <s-fieldset legend="Dados Pessoais">
68
+ <div style="display: flex; flex-direction: column; gap: 12px;">
69
+ <input type="text" placeholder="Nome completo" />
70
+ <input type="text" placeholder="CPF" />
71
+ </div>
72
+ </s-fieldset>
73
+ ```
74
+
75
+ ### Fieldset colapsável com ícone
76
+
77
+ ```html
78
+ <s-fieldset
79
+ legend="Informações de Contato"
80
+ icon="fas fa-phone"
81
+ [toggleable]="true"
82
+ (beforeToggle)="onBeforeToggle($event)"
83
+ (afterToggle)="onAfterToggle($event)"
84
+ >
85
+ <input type="tel" placeholder="(00) 00000-0000" />
86
+ <input type="email" placeholder="email@empresa.com" />
87
+ </s-fieldset>
88
+ ```
89
+
90
+ ### Colapsável preservando estado do formulário
91
+
92
+ ```html
93
+ <s-fieldset legend="Dados Opcionais" [toggleable]="true" [destroyOnHide]="false">
94
+ <input formControlName="complemento" placeholder="Complemento" />
95
+ </s-fieldset>
96
+ ```
97
+
98
+ ### Com cabeçalho customizado via template
99
+
100
+ ```html
101
+ <s-fieldset [toggleable]="true">
102
+ <ng-template sTemplate="header">
103
+ <div style="display: flex; align-items: center; gap: 8px;">
104
+ <span style="background: #fee2e2; width: 8px; height: 8px; border-radius: 50%;"></span>
105
+ <span>Dados Bancários</span>
106
+ <span style="font-size: 0.75rem; color: #dc2626;">(campos obrigatórios)</span>
107
+ </div>
108
+ </ng-template>
109
+ <input type="text" placeholder="Banco" />
110
+ </s-fieldset>
111
+ ```
112
+
113
+ ### Múltiplos fieldsets em um formulário
114
+
115
+ ```html
116
+ <div style="display: flex; flex-direction: column; gap: 16px;">
117
+ <s-fieldset legend="Dados Pessoais" icon="fas fa-user" [toggleable]="true">
118
+ <!-- campos -->
119
+ </s-fieldset>
120
+ <s-fieldset legend="Endereço" icon="fas fa-map-marker-alt" [toggleable]="true">
121
+ <!-- campos -->
122
+ </s-fieldset>
123
+ </div>
124
+ ```
125
+
126
+ ## Acessibilidade
127
+
128
+ - O botão de toggle é ativável por teclado (Enter e Space)
129
+ - A animação de recolher/expandir tem duração de 300ms (respeitando `prefers-reduced-motion` via CSS)
130
+ - O ícone decorativo não possui texto alternativo obrigatório
131
+
132
+ ## Componentes relacionados
133
+
134
+ - [`Accordion`](../accordion/README.md) — painéis expansíveis onde apenas um pode estar aberto por vez
135
+ - [`DynamicForm`](../dynamic-form/README.md) — usa fieldset internamente para estruturar formulários dinâmicos
@@ -0,0 +1,162 @@
1
+ # FilePicker
2
+
3
+ ![Status](https://img.shields.io/badge/status-stable-brightgreen)
4
+
5
+ Componente de upload de arquivos com suporte a seleção múltipla, validação de tipo e tamanho, controle granular de permissões (adicionar, ler, remover), exibição de progresso e cancelamento de uploads em andamento.
6
+
7
+ ## Quando usar
8
+
9
+ - Upload de anexos em formulários (documentos, imagens, relatórios)
10
+ - Envio de arquivos em processos ou entidades
11
+ - Exibição de arquivos já salvos com possibilidade de download e remoção
12
+
13
+ ## Quando não usar
14
+
15
+ - Upload de foto de perfil com recorte — use [`ProfilePicturePicker`](../profile-picture-picker/README.md)
16
+ - O seletor `s-file-upload` e o pacote `file-upload` estão descontinuados (remoção na v20.0.0) — use `s-file-picker`
17
+
18
+ ## Instalação
19
+
20
+ ```typescript
21
+ import { FilePickerModule } from '@seniorsistemas/angular-components/file-picker';
22
+
23
+ @Component({ standalone: true, imports: [FilePickerModule] })
24
+ export class MeuComponent {}
25
+ ```
26
+
27
+ ## Uso básico
28
+
29
+ ```html
30
+ <s-file-picker
31
+ [files]="arquivos"
32
+ [multiple]="true"
33
+ (uploadHandler)="onUpload($event)"
34
+ (removeFile)="onRemove($event)"
35
+ />
36
+ ```
37
+
38
+ ## API
39
+
40
+ ### Inputs
41
+
42
+ | Propriedade | Tipo | Padrão | Obrigatório | Descrição |
43
+ |-------------|------|--------|:-----------:|-----------|
44
+ | `files` | `FileDto[]` | — | — | Lista de arquivos já enviados a serem exibidos |
45
+ | `multiple` | `boolean` | — | — | Permite selecionar múltiplos arquivos |
46
+ | `accept` | `string` | — | — | Tipos MIME aceitos pelo seletor nativo (ex: `'application/pdf,image/*'`) |
47
+ | `supportedExtensions` | `string[]` | `[]` | — | Extensões aceitas para validação (ex: `['.pdf', '.docx']`) |
48
+ | `maxFileSize` | `number` | — | — | Tamanho máximo por arquivo em bytes |
49
+ | `maxCombinedFileSize` | `number` | — | — | Tamanho máximo combinado de todos os arquivos em bytes |
50
+ | `fileLimit` | `number` | — | — | Número máximo de arquivos que podem ser selecionados |
51
+ | `permissions` | `FilePickerPermissions[]` | `['add', 'read', 'remove']` | — | Permissões habilitadas no componente |
52
+ | `disabled` | `boolean` | `false` | — | Desabilita todas as interações do componente |
53
+ | `showFileUploadDate` | `boolean` | `false` | — | Exibe a data de upload de cada arquivo |
54
+ | `chooseLabel` | `string` | — | — | Rótulo customizado do botão de seleção |
55
+ | `removeLabel` | `string` | — | — | Rótulo customizado do link de remoção |
56
+ | `cancelLabel` | `string` | — | — | Rótulo customizado do botão de cancelamento |
57
+ | `successTooltip` | `string` | — | — | Texto do tooltip após upload bem-sucedido |
58
+ | `ariaLabelFileName` | `string` | — | — | Label ARIA para o nome do arquivo |
59
+ | `ariaLabelProgress` | `string` | — | — | Label ARIA para a barra de progresso |
60
+ | `ariaLabelSuccess` | `string` | — | — | Label ARIA para o ícone de sucesso |
61
+ | `ariaLabelError` | `string` | — | — | Label ARIA para mensagens de erro |
62
+ | `ariaLabelRemove` | `string` | — | — | Label ARIA para o botão de remoção |
63
+ | `formControl` | `FormControl` | — | — | FormControl externo para controle de estado |
64
+ | `id` | `string` | `s-file-picker-{n}` | — | Identificador único do componente |
65
+
66
+ ### Outputs
67
+
68
+ | Evento | Tipo | Descrição |
69
+ |--------|------|-----------|
70
+ | `uploadHandler` | `EventEmitter<{ files: FileDto[] }>` | Emitido quando arquivos válidos são selecionados para upload |
71
+ | `removeFile` | `EventEmitter<{ file: File }>` | Emitido quando um arquivo é removido da lista |
72
+ | `cancelUpload` | `EventEmitter<number>` | Emitido ao cancelar um upload em andamento (emite o índice) |
73
+ | `downloadFile` | `EventEmitter<{ index: number; anchor: ElementRef }>` | Emitido ao clicar para baixar um arquivo |
74
+ | `validateErrors` | `EventEmitter<UploadError>` | Emitido quando um arquivo não passa na validação |
75
+
76
+ ### Tipos
77
+
78
+ ```typescript
79
+ type FilePickerPermissions = 'add' | 'read' | 'remove';
80
+ // 'add' = exibe o botão de seleção de arquivo
81
+ // 'read' = exibe o nome do arquivo como link para download
82
+ // 'remove' = exibe o link de remoção
83
+
84
+ interface FileDto extends File {
85
+ objectId?: string; // ID do objeto no servidor
86
+ version?: string; // Versão do arquivo
87
+ objectURL?: string; // URL para preview/download
88
+ isUploading?: boolean; // Se está sendo enviado
89
+ savedFile?: boolean; // Se já foi salvo no servidor
90
+ progress?: number; // Progresso do upload (0-100)
91
+ error?: HttpErrorResponse;// Erro de upload, se houver
92
+ }
93
+
94
+ interface UploadError {
95
+ files: FileDto[];
96
+ validation: 'maxFileLimit' | 'maxFileSize' | 'maxCombinedFileSize' | 'unsupportedExtension';
97
+ }
98
+ ```
99
+
100
+ ## Exemplos
101
+
102
+ ### Upload básico com múltiplos arquivos
103
+
104
+ ```html
105
+ <s-file-picker
106
+ [files]="arquivos"
107
+ [multiple]="true"
108
+ [fileLimit]="5"
109
+ [maxFileSize]="5242880"
110
+ [permissions]="['add', 'read', 'remove']"
111
+ (uploadHandler)="onUpload($event)"
112
+ (removeFile)="onRemove($event)"
113
+ (validateErrors)="onErros($event)"
114
+ ></s-file-picker>
115
+ ```
116
+
117
+ ```typescript
118
+ arquivos: FileDto[] = [];
119
+
120
+ onUpload(event: { files: FileDto[] }) {
121
+ event.files.forEach(f => { f.progress = 100; });
122
+ this.arquivos = [...this.arquivos, ...event.files];
123
+ }
124
+
125
+ onRemove(event: { file: FileDto }) {
126
+ this.arquivos = this.arquivos.filter(f => f !== event.file);
127
+ }
128
+ ```
129
+
130
+ ### Somente leitura
131
+
132
+ ```html
133
+ <s-file-picker
134
+ [files]="arquivos"
135
+ [permissions]="['read']"
136
+ ></s-file-picker>
137
+ ```
138
+
139
+ ### Com filtro de extensões
140
+
141
+ ```html
142
+ <s-file-picker
143
+ [files]="arquivos"
144
+ accept=".pdf,.docx"
145
+ [supportedExtensions]="['.pdf', '.docx']"
146
+ [multiple]="true"
147
+ [fileLimit]="3"
148
+ (uploadHandler)="onUpload($event)"
149
+ (validateErrors)="onErros($event)"
150
+ ></s-file-picker>
151
+ ```
152
+
153
+ ## Acessibilidade
154
+
155
+ - O botão de seleção de arquivo ativa o seletor nativo do sistema operacional
156
+ - A barra de progresso possui `aria-label` configurável via `ariaLabelProgress`
157
+ - O nome do arquivo exibido é associado ao `ariaLabelFileName` para leitores de tela
158
+ - Drag and drop é suportado como alternativa ao clique
159
+
160
+ ## Componentes relacionados
161
+
162
+ - [`ProfilePicturePicker`](../profile-picture-picker/README.md) — upload específico para foto de perfil com recorte
@@ -1,17 +1,33 @@
1
- # File Upload (Descontinuado)
1
+ # FileUpload (Descontinuado)
2
2
 
3
- > ⚠️ **Este pacote está descontinuado e será removido na versão 20.0.0.**
3
+ ![Status](https://img.shields.io/badge/status-deprecated-red)
4
4
 
5
- Este pacote é um alias de compatibilidade para o componente `FilePicker`.
5
+ > **Este pacote está descontinuado e será removido na versão 20.0.0.**
6
+
7
+ Este pacote é um alias de compatibilidade para o componente `FilePicker`. O seletor `s-file-upload` também está descontinuado — use `s-file-picker`.
6
8
 
7
9
  ## Migração
8
10
 
9
- Use `FilePickerModule` e `FilePickerComponent` de `@seniorsistemas/angular-components/file-picker` em novos projetos.
11
+ Substitua as importações de `file-upload` por `file-picker`:
12
+
13
+ ```typescript
14
+ // Antes (descontinuado)
15
+ import { FileUploadModule } from '@seniorsistemas/angular-components/file-upload';
16
+
17
+ // Depois (correto)
18
+ import { FilePickerModule } from '@seniorsistemas/angular-components/file-picker';
19
+ ```
10
20
 
11
- O seletor `s-file-upload` também está descontinuado — use `s-file-picker`.
21
+ ```html
22
+ <!-- Antes (descontinuado) -->
23
+ <s-file-upload [files]="arquivos" (uploadHandler)="onUpload($event)" />
24
+
25
+ <!-- Depois (correto) -->
26
+ <s-file-picker [files]="arquivos" (uploadHandler)="onUpload($event)" />
27
+ ```
12
28
 
13
29
  ## Documentação
14
30
 
15
31
  Consulte a documentação completa do componente em:
16
- - **Storybook**: `Components/Base Components/File Picker`
17
- - **Pacote**: `@seniorsistemas/angular-components/file-picker`
32
+
33
+ - [`FilePicker`](../file-picker/README.md) — documentação do componente substituto
@@ -0,0 +1,173 @@
1
+ # Gantt
2
+
3
+ ![Status](https://img.shields.io/badge/status-stable-brightgreen)
4
+
5
+ Componente de diagrama de Gantt para visualização e gerenciamento de tarefas em linha do tempo. Suporta múltiplos modos de visualização (hora, dia, semana, mês, ano), movimentação de tarefas via drag-and-drop, dependências entre tarefas e popup de detalhes ao clicar.
6
+
7
+ ## Quando usar
8
+
9
+ - Planejamento e acompanhamento de cronogramas de projetos
10
+ - Visualização de tarefas com dependências e datas de início/fim
11
+ - Roadmaps de produto ou planejamento estratégico
12
+
13
+ ## Quando não usar
14
+
15
+ - Listas simples de tarefas sem contexto temporal — use uma tabela ou lista
16
+ - Gerenciamento de tarefas sem dimensão de data — use um Kanban
17
+
18
+ ## Instalação
19
+
20
+ ```typescript
21
+ import { GanttModule } from '@seniorsistemas/angular-components/gantt';
22
+
23
+ @Component({ standalone: true, imports: [GanttModule] })
24
+ export class MeuComponent {}
25
+ ```
26
+
27
+ ## Uso básico
28
+
29
+ ```html
30
+ <s-gantt
31
+ [tasks]="gruposDeTarefas"
32
+ [viewMode]="viewMode"
33
+ (taskClicked)="onTaskClicada($event)"
34
+ />
35
+ ```
36
+
37
+ ## API
38
+
39
+ ### Inputs
40
+
41
+ | Propriedade | Tipo | Padrão | Obrigatório | Descrição |
42
+ |-------------|------|--------|:-----------:|-----------|
43
+ | `tasks` | `TaskGroup[]` | — | Sim | Lista de grupos de tarefas a serem renderizados |
44
+ | `viewMode` | `ViewMode` | `ViewMode.Day` | — | Modo de visualização do gantt |
45
+ | `columnTitle` | `string` | — | — | Título da coluna lateral de identificação das tarefas |
46
+ | `showSideTable` | `boolean` | `true` | — | Exibe a tabela lateral com os nomes das tarefas |
47
+ | `multipleTaskPerLine` | `boolean` | `false` | — | Permite renderizar múltiplas tarefas na mesma linha |
48
+ | `allowMovement` | `boolean` | `true` | — | Habilita o arrastar de tarefas para alterar datas |
49
+ | `hasPopup` | `boolean` | `true` | — | Exibe popup com detalhes ao clicar em uma tarefa |
50
+ | `fullWidth` | `boolean` | `false` | — | Faz o gantt ocupar 100% da largura disponível |
51
+ | `containerWidth` | `number` | — | — | Largura do container em pixels |
52
+ | `marginBeforeStart` | `number` | — | — | Margem em dias antes do início da primeira tarefa |
53
+ | `marginAfterEnd` | `number` | — | — | Margem em dias após o fim da última tarefa |
54
+ | `showOnlyHours` | `boolean` | `false` | — | Exibe apenas horas na linha do tempo |
55
+ | `showOnlyDays` | `boolean` | `false` | — | Exibe apenas dias na linha do tempo |
56
+
57
+ ### Outputs
58
+
59
+ | Evento | Tipo | Descrição |
60
+ |--------|------|-----------|
61
+ | `taskClicked` | `EventEmitter<Task>` | Emitido quando o usuário clica em uma tarefa |
62
+ | `taskDateChanged` | `EventEmitter<{ task: Task; start: Date; end: Date }>` | Emitido quando as datas de uma tarefa são alteradas por drag |
63
+ | `viewChanged` | `EventEmitter<ViewMode>` | Emitido quando o modo de visualização é alterado |
64
+
65
+ ### Tipos
66
+
67
+ ```typescript
68
+ enum ViewMode {
69
+ QuarterHour = 'quarterHour',
70
+ Hour = 'hour',
71
+ QuarterDay = 'quarterDay',
72
+ HalfDay = 'halfDay',
73
+ Day = 'day',
74
+ Week = 'week',
75
+ Month = 'month',
76
+ Year = 'year',
77
+ }
78
+
79
+ interface Task {
80
+ id: string;
81
+ name: string;
82
+ start: Date;
83
+ end: Date; // Deve ser maior que start
84
+ showTaskName?: boolean;
85
+ dependencies?: string[]; // IDs de tarefas das quais esta depende
86
+ color?: string; // Cor customizada (ex: '#3b82f6')
87
+ custom_class?: string; // Classe CSS customizada
88
+ }
89
+
90
+ interface TaskGroup {
91
+ id: string;
92
+ title: string;
93
+ subtitle: string;
94
+ tasks: Task[];
95
+ }
96
+ ```
97
+
98
+ ## Exemplos
99
+
100
+ ### Visualização diária com grupos
101
+
102
+ ```typescript
103
+ const tasks: TaskGroup[] = [
104
+ {
105
+ id: 'grupo1',
106
+ title: 'Desenvolvimento',
107
+ subtitle: 'Sprint 1',
108
+ tasks: [
109
+ {
110
+ id: 'tarefa1',
111
+ name: 'Planejamento',
112
+ start: new Date('2025-06-01'),
113
+ end: new Date('2025-06-03'),
114
+ showTaskName: true,
115
+ },
116
+ {
117
+ id: 'tarefa2',
118
+ name: 'Implementação',
119
+ start: new Date('2025-06-03'),
120
+ end: new Date('2025-06-10'),
121
+ dependencies: ['tarefa1'],
122
+ color: '#3b82f6',
123
+ showTaskName: true,
124
+ },
125
+ ],
126
+ },
127
+ ];
128
+ ```
129
+
130
+ ```html
131
+ <s-gantt
132
+ [tasks]="tasks"
133
+ viewMode="day"
134
+ columnTitle="Equipes"
135
+ [showSideTable]="true"
136
+ [allowMovement]="true"
137
+ [hasPopup]="true"
138
+ (taskClicked)="onTaskClick($event)"
139
+ (taskDateChanged)="onDateChange($event)"
140
+ ></s-gantt>
141
+ ```
142
+
143
+ ### Somente visualização (sem movimentação)
144
+
145
+ ```html
146
+ <s-gantt
147
+ [tasks]="tasks"
148
+ viewMode="month"
149
+ [allowMovement]="false"
150
+ [hasPopup]="true"
151
+ columnTitle="Cronograma Aprovado"
152
+ ></s-gantt>
153
+ ```
154
+
155
+ ### Largura total
156
+
157
+ ```html
158
+ <s-gantt
159
+ [tasks]="tasks"
160
+ viewMode="week"
161
+ [fullWidth]="true"
162
+ ></s-gantt>
163
+ ```
164
+
165
+ ## Acessibilidade
166
+
167
+ - O gantt é renderizado via SVG e não possui suporte nativo a teclado para navegação entre tarefas
168
+ - Para acessibilidade plena, forneça uma representação alternativa (tabela) quando necessário
169
+ - Os popups de detalhes aparecem ao clicar/focar nas barras de tarefa
170
+
171
+ ## Componentes relacionados
172
+
173
+ - [`DynamicForm`](../dynamic-form/README.md) — para edição de dados de tarefas em formulários