@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,1172 @@
1
+ ---
2
+ tags: [seedgrid, front, component, layout]
3
+ fonte: front/seedgrid-fe-components/apps/showcase/src/app/components; front/seedgrid-fe-components/packages/seedgrid-fe-components/src/layout
4
+ branch: main
5
+ commit: ad30fc11de
6
+ analisado-em: 2026-10-14
7
+ ---
8
+
9
+ # Exemplos — layout
10
+
11
+ API: [[SeedGrid/SeedGrid-components/layout/API|Layout — API]] · Visão geral: [[SeedGrid/SeedGrid-components/layout/Visao-geral|Layout — visão geral]]
12
+
13
+ Exemplos copiados 1:1 dos arquivos `samples/*.tsx.sample` do showcase (caminhos relativos a `front/seedgrid-fe-components/`), salvo indicação. Todos foram verificados com type-check TypeScript (`strict`) contra `packages/seedgrid-fe-components/src/index.ts` em 2026-10-14 — sem erros. Classes Tailwind e ícones `lucide-react` vêm do showcase; `lucide-react` é peer dependency do pacote.
14
+
15
+
16
+ ## SgStack
17
+
18
+ ### column-row
19
+
20
+ Fonte: `apps/showcase/src/app/components/sg-stack/samples/column-row.tsx.sample`. Coluna com `gap` e linha com `justify="between"` / `align="center"`.
21
+
22
+ ```tsx
23
+ import React from "react";
24
+ import { SgButton, SgStack } from "@seedgrid/fe-components";
25
+
26
+ export default function Example() {
27
+ return (
28
+ <>
29
+ <SgStack gap={8}>
30
+ <SgButton>Save</SgButton>
31
+ <SgButton appearance="outline">Cancelar</SgButton>
32
+ </SgStack>
33
+ <SgStack direction="row" justify="between" align="center">
34
+ <span>Title</span>
35
+ <SgButton size="sm">Confirmar</SgButton>
36
+ </SgStack>
37
+ </>
38
+ );
39
+ }
40
+ ```
41
+
42
+
43
+ ## SgGrid
44
+
45
+ ### columns-responsivo
46
+
47
+ Fonte: `apps/showcase/src/app/components/sg-grid/samples/columns-responsivo.tsx.sample`. Colunas por breakpoint (`base`/`sm`/`lg`/`xl`) e filho `SgPanel` com `span={2}`.
48
+
49
+ ```tsx
50
+ import React from "react";
51
+ import { SgGrid, SgPanel, SgStack } from "@seedgrid/fe-components";
52
+
53
+ function Card(props: { title: string; subtitle?: string }) {
54
+ return <SgPanel padding={12} className="rounded-lg"><SgStack gap={8}><p className="font-medium">{props.title}</p><p className="text-xs text-muted-foreground">{props.subtitle ?? "Card padrao"}</p></SgStack></SgPanel>;
55
+ }
56
+
57
+ export default function Example() {
58
+ return (
59
+ <SgGrid columns={{ base: 1, sm: 2, lg: 3, xl: 4 }} gap={12}>
60
+ <Card title="Card 1" />
61
+ <Card title="Card 2" />
62
+ <SgPanel span={2} padding={12} className="rounded-lg"><SgStack gap={8}><p className="font-medium">Card 3 (span 2)</p><p className="text-xs text-muted-foreground">Ocupa 2 colunas.</p></SgStack></SgPanel>
63
+ <Card title="Card 4" />
64
+ <Card title="Card 5" />
65
+ <Card title="Card 6" />
66
+ </SgGrid>
67
+ );
68
+ }
69
+ ```
70
+
71
+ ### auto-fit-rowspan
72
+
73
+ Fonte: `apps/showcase/src/app/components/sg-grid/samples/auto-fit-rowspan.tsx.sample`. `minItemWidth` (auto-fit), `rowHeight`, `dense` e filhos com `span`/`rowSpan`.
74
+
75
+ ```tsx
76
+ import React from "react";
77
+ import { SgGrid, SgPanel, SgStack } from "@seedgrid/fe-components";
78
+
79
+ function Card(props: { title: string; subtitle?: string }) {
80
+ return <SgPanel padding={12} className="rounded-lg"><SgStack gap={8}><p className="font-medium">{props.title}</p><p className="text-xs text-muted-foreground">{props.subtitle ?? "Card padrao"}</p></SgStack></SgPanel>;
81
+ }
82
+
83
+ export default function Example() {
84
+ return (
85
+ <SgGrid minItemWidth="16rem" gap={12} rowHeight={120} dense>
86
+ <Card title="Card A" />
87
+ <SgPanel rowSpan={2} padding={12} className="rounded-lg"><SgStack gap={8}><p className="font-medium">Card B (rowSpan 2)</p><p className="text-xs text-muted-foreground">Ocupa 2 linhas do grid.</p></SgStack></SgPanel>
88
+ <Card title="Card C" />
89
+ <SgPanel span={2} padding={12} className="rounded-lg"><SgStack gap={8}><p className="font-medium">Card D (span 2)</p><p className="text-xs text-muted-foreground">Ocupa 2 colunas.</p></SgStack></SgPanel>
90
+ <Card title="Card E" />
91
+ <Card title="Card F" />
92
+ </SgGrid>
93
+ );
94
+ }
95
+ ```
96
+
97
+
98
+ ## SgPanel
99
+
100
+ ### align-width-height
101
+
102
+ Fonte: `apps/showcase/src/app/components/sg-panel/samples/align-width-height.tsx.sample`. Docking: painéis filhos com `align` top/left/right/bottom/client; `width`/`height` numéricos são %.
103
+
104
+ ```tsx
105
+ import React from "react";
106
+ import { SgPanel, SgStack } from "@seedgrid/fe-components";
107
+
108
+ export default function Example() {
109
+ return (
110
+ <SgPanel className="h-[430px] rounded-xl bg-muted/30" padding={12}>
111
+ <SgPanel className="h-full w-full rounded-lg bg-background p-3" contentGap={8}>
112
+ <SgPanel align="top" height={12} padding={10} className="rounded-md">
113
+ <SgStack direction="row" justify="between" align="center">
114
+ <span className="text-sm font-medium">Header</span>
115
+ <span className="rounded border border-border px-2 py-0.5 text-xs text-muted-foreground">top + height=12%</span>
116
+ </SgStack>
117
+ </SgPanel>
118
+ <SgPanel align="left" width={20} padding={10} className="rounded-md">
119
+ <SgStack gap={6}>
120
+ <span className="text-xs font-medium text-muted-foreground">MENU</span>
121
+ <SgPanel borderStyle="none" className="rounded bg-muted/40" padding={6}>Dashboard</SgPanel>
122
+ <SgPanel borderStyle="none" className="rounded bg-muted/40" padding={6}>Relatorios</SgPanel>
123
+ <SgPanel borderStyle="none" className="rounded bg-muted/40" padding={6}>Clientes</SgPanel>
124
+ <span className="pt-1 text-[11px] text-muted-foreground">left + width=20%</span>
125
+ </SgStack>
126
+ </SgPanel>
127
+ <SgPanel align="right" width="18%" padding={10} className="rounded-md">
128
+ <SgStack gap={6}>
129
+ <span className="text-xs font-medium text-muted-foreground">ACOES</span>
130
+ <SgPanel borderStyle="none" className="rounded bg-muted/40" padding={6}>Filtrar</SgPanel>
131
+ <SgPanel borderStyle="none" className="rounded bg-muted/40" padding={6}>Exportar</SgPanel>
132
+ <span className="pt-1 text-[11px] text-muted-foreground">right + width=18%</span>
133
+ </SgStack>
134
+ </SgPanel>
135
+ <SgPanel align="bottom" height="10%" padding={10} className="rounded-md">
136
+ <SgStack direction="row" justify="between" align="center">
137
+ <span className="text-sm">Footer</span>
138
+ <span className="rounded border border-border px-2 py-0.5 text-xs text-muted-foreground">bottom + height=10%</span>
139
+ </SgStack>
140
+ </SgPanel>
141
+ <SgPanel align="client" padding={10} className="rounded-md">
142
+ <SgStack gap={8}>
143
+ <span className="text-sm font-medium">Area client</span>
144
+ <SgPanel borderStyle="solid" className="h-24 rounded bg-muted/20" />
145
+ <span className="text-xs text-muted-foreground">client ocupa o restante automaticamente.</span>
146
+ </SgStack>
147
+ </SgPanel>
148
+ </SgPanel>
149
+ </SgPanel>
150
+ );
151
+ }
152
+ ```
153
+
154
+
155
+ ## SgScreen
156
+
157
+ ### complete-example
158
+
159
+ Fonte: `apps/showcase/src/app/components/sg-screen/samples/complete-example.tsx.sample`. `SgScreen` não-fullscreen contendo um `SgPanel` com docking.
160
+
161
+ ```tsx
162
+ "use client";
163
+
164
+ import React from "react";
165
+ import { SgScreen, SgPanel, SgStack } from "@seedgrid/fe-components";
166
+
167
+ export default function ExampleSgScreenPage() {
168
+ return (
169
+ <SgPanel className="h-[420px] rounded-xl bg-muted/30" padding={12}>
170
+ <SgScreen fullscreen={false} padding={10} className="rounded-lg bg-zinc-100">
171
+ <SgPanel className="h-full w-full" contentPadding={8} contentGap={8}>
172
+ <SgPanel align="top" height={12} padding={10} className="rounded-md">
173
+ <SgStack direction="row" justify="between" align="center">
174
+ <span className="text-sm font-medium">Header</span>
175
+ <span className="text-xs text-muted-foreground">top + height=12%</span>
176
+ </SgStack>
177
+ </SgPanel>
178
+
179
+ <SgPanel align="left" width={20} padding={10} className="rounded-md">
180
+ <SgStack gap={6}>
181
+ <span className="text-xs font-medium text-muted-foreground">MENU</span>
182
+ <SgPanel borderStyle="none" className="rounded bg-muted/40" padding={6}>Dashboard</SgPanel>
183
+ <SgPanel borderStyle="none" className="rounded bg-muted/40" padding={6}>Relatorios</SgPanel>
184
+ <SgPanel borderStyle="none" className="rounded bg-muted/40" padding={6}>Clientes</SgPanel>
185
+ </SgStack>
186
+ </SgPanel>
187
+
188
+ <SgPanel align="right" width="18%" padding={10} className="rounded-md">
189
+ <SgStack gap={6}>
190
+ <span className="text-xs font-medium text-muted-foreground">ACOES</span>
191
+ <SgPanel borderStyle="none" className="rounded bg-muted/40" padding={6}>Filtrar</SgPanel>
192
+ <SgPanel borderStyle="none" className="rounded bg-muted/40" padding={6}>Exportar</SgPanel>
193
+ </SgStack>
194
+ </SgPanel>
195
+
196
+ <SgPanel align="bottom" height="10%" padding={10} className="rounded-md">
197
+ <SgStack direction="row" justify="between" align="center">
198
+ <span className="text-sm">Footer</span>
199
+ <span className="text-xs text-muted-foreground">bottom + height=10%</span>
200
+ </SgStack>
201
+ </SgPanel>
202
+
203
+ <SgPanel align="client" padding={10} className="rounded-md">
204
+ <SgStack gap={8}>
205
+ <span className="text-sm font-medium">Area client</span>
206
+ <SgPanel borderStyle="solid" className="h-24 rounded bg-muted/20" />
207
+ <span className="text-xs text-muted-foreground">
208
+ Esta area ocupa todo o espaco restante.
209
+ </span>
210
+ </SgStack>
211
+ </SgPanel>
212
+ </SgPanel>
213
+ </SgScreen>
214
+ </SgPanel>
215
+ );
216
+ }
217
+ ```
218
+
219
+
220
+ ## SgGroupBox
221
+
222
+ ### basico
223
+
224
+ Fonte: `apps/showcase/src/app/components/sg-group-box/samples/basico.tsx.sample`. Agrupamento com título (`fieldset`/`legend`).
225
+
226
+ ```tsx
227
+ import { SgGroupBox } from "@seedgrid/fe-components";
228
+
229
+ export default function Example() {
230
+ return (
231
+ <SgGroupBox
232
+ title="Dados pessoais"
233
+ style={{ boxShadow: "inset 0 0 0 1px rgba(59, 130, 246, 0.2)" }}
234
+ >
235
+ <div className="grid gap-3 sm:grid-cols-2">
236
+ <div>Campo 1</div>
237
+ <div>Campo 2</div>
238
+ </div>
239
+ </SgGroupBox>
240
+ );
241
+ }
242
+ ```
243
+
244
+
245
+ ## SgCard
246
+
247
+ ### basico
248
+
249
+ Fonte: `apps/showcase/src/app/components/sg-card/samples/basico.tsx.sample`. Título, descrição, corpo e rodapé.
250
+
251
+ ```tsx
252
+ import React from "react";
253
+ import { SgCard } from "@seedgrid/fe-components";
254
+
255
+ export default function Example() {
256
+ return (
257
+ <SgCard
258
+ title="Resumo financeiro"
259
+ description="Visao consolidada do dia"
260
+ footer={
261
+ <div className="flex items-center justify-between text-xs text-muted-foreground">
262
+ <span>Atualizado agora</span>
263
+ <span>Ultima sincronizacao</span>
264
+ </div>
265
+ }
266
+ >
267
+ <div className="space-y-2 text-sm">
268
+ <div className="flex items-center justify-between">
269
+ <span className="text-muted-foreground">Receita</span>
270
+ <span className="font-semibold">R$ 12.400</span>
271
+ </div>
272
+ <div className="flex items-center justify-between">
273
+ <span className="text-muted-foreground">Pedidos</span>
274
+ <span className="font-semibold">83</span>
275
+ </div>
276
+ </div>
277
+ </SgCard>
278
+ );
279
+ }
280
+ ```
281
+
282
+ ### colapsavel
283
+
284
+ Fonte: `apps/showcase/src/app/components/sg-card/samples/colapsavel.tsx.sample`. `collapsible` com `defaultOpen` e alinhamento do botão de colapso.
285
+
286
+ ```tsx
287
+ import React from "react";
288
+ import { SgButton, SgCard } from "@seedgrid/fe-components";
289
+
290
+ export default function Example() {
291
+ return (
292
+ <>
293
+ <SgCard
294
+ title="Painel recolhido"
295
+ description="Abre sob demanda"
296
+ collapsible
297
+ defaultOpen={false}
298
+ collapseToggleAlign="right"
299
+ collapseIconSize={20}
300
+ footer={<div className="flex justify-end"><SgButton size="sm">Acao</SgButton></div>}
301
+ >
302
+ <div className="text-sm text-muted-foreground">Conteudo recolhivel do card.</div>
303
+ </SgCard>
304
+
305
+ <SgCard
306
+ title="Painel aberto"
307
+ description="Comeca expandido"
308
+ collapsible
309
+ defaultOpen
310
+ collapseToggleAlign="right"
311
+ collapseIconSize={20}
312
+ footer={
313
+ <div className="flex items-center justify-between text-xs text-muted-foreground">
314
+ <span>128 itens</span>
315
+ <span>R$ 9.820</span>
316
+ </div>
317
+ }
318
+ >
319
+ <div className="space-y-2 text-sm">
320
+ <div className="flex items-center justify-between">
321
+ <span className="text-muted-foreground">Tickets</span>
322
+ <span className="font-semibold">128</span>
323
+ </div>
324
+ <div className="flex items-center justify-between">
325
+ <span className="text-muted-foreground">Valor</span>
326
+ <span className="font-semibold">R$ 9.820</span>
327
+ </div>
328
+ </div>
329
+ </SgCard>
330
+ </>
331
+ );
332
+ }
333
+ ```
334
+
335
+ ### draggable-persistence
336
+
337
+ Fonte: `apps/showcase/src/app/components/sg-card/samples/draggable-persistence.tsx.sample`. Arraste pelo cabeçalho com posição persistida via `SgEnvironmentProvider` (`dragPersistKey`).
338
+
339
+ ```tsx
340
+ import React from "react";
341
+ import { SgCard, SgEnvironmentProvider } from "@seedgrid/fe-components";
342
+
343
+ export default function Example() {
344
+ return (
345
+ <SgEnvironmentProvider
346
+ value={{
347
+ namespaceProvider: { getNamespace: () => "showcase" },
348
+ persistence: { scope: "app:showcase", mode: "fallback", stateVersion: 1 }
349
+ }}
350
+ >
351
+ <div className="relative h-[300px] overflow-hidden rounded-xl border border-dashed border-border/70 bg-muted/20 p-2">
352
+ <SgCard
353
+ id="sg-card-draggable-demo"
354
+ draggable
355
+ defaultPosition={{ x: 16, y: 16 }}
356
+ dragPersistKey="sg-card-draggable-demo"
357
+ title="Drag me by the title bar"
358
+ description="Try moving and refreshing this page."
359
+ collapsible
360
+ collapseToggleAlign="right"
361
+ collapseIconSize={20}
362
+ bgColor="#ffffff"
363
+ footer={<div className="text-xs text-muted-foreground">Persisted drag position.</div>}
364
+ >
365
+ <div className="space-y-2 text-sm">
366
+ <div className="flex items-center justify-between">
367
+ <span className="text-muted-foreground">Status</span>
368
+ <span className="font-semibold text-emerald-600">Online</span>
369
+ </div>
370
+ <div className="flex items-center justify-between">
371
+ <span className="text-muted-foreground">Region</span>
372
+ <span className="font-semibold">Sao Paulo</span>
373
+ </div>
374
+ </div>
375
+ </SgCard>
376
+ </div>
377
+ </SgEnvironmentProvider>
378
+ );
379
+ }
380
+ ```
381
+
382
+
383
+ ## SgAccordion
384
+
385
+ ### basico-vertical-single
386
+
387
+ Fonte: `apps/showcase/src/app/components/sg-accordion/samples/basico-vertical-single.tsx.sample`. Uso mínimo: só `items` (abre o primeiro por padrão).
388
+
389
+ ```tsx
390
+ import * as React from "react";
391
+ import { SgAccordion, type SgAccordionItem } from "@seedgrid/fe-components";
392
+
393
+ const items: SgAccordionItem[] = [
394
+ { id: "personal", title: "Dados pessoais", content: <p className="text-sm">Nome, email e telefone.</p> },
395
+ { id: "address", title: "Endereco", content: <p className="text-sm">Rua, cidade e CEP.</p> },
396
+ { id: "billing", title: "Faturamento", content: <p className="text-sm">Cobranca e historico.</p> }
397
+ ];
398
+
399
+ export default function Example() {
400
+ return <SgAccordion items={items} />;
401
+ }
402
+ ```
403
+
404
+ ### controlado-por-estado
405
+
406
+ Fonte: `apps/showcase/src/app/components/sg-accordion/samples/controlado-por-estado.tsx.sample`. Modo controlado com `activeIndex` + `onActiveIndexChange`.
407
+
408
+ ```tsx
409
+ import * as React from "react";
410
+ import { SgAccordion, SgButton, type SgAccordionItem } from "@seedgrid/fe-components";
411
+
412
+ const items: SgAccordionItem[] = [
413
+ { id: "personal", title: "Dados pessoais", content: <p className="text-sm">Conteudo 1</p> },
414
+ { id: "address", title: "Endereco", content: <p className="text-sm">Conteudo 2</p> },
415
+ { id: "billing", title: "Faturamento", content: <p className="text-sm">Conteudo 3</p> }
416
+ ];
417
+
418
+ export default function Example() {
419
+ const [activeIndex, setActiveIndex] = React.useState<number[]>([0]);
420
+
421
+ return (
422
+ <div className="space-y-3">
423
+ <SgAccordion items={items} activeIndex={activeIndex} onActiveIndexChange={setActiveIndex} />
424
+ <div className="flex flex-wrap gap-2">
425
+ <SgButton size="sm" appearance="outline" onClick={() => setActiveIndex([0])}>Abrir 1</SgButton>
426
+ <SgButton size="sm" appearance="outline" onClick={() => setActiveIndex([1])}>Abrir 2</SgButton>
427
+ <SgButton size="sm" appearance="outline" onClick={() => setActiveIndex([2])}>Abrir 3</SgButton>
428
+ <SgButton size="sm" appearance="outline" onClick={() => setActiveIndex([])}>Fechar todos</SgButton>
429
+ </div>
430
+ </div>
431
+ );
432
+ }
433
+ ```
434
+
435
+
436
+ ## SgPageControl
437
+
438
+ ### basico
439
+
440
+ Fonte: `apps/showcase/src/app/components/sg-page-control/samples/basico.tsx.sample`. Abas declaradas com `SgPageControlPage` e página inicial por id.
441
+
442
+ ```tsx
443
+ import React from "react";
444
+ import { Receipt, ShieldCheck, UserRound } from "lucide-react";
445
+ import { SgPageControl, SgPageControlPage } from "@seedgrid/fe-components";
446
+
447
+ export default function Example() {
448
+ return (
449
+ <SgPageControl
450
+ defaultActivePageId="registration"
451
+ style={{ border: "1px solid rgba(59, 130, 246, 0.25)", borderRadius: 12 }}
452
+ >
453
+ <SgPageControlPage
454
+ id="registration"
455
+ title="Registration"
456
+ icon={<UserRound className="size-4" />}
457
+ style={{ backgroundColor: "rgba(59, 130, 246, 0.08)" }}
458
+ >
459
+ Registration content
460
+ </SgPageControlPage>
461
+ <SgPageControlPage id="fiscal" title="Fiscal" icon={<Receipt className="size-4" />}>
462
+ Fiscal content
463
+ </SgPageControlPage>
464
+ <SgPageControlPage id="access" title="Access" icon={<ShieldCheck className="size-4" />}>
465
+ Access content
466
+ </SgPageControlPage>
467
+ </SgPageControl>
468
+ );
469
+ }
470
+ ```
471
+
472
+ ### controle-externo
473
+
474
+ Fonte: `apps/showcase/src/app/components/sg-page-control/samples/controle-externo.tsx.sample`. Controle externo por `activePageId` e estilo `pills`.
475
+
476
+ ```tsx
477
+ import React from "react";
478
+ import { FolderKanban, Receipt, ShieldCheck, UserRound } from "lucide-react";
479
+ import { SgButton, SgPageControl, SgPageControlPage } from "@seedgrid/fe-components";
480
+
481
+ export default function Example() {
482
+ const [activePageId, setActivePageId] = React.useState("registration");
483
+
484
+ return (
485
+ <div className="space-y-4">
486
+ <div className="flex flex-wrap gap-2">
487
+ <SgButton size="sm" appearance="outline" onClick={() => setActivePageId("registration")}>Go to Registration</SgButton>
488
+ <SgButton size="sm" appearance="outline" onClick={() => setActivePageId("fiscal")}>Go to Fiscal</SgButton>
489
+ <SgButton size="sm" appearance="outline" onClick={() => setActivePageId("access")}>Go to Access</SgButton>
490
+ <SgButton size="sm" appearance="outline" onClick={() => setActivePageId("integrations")}>Go to Integrations</SgButton>
491
+ </div>
492
+
493
+ <SgPageControl activePageId={activePageId} onActivePageIdChange={(pageId) => setActivePageId(pageId)} pageControlStyle="pills">
494
+ <SgPageControlPage id="registration" title="Registration" icon={<UserRound className="size-4" />}>Registration content</SgPageControlPage>
495
+ <SgPageControlPage id="fiscal" title="Fiscal" icon={<Receipt className="size-4" />}>Fiscal content</SgPageControlPage>
496
+ <SgPageControlPage id="access" title="Access" icon={<ShieldCheck className="size-4" />}>Access content</SgPageControlPage>
497
+ <SgPageControlPage id="integrations" title="Integrations" icon={<FolderKanban className="size-4" />}>Integrations content</SgPageControlPage>
498
+ </SgPageControl>
499
+ </div>
500
+ );
501
+ }
502
+ ```
503
+
504
+
505
+ ## SgExpandablePanel
506
+
507
+ ### overlay-comportamento
508
+
509
+ Fonte: `apps/showcase/src/app/components/sg-expandable-panel/samples/overlay-comportamento.tsx.sample`. Overlay com foco preso, Esc, clique fora, backdrop e resize.
510
+
511
+ ```tsx
512
+ import React from "react";
513
+ import { SgButton, SgExpandablePanel } from "@seedgrid/fe-components";
514
+
515
+ export default function Example() {
516
+ const [open, setOpen] = React.useState(false);
517
+
518
+ return (
519
+ <>
520
+ <div className="flex flex-wrap gap-2">
521
+ <SgButton onClick={() => setOpen(true)}>Abrir drawer</SgButton>
522
+ </div>
523
+
524
+ <SgExpandablePanel
525
+ mode="overlay"
526
+ expandTo="left"
527
+ placement="center"
528
+ open={open}
529
+ onOpenChange={setOpen}
530
+ size={{ default: 360, min: 260, max: 640 }}
531
+ resizable
532
+ closeOnEsc
533
+ closeOnOutsideClick
534
+ trapFocus
535
+ showBackdrop
536
+ handle={<div className="mx-auto h-1.5 w-12 rounded-full bg-muted-foreground/35" />}
537
+ header={<div className="font-medium">Drawer com foco preso</div>}
538
+ footer={
539
+ <div className="flex justify-end">
540
+ <SgButton size="sm" onClick={() => setOpen(false)}>Fechar</SgButton>
541
+ </div>
542
+ }
543
+ >
544
+ <div className="space-y-2 text-sm">
545
+ <p>Props: placement, closeOnEsc, closeOnOutsideClick, trapFocus e showBackdrop.</p>
546
+ <label className="flex items-center gap-2">
547
+ <input type="checkbox" defaultChecked />
548
+ <span>Somente ativos</span>
549
+ </label>
550
+ </div>
551
+ </SgExpandablePanel>
552
+ </>
553
+ );
554
+ }
555
+ ```
556
+
557
+ ### inline-controlado-resize
558
+
559
+ Fonte: `apps/showcase/src/app/components/sg-expandable-panel/samples/inline-controlado-resize.tsx.sample`. Inline controlado com `onSizeChange`.
560
+
561
+ ```tsx
562
+ import React from "react";
563
+ import { SgButton, SgExpandablePanel } from "@seedgrid/fe-components";
564
+
565
+ export default function Example() {
566
+ const [open, setOpen] = React.useState(true);
567
+ const [size, setSize] = React.useState<number | string>(320);
568
+
569
+ return (
570
+ <div className="h-[360px] overflow-hidden rounded-lg border border-border">
571
+ <div className="flex h-full">
572
+ <div className="flex-1 space-y-3 p-4">
573
+ <h3 className="text-base font-semibold">Area principal</h3>
574
+ <p className="text-sm text-muted-foreground">Exemplo inline controlado com resize.</p>
575
+ <div className="flex flex-wrap gap-2">
576
+ <SgButton size="sm" onClick={() => setOpen((v) => !v)}>
577
+ {open ? "Fechar inspector" : "Abrir inspector"}
578
+ </SgButton>
579
+ </div>
580
+ <p className="text-xs text-muted-foreground">Largura atual: {String(size)}px</p>
581
+ </div>
582
+
583
+ <SgExpandablePanel
584
+ mode="inline"
585
+ expandTo="left"
586
+ open={open}
587
+ onOpenChange={setOpen}
588
+ size={{ default: 320, min: 240, max: 560 }}
589
+ resizable
590
+ onSizeChange={setSize}
591
+ header={<div className="font-medium">Inspector</div>}
592
+ footer={<div className="text-xs text-muted-foreground">Rodape inline</div>}
593
+ >
594
+ <div className="space-y-3 text-sm">
595
+ <p>Conteudo do inspector.</p>
596
+ <p>Props: open, onOpenChange, size, resizable, onSizeChange.</p>
597
+ </div>
598
+ </SgExpandablePanel>
599
+ </div>
600
+ </div>
601
+ );
602
+ }
603
+ ```
604
+
605
+
606
+ ## SgCarousel
607
+
608
+ ### layout-carousel-autoplay
609
+
610
+ Autoplay com `onIndexChange`. **Composto** a partir de `apps/showcase/src/app/components/sg-carousel/samples/auto-play.tsx.sample` e `com-callbacks.tsx.sample` (que no showcase são fragmentos JSX) mais a função `createCarouselItems` de `sg-carousel/page.tsx` (3 imagens em vez de 6).
611
+
612
+ ```tsx
613
+ import React from "react";
614
+ import { SgCarousel, SgGrid } from "@seedgrid/fe-components";
615
+
616
+ const sampleImages = [
617
+ { id: 1, title: "Item 1", url: "https://picsum.photos/1200/700?random=101" },
618
+ { id: 2, title: "Item 2", url: "https://picsum.photos/1200/700?random=102" },
619
+ { id: 3, title: "Item 3", url: "https://picsum.photos/1200/700?random=103" }
620
+ ];
621
+
622
+ const createCarouselItems = (items = sampleImages) =>
623
+ items.map((item) => (
624
+ <div key={item.id} className="relative h-full overflow-hidden rounded-lg text-white shadow-lg">
625
+ <img src={item.url} alt={item.title} loading="lazy" className="h-full w-full object-cover" />
626
+ <div className="pointer-events-none absolute inset-0 bg-black/35" />
627
+ <SgGrid columns={1} justify="center" align="center" className="absolute inset-0">
628
+ <div className="text-center">
629
+ <h3 className="text-3xl font-bold">{item.title}</h3>
630
+ <p className="mt-2 text-sm opacity-90">Slide {item.id}</p>
631
+ </div>
632
+ </SgGrid>
633
+ </div>
634
+ ));
635
+
636
+ export default function Example() {
637
+ const [activeIndex, setActiveIndex] = React.useState(0);
638
+ return (
639
+ <div className="space-y-2">
640
+ <div className="h-64">
641
+ <SgCarousel
642
+ items={createCarouselItems()}
643
+ numVisible={1}
644
+ autoPlay
645
+ autoPlayInterval={2000}
646
+ orientation="horizontal"
647
+ height="100%"
648
+ onIndexChange={setActiveIndex}
649
+ />
650
+ </div>
651
+ <p className="text-sm">Índice ativo: {activeIndex}</p>
652
+ </div>
653
+ );
654
+ }
655
+ ```
656
+
657
+
658
+ ## SgBreadcrumb
659
+
660
+ ### basico
661
+
662
+ Fonte: `apps/showcase/src/app/components/sg-breadcrumb/samples/basico.tsx.sample`. Itens com ícone, separador `chevron` e ícone de início.
663
+
664
+ ```tsx
665
+ import React from "react";
666
+ import { Box, Building2, FilePenLine, Layers3 } from "lucide-react";
667
+ import { SgBreadcrumb, type SgBreadcrumbItem } from "@seedgrid/fe-components";
668
+
669
+ const items: SgBreadcrumbItem[] = [
670
+ { id: "modules", label: "Modules", href: "/modules", icon: <Layers3 className="size-4" /> },
671
+ { id: "registrations", label: "Registrations", href: "/modules/registrations", icon: <Building2 className="size-4" /> },
672
+ { id: "products", label: "Products", href: "/modules/registrations/products", icon: <Box className="size-4" /> },
673
+ { id: "edit", label: "Edit", icon: <FilePenLine className="size-4" /> }
674
+ ];
675
+
676
+ export default function Example() {
677
+ return <SgBreadcrumb items={items} separator="chevron" showHomeIcon />;
678
+ }
679
+ ```
680
+
681
+ ### overflow
682
+
683
+ Fonte: `apps/showcase/src/app/components/sg-breadcrumb/samples/overflow.tsx.sample`. `maxItems` com colapso e `overflowBehavior="scroll"`.
684
+
685
+ ```tsx
686
+ import React from "react";
687
+ import { SgBreadcrumb, type SgBreadcrumbItem } from "@seedgrid/fe-components";
688
+
689
+ const longItems: SgBreadcrumbItem[] = [
690
+ { id: "home", label: "Home", href: "/" },
691
+ { id: "admin", label: "Admin", href: "/admin" },
692
+ { id: "tenant", label: "Multi Tenancy", href: "/admin/tenant" },
693
+ { id: "billing", label: "Billing", href: "/admin/tenant/billing" },
694
+ { id: "plans", label: "Subscription", href: "/admin/tenant/billing/subscription" },
695
+ { id: "edit", label: "Edit plan" }
696
+ ];
697
+
698
+ export default function Example() {
699
+ return (
700
+ <div className="space-y-4">
701
+ <SgBreadcrumb items={longItems} maxItems={4} overflowBehavior="collapse" separator="slash" />
702
+ <div className="max-w-[360px] rounded-lg border border-border p-2">
703
+ <SgBreadcrumb items={longItems} overflowBehavior="scroll" separator="dot" />
704
+ </div>
705
+ </div>
706
+ );
707
+ }
708
+ ```
709
+
710
+
711
+ ## SgMenu
712
+
713
+ ### sidebar-fixa
714
+
715
+ Fonte: `apps/showcase/src/app/components/sg-menu/samples/sidebar-fixa.tsx.sample`. Sidebar recolhível controlada, busca, marca, usuário e `onNavigate`.
716
+
717
+ ```tsx
718
+ import React from "react";
719
+ import { ClipboardList, Home, LayoutGrid, Search, Settings, Users } from "lucide-react";
720
+ import { SgMenu, type SgMenuNode } from "@seedgrid/fe-components";
721
+
722
+ const MENU: SgMenuNode[] = [
723
+ { id: "dashboard", label: "Dashboard", url: "/dashboard", icon: <Home className="size-4" /> },
724
+ { id: "customers", label: "Customers", icon: <Users className="size-4" />, children: [{ id: "customers-new", label: "New", icon: <LayoutGrid className="size-4" /> }, { id: "customers-reports", label: "Reports", icon: <ClipboardList className="size-4" /> }] },
725
+ { id: "orders", label: "Orders", icon: <LayoutGrid className="size-4" />, children: [{ id: "orders-sales", label: "Sales", icon: <Search className="size-4" /> }] },
726
+ { id: "profile", label: "Profile", url: "/profile", icon: <Settings className="size-4" /> }
727
+ ];
728
+
729
+ const USER_MENU: SgMenuNode[] = [{ id: "perfil", label: "My profile", onClick: () => {} }, { id: "logout", label: "Sign out", onClick: () => {} }];
730
+
731
+ export default function Example() {
732
+ const [activeId, setActiveId] = React.useState("dashboard");
733
+ const [collapsed, setCollapsed] = React.useState(false);
734
+ return (
735
+ <div className="h-[460px] overflow-hidden rounded-lg border border-border">
736
+ <div className="flex h-full">
737
+ <SgMenu menu={MENU} selection={{ activeId }} menuStyle="sidebar" mode="accordion" collapsed={collapsed} onCollapsedChange={setCollapsed} showCollapseButton search={{ enabled: true, placeholder: "Search module..." }} brand={{ title: "SeedGrid ERP" }} user={{ name: "Lucia Souza", subtitle: "Finance" }} userMenu={USER_MENU} onNavigate={(node) => setActiveId(node.id)} />
738
+ <div className="flex-1 space-y-3 p-4"><h3 className="text-base font-semibold">Main content</h3><p className="text-sm text-muted-foreground">Active item: <span className="font-medium text-foreground">{activeId}</span></p></div>
739
+ </div>
740
+ </div>
741
+ );
742
+ }
743
+ ```
744
+
745
+ ### drawer-mobile
746
+
747
+ Fonte: `apps/showcase/src/app/components/sg-menu/samples/drawer-mobile.tsx.sample`. Drawer controlado (`open`/`onOpenChange`) com pin.
748
+
749
+ ```tsx
750
+ import React from "react";
751
+ import { ClipboardList, Home, LayoutGrid, Search, Settings, Users } from "lucide-react";
752
+ import { SgButton, SgMenu, type SgMenuNode } from "@seedgrid/fe-components";
753
+
754
+ const MENU: SgMenuNode[] = [
755
+ { id: "dashboard", label: "Dashboard", url: "/dashboard", icon: <Home className="size-4" /> },
756
+ { id: "customers", label: "Customers", icon: <Users className="size-4" />, children: [{ id: "customers-new", label: "New", icon: <LayoutGrid className="size-4" /> }, { id: "customers-reports", label: "Reports", icon: <ClipboardList className="size-4" /> }] },
757
+ { id: "orders", label: "Orders", icon: <LayoutGrid className="size-4" />, children: [{ id: "orders-sales", label: "Sales", icon: <Search className="size-4" /> }] },
758
+ { id: "profile", label: "Profile", url: "/profile", icon: <Settings className="size-4" /> }
759
+ ];
760
+
761
+ export default function Example() {
762
+ const [activeId, setActiveId] = React.useState("dashboard");
763
+ const [drawerOpen, setDrawerOpen] = React.useState(false);
764
+ const [drawerPinned, setDrawerPinned] = React.useState(false);
765
+ return (
766
+ <>
767
+ <div className="flex flex-wrap gap-2">
768
+ <SgButton onClick={() => setDrawerOpen(true)}>Open mobile menu</SgButton>
769
+ <SgButton appearance="outline" onClick={() => setDrawerPinned((v) => !v)}>{drawerPinned ? "Unpin drawer" : "Pin drawer"}</SgButton>
770
+ </div>
771
+ <SgMenu menu={MENU} selection={{ activeId }} menuStyle="drawer" open={drawerOpen} onOpenChange={setDrawerOpen} pinned={drawerPinned} onPinnedChange={setDrawerPinned} showPinButton closeOnNavigate search={{ enabled: true, placeholder: "Search..." }} brand={{ title: "SeedGrid ERP" }} onNavigate={(node) => setActiveId(node.id)} />
772
+ </>
773
+ );
774
+ }
775
+ ```
776
+
777
+
778
+ ## SgTreeView
779
+
780
+ ### basico
781
+
782
+ Fonte: `apps/showcase/src/app/components/sg-tree-view/samples/basico.tsx.sample`. Checkboxes controlados, busca e leitura via `SgTreeViewRef`.
783
+
784
+ ```tsx
785
+ import React from "react";
786
+ import { BarChart3, FileText, Shield, Users } from "lucide-react";
787
+ import { SgCard, SgTreeView, type SgTreeNode, type SgTreeViewRef } from "@seedgrid/fe-components";
788
+
789
+ const nodes: SgTreeNode[] = [
790
+ {
791
+ id: "root",
792
+ label: "Admin",
793
+ icon: <Shield className="h-4 w-4" />,
794
+ children: [
795
+ {
796
+ id: "users",
797
+ label: "Users",
798
+ icon: <Users className="h-4 w-4" />,
799
+ children: [
800
+ { id: "users.list", label: "List users", icon: <FileText className="h-4 w-4" /> },
801
+ { id: "users.create", label: "Create user", icon: <FileText className="h-4 w-4" /> }
802
+ ]
803
+ },
804
+ {
805
+ id: "reports",
806
+ label: "Reports",
807
+ icon: <BarChart3 className="h-4 w-4" />,
808
+ children: [
809
+ { id: "reports.sales", label: "Sales report", icon: <FileText className="h-4 w-4" /> },
810
+ { id: "reports.financial", label: "Financial report", icon: <FileText className="h-4 w-4" /> }
811
+ ]
812
+ }
813
+ ]
814
+ }
815
+ ];
816
+
817
+ export default function Example() {
818
+ const [checkedIds, setCheckedIds] = React.useState<string[]>([]);
819
+ const [readAll, setReadAll] = React.useState<string[]>([]);
820
+ const [readLeafs, setReadLeafs] = React.useState<string[]>([]);
821
+ const treeRef = React.useRef<SgTreeViewRef>(null);
822
+
823
+ return (
824
+ <>
825
+ <SgCard title="Permissions">
826
+ <SgTreeView
827
+ ref={treeRef}
828
+ nodes={nodes}
829
+ searchable
830
+ searchPlaceholder="Search..."
831
+ checkable
832
+ checkedIds={checkedIds}
833
+ onCheckedChange={setCheckedIds}
834
+ onLeafClick={(id) => console.log(id)}
835
+ style={{ border: "1px solid rgba(59, 130, 246, 0.2)", borderRadius: 12, padding: 8 }}
836
+ />
837
+ </SgCard>
838
+
839
+ <div className="mt-3 flex gap-2">
840
+ <button type="button" className="rounded-md border border-border px-3 py-2 text-sm" onClick={() => setReadAll(treeRef.current?.getCheckedIds() ?? [])}>
841
+ Ler todos os checkeds
842
+ </button>
843
+ <button type="button" className="rounded-md border border-border px-3 py-2 text-sm" onClick={() => setReadLeafs(treeRef.current?.getCheckedLeafIds() ?? [])}>
844
+ Ler apenas leafs
845
+ </button>
846
+ </div>
847
+
848
+ <div className="mt-3 grid gap-2 text-xs text-muted-foreground">
849
+ <div>checkedIds: {readAll.join(", ") || "-"}</div>
850
+ <div>leafIds: {readLeafs.join(", ") || "-"}</div>
851
+ </div>
852
+ </>
853
+ );
854
+ }
855
+ ```
856
+
857
+ ### confirm
858
+
859
+ Fonte: `apps/showcase/src/app/components/sg-tree-view/samples/confirm.tsx.sample`. `checkMode="confirm"` com `confirmBar`.
860
+
861
+ ```tsx
862
+ import React from "react";
863
+ import { BarChart3, FileText, Shield, Users } from "lucide-react";
864
+ import { SgCard, SgTreeView, type SgTreeNode, type SgTreeViewRef } from "@seedgrid/fe-components";
865
+
866
+ const nodes: SgTreeNode[] = [
867
+ {
868
+ id: "root",
869
+ label: "Admin",
870
+ icon: <Shield className="h-4 w-4" />,
871
+ children: [
872
+ {
873
+ id: "users",
874
+ label: "Users",
875
+ icon: <Users className="h-4 w-4" />,
876
+ children: [
877
+ { id: "users.list", label: "List users", icon: <FileText className="h-4 w-4" /> },
878
+ { id: "users.create", label: "Create user", icon: <FileText className="h-4 w-4" /> }
879
+ ]
880
+ },
881
+ {
882
+ id: "reports",
883
+ label: "Reports",
884
+ icon: <BarChart3 className="h-4 w-4" />,
885
+ children: [
886
+ { id: "reports.sales", label: "Sales report", icon: <FileText className="h-4 w-4" /> },
887
+ { id: "reports.financial", label: "Financial report", icon: <FileText className="h-4 w-4" /> }
888
+ ]
889
+ }
890
+ ]
891
+ }
892
+ ];
893
+
894
+ export default function Example() {
895
+ const [confirmed, setConfirmed] = React.useState<string[]>([]);
896
+ const treeRef = React.useRef<SgTreeViewRef>(null);
897
+
898
+ return (
899
+ <>
900
+ <SgCard title="Confirm selection">
901
+ <SgTreeView
902
+ ref={treeRef}
903
+ nodes={nodes}
904
+ searchable
905
+ searchPlaceholder="Search..."
906
+ checkable
907
+ checkMode="confirm"
908
+ confirmSelection="leafOnly"
909
+ confirmBar={{
910
+ label: "Confirmar",
911
+ showCancel: true,
912
+ cancelLabel: "Limpar",
913
+ onConfirm: (ids) => setConfirmed(ids),
914
+ onCancel: () => treeRef.current?.clearChecked()
915
+ }}
916
+ />
917
+ </SgCard>
918
+ <div className="mt-3 text-xs text-muted-foreground">confirmIds: {confirmed.join(", ") || "-"}</div>
919
+ </>
920
+ );
921
+ }
922
+ ```
923
+
924
+ ### json-checked
925
+
926
+ Fonte: `apps/showcase/src/app/components/sg-tree-view/samples/json-checked.tsx.sample`. Montagem a partir de JSON com `sgTreeFromJsonWithChecked`.
927
+
928
+ ```tsx
929
+ import React from "react";
930
+ import { SgTreeView, sgTreeFromJsonWithChecked } from "@seedgrid/fe-components";
931
+
932
+ const json = [
933
+ {
934
+ id: "root",
935
+ label: "Admin",
936
+ children: [
937
+ {
938
+ id: "users",
939
+ label: "Users",
940
+ children: [
941
+ { id: "users.list", label: "List users", checked: true },
942
+ { id: "users.create", label: "Create user" }
943
+ ]
944
+ },
945
+ {
946
+ id: "reports",
947
+ label: "Reports",
948
+ children: [
949
+ { id: "reports.sales", label: "Sales report", checked: true },
950
+ { id: "reports.financial", label: "Financial report" }
951
+ ]
952
+ }
953
+ ]
954
+ }
955
+ ];
956
+
957
+ export default function Example() {
958
+ const { nodes, checkedIds } = sgTreeFromJsonWithChecked(json);
959
+
960
+ return (
961
+ <SgTreeView
962
+ nodes={nodes}
963
+ checkable
964
+ defaultCheckedIds={checkedIds}
965
+ defaultExpandedIds={["root", "users"]}
966
+ />
967
+ );
968
+ }
969
+ ```
970
+
971
+
972
+ ## SgDockLayout + SgDockZone
973
+
974
+ ### basico
975
+
976
+ Fonte: `apps/showcase/src/app/components/sg-dock-layout/samples/basico.tsx.sample`. Layout com quatro zonas e toolbars arrastáveis (estado persistido em `dock-layout:<id>`).
977
+
978
+ ```tsx
979
+ import React from "react";
980
+ import { SgDockLayout, SgDockZone, SgToolBar, SgToolbarIconButton } from "@seedgrid/fe-components";
981
+ import { ClipboardList, Home, LayoutGrid, Search, Settings, Users } from "lucide-react";
982
+
983
+ export default function Example() {
984
+ return (
985
+ <div className="relative h-[420px] overflow-hidden rounded-xl border border-border bg-black">
986
+ <SgDockLayout
987
+ id="showcase-dock-basic-v9"
988
+ className="grid h-full grid-cols-[8rem_1fr_8rem] grid-rows-[auto_1fr_auto]"
989
+ style={{ boxShadow: "inset 0 0 0 1px rgba(255, 255, 255, 0.08)" }}
990
+ >
991
+ <SgDockZone
992
+ zone="top"
993
+ className="col-span-3 row-start-1 items-start border-b border-white/20"
994
+ style={{ backgroundColor: "rgba(255, 255, 255, 0.03)" }}
995
+ >
996
+ <SgToolBar id="tb-main-basic-v9" dockZone="top" orientationDirection="horizontal-left" title="Topo" draggable>
997
+ <SgToolbarIconButton icon={<Home className="size-4" />} label="Home" hint="Ir para inicio" />
998
+ <SgToolbarIconButton icon={<Search className="size-4" />} label="Buscar" hint="Pesquisar registros" />
999
+ </SgToolBar>
1000
+ <SgToolBar id="tb-top-extra-basic-v9" dockZone="top" orientationDirection="horizontal-left" title="Acoes" draggable>
1001
+ <SgToolbarIconButton icon={<LayoutGrid className="size-4" />} label="Painel" hint="Abrir painel" />
1002
+ <SgToolbarIconButton icon={<ClipboardList className="size-4" />} label="Relatorio" hint="Abrir relatorios" />
1003
+ </SgToolBar>
1004
+ </SgDockZone>
1005
+
1006
+ <SgDockZone zone="left" className="col-start-1 row-start-2 items-start border-r border-white/20">
1007
+ <SgToolBar id="tb-left-basic-v9" dockZone="left" orientationDirection="vertical-down" title="Navegacao" collapsible draggable>
1008
+ <SgToolbarIconButton icon={<Users className="size-4" />} label="Clientes" hint="Abrir clientes" />
1009
+ <SgToolbarIconButton icon={<Settings className="size-4" />} label="Config" hint="Abrir configuracoes" />
1010
+ </SgToolBar>
1011
+ </SgDockZone>
1012
+
1013
+ <SgDockZone zone="right" className="col-start-3 row-start-2 items-start border-l border-white/20">
1014
+ <SgToolBar id="tb-right-basic-v9" dockZone="right" orientationDirection="vertical-down" title="Equipe" collapsible draggable>
1015
+ <SgToolbarIconButton icon={<Users className="size-4" />} label="Usuarios" hint="Gerenciar usuarios" />
1016
+ <SgToolbarIconButton icon={<Settings className="size-4" />} label="Ajustes" hint="Abrir ajustes" />
1017
+ </SgToolBar>
1018
+ </SgDockZone>
1019
+
1020
+ <SgDockZone zone="bottom" className="col-span-3 row-start-3 items-end border-t border-white/20">
1021
+ <SgToolBar id="tb-bottom-a-basic-v9" dockZone="bottom" orientationDirection="horizontal-left" title="Rodape A" draggable>
1022
+ <SgToolbarIconButton icon={<LayoutGrid className="size-4" />} label="Painel" hint="Abrir painel" />
1023
+ <SgToolbarIconButton icon={<Search className="size-4" />} label="Buscar" hint="Pesquisar no rodape" />
1024
+ </SgToolBar>
1025
+ <SgToolBar id="tb-bottom-b-basic-v9" dockZone="bottom" orientationDirection="horizontal-left" title="Rodape B" draggable>
1026
+ <SgToolbarIconButton icon={<ClipboardList className="size-4" />} label="Tarefas" hint="Abrir tarefas" />
1027
+ <SgToolbarIconButton icon={<Home className="size-4" />} label="Home" hint="Voltar ao inicio" />
1028
+ </SgToolBar>
1029
+ </SgDockZone>
1030
+ </SgDockLayout>
1031
+ </div>
1032
+ );
1033
+ }
1034
+ ```
1035
+
1036
+
1037
+ ## SgDockScreen
1038
+
1039
+ ### basico
1040
+
1041
+ Fonte: `apps/showcase/src/app/components/sg-dock-screen/samples/basico.tsx.sample`. Mesma composição com a grade pronta do `SgDockScreen` (zonas sem `className`).
1042
+
1043
+ ```tsx
1044
+ import React from "react";
1045
+ import { SgDockScreen, SgDockZone, SgToolBar, SgToolbarIconButton } from "@seedgrid/fe-components";
1046
+ import { ClipboardList, Home, LayoutGrid, Search, Settings, Users } from "lucide-react";
1047
+
1048
+ export default function Example() {
1049
+ return (
1050
+ <SgDockScreen
1051
+ id="showcase-dock-screen-basic-v1"
1052
+ fullscreen={false}
1053
+ height={420}
1054
+ className="overflow-hidden rounded-xl border border-border bg-background"
1055
+ >
1056
+ <SgDockZone zone="top">
1057
+ <SgToolBar id="tb-top-dock-screen-v1" dockZone="top" orientationDirection="horizontal-left" title="Topo" draggable>
1058
+ <SgToolbarIconButton icon={<Home className="size-4" />} label="Inicio" hint="Ir para inicio" />
1059
+ <SgToolbarIconButton icon={<Search className="size-4" />} label="Buscar" hint="Pesquisar dados" />
1060
+ </SgToolBar>
1061
+ </SgDockZone>
1062
+
1063
+ <SgDockZone zone="bottom">
1064
+ <SgToolBar id="tb-bottom-dock-screen-v1" dockZone="bottom" orientationDirection="horizontal-left" title="Base" draggable>
1065
+ <SgToolbarIconButton icon={<LayoutGrid className="size-4" />} label="Painel" hint="Abrir painel" />
1066
+ <SgToolbarIconButton icon={<ClipboardList className="size-4" />} label="Relatorio" hint="Abrir relatorios" />
1067
+ </SgToolBar>
1068
+ </SgDockZone>
1069
+
1070
+ <SgDockZone zone="left">
1071
+ <SgToolBar id="tb-left-dock-screen-v1" dockZone="left" orientationDirection="vertical-down" title="Navegacao" collapsible draggable>
1072
+ <SgToolbarIconButton icon={<Users className="size-4" />} label="Clientes" hint="Abrir clientes" />
1073
+ <SgToolbarIconButton icon={<Settings className="size-4" />} label="Config" hint="Abrir configuracoes" />
1074
+ </SgToolBar>
1075
+ </SgDockZone>
1076
+
1077
+ <SgDockZone zone="right">
1078
+ <SgToolBar id="tb-right-dock-screen-v1" dockZone="right" orientationDirection="vertical-down" title="Equipe" collapsible draggable>
1079
+ <SgToolbarIconButton icon={<Users className="size-4" />} label="Usuarios" hint="Gerenciar usuarios" />
1080
+ <SgToolbarIconButton icon={<Settings className="size-4" />} label="Ajustes" hint="Abrir ajustes" />
1081
+ </SgToolBar>
1082
+ </SgDockZone>
1083
+
1084
+ <SgDockZone zone="free">
1085
+ <div className="pointer-events-none text-sm text-muted-foreground">Area central livre</div>
1086
+ </SgDockZone>
1087
+ </SgDockScreen>
1088
+ );
1089
+ }
1090
+ ```
1091
+
1092
+
1093
+ ## SgToolBar + SgToolbarIconButton
1094
+
1095
+ ### basico
1096
+
1097
+ Fonte: `apps/showcase/src/app/components/sg-toolbar/samples/basico.tsx.sample`. Toolbar vertical numa zona `free`, botões com `hint` e `severity`.
1098
+
1099
+ ```tsx
1100
+ import React from "react";
1101
+ import { SgDockLayout, SgDockZone, SgToolBar, SgToolbarIconButton } from "@seedgrid/fe-components";
1102
+ import { Home, Settings, Users } from "lucide-react";
1103
+
1104
+ export default function Example() {
1105
+ return (
1106
+ <div className="w-full">
1107
+ <SgDockLayout id="tb-layout-basic" className="grid grid-cols-1 grid-rows-1">
1108
+ <SgDockZone zone="free" className="col-start-1 row-start-1 !items-start !justify-start !p-0">
1109
+ <SgToolBar id="tb-basic" title="Navegacao" orientationDirection="vertical-down">
1110
+ <SgToolbarIconButton icon={<Home className="size-4" />} label="Home" hint="Ir para Home" severity="primary" className="ring-1 ring-primary/30" style={{ minWidth: 132 }} />
1111
+ <SgToolbarIconButton icon={<Users className="size-4" />} label="Usuarios" hint="Abrir lista de usuarios" />
1112
+ <SgToolbarIconButton icon={<Settings className="size-4" />} label="Configuracoes" hint="Abrir configuracoes" />
1113
+ </SgToolBar>
1114
+ </SgDockZone>
1115
+ </SgDockLayout>
1116
+ </div>
1117
+ );
1118
+ }
1119
+ ```
1120
+
1121
+ ### onclick-assincrono-com-toast
1122
+
1123
+ Fonte: `apps/showcase/src/app/components/sg-toolbar/samples/onclick-assincrono-com-toast.tsx.sample`. `onClick` assíncrono: o botão entra em loading até a Promise resolver.
1124
+
1125
+ ```tsx
1126
+ import React from "react";
1127
+ import { SgDockLayout, SgDockZone, SgToolBar, SgToolbarIconButton, toast } from "@seedgrid/fe-components";
1128
+ import { Pencil, Plus, Trash2 } from "lucide-react";
1129
+
1130
+ export default function Example() {
1131
+ return (
1132
+ <div className="w-full">
1133
+ <SgDockLayout id="tb-layout-async" className="grid grid-cols-1 grid-rows-1">
1134
+ <SgDockZone zone="free" className="col-start-1 row-start-1 !items-start !justify-start !p-0">
1135
+ <SgToolBar id="tb-async" title="Acoes rapidas" orientationDirection="horizontal-left" collapsible>
1136
+ <SgToolbarIconButton
1137
+ icon={<Plus className="size-4" />}
1138
+ label="Criar"
1139
+ hint="Criar novo registro"
1140
+ severity="success"
1141
+ onClick={async () => {
1142
+ await new Promise((resolve) => setTimeout(resolve, 1000));
1143
+ toast.success("Acao Criar concluida");
1144
+ }}
1145
+ />
1146
+ <SgToolbarIconButton
1147
+ icon={<Pencil className="size-4" />}
1148
+ label="Editar"
1149
+ hint="Editar registro selecionado"
1150
+ severity="info"
1151
+ onClick={async () => {
1152
+ await new Promise((resolve) => setTimeout(resolve, 1000));
1153
+ toast.info("Acao Editar concluida");
1154
+ }}
1155
+ />
1156
+ <SgToolbarIconButton
1157
+ icon={<Trash2 className="size-4" />}
1158
+ label="Excluir"
1159
+ hint="Excluir registro selecionado"
1160
+ severity="danger"
1161
+ onClick={async () => {
1162
+ await new Promise((resolve) => setTimeout(resolve, 1000));
1163
+ toast.warning("Acao Excluir concluida");
1164
+ }}
1165
+ />
1166
+ </SgToolBar>
1167
+ </SgDockZone>
1168
+ </SgDockLayout>
1169
+ </div>
1170
+ );
1171
+ }
1172
+ ```