@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
@@ -0,0 +1,151 @@
1
+ # GlobalSearch
2
+
3
+ ![Status](https://img.shields.io/badge/status-stable-brightgreen)
4
+
5
+ Componente de busca global com campo de input, dropdown de resultados animado, estado de carregamento, empty state e suporte a itens customizáveis via `s-global-search-dropdown-item`. Os resultados são projetados via `ng-content`.
6
+
7
+ ## Quando usar
8
+
9
+ - Busca global na topbar da aplicação para pesquisar entidades (colaboradores, clientes, documentos)
10
+ - Pesquisa com resultados em dropdown com link para busca avançada
11
+ - Interfaces que precisam de busca rápida com feedback de carregamento e estado vazio
12
+
13
+ ## Quando não usar
14
+
15
+ - Busca com seleção de valor vinculada a um `FormControl` — use [`Autocomplete`](../autocomplete/README.md)
16
+ - Filtros de listagem local — use um campo de texto simples com pipe de filtro
17
+
18
+ ## Instalação
19
+
20
+ ```typescript
21
+ import { GlobalSearchModule } from '@seniorsistemas/angular-components/global-search';
22
+
23
+ @Component({ standalone: true, imports: [GlobalSearchModule] })
24
+ export class MeuComponent {}
25
+ ```
26
+
27
+ ## Uso básico
28
+
29
+ ```html
30
+ <s-global-search
31
+ totalItensLabel="resultados encontrados"
32
+ showMoreLabel="Ver busca avançada"
33
+ [totalElements]="total"
34
+ [isLoading]="carregando"
35
+ (searched)="onSearch($event)"
36
+ (moreShown)="onVerMais()"
37
+ >
38
+ @for (item of resultados; track item.id) {
39
+ <s-global-search-dropdown-item
40
+ [primaryLabel]="item.nome"
41
+ [secondaryLabel]="item.cargo"
42
+ ></s-global-search-dropdown-item>
43
+ }
44
+ </s-global-search>
45
+ ```
46
+
47
+ ## API
48
+
49
+ ### Inputs
50
+
51
+ | Propriedade | Tipo | Padrão | Obrigatório | Descrição |
52
+ |-------------|------|--------|:-----------:|-----------|
53
+ | `totalItensLabel` | `string` | — | Sim | Label que acompanha o total de resultados no rodapé |
54
+ | `showMoreLabel` | `string` | — | Sim | Rótulo do link para exibir mais resultados |
55
+ | `placeholder` | `string` | — | — | Placeholder do input de busca |
56
+ | `delay` | `number` | `500` | — | Tempo de debounce em ms antes de emitir o evento de busca |
57
+ | `isLoading` | `boolean` | `false` | — | Exibe indicador de carregamento no dropdown |
58
+ | `totalElements` | `number` | — | — | Número total de resultados encontrados |
59
+ | `emptyTitle` | `string` | — | — | Título do empty state quando não há resultados |
60
+ | `emptyDescription` | `string` | — | — | Descrição do empty state exibida abaixo do título |
61
+ | `emptyIcon` | `string` | — | — | Classe do ícone exibido no empty state |
62
+ | `showFooter` | `boolean` | `true` | — | Exibe o rodapé com link "ver mais" e contagem de resultados |
63
+ | `id` | `string` | `s-global-search-{n}` | — | Identificador único do componente |
64
+
65
+ ### Outputs
66
+
67
+ | Evento | Tipo | Descrição |
68
+ |--------|------|-----------|
69
+ | `searched` | `EventEmitter<string>` | Emitido ao digitar no campo (com debounce), com o valor atual |
70
+ | `focused` | `EventEmitter<boolean>` | Emitido quando o campo ganha (`true`) ou perde (`false`) foco |
71
+ | `moreShown` | `EventEmitter<void>` | Emitido ao clicar no link para exibir mais resultados |
72
+
73
+ ## Exemplos
74
+
75
+ ### Busca com resultados dinâmicos
76
+
77
+ ```html
78
+ <s-global-search
79
+ totalItensLabel="colaboradores encontrados"
80
+ showMoreLabel="Ver busca avançada"
81
+ [totalElements]="resultados.length"
82
+ [isLoading]="carregando"
83
+ placeholder="Buscar colaborador..."
84
+ emptyTitle="Nenhum resultado encontrado"
85
+ emptyDescription="Tente buscar por outro termo"
86
+ emptyIcon="fa fa-search"
87
+ (searched)="onSearch($event)"
88
+ (moreShown)="irParaBuscaAvancada()"
89
+ >
90
+ @for (item of resultados; track item.id) {
91
+ <s-global-search-dropdown-item
92
+ [primaryLabel]="item.nome"
93
+ [secondaryLabel]="item.cargo"
94
+ [tertiaryLabel]="item.departamento"
95
+ iconClass="far fa-user"
96
+ size="standart"
97
+ ></s-global-search-dropdown-item>
98
+ }
99
+ </s-global-search>
100
+ ```
101
+
102
+ ```typescript
103
+ resultados: any[] = [];
104
+ carregando = false;
105
+
106
+ onSearch(query: string) {
107
+ if (!query) { this.resultados = []; return; }
108
+ this.carregando = true;
109
+ this.searchService.buscar(query).subscribe(data => {
110
+ this.resultados = data;
111
+ this.carregando = false;
112
+ });
113
+ }
114
+ ```
115
+
116
+ ### Sem rodapé
117
+
118
+ ```html
119
+ <s-global-search
120
+ totalItensLabel="itens"
121
+ showMoreLabel="Ver mais"
122
+ [showFooter]="false"
123
+ (searched)="onSearch($event)"
124
+ >
125
+ <!-- itens -->
126
+ </s-global-search>
127
+ ```
128
+
129
+ ### s-global-search-dropdown-item
130
+
131
+ Campos do componente de item de resultado:
132
+
133
+ | Propriedade | Tipo | Descrição |
134
+ |-------------|------|-----------|
135
+ | `primaryLabel` | `string` | Texto principal do item (obrigatório) |
136
+ | `secondaryLabel` | `string` | Texto secundário |
137
+ | `tertiaryLabel` | `string` | Texto terciário |
138
+ | `iconClass` | `string` | Classe de ícone Font Awesome |
139
+ | `imageSource` | `string` | URL de imagem (thumbnail) |
140
+ | `size` | `'standart' \| 'medium' \| 'small'` | Tamanho do item |
141
+
142
+ ## Acessibilidade
143
+
144
+ - O campo de busca possui suporte a `placeholder` e pode receber `aria-label` via configuração
145
+ - O dropdown abre automaticamente ao digitar e fecha ao limpar o campo
146
+ - Os itens do dropdown são elementos clicáveis com rótulo visível via `primaryLabel`
147
+
148
+ ## Componentes relacionados
149
+
150
+ - [`Autocomplete`](../autocomplete/README.md) — busca com seleção de valor vinculada a formulário
151
+ - [`Topbar`](../topbar/README.md) — barra superior onde o GlobalSearch é tipicamente posicionado
@@ -0,0 +1,123 @@
1
+ # GridMenu
2
+
3
+ ![Status](https://img.shields.io/badge/status-stable-brightgreen)
4
+
5
+ Componente de menu em grade que exibe uma coleção de itens como cards clicáveis. Suporta seleção de item ativo, ícones Font Awesome e itens desabilitados.
6
+
7
+ ## Quando usar
8
+
9
+ - Menus de navegação rápida em dashboards ou launchers de módulos
10
+ - Atalhos para ações frequentes dispostos em grade
11
+ - Menus onde o usuário precisa indicar qual módulo ou contexto está ativo (modo selecionável)
12
+
13
+ ## Quando não usar
14
+
15
+ - Menus com hierarquia (submenus) — prefira [`TieredMenu`](../tiered-menu/README.md)
16
+ - Listas longas de itens com mais de uma coluna de informação — prefira uma tabela ou lista
17
+
18
+ ## Instalação
19
+
20
+ ```typescript
21
+ import { GridMenuModule } from '@seniorsistemas/angular-components/grid-menu';
22
+
23
+ @NgModule({
24
+ imports: [GridMenuModule],
25
+ })
26
+ export class MeuModule {}
27
+ ```
28
+
29
+ ## Uso básico
30
+
31
+ ```html
32
+ <s-grid-menu [items]="menuItems" [useFontAwesomeIcons]="true" />
33
+ ```
34
+
35
+ ## API
36
+
37
+ ### Inputs
38
+
39
+ | Propriedade | Tipo | Padrão | Obrigatório | Descrição |
40
+ |-------------|------|--------|:-----------:|-----------|
41
+ | `items` | `GridMenuItem \| GridMenuItem[]` | `[]` | Não | Lista de itens exibidos no grid. Valores nulos resultam em lista vazia. |
42
+ | `useFontAwesomeIcons` | `boolean` | `false` | Não | Quando `true`, o campo `icon` é tratado como classe Font Awesome. Quando `false`, como URL de imagem SVG. |
43
+ | `selectable` | `boolean` | `false` | Não | Habilita o modo de seleção. O item clicado fica marcado como ativo. |
44
+ | `selected` | `GridMenuItem` | — | Não | Item atualmente selecionado. Suporta two-way binding via `[(selected)]`. |
45
+
46
+ ### Outputs
47
+
48
+ | Evento | Tipo | Descrição |
49
+ |--------|------|-----------|
50
+ | `selectedChange` | `EventEmitter<GridMenuItem>` | Emitido quando o usuário seleciona um novo item. Usado para two-way binding com `[(selected)]`. |
51
+
52
+ ### Tipos
53
+
54
+ ```typescript
55
+ type GridMenuItem = {
56
+ icon?: string; // Classe FA (ex: 'fa-home') ou URL de imagem SVG
57
+ label?: string; // Texto exibido abaixo do ícone
58
+ action: () => void; // Função executada ao clicar (obrigatório)
59
+ disabled?: boolean | (() => boolean); // Desabilita o item
60
+ active?: boolean; // Estado de seleção ativo (gerenciado internamente)
61
+ };
62
+ ```
63
+
64
+ ## Exemplos
65
+
66
+ ### Menu básico com ícones Font Awesome
67
+
68
+ ```html
69
+ <s-grid-menu
70
+ [items]="items"
71
+ [useFontAwesomeIcons]="true"
72
+ [selectable]="false"
73
+ ></s-grid-menu>
74
+ ```
75
+
76
+ ```typescript
77
+ items: GridMenuItem[] = [
78
+ { icon: 'fa-home', label: 'Início', action: () => this.navegar('home') },
79
+ { icon: 'fa-user', label: 'Perfil', action: () => this.navegar('perfil') },
80
+ { icon: 'fa-cog', label: 'Configurações', action: () => this.navegar('config') },
81
+ ];
82
+ ```
83
+
84
+ ### Menu com seleção e two-way binding
85
+
86
+ ```html
87
+ <s-grid-menu
88
+ [items]="items"
89
+ [useFontAwesomeIcons]="true"
90
+ [selectable]="true"
91
+ [(selected)]="itemSelecionado"
92
+ (selectedChange)="onItemSelecionado($event)"
93
+ ></s-grid-menu>
94
+ <div>Selecionado: {{ itemSelecionado?.label }}</div>
95
+ ```
96
+
97
+ ### Menu com itens desabilitados
98
+
99
+ ```html
100
+ <s-grid-menu
101
+ [items]="itemsComDesabilitados"
102
+ [useFontAwesomeIcons]="true"
103
+ ></s-grid-menu>
104
+ ```
105
+
106
+ ```typescript
107
+ itemsComDesabilitados: GridMenuItem[] = [
108
+ { icon: 'fa-home', label: 'Início', action: () => {} },
109
+ { icon: 'fa-lock', label: 'Bloqueado', action: () => {}, disabled: true },
110
+ { icon: 'fa-cog', label: 'Dinâmico', action: () => {}, disabled: () => !this.temPermissao },
111
+ ];
112
+ ```
113
+
114
+ ## Acessibilidade
115
+
116
+ - Cada item do grid é um elemento clicável — utilize o `label` para descrição adequada
117
+ - Itens desabilitados bloqueiam interação e não emitem eventos
118
+ - O estado ativo (`active`) é visualmente distinguido para indicar a seleção atual
119
+
120
+ ## Componentes relacionados
121
+
122
+ - [`TieredMenu`](../tiered-menu/README.md) — quando precisar de menus com hierarquia e submenus
123
+ - [`NavigationButton`](../navigation-button/README.md) — quando precisar de navegação sequencial entre etapas
@@ -0,0 +1,134 @@
1
+ # HelpPopover
2
+
3
+ ![Status](https://img.shields.io/badge/status-stable-brightgreen)
4
+
5
+ Diretiva que exibe um popover de ajuda ao clicar no elemento hospedeiro. Suporta conteúdo como texto simples ou `TemplateRef`, com cabeçalho, rodapé, ícone, botão de fechar e posicionamento automático.
6
+
7
+ ## Quando usar
8
+
9
+ - Explicar campos de formulário com regras complexas de preenchimento
10
+ - Fornecer contexto adicional sobre funcionalidades sem sobrecarregar a interface
11
+ - Quando o conteúdo de ajuda é extenso demais para um tooltip simples
12
+
13
+ ## Quando não usar
14
+
15
+ - Mensagens curtas ao passar o mouse — prefira [`Tooltip`](../tooltip/README.md)
16
+ - Ícone de informação simples ao lado de um label — prefira [`InfoSign`](../info-sign/README.md)
17
+
18
+ ## Instalação
19
+
20
+ ```typescript
21
+ import { HelpPopoverModule } from '@seniorsistemas/angular-components/help-popover';
22
+
23
+ @NgModule({
24
+ imports: [HelpPopoverModule],
25
+ })
26
+ export class MeuModule {}
27
+ ```
28
+
29
+ ## Uso básico
30
+
31
+ ```html
32
+ <button [sHelpPopover]="'Informe aqui o seu CPF'" popoverPosition="right">?</button>
33
+ ```
34
+
35
+ ## API
36
+
37
+ ### Inputs
38
+
39
+ | Propriedade | Tipo | Padrão | Obrigatório | Descrição |
40
+ |-------------|------|--------|:-----------:|-----------|
41
+ | `sHelpPopover` | `string \| TemplateRef<any> \| null` | `null` | Sim | Conteúdo do popover. Aceita texto simples ou `TemplateRef` Angular. |
42
+ | `closeButton` | `boolean` | `true` | Não | Exibe o botão de fechar (X) no cabeçalho. |
43
+ | `popoverIcon` | `string` | `''` | Não | Classe Font Awesome do ícone exibido no cabeçalho (ex: `'fas fa-info-circle'`). |
44
+ | `popoverHeader` | `string` | `''` | Não | Texto exibido no cabeçalho do popover. |
45
+ | `popoverFooter` | `string` | `''` | Não | Texto exibido no rodapé do popover. |
46
+ | `popoverButtonText` | `string` | `''` | Não | Texto do botão de ação no rodapé. Ao clicar, emite `buttonClicked`. |
47
+ | `popoverPosition` | `HelpPopoverPosition` | `'bottom'` | Não | Posição do popover em relação ao elemento. Reposiciona automaticamente se não houver espaço. |
48
+ | `popoverArrowPosition` | `HelpPopoverArrowPosition` | `'beginning'` | Não | Alinhamento da seta indicadora em relação ao lado do popover. |
49
+
50
+ ### Outputs
51
+
52
+ | Evento | Tipo | Descrição |
53
+ |--------|------|-----------|
54
+ | `buttonClicked` | `EventEmitter<void>` | Emitido quando o usuário clica no botão de ação do rodapé. |
55
+
56
+ ### Tipos
57
+
58
+ ```typescript
59
+ type HelpPopoverPosition = 'top' | 'right' | 'bottom' | 'left';
60
+ type HelpPopoverArrowPosition = 'beginning' | 'middle' | 'end';
61
+ ```
62
+
63
+ ## Exemplos
64
+
65
+ ### Popover básico com texto simples
66
+
67
+ ```html
68
+ <button
69
+ [sHelpPopover]="'Informe o CPF sem pontos e traços. Apenas números.'"
70
+ popoverHeader="CPF"
71
+ popoverIcon="fas fa-info-circle"
72
+ popoverPosition="right"
73
+ >
74
+ ?
75
+ </button>
76
+ ```
77
+
78
+ ### Popover com template customizado
79
+
80
+ ```html
81
+ <ng-template #ajudaTemplate>
82
+ <div>
83
+ <p><strong>Formatos aceitos:</strong></p>
84
+ <ul>
85
+ <li>JPG / JPEG</li>
86
+ <li>PNG</li>
87
+ </ul>
88
+ </div>
89
+ </ng-template>
90
+
91
+ <button [sHelpPopover]="ajudaTemplate" popoverHeader="Upload de imagem">
92
+ Ajuda
93
+ </button>
94
+ ```
95
+
96
+ ### Popover com rodapé e botão de ação
97
+
98
+ ```html
99
+ <button
100
+ [sHelpPopover]="'Esta funcionalidade permite exportar dados.'"
101
+ popoverHeader="Exportar dados"
102
+ popoverFooter="Disponível nos planos Pro e Enterprise."
103
+ popoverButtonText="Ver planos"
104
+ (buttonClicked)="abrirPlanos()"
105
+ >
106
+ Mais informações
107
+ </button>
108
+ ```
109
+
110
+ ### Acionamento programático
111
+
112
+ ```html
113
+ <span
114
+ [sHelpPopover]="'Este campo aceita apenas números inteiros positivos.'"
115
+ popoverHeader="Formato do campo"
116
+ popoverPosition="right"
117
+ #popoverRef="sHelpPopover"
118
+ >
119
+ Quantidade em estoque
120
+ </span>
121
+ <button (click)="popoverRef.show()">?</button>
122
+ ```
123
+
124
+ ## Acessibilidade
125
+
126
+ - O popover é aberto ao clicar no elemento hospedeiro e fechado ao clicar fora
127
+ - Use `popoverHeader` para fornecer contexto sobre o conteúdo do popover
128
+ - Pode ser acionado programaticamente via `#ref="sHelpPopover"` e `ref.show()`
129
+ - Reposiciona automaticamente quando não há espaço na posição configurada
130
+
131
+ ## Componentes relacionados
132
+
133
+ - [`InfoSign`](../info-sign/README.md) — ícone de informação simples com tooltip ao passar o mouse
134
+ - [`Tooltip`](../tooltip/README.md) — dica contextual leve ao passar o mouse sobre um elemento
@@ -1,17 +1,35 @@
1
1
  # IA Insight (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 `Insights`.
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 `Insights`. O seletor `s-ia-insight` e o pacote `ia-insight` foram substituídos por `s-insights` e `insights`.
6
8
 
7
9
  ## Migração
8
10
 
9
- Use `InsightsModule` e `InsightsComponent` de `@seniorsistemas/angular-components/insights` em novos projetos.
11
+ Substitua as importações do pacote antigo pelo novo:
12
+
13
+ ```typescript
14
+ // Antes (descontinuado)
15
+ import { IaInsightModule } from '@seniorsistemas/angular-components/ia-insight';
16
+
17
+ // Depois (recomendado)
18
+ import { InsightsModule } from '@seniorsistemas/angular-components/insights';
19
+ ```
10
20
 
11
- O seletor `s-ia-insight` também está descontinuado — use `s-insights`.
21
+ Substitua o seletor no template:
22
+
23
+ ```html
24
+ <!-- Antes (descontinuado) -->
25
+ <s-ia-insight [insights]="insights"></s-ia-insight>
26
+
27
+ <!-- Depois (recomendado) -->
28
+ <s-insights [insights]="insights"></s-insights>
29
+ ```
12
30
 
13
31
  ## Documentação
14
32
 
15
33
  Consulte a documentação completa do componente em:
16
- - **Storybook**: `Components/Structure/Insights`
17
- - **Pacote**: `@seniorsistemas/angular-components/insights`
34
+
35
+ - [`Insights`](../insights/README.md) — documentação atualizada do componente
@@ -0,0 +1,140 @@
1
+ # ImageCropper
2
+
3
+ ![Status](https://img.shields.io/badge/status-stable-brightgreen)
4
+
5
+ Componente de recorte de imagem baseado na biblioteca `cropperjs`. Exibe um dialog com área interativa para selecionar, recortar e remover imagens, com suporte a proporção de aspecto configurável e recorte circular.
6
+
7
+ ## Quando usar
8
+
9
+ - Recorte de foto de perfil ou avatar antes do upload
10
+ - Ajuste de imagens com proporção específica (1:1, 16:9, etc.)
11
+ - Fluxos de upload onde o usuário precisa selecionar e ajustar a área da imagem
12
+
13
+ ## Quando não usar
14
+
15
+ - Visualização simples de imagens sem necessidade de edição — prefira `<img>` ou o componente Thumbnail
16
+ - Upload de imagens sem recorte — use um campo de arquivo comum
17
+
18
+ ## Instalação
19
+
20
+ ```typescript
21
+ import { ImageCropperModule, ImageCropperService } from '@seniorsistemas/angular-components/image-cropper';
22
+
23
+ @NgModule({
24
+ imports: [ImageCropperModule],
25
+ providers: [ImageCropperService],
26
+ })
27
+ export class MeuModule {}
28
+ ```
29
+
30
+ ## Uso básico
31
+
32
+ ```html
33
+ <s-image-cropper
34
+ [(visible)]="cropperVisivel"
35
+ [imageSource]="imagemBase64"
36
+ [aspectRatio]="1"
37
+ (croppedImage)="onImagemRecortada($event)"
38
+ ></s-image-cropper>
39
+ ```
40
+
41
+ ## API
42
+
43
+ ### Inputs
44
+
45
+ | Propriedade | Tipo | Padrão | Obrigatório | Descrição |
46
+ |-------------|------|--------|:-----------:|-----------|
47
+ | `visible` | `boolean` | `false` | Não | Controla a visibilidade do dialog. Suporta two-way binding via `[(visible)]`. |
48
+ | `imageSource` | `string` | `undefined` | Não | URL ou base64 da imagem a ser carregada no cropper. |
49
+ | `header` | `string` | `'Recortar imagem'` | Não | Título exibido no cabeçalho do dialog. |
50
+ | `cropLabel` | `string` | `'Recortar'` | Não | Rótulo do botão de confirmar o recorte. |
51
+ | `selectAnotherLabel` | `string` | `'Trocar'` | Não | Rótulo do botão de trocar a imagem. |
52
+ | `removeLabel` | `string` | `'Remover'` | Não | Rótulo do botão de remover a imagem. |
53
+ | `cancelLabel` | `string` | `'Cancelar'` | Não | Rótulo do botão de cancelar. |
54
+ | `emptyStateTitle` | `string` | `'Selecione uma foto...'` | Não | Título do estado vazio (sem imagem selecionada). |
55
+ | `emptyStateActionLabel` | `string` | `'Escolher imagem'` | Não | Rótulo do botão de ação do estado vazio. |
56
+ | `emptyStateIconClass` | `string` | `'fa fa-picture-o'` | Não | Classe do ícone exibido no estado vazio. |
57
+ | `aspectRatio` | `number` | `NaN` | Não | Proporção de aspecto para o recorte. `1` = quadrado, `16/9` = widescreen, `NaN` = livre. |
58
+ | `rounded` | `boolean` | `false` | Não | Quando `true`, exibe a área de recorte no formato circular. |
59
+ | `allowSelectAnother` | `boolean` | `true` | Não | Exibe o botão para trocar a imagem selecionada. |
60
+ | `allowRemove` | `boolean` | `true` | Não | Exibe o botão para remover a imagem. |
61
+ | `allowCancel` | `boolean` | `true` | Não | Exibe o botão de cancelar. |
62
+ | `id` | `string` | `s-image-cropper-{auto}` | Não | Identificador único do componente no DOM. |
63
+
64
+ ### Outputs
65
+
66
+ | Evento | Tipo | Descrição |
67
+ |--------|------|-----------|
68
+ | `visibleChange` | `EventEmitter<boolean>` | Emitido quando a visibilidade muda, habilitando `[(visible)]`. |
69
+ | `croppedImage` | `EventEmitter<string>` | Emitido com a imagem recortada em formato base64 string. |
70
+ | `croppedCanvas` | `EventEmitter<HTMLCanvasElement>` | Emitido com o `HTMLCanvasElement` resultante do recorte. |
71
+ | `removedImage` | `EventEmitter<void>` | Emitido quando o usuário confirma a remoção da imagem. |
72
+ | `changeImage` | `EventEmitter<void>` | Emitido quando o usuário clica em "Trocar" para selecionar outra imagem. |
73
+ | `cancel` | `EventEmitter<void>` | Emitido quando o usuário cancela o recorte. |
74
+
75
+ ## Exemplos
76
+
77
+ ### Recorte de foto de perfil (1:1 circular)
78
+
79
+ ```html
80
+ <s-button label="Editar foto" (clicked)="cropperVisivel = true"></s-button>
81
+
82
+ <s-image-cropper
83
+ [(visible)]="cropperVisivel"
84
+ [imageSource]="imagemBase64"
85
+ [aspectRatio]="1"
86
+ [rounded]="true"
87
+ header="Foto de perfil"
88
+ (croppedImage)="fotoPerfil = $event"
89
+ (changeImage)="selecionarNovaImagem()"
90
+ ></s-image-cropper>
91
+ ```
92
+
93
+ ### Recorte com proporção livre
94
+
95
+ ```html
96
+ <s-image-cropper
97
+ [(visible)]="cropperVisivel"
98
+ [imageSource]="imagemBase64"
99
+ (croppedImage)="onImagemRecortada($event)"
100
+ (removedImage)="onImagemRemovida()"
101
+ ></s-image-cropper>
102
+ ```
103
+
104
+ ### Uso via serviço (recomendado para fluxos simples)
105
+
106
+ ```typescript
107
+ constructor(private imageCropperService: ImageCropperService) {}
108
+
109
+ abrirCropper(imagemBase64: string) {
110
+ this.imageCropperService.show({
111
+ imageSource: imagemBase64,
112
+ aspectRatio: 1,
113
+ croppedImage: (imagem) => this.fotoPerfil = imagem,
114
+ changeImage: () => this.selecionarNovaImagem(),
115
+ });
116
+ }
117
+ ```
118
+
119
+ ### Com header e footer customizados
120
+
121
+ ```html
122
+ <s-image-cropper #cropper [(visible)]="cropperVisivel" [imageSource]="imagemBase64">
123
+ <s-header>
124
+ <span>Header Personalizado</span>
125
+ </s-header>
126
+ <s-footer>
127
+ <s-button label="Recortar" priority="primary" (clicked)="cropper.onCropImage()"></s-button>
128
+ </s-footer>
129
+ </s-image-cropper>
130
+ ```
131
+
132
+ ## Acessibilidade
133
+
134
+ - O dialog possui cabeçalho com título configurável via `header`
135
+ - Os botões de ação têm rótulos customizáveis para internacionalização
136
+ - O estado vazio orienta o usuário sobre a próxima ação via `emptyStateTitle`
137
+
138
+ ## Componentes relacionados
139
+
140
+ - [`Thumbnail`](../thumbnail/README.md) — exibição da imagem recortada