ngx-opalbytes-components 1.27.0 → 1.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/README.md +361 -1
  2. package/cli/cao-comp.cjs +10 -10
  3. package/fesm2022/ngx-opalbytes-components.mjs +350 -4
  4. package/fesm2022/ngx-opalbytes-components.mjs.map +1 -1
  5. package/package.json +1 -1
  6. package/src/lib/shared/components/accordion/accordion.component.css +30 -0
  7. package/src/lib/shared/components/accordion/accordion.component.html +1 -0
  8. package/src/lib/shared/components/accordion/accordion.component.spec.ts +117 -0
  9. package/src/lib/shared/components/accordion/accordion.component.ts +195 -0
  10. package/src/lib/shared/components/accordion/accordion.token.ts +40 -0
  11. package/src/lib/shared/components/accordion-item/accordion-item.component.css +137 -0
  12. package/src/lib/shared/components/accordion-item/accordion-item.component.html +52 -0
  13. package/src/lib/shared/components/accordion-item/accordion-item.component.ts +157 -0
  14. package/src/lib/shared/components/accordion-item/accordion-item.spec.ts +22 -0
  15. package/src/lib/shared/components/avatar/avatar.constants.ts +17 -0
  16. package/src/lib/shared/components/avatar/avatar.css +44 -0
  17. package/src/lib/shared/components/avatar/avatar.html +27 -0
  18. package/src/lib/shared/components/avatar/avatar.model.ts +3 -0
  19. package/src/lib/shared/components/avatar/avatar.spec.ts +88 -0
  20. package/src/lib/shared/components/avatar/avatar.stories.ts +85 -0
  21. package/src/lib/shared/components/avatar/avatar.ts +83 -0
  22. package/src/lib/shared/components/avatar/index.ts +3 -0
  23. package/src/lib/shared/components/breadcrumb/breadcrumb.css +105 -0
  24. package/src/lib/shared/components/breadcrumb/breadcrumb.html +108 -0
  25. package/src/lib/shared/components/breadcrumb/breadcrumb.model.ts +54 -0
  26. package/src/lib/shared/components/breadcrumb/breadcrumb.spec.ts +93 -0
  27. package/src/lib/shared/components/breadcrumb/breadcrumb.stories.ts +122 -0
  28. package/src/lib/shared/components/breadcrumb/breadcrumb.ts +72 -0
  29. package/src/lib/shared/components/breadcrumb/index.ts +2 -0
  30. package/src/lib/shared/components/index.ts +5 -1
  31. package/types/ngx-opalbytes-components.d.ts +354 -129
package/README.md CHANGED
@@ -232,12 +232,15 @@ src/
232
232
  └── lib/
233
233
  └── shared/
234
234
  └── components/
235
- | ├── autocomplete/
235
+ | ├── accordion/
236
+ | ├── accordion-item/
237
+ | ├── avatar/
236
238
  | ├── base-button/
237
239
  | ├── base-icon/
238
240
  | ├── base-input/
239
241
  | ├── base-time-range/
240
242
  | ├── base-toggle/
243
+ | ├── breadcrumb/
241
244
  | ├── checkbox/
242
245
  | ├── drop-down/
243
246
  | ├── footer/
@@ -931,6 +934,363 @@ Um componente de alternância (toggle switch) que funciona com `ngModel` ou `for
931
934
 
932
935
  ---
933
936
 
937
+ ### `CaoBreadcrumbComponent`
938
+
939
+ Trilha de navegação (breadcrumb) com ícones Lucide ou imagem, link de navegação, badge e divisor customizável.
940
+
941
+ **Seletor:** `<cao-breadcrumb>`
942
+
943
+ **Interface `ICaoBreadcrumbItem`**
944
+
945
+ | Propriedade | Tipo | Padrão | Descrição |
946
+ | --- | --- | --- | --- |
947
+ | `label` | `string` | — | Texto do item. |
948
+ | `icon` | `string` | — | Nome do ícone Lucide ou URL/caminho/data URI de imagem. |
949
+ | `isLucideIcon` | `boolean` | `true` | Define se `icon` é Lucide. |
950
+ | `iconPosition` | `'left' \| 'right'` | `'left'` | Direção do ícone em relação ao texto. |
951
+ | `iconColor` / `iconSize` / `iconStrokeWidth` | `string` / `number` / `number` | — / `16` / `1.5` | Aparência do ícone. |
952
+ | `link` | `string \| unknown[]` | — | Navegação interna (`routerLink`). |
953
+ | `queryParams` | `Params` | — | Query params do `link`. |
954
+ | `href` / `target` | `string` / `'_self' \| '_blank' ...` | — | Navegação externa. |
955
+ | `command` | `(e: ICaoBreadcrumbItemClickEvent) => void` | — | Callback de clique (sem `link`/`href` vira `<button>`). |
956
+ | `badge` / `badgeColor` / `badgeBgColor` | `string \| number` / `string` / `string` | — | Badge do item. |
957
+ | `disabled` | `boolean` | `false` | Desabilita o item. |
958
+ | `ariaLabel` / `dataCy` | `string` | — | Acessibilidade e testes E2E. |
959
+
960
+ **Atributos (Inputs)**
961
+
962
+ | Atributo | Tipo | Padrão | Descrição |
963
+ | --- | --- | --- | --- |
964
+ | `items` | `ICaoBreadcrumbItem[]` | `[]` | Itens; o último é a página atual (`aria-current="page"`). |
965
+ | `home` | `ICaoBreadcrumbItem` | `undefined` | Item inicial opcional. |
966
+ | `separator` | `string` | `'/'` | Texto do divisor. |
967
+ | `separatorIcon` | `string` | `''` | Ícone do divisor (sobrepõe `separator`). |
968
+ | `isLucideSeparatorIcon` | `boolean` | `true` | Define se `separatorIcon` é Lucide. |
969
+ | `separatorIconSize` / `separatorIconStrokeWidth` | `number` | `14` / `1.5` | Aparência do ícone divisor. |
970
+ | `linkColor`, `linkHoverColor`, `currentColor`, `separatorColor`, `fontSize`, `gap` | `string` | `''` | Atalhos para as CSS custom properties. |
971
+ | `ariaLabel` | `string` | `'Breadcrumb'` | `aria-label` do `<nav>`. |
972
+ | `dataCy` | `string` | `''` | Atributo para testes E2E. |
973
+
974
+ **Eventos (Outputs):** `itemClick` → `ICaoBreadcrumbItemClickEvent` (`item`, `index`, `originalEvent`).
975
+
976
+ **CSS Custom Properties:** `--cao-breadcrumb-link-color` (`#6b7280`), `--cao-breadcrumb-link-hover-color` (`#4f46e5`), `--cao-breadcrumb-current-color` (`#111827`), `--cao-breadcrumb-separator-color` (`#9ca3af`), `--cao-breadcrumb-disabled-color`, `--cao-breadcrumb-focus-ring`, `--cao-breadcrumb-badge-bg`, `--cao-breadcrumb-badge-text`, `--cao-breadcrumb-gap` (`8px`), `--cao-breadcrumb-font-size` (`0.875rem`).
977
+
978
+ ```html
979
+ <cao-breadcrumb
980
+ [home]="{ icon: 'house', ariaLabel: 'Início', link: '/' }"
981
+ [items]="[
982
+ { label: 'Pedidos', icon: 'package', iconPosition: 'right', link: '/pedidos', badge: 12 },
983
+ { label: 'Pedido #42' }
984
+ ]"
985
+ separatorIcon="chevron-right" />
986
+ ```
987
+
988
+ > Depende de `BaseIcon` (copie junto ao usar `cao-comp`) e de `@angular/router`.
989
+
990
+ ---
991
+ ### `CaoAccordionComponent` e `CaoAccordionItemComponent`
992
+
993
+ Um accordion (painéis expansíveis) acessível e totalmente customizável, inspirado na API do `CdkAccordion`, mas **sem depender do `@angular/cdk`, do Angular Material ou de qualquer outra biblioteca externa** — usa apenas `@angular/core` e `@angular/common`. Cores, posições, textos e visibilidade são configuráveis por inputs ou por CSS custom properties. A animação de abrir/fechar é feita só com CSS e respeita `prefers-reduced-motion`.
994
+
995
+ **Seletores:**
996
+ - `<cao-accordion>` — container (controla modo único/múltiplo e o tema herdado pelos itens)
997
+ - `<cao-accordion-item>` — painel individual (também pode ser usado isolado, como um cartão expansível)
998
+
999
+ #### Atributos do `CaoAccordionComponent` (Inputs)
1000
+
1001
+ | Atributo | Tipo | Padrão | Descrição |
1002
+ | --- | --- | --- | --- |
1003
+ | `multi` | `boolean` | `false` | Permite vários itens expandidos ao mesmo tempo. No modo único, expandir um item recolhe os demais. |
1004
+ | `displayMode` | `'default' \| 'flat' \| 'separated'` | `'default'` | `default`: painéis unidos em um único contorno arredondado; `flat`: unidos, sem bordas laterais/cantos; `separated`: cada painel é um cartão separado por `gap`. |
1005
+ | `hideToggle` | `boolean` | `false` | Oculta o ícone de expandir/recolher em todos os itens. |
1006
+ | `isVisible` | `boolean` | `true` | Exibe ou oculta o accordion inteiro. |
1007
+ | `togglePosition` | `'before' \| 'after'` | `'after'` | Posição do ícone em relação ao texto do cabeçalho. |
1008
+ | `headerAlign` | `'start' \| 'center' \| 'end'` | `'start'` | Alinhamento do texto do cabeçalho. |
1009
+ | `contentAlign` | `'start' \| 'center' \| 'end'` | `'start'` | Alinhamento do texto do conteúdo. |
1010
+ | `headerBgColor` | `string` | `#ffffff` | Cor de fundo do cabeçalho. |
1011
+ | `headerTextColor` | `string` | `#111827` | Cor do texto do cabeçalho. |
1012
+ | `headerHoverBgColor` | `string` | `#f3f4f6` | Cor de fundo do cabeçalho ao passar o mouse. |
1013
+ | `headerActiveBgColor` | `string` | cor do cabeçalho | Cor de fundo do cabeçalho do item expandido. |
1014
+ | `activeColor` | `string` | `#4f46e5` | Cor do texto/ícone do cabeçalho do item expandido. |
1015
+ | `contentBgColor` | `string` | `#ffffff` | Cor de fundo do conteúdo. |
1016
+ | `contentTextColor` | `string` | `#374151` | Cor do texto do conteúdo. |
1017
+ | `borderColor` | `string` | `#e5e7eb` | Cor das bordas e divisórias. |
1018
+ | `disabledColor` | `string` | `#9ca3af` | Cor do texto de itens desabilitados. |
1019
+ | `focusRingColor` | `string` | `rgba(79, 70, 229, 0.35)` | Cor do anel de foco do teclado. |
1020
+ | `iconColor` | `string` | `currentColor` | Cor do ícone de expandir/recolher. |
1021
+ | `borderRadius` | `string` | `8px` | Raio da borda. |
1022
+ | `gap` | `string` | `8px` | Espaçamento entre os itens (modo `separated`). |
1023
+ | `headerPadding` | `string` | `12px 16px` | Padding do cabeçalho. |
1024
+ | `contentPadding` | `string` | `16px` | Padding do conteúdo. |
1025
+ | `animationDuration` | `string` | `250ms` | Duração da animação. |
1026
+ | `dataCy` | `string` | `''` | Atributo `data-cy` para testes E2E. |
1027
+
1028
+ #### Métodos do `CaoAccordionComponent`
1029
+
1030
+ | Método | Descrição |
1031
+ | --- | --- |
1032
+ | `openAll()` | Expande todos os itens. Só tem efeito quando `multi` está ativo. |
1033
+ | `closeAll()` | Recolhe todos os itens. |
1034
+
1035
+ #### Atributos do `CaoAccordionItemComponent` (Inputs)
1036
+
1037
+ | Atributo | Tipo | Padrão | Descrição |
1038
+ | --- | --- | --- | --- |
1039
+ | `label` | `string` | `''` | Texto do cabeçalho. |
1040
+ | `description` | `string` | `''` | Texto secundário exibido abaixo do `label`. |
1041
+ | `expanded` | `boolean` | `false` | Estado de expansão. Suporta two-way binding: `[(expanded)]`. |
1042
+ | `isDisabled` | `boolean` | `false` | Desabilita a interação do usuário com o item. |
1043
+ | `isVisible` | `boolean` | `true` | Exibe ou oculta o item. |
1044
+ | `headingLevel` | `number` | `3` | Nível do heading (`aria-level`) do cabeçalho. |
1045
+ | `hideToggle` | `boolean` | herda do accordion | Oculta o ícone neste item. |
1046
+ | `togglePosition` | `'before' \| 'after'` | herda do accordion | Posição do ícone neste item. |
1047
+ | `headerAlign` | `'start' \| 'center' \| 'end'` | herda do accordion | Alinhamento do cabeçalho neste item. |
1048
+ | `headerBgColor` | `string` | herda do accordion | Cor de fundo do cabeçalho deste item. |
1049
+ | `headerTextColor` | `string` | herda do accordion | Cor do texto do cabeçalho deste item. |
1050
+ | `headerActiveBgColor` | `string` | herda do accordion | Cor de fundo do cabeçalho quando expandido. |
1051
+ | `activeColor` | `string` | herda do accordion | Cor do texto/ícone quando expandido. |
1052
+ | `contentBgColor` | `string` | herda do accordion | Cor de fundo do conteúdo. |
1053
+ | `contentTextColor` | `string` | herda do accordion | Cor do texto do conteúdo. |
1054
+ | `borderColor` | `string` | herda do accordion | Cor das bordas. |
1055
+ | `iconColor` | `string` | herda do accordion | Cor do ícone. |
1056
+ | `dataCy` | `string` | `''` | Atributo `data-cy` para testes E2E (veja abaixo). |
1057
+
1058
+ #### Eventos do `CaoAccordionItemComponent` (Outputs)
1059
+
1060
+ | Evento | Tipo | Descrição |
1061
+ | --- | --- | --- |
1062
+ | `opened` | `output<void>` | Emitido quando o item é expandido. |
1063
+ | `closed` | `output<void>` | Emitido quando o item é recolhido. |
1064
+ | `expandedChange` | `output<boolean>` | Emitido a cada mudança de estado (usado pelo `[(expanded)]`). |
1065
+
1066
+ #### Métodos do `CaoAccordionItemComponent`
1067
+
1068
+ | Método | Descrição |
1069
+ | --- | --- |
1070
+ | `toggle()` | Alterna o estado (ignorado se o item estiver desabilitado). |
1071
+ | `open()` | Expande o item. |
1072
+ | `close()` | Recolhe o item. |
1073
+
1074
+ #### Projeção de conteúdo
1075
+
1076
+ | Recurso | Descrição |
1077
+ | --- | --- |
1078
+ | Slot padrão (`<ng-content />`) | Conteúdo do painel. |
1079
+ | `[caoAccordionHeader]` | Conteúdo extra projetado no cabeçalho, abaixo do `label`/`description` (ex.: badges, status). |
1080
+
1081
+ #### `data-cy` para testes E2E
1082
+
1083
+ Ao informar `dataCy="faq"` em um item, são gerados automaticamente os seletores:
1084
+
1085
+ | Elemento | Atributo |
1086
+ | --- | --- |
1087
+ | Item (host) | `data-cy="faq"` |
1088
+ | Botão do cabeçalho | `data-cy="faq-header"` |
1089
+ | Painel de conteúdo | `data-cy="faq-content"` |
1090
+
1091
+ ```typescript
1092
+ cy.get('[data-cy="faq-header"]').click();
1093
+ cy.get('[data-cy="faq-content"]').should('be.visible');
1094
+ ```
1095
+
1096
+ #### CSS Custom Properties
1097
+
1098
+ Podem ser definidas globalmente, por accordion ou por item (têm precedência sobre os valores padrão, e os inputs equivalentes as definem automaticamente).
1099
+
1100
+ | Propriedade | Padrão | Descrição |
1101
+ | --- | --- | --- |
1102
+ | `--cao-accordion-header-bg` | `#ffffff` | Fundo do cabeçalho. |
1103
+ | `--cao-accordion-header-text` | `#111827` | Texto do cabeçalho. |
1104
+ | `--cao-accordion-header-hover-bg` | `#f3f4f6` | Fundo do cabeçalho no hover. |
1105
+ | `--cao-accordion-header-active-bg` | `var(--cao-accordion-header-bg)` | Fundo do cabeçalho expandido. |
1106
+ | `--cao-accordion-active-color` | `#4f46e5` | Texto/ícone do cabeçalho expandido. |
1107
+ | `--cao-accordion-content-bg` | `#ffffff` | Fundo do conteúdo. |
1108
+ | `--cao-accordion-content-text` | `#374151` | Texto do conteúdo. |
1109
+ | `--cao-accordion-border-color` | `#e5e7eb` | Bordas e divisórias. |
1110
+ | `--cao-accordion-disabled-color` | `#9ca3af` | Texto desabilitado. |
1111
+ | `--cao-accordion-focus-ring` | `rgba(79, 70, 229, 0.35)` | Anel de foco. |
1112
+ | `--cao-accordion-icon-color` | `currentColor` | Cor do ícone. |
1113
+ | `--cao-accordion-radius` | `8px` | Raio da borda. |
1114
+ | `--cao-accordion-gap` | `8px` | Espaço entre itens (`separated`). |
1115
+ | `--cao-accordion-header-padding` | `12px 16px` | Padding do cabeçalho. |
1116
+ | `--cao-accordion-content-padding` | `16px` | Padding do conteúdo. |
1117
+ | `--cao-accordion-header-align` | `start` | Alinhamento do texto do cabeçalho. |
1118
+ | `--cao-accordion-content-align` | `start` | Alinhamento do texto do conteúdo. |
1119
+ | `--cao-accordion-duration` | `250ms` | Duração da animação. |
1120
+
1121
+ **Exemplo básico:**
1122
+
1123
+ ```typescript
1124
+ import { Component } from '@angular/core';
1125
+ import { CaoAccordionComponent, CaoAccordionItemComponent } from 'ngx-opalbytes-components';
1126
+
1127
+ @Component({
1128
+ selector: 'app-faq',
1129
+ imports: [CaoAccordionComponent, CaoAccordionItemComponent],
1130
+ template: `
1131
+ <cao-accordion dataCy="faq-accordion">
1132
+ <cao-accordion-item label="Como funciona?" dataCy="faq-1" [expanded]="true">
1133
+ Conteúdo da primeira pergunta.
1134
+ </cao-accordion-item>
1135
+ <cao-accordion-item label="Posso cancelar?" description="Sem multa" dataCy="faq-2">
1136
+ Conteúdo da segunda pergunta.
1137
+ </cao-accordion-item>
1138
+ </cao-accordion>
1139
+ `,
1140
+ })
1141
+ export class FaqComponent {}
1142
+ ```
1143
+
1144
+ **Exemplo com múltiplos itens abertos, cores, ícone antes do texto e controle externo:**
1145
+
1146
+ ```html
1147
+ <cao-accordion
1148
+ #acc
1149
+ [multi]="true"
1150
+ displayMode="separated"
1151
+ togglePosition="before"
1152
+ headerAlign="center"
1153
+ headerBgColor="#eef2ff"
1154
+ headerTextColor="#312e81"
1155
+ activeColor="#16a34a"
1156
+ contentBgColor="#ffffff"
1157
+ borderColor="#c7d2fe"
1158
+ borderRadius="12px"
1159
+ animationDuration="400ms"
1160
+ dataCy="meu-accordion">
1161
+
1162
+ <cao-accordion-item label="Dados pessoais" [(expanded)]="dadosAbertos" (opened)="onAbriu()" (closed)="onFechou()">
1163
+ ...
1164
+ </cao-accordion-item>
1165
+
1166
+ <cao-accordion-item label="Pagamento" [isDisabled]="semPermissao" headerBgColor="#fef3c7">
1167
+ <span caoAccordionHeader>Pendente</span>
1168
+ ...
1169
+ </cao-accordion-item>
1170
+
1171
+ <cao-accordion-item label="Somente admin" [isVisible]="ehAdmin" [hideToggle]="true">
1172
+ ...
1173
+ </cao-accordion-item>
1174
+ </cao-accordion>
1175
+
1176
+ <cao-button buttonText="Abrir todos" (buttonClick)="acc.openAll()"></cao-button>
1177
+ <cao-button buttonText="Fechar todos" (buttonClick)="acc.closeAll()"></cao-button>
1178
+ ```
1179
+
1180
+ **Observações:**
1181
+
1182
+ - Sem dependências externas: não usa `@angular/cdk`, `@angular/material`, `@lucide/angular` nem `ngx-mask`; o ícone é um SVG inline.
1183
+ - Acessibilidade: o cabeçalho é um `<button>` dentro de um `role="heading"`, com `aria-expanded`, `aria-controls` e painel `role="region"` com `aria-labelledby`. Painéis recolhidos ficam fora da ordem de tabulação e do leitor de tela.
1184
+ - Teclado: `Enter`/`Espaço` alternam o item; `↑`/`↓` movem o foco entre cabeçalhos; `Home`/`End` vão ao primeiro/último.
1185
+ - Itens definidos como `isDisabled` bloqueiam apenas a interação do usuário; `open()`, `close()` e `[expanded]` continuam funcionando programaticamente.
1186
+ - Os inputs do `<cao-accordion-item>` sobrescrevem os do `<cao-accordion>` apenas naquele item.
1187
+ - Fora de um `<cao-accordion>`, o item se comporta como um cartão expansível independente.
1188
+
1189
+ ---
1190
+ ### `CaoAvatarComponent`
1191
+
1192
+ Avatar para representar usuários ou entidades, com imagem, ícone (Lucide ou imagem) ou texto (iniciais). Possui imagem padrão embutida, usada enquanto nenhuma fonte for informada ou quando a imagem falha ao carregar. Tamanho, formato e contorno (stroke) são configuráveis.
1193
+
1194
+ **Seletor:** `<cao-avatar>`
1195
+
1196
+ **Tipos**
1197
+
1198
+ | Tipo | Valores |
1199
+ | --- | --- |
1200
+ | `CaoAvatarPresetSize` | `'small'` (24px) \| `'normal'` (32px) \| `'large'` (48px) \| `'xlarge'` (64px) |
1201
+ | `CaoAvatarShape` | `'circle'` \| `'rounded'` \| `'square'` |
1202
+ | `CaoAvatarStrokeStyle` | `'solid'` \| `'dashed'` \| `'dotted'` \| `'double'` |
1203
+
1204
+ **Atributos (Inputs)**
1205
+
1206
+ | Atributo | Tipo | Padrão | Descrição |
1207
+ | --- | --- | --- | --- |
1208
+ | `src` | `string \| null \| undefined` | `''` | URL da imagem. Se vazia ou se falhar ao carregar, o avatar usa `icon`, `label` ou a imagem padrão (nessa ordem). |
1209
+ | `defaultSrc` | `string` | `''` | Imagem padrão customizada. Se vazia, usa a silhueta embutida (`CAO_AVATAR_DEFAULT_SRC`). |
1210
+ | `label` | `string` | `''` | Texto exibido (ex.: iniciais) quando não há imagem nem ícone. |
1211
+ | `icon` | `string` | `''` | Nome do ícone Lucide ou caminho/URL de imagem usada como ícone. |
1212
+ | `isLucideIcon` | `boolean` | `true` | Define se `icon` é um ícone Lucide. |
1213
+ | `iconColor` | `string` | `''` | Cor do ícone Lucide. Se vazia, usa `textColor`. |
1214
+ | `size` | `CaoAvatarPresetSize \| number \| string` | `'normal'` | Tamanho predefinido, número em px ou texto (`'72px'`, `'4.5rem'`). Valores inválidos voltam para `'normal'`. |
1215
+ | `shape` | `CaoAvatarShape` | `'circle'` | Formato do avatar. |
1216
+ | `strokeWidth` | `number \| string` | `0` | Espessura do contorno. Número é convertido para `px`; `0` remove o contorno. |
1217
+ | `strokeColor` | `string` | `'#ffffff'` | Cor do contorno. |
1218
+ | `strokeStyle` | `CaoAvatarStrokeStyle` | `'solid'` | Estilo do contorno. |
1219
+ | `bgColor` | `string` | `''` | Cor de fundo (sobrescreve `--cao-avatar-bg`). |
1220
+ | `textColor` | `string` | `''` | Cor do texto/ícone (sobrescreve `--cao-avatar-text`). |
1221
+ | `alt` | `string` | `''` | Texto alternativo do avatar. |
1222
+ | `ariaLabel` | `string` | `''` | `aria-label` do avatar. Prioridade: `ariaLabel` → `alt` → `label` → `'Avatar'`. |
1223
+ | `dataCy` | `string` | `''` | Atributo para testes E2E com Cypress. |
1224
+
1225
+ **Ordem de exibição**
1226
+
1227
+ 1. `src` (se informado e carregado com sucesso);
1228
+ 2. `icon`;
1229
+ 3. `label`;
1230
+ 4. imagem padrão (`defaultSrc` ou a silhueta embutida).
1231
+
1232
+ Se o `src` falhar ao carregar (erro 404, URL inválida etc.), o componente passa automaticamente para o próximo item da lista.
1233
+
1234
+ **Constantes exportadas**
1235
+
1236
+ | Constante | Descrição |
1237
+ | --- | --- |
1238
+ | `CAO_AVATAR_DEFAULT_SRC` | Data URI da imagem padrão (silhueta em SVG, funciona offline). |
1239
+ | `CAO_AVATAR_SIZES` | Mapa dos tamanhos predefinidos em px (`small`, `normal`, `large`, `xlarge`). |
1240
+
1241
+ **CSS Custom Properties**
1242
+
1243
+ | Propriedade | Padrão | Descrição |
1244
+ | --- | --- | --- |
1245
+ | `--cao-avatar-bg` | `#e5e7eb` | Cor de fundo. |
1246
+ | `--cao-avatar-text` | `#374151` | Cor do texto/ícone. |
1247
+ | `--cao-avatar-radius` | `25%` | Raio da borda no formato `rounded`. |
1248
+
1249
+ **Exemplo básico:**
1250
+
1251
+ ```html
1252
+ <!-- Sem src: exibe a imagem padrão -->
1253
+ <cao-avatar></cao-avatar>
1254
+
1255
+ <!-- Com imagem -->
1256
+ <cao-avatar src="https://exemplo.com/foto.png" alt="Foto de Maria" size="large"></cao-avatar>
1257
+
1258
+ <!-- Com iniciais -->
1259
+ <cao-avatar label="MB" bgColor="#eef2ff" textColor="#4338ca"></cao-avatar>
1260
+
1261
+ <!-- Com ícone Lucide -->
1262
+ <cao-avatar icon="user" bgColor="#dcfce7" iconColor="#166534"></cao-avatar>
1263
+ ```
1264
+
1265
+ **Exemplo com tamanho, formato e contorno:**
1266
+
1267
+ ```html
1268
+ <cao-avatar src="assets/foto.png" size="xlarge" shape="rounded"></cao-avatar>
1269
+ <cao-avatar src="assets/foto.png" [size]="96" shape="square"></cao-avatar>
1270
+ <cao-avatar src="assets/foto.png" size="7rem"></cao-avatar>
1271
+
1272
+ <cao-avatar
1273
+ src="assets/foto.png"
1274
+ size="xlarge"
1275
+ [strokeWidth]="3"
1276
+ strokeColor="#4f46e5"
1277
+ strokeStyle="dashed">
1278
+ </cao-avatar>
1279
+ ```
1280
+
1281
+ **Exemplo com imagem padrão customizada:**
1282
+
1283
+ ```html
1284
+ <cao-avatar [src]="usuario.foto" defaultSrc="assets/avatar-padrao.png"></cao-avatar>
1285
+ ```
1286
+
1287
+ **Observações:**
1288
+
1289
+ - Possui `role="img"` com `aria-label`; a imagem interna é decorativa (`alt=""`), evitando leitura duplicada.
1290
+ - A imagem padrão é um SVG em data URI e passa por `DomSanitizer.bypassSecurityTrustUrl` (conteúdo controlado pela lib). Data URIs em SVG informadas em `src` **não** recebem esse tratamento e podem ser bloqueadas pelo sanitizador do Angular — use URL, caminho de arquivo ou PNG/JPEG em base64.
1291
+ - Para ícones Lucide, registre os ícones usados com `provideLucideIcons` (de `@lucide/angular`).
1292
+ - Depende de `BaseIcon` (copie junto ao usar `cao-comp`).
1293
+ ---
934
1294
  ### `CaoSlideToggleComponent`
935
1295
 
936
1296
  Um switch (slide toggle) acessível e customizável, com suporte a `ngModel` e formulários reativos via `ControlValueAccessor`. O visual é construído com trilho e thumb animados, sem depender do Material em runtime.
package/cli/cao-comp.cjs CHANGED
@@ -185,7 +185,7 @@ import { fn } from 'storybook/test';
185
185
  import { CaoBaseButtonComponent } from '../../app/components/base-button/base-button.component';
186
186
 
187
187
  const meta: Meta<CaoBaseButtonComponent> = {
188
- title: 'Components/Base Button',
188
+ title: 'Componentes/Base Button',
189
189
  component: CaoBaseButtonComponent,
190
190
  tags: ['autodocs'],
191
191
  args: { buttonClick: fn() },
@@ -327,18 +327,18 @@ function setupStorybook(destination, force) {
327
327
  if (conflicts.length) {
328
328
  process.stderr.write(
329
329
  `Erro: os seguintes arquivos ja existem no destino (use --force para sobrescrever):\n` +
330
- conflicts.map((c) => ` - ${c}`).join('\n') +
331
- '\n'
330
+ conflicts.map((c) => ` - ${c}`).join('\n') +
331
+ '\n'
332
332
  );
333
333
  return 1;
334
334
  }
335
335
 
336
336
  process.stdout.write(
337
337
  `Setup de Storybook gerado em "${root}".\n` +
338
- `Arquivos criados:\n` +
339
- created.map((c) => ` - ${c}`).join('\n') +
340
- '\n' +
341
- `Leia ${path.join(root, 'STORYBOOK-SETUP.md')} para instalar as dependencias e rodar.\n`
338
+ `Arquivos criados:\n` +
339
+ created.map((c) => ` - ${c}`).join('\n') +
340
+ '\n' +
341
+ `Leia ${path.join(root, 'STORYBOOK-SETUP.md')} para instalar as dependencias e rodar.\n`
342
342
  );
343
343
  return 0;
344
344
  }
@@ -429,7 +429,7 @@ function main() {
429
429
  const available = listComponents(templatesDir).join(', ');
430
430
  process.stderr.write(
431
431
  `Erro: componente "${component}" nao encontrado.\n` +
432
- `Componentes disponiveis: ${available}\n`
432
+ `Componentes disponiveis: ${available}\n`
433
433
  );
434
434
  return 1;
435
435
  }
@@ -441,8 +441,8 @@ function main() {
441
441
  if (conflicts.length) {
442
442
  process.stderr.write(
443
443
  `Erro: os seguintes arquivos ja existem no destino (use --force para sobrescrever):\n` +
444
- conflicts.map((c) => ` - ${c}`).join('\n') +
445
- '\n'
444
+ conflicts.map((c) => ` - ${c}`).join('\n') +
445
+ '\n'
446
446
  );
447
447
  return 1;
448
448
  }