@seedgrid/ai-toolkit 0.0.0-stage → 0.3.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 (225) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +151 -2
  3. package/dist/adapters/claude.js +114 -0
  4. package/dist/adapters/codex.js +108 -0
  5. package/dist/adapters/index.js +17 -0
  6. package/dist/adapters/shared.js +142 -0
  7. package/dist/adapters/types.js +1 -0
  8. package/dist/cli.js +203 -0
  9. package/dist/commands/common.js +98 -0
  10. package/dist/commands/doctor.js +290 -0
  11. package/dist/commands/init.js +9 -0
  12. package/dist/commands/install.js +107 -0
  13. package/dist/commands/remove.js +54 -0
  14. package/dist/commands/review.js +127 -0
  15. package/dist/commands/status.js +73 -0
  16. package/dist/commands/update.js +8 -0
  17. package/dist/commands/validate.js +27 -0
  18. package/dist/core/apply.js +181 -0
  19. package/dist/core/blocks.js +64 -0
  20. package/dist/core/content.js +528 -0
  21. package/dist/core/env.js +40 -0
  22. package/dist/core/frontmatter.js +29 -0
  23. package/dist/core/hash.js +14 -0
  24. package/dist/core/inspect.js +51 -0
  25. package/dist/core/lock.js +124 -0
  26. package/dist/core/paths.js +65 -0
  27. package/dist/core/plan.js +242 -0
  28. package/dist/core/tools.js +62 -0
  29. package/dist/core/types.js +11 -0
  30. package/dist/core/updates.js +121 -0
  31. package/docs/arquitetura.md +80 -0
  32. package/docs/compatibilidade.md +50 -0
  33. package/docs/formato.md +155 -0
  34. package/docs/instalacao.md +105 -0
  35. package/docs/manutencao.md +115 -0
  36. package/package.json +43 -4
  37. package/seedgridKB/SeedGrid/Extensions/Catalogo-de-enums.md +161 -0
  38. package/seedgridKB/SeedGrid/Extensions/Catalogo-de-propriedades.md +971 -0
  39. package/seedgridKB/SeedGrid/Extensions/Indice.md +63 -0
  40. package/seedgridKB/SeedGrid/Extensions/ai-pricing/Configuracao.md +124 -0
  41. package/seedgridKB/SeedGrid/Extensions/ai-pricing/Enums.md +40 -0
  42. package/seedgridKB/SeedGrid/Extensions/ai-pricing/Exemplos.md +97 -0
  43. package/seedgridKB/SeedGrid/Extensions/ai-pricing/Visao-geral.md +114 -0
  44. package/seedgridKB/SeedGrid/Extensions/apikeys/Configuracao-Rust.md +69 -0
  45. package/seedgridKB/SeedGrid/Extensions/apikeys/Configuracao.md +88 -0
  46. package/seedgridKB/SeedGrid/Extensions/apikeys/Enums.md +33 -0
  47. package/seedgridKB/SeedGrid/Extensions/apikeys/Exemplos.md +121 -0
  48. package/seedgridKB/SeedGrid/Extensions/apikeys/Rust.md +126 -0
  49. package/seedgridKB/SeedGrid/Extensions/apikeys/Visao-geral.md +111 -0
  50. package/seedgridKB/SeedGrid/Extensions/audit/Configuracao-Rust.md +93 -0
  51. package/seedgridKB/SeedGrid/Extensions/audit/Configuracao.md +127 -0
  52. package/seedgridKB/SeedGrid/Extensions/audit/Enums.md +66 -0
  53. package/seedgridKB/SeedGrid/Extensions/audit/Exemplos.md +151 -0
  54. package/seedgridKB/SeedGrid/Extensions/audit/Rust.md +120 -0
  55. package/seedgridKB/SeedGrid/Extensions/audit/Visao-geral.md +114 -0
  56. package/seedgridKB/SeedGrid/Extensions/backup/Configuracao-Rust.md +136 -0
  57. package/seedgridKB/SeedGrid/Extensions/backup/Configuracao.md +319 -0
  58. package/seedgridKB/SeedGrid/Extensions/backup/Enums.md +131 -0
  59. package/seedgridKB/SeedGrid/Extensions/backup/Exemplos.md +210 -0
  60. package/seedgridKB/SeedGrid/Extensions/backup/Rust.md +135 -0
  61. package/seedgridKB/SeedGrid/Extensions/backup/Visao-geral.md +150 -0
  62. package/seedgridKB/SeedGrid/Extensions/billing/Configuracao-Rust.md +86 -0
  63. package/seedgridKB/SeedGrid/Extensions/billing/Configuracao.md +243 -0
  64. package/seedgridKB/SeedGrid/Extensions/billing/Enums.md +165 -0
  65. package/seedgridKB/SeedGrid/Extensions/billing/Exemplos.md +205 -0
  66. package/seedgridKB/SeedGrid/Extensions/billing/Rust.md +109 -0
  67. package/seedgridKB/SeedGrid/Extensions/billing/Visao-geral.md +181 -0
  68. package/seedgridKB/SeedGrid/Extensions/broker/Configuracao-Rust.md +40 -0
  69. package/seedgridKB/SeedGrid/Extensions/broker/Visao-geral.md +114 -0
  70. package/seedgridKB/SeedGrid/Extensions/cache/Configuracao-Rust.md +73 -0
  71. package/seedgridKB/SeedGrid/Extensions/cache/Configuracao.md +112 -0
  72. package/seedgridKB/SeedGrid/Extensions/cache/Enums.md +36 -0
  73. package/seedgridKB/SeedGrid/Extensions/cache/Exemplos.md +149 -0
  74. package/seedgridKB/SeedGrid/Extensions/cache/Rust.md +81 -0
  75. package/seedgridKB/SeedGrid/Extensions/cache/Visao-geral.md +90 -0
  76. package/seedgridKB/SeedGrid/Extensions/commons/Configuracao.md +107 -0
  77. package/seedgridKB/SeedGrid/Extensions/commons/Enums.md +105 -0
  78. package/seedgridKB/SeedGrid/Extensions/commons/Exemplos.md +141 -0
  79. package/seedgridKB/SeedGrid/Extensions/commons/Visao-geral.md +99 -0
  80. package/seedgridKB/SeedGrid/Extensions/exchange/Configuracao.md +122 -0
  81. package/seedgridKB/SeedGrid/Extensions/exchange/Enums.md +29 -0
  82. package/seedgridKB/SeedGrid/Extensions/exchange/Exemplos.md +82 -0
  83. package/seedgridKB/SeedGrid/Extensions/exchange/Visao-geral.md +118 -0
  84. package/seedgridKB/SeedGrid/Extensions/filemanagement/Configuracao-Rust.md +110 -0
  85. package/seedgridKB/SeedGrid/Extensions/filemanagement/Configuracao.md +157 -0
  86. package/seedgridKB/SeedGrid/Extensions/filemanagement/Exemplos.md +157 -0
  87. package/seedgridKB/SeedGrid/Extensions/filemanagement/Rust.md +70 -0
  88. package/seedgridKB/SeedGrid/Extensions/filemanagement/Visao-geral.md +88 -0
  89. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Configuracao-Rust.md +124 -0
  90. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Configuracao.md +195 -0
  91. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Enums.md +71 -0
  92. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Exemplos.md +149 -0
  93. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Rust.md +139 -0
  94. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Visao-geral.md +130 -0
  95. package/seedgridKB/SeedGrid/Extensions/notification/Configuracao.md +141 -0
  96. package/seedgridKB/SeedGrid/Extensions/notification/Enums.md +52 -0
  97. package/seedgridKB/SeedGrid/Extensions/notification/Exemplos.md +141 -0
  98. package/seedgridKB/SeedGrid/Extensions/notification/Visao-geral.md +113 -0
  99. package/seedgridKB/SeedGrid/Extensions/privacy/Configuracao-Rust.md +67 -0
  100. package/seedgridKB/SeedGrid/Extensions/privacy/Configuracao.md +94 -0
  101. package/seedgridKB/SeedGrid/Extensions/privacy/Enums.md +79 -0
  102. package/seedgridKB/SeedGrid/Extensions/privacy/Exemplos.md +172 -0
  103. package/seedgridKB/SeedGrid/Extensions/privacy/Rust.md +107 -0
  104. package/seedgridKB/SeedGrid/Extensions/privacy/Visao-geral.md +90 -0
  105. package/seedgridKB/SeedGrid/Extensions/realtime/Configuracao-Rust.md +72 -0
  106. package/seedgridKB/SeedGrid/Extensions/realtime/Configuracao.md +104 -0
  107. package/seedgridKB/SeedGrid/Extensions/realtime/Exemplos.md +104 -0
  108. package/seedgridKB/SeedGrid/Extensions/realtime/Rust.md +69 -0
  109. package/seedgridKB/SeedGrid/Extensions/realtime/Visao-geral.md +105 -0
  110. package/seedgridKB/SeedGrid/Extensions/resilience/Configuracao-Rust.md +68 -0
  111. package/seedgridKB/SeedGrid/Extensions/resilience/Configuracao.md +186 -0
  112. package/seedgridKB/SeedGrid/Extensions/resilience/Enums.md +96 -0
  113. package/seedgridKB/SeedGrid/Extensions/resilience/Exemplos.md +229 -0
  114. package/seedgridKB/SeedGrid/Extensions/resilience/Rust.md +80 -0
  115. package/seedgridKB/SeedGrid/Extensions/resilience/Visao-geral.md +112 -0
  116. package/seedgridKB/SeedGrid/Extensions/runtime/Configuracao-Rust.md +90 -0
  117. package/seedgridKB/SeedGrid/Extensions/runtime/Visao-geral.md +114 -0
  118. package/seedgridKB/SeedGrid/Extensions/security/Configuracao-Rust.md +327 -0
  119. package/seedgridKB/SeedGrid/Extensions/security/Configuracao.md +510 -0
  120. package/seedgridKB/SeedGrid/Extensions/security/Enums.md +95 -0
  121. package/seedgridKB/SeedGrid/Extensions/security/Exemplos.md +218 -0
  122. package/seedgridKB/SeedGrid/Extensions/security/Rust.md +203 -0
  123. package/seedgridKB/SeedGrid/Extensions/security/Visao-geral.md +131 -0
  124. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Configuracao-Rust.md +188 -0
  125. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Configuracao.md +345 -0
  126. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Enums.md +117 -0
  127. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Exemplos.md +205 -0
  128. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Rust.md +161 -0
  129. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Visao-geral.md +142 -0
  130. package/seedgridKB/SeedGrid/Extensions/whatsapp/Configuracao-Rust.md +75 -0
  131. package/seedgridKB/SeedGrid/Extensions/whatsapp/Configuracao.md +152 -0
  132. package/seedgridKB/SeedGrid/Extensions/whatsapp/Enums.md +198 -0
  133. package/seedgridKB/SeedGrid/Extensions/whatsapp/Exemplos.md +173 -0
  134. package/seedgridKB/SeedGrid/Extensions/whatsapp/Rust.md +83 -0
  135. package/seedgridKB/SeedGrid/Extensions/whatsapp/Visao-geral.md +99 -0
  136. package/seedgridKB/SeedGrid/Mapa-dos-repositorios.md +112 -0
  137. package/seedgridKB/SeedGrid/SeedGrid-components/Indice.md +323 -0
  138. package/seedgridKB/SeedGrid/SeedGrid-components/buttons/API.md +257 -0
  139. package/seedgridKB/SeedGrid/SeedGrid-components/buttons/Exemplos.md +307 -0
  140. package/seedgridKB/SeedGrid/SeedGrid-components/buttons/Visao-geral.md +51 -0
  141. package/seedgridKB/SeedGrid/SeedGrid-components/datatable/API.md +174 -0
  142. package/seedgridKB/SeedGrid/SeedGrid-components/datatable/Exemplos.md +236 -0
  143. package/seedgridKB/SeedGrid/SeedGrid-components/datatable/Visao-geral.md +76 -0
  144. package/seedgridKB/SeedGrid/SeedGrid-components/digits/API.md +339 -0
  145. package/seedgridKB/SeedGrid/SeedGrid-components/digits/Exemplos.md +311 -0
  146. package/seedgridKB/SeedGrid/SeedGrid-components/digits/Visao-geral.md +57 -0
  147. package/seedgridKB/SeedGrid/SeedGrid-components/editor/API.md +125 -0
  148. package/seedgridKB/SeedGrid/SeedGrid-components/editor/Exemplos.md +116 -0
  149. package/seedgridKB/SeedGrid/SeedGrid-components/editor/Visao-geral.md +86 -0
  150. package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/API.md +490 -0
  151. package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/Exemplos.md +544 -0
  152. package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/Visao-geral.md +69 -0
  153. package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/API.md +113 -0
  154. package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/Exemplos.md +159 -0
  155. package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/Visao-geral.md +92 -0
  156. package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/API.md +516 -0
  157. package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/Exemplos.md +629 -0
  158. package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/Visao-geral.md +80 -0
  159. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/API.md +615 -0
  160. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/Exemplos.md +384 -0
  161. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/Visao-geral.md +111 -0
  162. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/API.md +661 -0
  163. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/Exemplos.md +312 -0
  164. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/Visao-geral.md +123 -0
  165. package/seedgridKB/SeedGrid/SeedGrid-components/layout/API.md +1090 -0
  166. package/seedgridKB/SeedGrid/SeedGrid-components/layout/Exemplos.md +1172 -0
  167. package/seedgridKB/SeedGrid/SeedGrid-components/layout/Visao-geral.md +98 -0
  168. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/Visao-geral.md +98 -0
  169. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-apikeys.md +118 -0
  170. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-audit.md +88 -0
  171. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-backup.md +131 -0
  172. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-billing-platform.md +132 -0
  173. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-billing-user.md +120 -0
  174. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-login-tenancy.md +119 -0
  175. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-security.md +427 -0
  176. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-self-enter.md +104 -0
  177. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-subdomain-tenancy.md +110 -0
  178. package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/API.md +490 -0
  179. package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/Exemplos.md +561 -0
  180. package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/Visao-geral.md +82 -0
  181. package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/Visao-geral.md +68 -0
  182. package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-commons.md +61 -0
  183. package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-core.md +140 -0
  184. package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-playground.md +112 -0
  185. package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-theme.md +97 -0
  186. package/seedgridKB/SeedGrid/SeedGrid-components/providers/API.md +177 -0
  187. package/seedgridKB/SeedGrid/SeedGrid-components/providers/Exemplos.md +332 -0
  188. package/seedgridKB/SeedGrid/SeedGrid-components/providers/Visao-geral.md +106 -0
  189. package/seedgridKB/SeedGrid/SeedGrid-components/showcase.md +70 -0
  190. package/seedgridKB/SeedGrid/Toolkit/agents/arquiteto.md +53 -0
  191. package/seedgridKB/SeedGrid/Toolkit/agents/backend-java.md +45 -0
  192. package/seedgridKB/SeedGrid/Toolkit/agents/backend-rust.md +43 -0
  193. package/seedgridKB/SeedGrid/Toolkit/agents/frontend-react.md +41 -0
  194. package/seedgridKB/SeedGrid/Toolkit/agents/qa.md +44 -0
  195. package/seedgridKB/SeedGrid/Toolkit/agents/revisor.md +40 -0
  196. package/seedgridKB/SeedGrid/Toolkit/references/fluxo-de-trabalho.md +78 -0
  197. package/seedgridKB/SeedGrid/Toolkit/references/glossario.md +15 -0
  198. package/seedgridKB/SeedGrid/Toolkit/references/modos-shared-native.md +27 -0
  199. package/seedgridKB/SeedGrid/Toolkit/rules/backend-java-seedgrid.md +54 -0
  200. package/seedgridKB/SeedGrid/Toolkit/rules/coordenacao.md +39 -0
  201. package/seedgridKB/SeedGrid/Toolkit/rules/formato-entrega.md +29 -0
  202. package/seedgridKB/SeedGrid/Toolkit/rules/frontend-seedgrid.md +47 -0
  203. package/seedgridKB/SeedGrid/Toolkit/rules/personalizacao-local.md +22 -0
  204. package/seedgridKB/SeedGrid/Toolkit/skills/planejar-mudanca/SKILL.md +38 -0
  205. package/seedgridKB/SeedGrid/Toolkit/skills/revisar-codigo/SKILL.md +33 -0
  206. package/seedgridKB/SeedGrid/Toolkit/skills/revisar-codigo/references/checklist.md +25 -0
  207. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-backend-crud/SKILL.md +29 -0
  208. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-bump/SKILL.md +26 -0
  209. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/SKILL.md +221 -0
  210. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/agents/openai.yaml +4 -0
  211. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/checklist.md +31 -0
  212. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/patterns.md +185 -0
  213. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/routing.md +66 -0
  214. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/SKILL.md +56 -0
  215. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/agents/openai.yaml +4 -0
  216. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/references/checklist.md +32 -0
  217. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/references/steps.md +114 -0
  218. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-review/SKILL.md +61 -0
  219. package/seedgridKB/SeedGrid/Toolkit/skills/validar-mudanca/SKILL.md +29 -0
  220. package/seedgridKB/SeedGrid/Toolkit/templates/decisao-arquitetura.md +29 -0
  221. package/seedgridKB/SeedGrid/Toolkit/templates/especificacao-tarefa.md +32 -0
  222. package/seedgridKB/SeedGrid/Toolkit/templates/relatorio-validacao.md +30 -0
  223. package/seedgridKB/SeedGrid/Versoes.md +64 -0
  224. package/seedgridKB/SeedGrid/Visao-geral.md +35 -0
  225. package/seedgridKB/manifest.json +142 -0
@@ -0,0 +1,544 @@
1
+ ---
2
+ tags: [seedgrid, front, component, feedback-e-exibicao]
3
+ fonte: front/seedgrid-fe-components/apps/showcase/src/app/components
4
+ branch: main
5
+ commit: ad30fc11de
6
+ analisado-em: 2026-10-14
7
+ ---
8
+
9
+ # Exemplos — feedback e exibição
10
+
11
+ Copiados 1:1 dos `samples/*.tsx.sample` do showcase e verificados com type-check (TypeScript `strict`) contra `packages/seedgrid-fe-components/src/index.ts` em 2026-10-14 — todos sem erros. API: [[SeedGrid/SeedGrid-components/feedback-e-exibicao/API|API de feedback e exibição]] · Visão geral: [[SeedGrid/SeedGrid-components/feedback-e-exibicao/Visao-geral|Feedback e exibição]].
12
+
13
+ ## SgAvatar e SgAvatarGroup
14
+
15
+ ### Básico
16
+
17
+ Iniciais (`label`), ícone e imagem.
18
+
19
+ Fonte: `front/seedgrid-fe-components/apps/showcase/src/app/components/sg-avatar/samples/basico.tsx.sample`
20
+
21
+ ```tsx
22
+ import React from "react";
23
+ import { User } from "lucide-react";
24
+ import { SgAvatar } from "@seedgrid/fe-components";
25
+
26
+ export default function Example() {
27
+ return (
28
+ <div className="flex flex-wrap items-center gap-4">
29
+ <SgAvatar label="P" />
30
+ <SgAvatar icon={<User />} severity="secondary" />
31
+ <SgAvatar src="https://i.pravatar.cc/150?img=32" alt="Amy Elsner" />
32
+ </div>
33
+ );
34
+ }
35
+ ```
36
+
37
+ ### Grupo com excedentes
38
+
39
+ O segundo grupo mostra 3 avatares e `+3` (`total={6}`), com o contador em `moreSeverity="secondary"`. Note que `size="sm"` é repetido em cada filho porque o grupo só o aplica ao contador.
40
+
41
+ Fonte: `front/seedgrid-fe-components/apps/showcase/src/app/components/sg-avatar/samples/avatar-group.tsx.sample`
42
+
43
+ ```tsx
44
+ import React from "react";
45
+ import { Users } from "lucide-react";
46
+ import { SgAvatar, SgAvatarGroup } from "@seedgrid/fe-components";
47
+
48
+ export default function Example() {
49
+ return (
50
+ <div className="space-y-4">
51
+ <SgAvatarGroup>
52
+ <SgAvatar src="https://i.pravatar.cc/150?img=32" />
53
+ <SgAvatar src="https://i.pravatar.cc/150?img=47" />
54
+ <SgAvatar src="https://i.pravatar.cc/150?img=12" />
55
+ <SgAvatar src="https://i.pravatar.cc/150?img=56" />
56
+ </SgAvatarGroup>
57
+ <SgAvatarGroup max={3} total={6} size="sm" moreSeverity="secondary">
58
+ <SgAvatar icon={<Users />} severity="info" size="sm" />
59
+ <SgAvatar label="AL" severity="success" size="sm" />
60
+ <SgAvatar label="BK" severity="warning" size="sm" />
61
+ <SgAvatar label="CM" severity="danger" size="sm" />
62
+ </SgAvatarGroup>
63
+ </div>
64
+ );
65
+ }
66
+ ```
67
+
68
+ ## SgBadge
69
+
70
+ ### Contador e ponto
71
+
72
+ `max` gera `99+`; `dot` com `pulse`.
73
+
74
+ Fonte: `front/seedgrid-fe-components/apps/showcase/src/app/components/sg-badge/samples/counter.tsx.sample`
75
+
76
+ ```tsx
77
+ import React from "react";
78
+ import { SgBadge } from "@seedgrid/fe-components";
79
+
80
+ export default function Example() {
81
+ return (
82
+ <>
83
+ <SgBadge value={3} severity="danger" />
84
+ <SgBadge value={120} max={99} severity="danger" />
85
+ <SgBadge dot severity="success" />
86
+ <SgBadge dot severity="success" pulse />
87
+ </>
88
+ );
89
+ }
90
+ ```
91
+
92
+ ### Remoção
93
+
94
+ `autoRemove` oculta o badge sozinho; sem ele, o pai controla a visibilidade em `onRemove`.
95
+
96
+ Fonte: `front/seedgrid-fe-components/apps/showcase/src/app/components/sg-badge/samples/actions.tsx.sample`
97
+
98
+ ```tsx
99
+ import React from "react";
100
+ import { SgBadge } from "@seedgrid/fe-components";
101
+
102
+ export default function Example() {
103
+ const [visible, setVisible] = React.useState(true);
104
+ return (
105
+ <>
106
+ <SgBadge value="Remover auto" removable autoRemove onRemove={() => alert("onRemove")} />
107
+ {visible ? (
108
+ <SgBadge
109
+ value="Remover manual"
110
+ removable
111
+ autoRemove={false}
112
+ onRemove={() => {
113
+ alert("onRemove");
114
+ setVisible(false);
115
+ }}
116
+ />
117
+ ) : null}
118
+ </>
119
+ );
120
+ }
121
+ ```
122
+
123
+ ## SgBadgeOverlay
124
+
125
+ Fonte: `front/seedgrid-fe-components/apps/showcase/src/app/components/sg-badge-overlay/samples/basico.tsx.sample`
126
+
127
+ ```tsx
128
+ import React from "react";
129
+ import { SgBadge, SgBadgeOverlay } from "@seedgrid/fe-components";
130
+
131
+ export default function Example() {
132
+ return (
133
+ <>
134
+ <SgBadgeOverlay badge={<SgBadge value={7} severity="danger" size="xs" />} style={{ borderRadius: 12, padding: 2 }}>
135
+ <span className="inline-flex size-10 items-center justify-center rounded-lg border">Bell</span>
136
+ </SgBadgeOverlay>
137
+ <SgBadgeOverlay badge={<SgBadge dot severity="success" />}>
138
+ <span className="inline-flex size-10 items-center justify-center rounded-lg border">Check</span>
139
+ </SgBadgeOverlay>
140
+ </>
141
+ );
142
+ }
143
+ ```
144
+
145
+ ## SgSkeleton
146
+
147
+ ### Placeholder de card
148
+
149
+ Fonte: `front/seedgrid-fe-components/apps/showcase/src/app/components/sg-skeleton/samples/card-placeholder.tsx.sample`
150
+
151
+ ```tsx
152
+ import * as React from "react";
153
+ import { SgSkeleton } from "@seedgrid/fe-components";
154
+
155
+ export default function Example() {
156
+ return (
157
+ <div className="w-full max-w-sm rounded-xl border border-border p-4">
158
+ <SgSkeleton shape="rounded" height={160} />
159
+ <div className="mt-4 space-y-2">
160
+ <SgSkeleton shape="text" width="60%" />
161
+ <SgSkeleton shape="text" />
162
+ <SgSkeleton shape="text" width="82%" />
163
+ </div>
164
+ </div>
165
+ );
166
+ }
167
+ ```
168
+
169
+ ## SgToaster e `toast`
170
+
171
+ ### Configuração base
172
+
173
+ Monte um `SgToaster` e dispare com `toast.*`; `toast.dismiss()` fecha todos.
174
+
175
+ Fonte: `front/seedgrid-fe-components/apps/showcase/src/app/components/sg-toaster/samples/base-setup.tsx.sample`
176
+
177
+ ```tsx
178
+ "use client";
179
+
180
+ import { SgButton, SgToaster, toast } from "@seedgrid/fe-components";
181
+
182
+ export default function Example() {
183
+ return (
184
+ <div className="space-y-3">
185
+ <SgToaster />
186
+ <div className="flex flex-wrap gap-2">
187
+ <SgButton onClick={() => toast.message("Mensagem básica")}>toast.message</SgButton>
188
+ <SgButton severity="success" onClick={() => toast.success("Sucesso!")}>
189
+ toast.success
190
+ </SgButton>
191
+ <SgButton appearance="outline" onClick={() => toast.dismiss()}>
192
+ toast.dismiss
193
+ </SgButton>
194
+ </div>
195
+ </div>
196
+ );
197
+ }
198
+ ```
199
+
200
+ ### Opções por toast
201
+
202
+ `description`, `duration`, `closeButton`, `className` e `style` por chamada.
203
+
204
+ Fonte: `front/seedgrid-fe-components/apps/showcase/src/app/components/sg-toaster/samples/options-per-toast.tsx.sample`
205
+
206
+ ```tsx
207
+ "use client";
208
+
209
+ import { SgButton, SgToaster, toast } from "@seedgrid/fe-components";
210
+
211
+ export default function Example() {
212
+ return (
213
+ <div className="space-y-3">
214
+ <SgToaster />
215
+ <SgButton
216
+ onClick={() =>
217
+ toast.info("Toast com opções", {
218
+ description: "10s de duração, sem closeButton e com estilo customizado.",
219
+ duration: 10000,
220
+ closeButton: false,
221
+ className: "border-[#c56a2d]",
222
+ style: {
223
+ background: "#fff7f1",
224
+ color: "#5b3b23"
225
+ }
226
+ })
227
+ }
228
+ >
229
+ Trigger toast with options
230
+ </SgButton>
231
+ </div>
232
+ );
233
+ }
234
+ ```
235
+
236
+ ### `toast.promise`
237
+
238
+ Loading → sucesso/erro no mesmo toast; o erro é relançado (por isso o `try/catch`).
239
+
240
+ Fonte: `front/seedgrid-fe-components/apps/showcase/src/app/components/sg-toaster/samples/toast-promise.tsx.sample`
241
+
242
+ ```tsx
243
+ "use client";
244
+
245
+ import { SgButton, SgToaster, toast } from "@seedgrid/fe-components";
246
+
247
+ export default function Example() {
248
+ async function runDemo() {
249
+ const task = async () => {
250
+ await new Promise((resolve) => setTimeout(resolve, 1200));
251
+ if (Math.random() < 0.35) {
252
+ throw new Error("Erro aleatório da demo");
253
+ }
254
+ return { id: "ORD-2026-001" };
255
+ };
256
+
257
+ try {
258
+ await toast.promise(task, {
259
+ loading: "Salvando pedido...",
260
+ success: (value) => `Pedido salvo: ${value.id}`,
261
+ error: (error) => `Falha: ${error instanceof Error ? error.message : "erro"}`
262
+ });
263
+ } catch {
264
+ // a notificação já foi tratada pelo helper
265
+ }
266
+ }
267
+
268
+ return (
269
+ <div className="space-y-3">
270
+ <SgToaster />
271
+ <SgButton onClick={runDemo}>Run promise demo</SgButton>
272
+ </div>
273
+ );
274
+ }
275
+ ```
276
+
277
+ ### Assinando o store
278
+
279
+ O retorno de `subscribeSgToasts` é a função de limpeza do efeito.
280
+
281
+ Fonte: `front/seedgrid-fe-components/apps/showcase/src/app/components/sg-toaster/samples/subscribe-effect.tsx.sample`
282
+
283
+ ```tsx
284
+ "use client";
285
+
286
+ import * as React from "react";
287
+ import { SgButton, SgToaster, subscribeSgToasts, toast } from "@seedgrid/fe-components";
288
+
289
+ export default function Example() {
290
+ const [total, setTotal] = React.useState(0);
291
+
292
+ // O retorno de subscribeSgToasts e' a propria funcao de limpeza, entao ele pode ser
293
+ // devolvido direto do efeito: a inscricao morre junto com o componente.
294
+ React.useEffect(() => subscribeSgToasts((toasts) => setTotal(toasts.length)), []);
295
+
296
+ return (
297
+ <div className="space-y-3">
298
+ <SgToaster />
299
+ <div className="flex flex-wrap items-center gap-2">
300
+ <SgButton onClick={() => toast.message("Mais um", { duration: 0 })}>Abrir toast</SgButton>
301
+ <span className="text-sm text-muted-foreground">{total} toast(s) abertos</span>
302
+ </div>
303
+ </div>
304
+ );
305
+ }
306
+ ```
307
+
308
+ ## SgToastHost
309
+
310
+ ### Prioridade entre hosts
311
+
312
+ Dois hosts montados: o mais profundo/último montado (`bottom-right`) renderiza os toasts.
313
+
314
+ Fonte: `front/seedgrid-fe-components/apps/showcase/src/app/components/sg-toast-host/samples/prioridade-layout-vs-pagina.tsx.sample`
315
+
316
+ ```tsx
317
+ "use client";
318
+
319
+ import { SgButton, SgToastHost, toast } from "@seedgrid/fe-components";
320
+
321
+ export default function Example() {
322
+ return (
323
+ <div className="space-y-4">
324
+ <div className="rounded-md border border-border p-4">
325
+ <div className="text-sm font-semibold">Layout host</div>
326
+ <SgToastHost position="top-right" />
327
+ </div>
328
+
329
+ <div className="rounded-md border border-border bg-muted/20 p-4">
330
+ <div className="text-sm font-semibold">Page host</div>
331
+ <p className="mb-3 text-sm text-muted-foreground">
332
+ Enquanto este host estiver montado, ele tem prioridade sobre o host do layout.
333
+ </p>
334
+ <SgToastHost position="bottom-right" />
335
+ <SgButton onClick={() => toast.info("Toast renderizado pelo host mais profundo")}>
336
+ Disparar toast
337
+ </SgButton>
338
+ </div>
339
+ </div>
340
+ );
341
+ }
342
+ ```
343
+
344
+ ## SgWhistler e `sgWhistle`
345
+
346
+ ### Configuração base
347
+
348
+ O `SgWhistler` fica no fluxo, dentro do container tracejado.
349
+
350
+ Fonte: `front/seedgrid-fe-components/apps/showcase/src/app/components/sg-whistler/samples/base-setup.tsx.sample`
351
+
352
+ ```tsx
353
+ import React from "react";
354
+ import { SgButton, SgWhistler, sgWhistle } from "@seedgrid/fe-components";
355
+
356
+ export default function Example() {
357
+ return (
358
+ <div className="space-y-4">
359
+ <div className="rounded-xl border border-dashed border-border p-4">
360
+ <SgWhistler />
361
+ </div>
362
+
363
+ <div className="flex flex-wrap gap-2">
364
+ <SgButton
365
+ onClick={() =>
366
+ sgWhistle.show({
367
+ title: "Base example",
368
+ message: "A default whistle rendered inside the host."
369
+ })
370
+ }
371
+ >
372
+ sgWhistle.show
373
+ </SgButton>
374
+ <SgButton
375
+ severity="success"
376
+ onClick={() =>
377
+ sgWhistle.success({
378
+ title: "Saved",
379
+ message: "The feedback remained inside the layout flow."
380
+ })
381
+ }
382
+ >
383
+ sgWhistle.success
384
+ </SgButton>
385
+ <SgButton appearance="outline" onClick={() => sgWhistle.dismiss()}>
386
+ Clear
387
+ </SgButton>
388
+ </div>
389
+ </div>
390
+ );
391
+ }
392
+ ```
393
+
394
+ ### Atualização por id
395
+
396
+ `sgWhistle.loading` retorna o id; `sgWhistle.update` reaproveita o mesmo aviso.
397
+
398
+ Fonte: `front/seedgrid-fe-components/apps/showcase/src/app/components/sg-whistler/samples/update-by-id.tsx.sample`
399
+
400
+ ```tsx
401
+ import React from "react";
402
+ import { SgButton, SgWhistler, sgWhistle, type SgWhistleId } from "@seedgrid/fe-components";
403
+
404
+ export default function Example() {
405
+ const [id, setId] = React.useState<SgWhistleId | null>(null);
406
+
407
+ return (
408
+ <div className="space-y-4">
409
+ <div className="flex flex-wrap items-center gap-2">
410
+ <SgButton
411
+ onClick={() =>
412
+ setId(
413
+ sgWhistle.loading({
414
+ title: "Synchronizing",
415
+ message: "This whistle will be updated in place.",
416
+ dismissible: false
417
+ })
418
+ )
419
+ }
420
+ >
421
+ Start loading
422
+ </SgButton>
423
+ <SgButton
424
+ severity="success"
425
+ onClick={() =>
426
+ id &&
427
+ sgWhistle.update(id, {
428
+ severity: "success",
429
+ title: "Sync complete",
430
+ message: "The existing whistle id was reused.",
431
+ dismissible: true
432
+ })
433
+ }
434
+ >
435
+ Finish success
436
+ </SgButton>
437
+ <SgButton severity="danger" appearance="outline" onClick={() => id && sgWhistle.dismiss(id)}>
438
+ Dismiss active
439
+ </SgButton>
440
+ </div>
441
+
442
+ <div className="rounded-xl border border-dashed border-border p-4">
443
+ <SgWhistler />
444
+ </div>
445
+ </div>
446
+ );
447
+ }
448
+ ```
449
+
450
+ ### `sgWhistle.promise`
451
+
452
+ Fonte: `front/seedgrid-fe-components/apps/showcase/src/app/components/sg-whistler/samples/promise.tsx.sample`
453
+
454
+ ```tsx
455
+ import React from "react";
456
+ import { SgButton, SgWhistler, sgWhistle } from "@seedgrid/fe-components";
457
+
458
+ export default function Example() {
459
+ const runDemo = React.useCallback(async () => {
460
+ try {
461
+ await sgWhistle.promise(
462
+ async () => {
463
+ await new Promise((resolve) => setTimeout(resolve, 1200));
464
+ if (Math.random() < 0.35) throw new Error("simulated network error");
465
+ return { protocol: "SG-2026-031" };
466
+ },
467
+ {
468
+ loading: { title: "Submitting report", message: "Waiting for the server..." },
469
+ success: (value) => ({ title: "Report sent", message: `Protocol ${value.protocol} generated.` }),
470
+ error: (error) => ({
471
+ title: "Submission failed",
472
+ message: error instanceof Error ? error.message : "Unknown error"
473
+ })
474
+ }
475
+ );
476
+ } catch {
477
+ // represented by sgWhistle.promise
478
+ }
479
+ }, []);
480
+
481
+ return (
482
+ <div className="space-y-4">
483
+ <SgButton onClick={runDemo}>Run promise demo</SgButton>
484
+ <div className="rounded-xl border border-dashed border-border p-4">
485
+ <SgWhistler />
486
+ </div>
487
+ </div>
488
+ );
489
+ }
490
+ ```
491
+
492
+ ## SgWhistleHost
493
+
494
+ ### Renderer customizado e cores por severidade
495
+
496
+ `sgWhistle.custom` com JSX livre; `customColors` no host.
497
+
498
+ Fonte: `front/seedgrid-fe-components/apps/showcase/src/app/components/sg-whistle-host/samples/custom-renderer-and-colors.tsx.sample`
499
+
500
+ ```tsx
501
+ import React from "react";
502
+ import { SgButton, SgWhistleHost, sgWhistle } from "@seedgrid/fe-components";
503
+
504
+ const warmColors = {
505
+ default: { bg: "#fff7ed", fg: "#7c2d12", border: "#fdba74" },
506
+ success: { bg: "#ecfdf5", fg: "#065f46", border: "#34d399" },
507
+ info: { bg: "#eff6ff", fg: "#1d4ed8", border: "#60a5fa" },
508
+ warning: { bg: "#fffbeb", fg: "#92400e", border: "#f59e0b" },
509
+ error: { bg: "#fef2f2", fg: "#b91c1c", border: "#f87171" },
510
+ loading: { bg: "#f5f3ff", fg: "#6d28d9", border: "#a78bfa" }
511
+ };
512
+
513
+ export default function Example() {
514
+ return (
515
+ <div className="space-y-4">
516
+ <SgButton
517
+ onClick={() =>
518
+ sgWhistle.custom(
519
+ (id) => (
520
+ <div className="space-y-2">
521
+ <div className="text-sm font-semibold">Custom renderer</div>
522
+ <p className="text-sm opacity-90">Free-form JSX rendered by sgWhistle.custom(...).</p>
523
+ <SgButton size="sm" onClick={() => sgWhistle.dismiss(id)}>Close</SgButton>
524
+ </div>
525
+ ),
526
+ {
527
+ message: "custom",
528
+ duration: 0,
529
+ dismissible: false,
530
+ borderStyle: "full-accent"
531
+ }
532
+ )
533
+ }
534
+ >
535
+ Custom whistle
536
+ </SgButton>
537
+
538
+ <div className="rounded-xl border border-dashed border-border p-4">
539
+ <SgWhistleHost customColors={warmColors} />
540
+ </div>
541
+ </div>
542
+ );
543
+ }
544
+ ```
@@ -0,0 +1,69 @@
1
+ ---
2
+ tags: [seedgrid, front, component, feedback-e-exibicao]
3
+ fonte: front/seedgrid-fe-components/packages/seedgrid-fe-components/src/commons
4
+ branch: main
5
+ commit: ad30fc11de
6
+ analisado-em: 2026-10-14
7
+ ---
8
+
9
+ # Feedback e exibição (`src/commons`)
10
+
11
+ Componentes de exibição (avatar, badge, skeleton) e de feedback (toasts e whistles) do `@seedgrid/fe-components`. A pasta de origem é `src/commons`; aqui recebe o nome `feedback-e-exibicao`.
12
+
13
+ - API completa: [[SeedGrid/SeedGrid-components/feedback-e-exibicao/API|API de feedback e exibição]]
14
+ - Exemplos: [[SeedGrid/SeedGrid-components/feedback-e-exibicao/Exemplos|Exemplos de feedback e exibição]]
15
+ - Fundamentos (instalação, CSS, i18n): [[SeedGrid/SeedGrid-components/fundamentos/Visao-geral|Fundamentos]]
16
+
17
+ ## Componentes
18
+
19
+ | Componente | Exportado | Para que serve | Showcase |
20
+ |---|---|---|---|
21
+ | `SgAvatar` | sim | Avatar com imagem, ícone, iniciais ou fallback; severidade, formato e tamanhos | `/components/sg-avatar` |
22
+ | `SgAvatarGroup` | sim | Avatares sobrepostos com contador `+N` | `/components/sg-avatar` |
23
+ | `SgBadge` | sim | Etiqueta/contador com severidade, variantes, ponto pulsante, ícones e remoção | `/components/sg-badge` |
24
+ | `SgBadgeOverlay` | sim | Posiciona um badge sobre outro elemento | `/components/sg-badge-overlay` |
25
+ | `SgSkeleton` | sim | Placeholder de carregamento (formas e animações `wave`/`pulse`) | `/components/sg-skeleton` |
26
+ | `SgToaster` | sim | Pilha fixa de toasts disparados por `toast(...)` | `/components/sg-toaster` |
27
+ | `SgToastHost` | sim | Define onde os toasts aparecem; vários hosts → o último montado vence | `/components/sg-toast-host` |
28
+ | `SgWhistler` | sim | Lista de avisos no fluxo do layout, disparados por `sgWhistle.*` | `/components/sg-whistler` |
29
+ | `SgWhistleHost` | sim | Define onde os whistles aparecem (mesma regra de prioridade) | `/components/sg-whistle-host` |
30
+ | `SgToasterHostContext` | não (interno) | Contexto booleano que faz o `SgToaster` interno do host pular a checagem de host | — |
31
+ | `SgWhistlerHostContext` | não (interno) | Idem para whistles | — |
32
+
33
+ ## Funções e tipos exportados relacionados
34
+
35
+ - Toasts (`src/commons/SgToast.ts`): `toast` (com `.message/.success/.info/.warning/.error/.loading/.custom/.dismiss/.promise`), `dismissSgToast`, `subscribeSgToasts`; tipos `SgToastFn`, `SgToastId`, `SgToastType`, `SgToastAction`, `SgToastOptions`, `SgToastRecord`, `SgToastPromiseMessages`.
36
+ - Whistles (`src/commons/SgWhistle.ts`): `sgWhistle` (com `.show/.success/.info/.warning/.error/.loading/.dismiss/.update/.custom/.promise`), `dismissSgWhistle`, `subscribeSgWhistles`; tipos `SgWhistleId`, `SgWhistleSeverity`, `SgWhistleBorderStyle`, `SgWhistleAction`, `SgWhistleOptions`, `SgWhistleCustomOptions`, `SgWhistleRecord`, `SgWhistlePromiseStates`.
37
+ - Registro de hosts de toast (`src/commons/sgToastHostRegistry.ts`, exportado): `registerHost`, `unregisterHost`, `getActiveHostId`, `hasAnyHost`, `subscribeHostRegistry`, `nextHostId`. O registro equivalente de whistles (`sgWhistleHostRegistry.ts`) **não** é exportado.
38
+ - Tipos de props: `SgAvatarProps`, `SgAvatarGroupProps`, `SgAvatarSeverity`, `SgAvatarShape`, `SgAvatarSize`, `SgAvatarCustomColors`, `SgAvatarGroupOverlap`, `SgBadgeProps`, `SgBadgeSeverity`, `SgBadgeVariant`, `SgBadgeSize`, `SgBadgeCustomColors`, `SgBadgePartsClassName`, `SgBadgeOverlayProps`, `SgBadgeOverlayPlacement`, `SgSkeletonProps`, `SgSkeletonAnimation`, `SgSkeletonShape`, `SgToasterProps`, `SgToasterPosition`, `SgToasterTypeColors`, `SgToasterCustomColors`, `SgToastHostProps`, `SgWhistlerProps`, `SgWhistleHostProps`.
39
+ - Não relacionado a UI, mas na mesma pasta: `src/commons/common-passwords.ts` (lista usada pelos validadores — ver [[SeedGrid/SeedGrid-components/fundamentos/API|Fundamentos › validadores]]).
40
+
41
+ ## Como se compõem
42
+
43
+ ```mermaid
44
+ flowchart LR
45
+ A["toast(...) / sgWhistle.*"] --> S["store global em módulo<br/>(SgToast.ts / SgWhistle.ts)"]
46
+ S -->|subscribeSgToasts| T["SgToaster"]
47
+ S -->|subscribeSgWhistles| W["SgWhistler"]
48
+ H1["SgToastHost (pilha de hosts)"] -->|ativo renderiza| T
49
+ H2["SgWhistleHost (pilha de hosts)"] -->|ativo renderiza| W
50
+ ```
51
+
52
+ - As APIs `toast`/`sgWhistle` funcionam fora de componentes React (store em variável de módulo + listeners) — Confirmado.
53
+ - Basta **um** `SgToaster` ou `SgToastHost` montado para os toasts aparecerem; com hosts presentes, o `SgToaster` "solto" deixa de renderizar. Idem `SgWhistler`/`SgWhistleHost`.
54
+ - Toast = sobreposição fixa (`position: fixed`, `z-index 1100`) com posição configurável; whistle = bloco no fluxo do layout, onde o componente for colocado.
55
+ - `SgBadgeOverlay` costuma receber um `SgBadge` em `badge`; `SgAvatarGroup` recebe `SgAvatar` como filhos.
56
+ - Nenhum provider é obrigatório; textos padrão vêm do i18n interno. Sem dependências externas além de `react`.
57
+
58
+ ## Testes existentes (não executados)
59
+
60
+ | Arquivo | Cobre |
61
+ |---|---|
62
+ | `packages/seedgrid-fe-components/tests/commons.test.mjs` | `aria-label` traduzido e override do `SgAvatar` e do botão remover do `SgBadge`; fallback de loading do `toast.promise`; registro de hosts de toast (último ativo, duplicados, unsubscribe); `sgWhistle.promise` atualizando o mesmo registro; `sgWhistle.update` + `onClose` no dismiss |
63
+ | `packages/seedgrid-fe-components/tests/commons-dom.test.mjs` (jsdom) | `SgWhistleHost` no fluxo respeitando `max`/`newestOnTop`; renderer customizado, ação que fecha e fechamento por tempo |
64
+
65
+ ## Limitações e pontos de atenção
66
+
67
+ - `SgAvatarGroup`: `size`, `shape` e `bordered` só afetam o avatar contador `+N` (Confirmado).
68
+ - `SgAvatar` clicável não trata teclado; `SgSkeleton` não declara `aria-busy`.
69
+ - `SgBadge`, `SgBadgeOverlay`, `SgSkeleton`, `SgToaster`, `SgWhistler` e hosts não aceitam `ref`.