@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.
- package/LICENSE +21 -0
- package/README.md +151 -2
- package/dist/adapters/claude.js +114 -0
- package/dist/adapters/codex.js +108 -0
- package/dist/adapters/index.js +17 -0
- package/dist/adapters/shared.js +142 -0
- package/dist/adapters/types.js +1 -0
- package/dist/cli.js +203 -0
- package/dist/commands/common.js +98 -0
- package/dist/commands/doctor.js +290 -0
- package/dist/commands/init.js +9 -0
- package/dist/commands/install.js +107 -0
- package/dist/commands/remove.js +54 -0
- package/dist/commands/review.js +127 -0
- package/dist/commands/status.js +73 -0
- package/dist/commands/update.js +8 -0
- package/dist/commands/validate.js +27 -0
- package/dist/core/apply.js +181 -0
- package/dist/core/blocks.js +64 -0
- package/dist/core/content.js +528 -0
- package/dist/core/env.js +40 -0
- package/dist/core/frontmatter.js +29 -0
- package/dist/core/hash.js +14 -0
- package/dist/core/inspect.js +51 -0
- package/dist/core/lock.js +124 -0
- package/dist/core/paths.js +65 -0
- package/dist/core/plan.js +242 -0
- package/dist/core/tools.js +62 -0
- package/dist/core/types.js +11 -0
- package/dist/core/updates.js +121 -0
- package/docs/arquitetura.md +80 -0
- package/docs/compatibilidade.md +50 -0
- package/docs/formato.md +155 -0
- package/docs/instalacao.md +105 -0
- package/docs/manutencao.md +115 -0
- package/package.json +43 -4
- package/seedgridKB/SeedGrid/Extensions/Catalogo-de-enums.md +161 -0
- package/seedgridKB/SeedGrid/Extensions/Catalogo-de-propriedades.md +971 -0
- package/seedgridKB/SeedGrid/Extensions/Indice.md +63 -0
- package/seedgridKB/SeedGrid/Extensions/ai-pricing/Configuracao.md +124 -0
- package/seedgridKB/SeedGrid/Extensions/ai-pricing/Enums.md +40 -0
- package/seedgridKB/SeedGrid/Extensions/ai-pricing/Exemplos.md +97 -0
- package/seedgridKB/SeedGrid/Extensions/ai-pricing/Visao-geral.md +114 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Configuracao-Rust.md +69 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Configuracao.md +88 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Enums.md +33 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Exemplos.md +121 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Rust.md +126 -0
- package/seedgridKB/SeedGrid/Extensions/apikeys/Visao-geral.md +111 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Configuracao-Rust.md +93 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Configuracao.md +127 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Enums.md +66 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Exemplos.md +151 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Rust.md +120 -0
- package/seedgridKB/SeedGrid/Extensions/audit/Visao-geral.md +114 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Configuracao-Rust.md +136 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Configuracao.md +319 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Enums.md +131 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Exemplos.md +210 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Rust.md +135 -0
- package/seedgridKB/SeedGrid/Extensions/backup/Visao-geral.md +150 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Configuracao-Rust.md +86 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Configuracao.md +243 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Enums.md +165 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Exemplos.md +205 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Rust.md +109 -0
- package/seedgridKB/SeedGrid/Extensions/billing/Visao-geral.md +181 -0
- package/seedgridKB/SeedGrid/Extensions/broker/Configuracao-Rust.md +40 -0
- package/seedgridKB/SeedGrid/Extensions/broker/Visao-geral.md +114 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Configuracao-Rust.md +73 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Configuracao.md +112 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Enums.md +36 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Exemplos.md +149 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Rust.md +81 -0
- package/seedgridKB/SeedGrid/Extensions/cache/Visao-geral.md +90 -0
- package/seedgridKB/SeedGrid/Extensions/commons/Configuracao.md +107 -0
- package/seedgridKB/SeedGrid/Extensions/commons/Enums.md +105 -0
- package/seedgridKB/SeedGrid/Extensions/commons/Exemplos.md +141 -0
- package/seedgridKB/SeedGrid/Extensions/commons/Visao-geral.md +99 -0
- package/seedgridKB/SeedGrid/Extensions/exchange/Configuracao.md +122 -0
- package/seedgridKB/SeedGrid/Extensions/exchange/Enums.md +29 -0
- package/seedgridKB/SeedGrid/Extensions/exchange/Exemplos.md +82 -0
- package/seedgridKB/SeedGrid/Extensions/exchange/Visao-geral.md +118 -0
- package/seedgridKB/SeedGrid/Extensions/filemanagement/Configuracao-Rust.md +110 -0
- package/seedgridKB/SeedGrid/Extensions/filemanagement/Configuracao.md +157 -0
- package/seedgridKB/SeedGrid/Extensions/filemanagement/Exemplos.md +157 -0
- package/seedgridKB/SeedGrid/Extensions/filemanagement/Rust.md +70 -0
- package/seedgridKB/SeedGrid/Extensions/filemanagement/Visao-geral.md +88 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Configuracao-Rust.md +124 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Configuracao.md +195 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Enums.md +71 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Exemplos.md +149 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Rust.md +139 -0
- package/seedgridKB/SeedGrid/Extensions/login-tenancy/Visao-geral.md +130 -0
- package/seedgridKB/SeedGrid/Extensions/notification/Configuracao.md +141 -0
- package/seedgridKB/SeedGrid/Extensions/notification/Enums.md +52 -0
- package/seedgridKB/SeedGrid/Extensions/notification/Exemplos.md +141 -0
- package/seedgridKB/SeedGrid/Extensions/notification/Visao-geral.md +113 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Configuracao-Rust.md +67 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Configuracao.md +94 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Enums.md +79 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Exemplos.md +172 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Rust.md +107 -0
- package/seedgridKB/SeedGrid/Extensions/privacy/Visao-geral.md +90 -0
- package/seedgridKB/SeedGrid/Extensions/realtime/Configuracao-Rust.md +72 -0
- package/seedgridKB/SeedGrid/Extensions/realtime/Configuracao.md +104 -0
- package/seedgridKB/SeedGrid/Extensions/realtime/Exemplos.md +104 -0
- package/seedgridKB/SeedGrid/Extensions/realtime/Rust.md +69 -0
- package/seedgridKB/SeedGrid/Extensions/realtime/Visao-geral.md +105 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Configuracao-Rust.md +68 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Configuracao.md +186 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Enums.md +96 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Exemplos.md +229 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Rust.md +80 -0
- package/seedgridKB/SeedGrid/Extensions/resilience/Visao-geral.md +112 -0
- package/seedgridKB/SeedGrid/Extensions/runtime/Configuracao-Rust.md +90 -0
- package/seedgridKB/SeedGrid/Extensions/runtime/Visao-geral.md +114 -0
- package/seedgridKB/SeedGrid/Extensions/security/Configuracao-Rust.md +327 -0
- package/seedgridKB/SeedGrid/Extensions/security/Configuracao.md +510 -0
- package/seedgridKB/SeedGrid/Extensions/security/Enums.md +95 -0
- package/seedgridKB/SeedGrid/Extensions/security/Exemplos.md +218 -0
- package/seedgridKB/SeedGrid/Extensions/security/Rust.md +203 -0
- package/seedgridKB/SeedGrid/Extensions/security/Visao-geral.md +131 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Configuracao-Rust.md +188 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Configuracao.md +345 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Enums.md +117 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Exemplos.md +205 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Rust.md +161 -0
- package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Visao-geral.md +142 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Configuracao-Rust.md +75 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Configuracao.md +152 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Enums.md +198 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Exemplos.md +173 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Rust.md +83 -0
- package/seedgridKB/SeedGrid/Extensions/whatsapp/Visao-geral.md +99 -0
- package/seedgridKB/SeedGrid/Mapa-dos-repositorios.md +112 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/Indice.md +323 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/buttons/API.md +257 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/buttons/Exemplos.md +307 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/buttons/Visao-geral.md +51 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/datatable/API.md +174 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/datatable/Exemplos.md +236 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/datatable/Visao-geral.md +76 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/digits/API.md +339 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/digits/Exemplos.md +311 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/digits/Visao-geral.md +57 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/editor/API.md +125 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/editor/Exemplos.md +116 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/editor/Visao-geral.md +86 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/API.md +490 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/Exemplos.md +544 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/Visao-geral.md +69 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/API.md +113 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/Exemplos.md +159 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/Visao-geral.md +92 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/API.md +516 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/Exemplos.md +629 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/Visao-geral.md +80 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/API.md +615 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/Exemplos.md +384 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/Visao-geral.md +111 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/API.md +661 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/Exemplos.md +312 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/Visao-geral.md +123 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/layout/API.md +1090 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/layout/Exemplos.md +1172 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/layout/Visao-geral.md +98 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/Visao-geral.md +98 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-apikeys.md +118 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-audit.md +88 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-backup.md +131 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-billing-platform.md +132 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-billing-user.md +120 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-login-tenancy.md +119 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-security.md +427 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-self-enter.md +104 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-subdomain-tenancy.md +110 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/API.md +490 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/Exemplos.md +561 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/Visao-geral.md +82 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/Visao-geral.md +68 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-commons.md +61 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-core.md +140 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-playground.md +112 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-theme.md +97 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/providers/API.md +177 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/providers/Exemplos.md +332 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/providers/Visao-geral.md +106 -0
- package/seedgridKB/SeedGrid/SeedGrid-components/showcase.md +70 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/arquiteto.md +53 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/backend-java.md +45 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/backend-rust.md +43 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/frontend-react.md +41 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/qa.md +44 -0
- package/seedgridKB/SeedGrid/Toolkit/agents/revisor.md +40 -0
- package/seedgridKB/SeedGrid/Toolkit/references/fluxo-de-trabalho.md +78 -0
- package/seedgridKB/SeedGrid/Toolkit/references/glossario.md +15 -0
- package/seedgridKB/SeedGrid/Toolkit/references/modos-shared-native.md +27 -0
- package/seedgridKB/SeedGrid/Toolkit/rules/backend-java-seedgrid.md +54 -0
- package/seedgridKB/SeedGrid/Toolkit/rules/coordenacao.md +39 -0
- package/seedgridKB/SeedGrid/Toolkit/rules/formato-entrega.md +29 -0
- package/seedgridKB/SeedGrid/Toolkit/rules/frontend-seedgrid.md +47 -0
- package/seedgridKB/SeedGrid/Toolkit/rules/personalizacao-local.md +22 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/planejar-mudanca/SKILL.md +38 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/revisar-codigo/SKILL.md +33 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/revisar-codigo/references/checklist.md +25 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-backend-crud/SKILL.md +29 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-bump/SKILL.md +26 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/SKILL.md +221 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/agents/openai.yaml +4 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/checklist.md +31 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/patterns.md +185 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/routing.md +66 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/SKILL.md +56 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/agents/openai.yaml +4 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/references/checklist.md +32 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/references/steps.md +114 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-review/SKILL.md +61 -0
- package/seedgridKB/SeedGrid/Toolkit/skills/validar-mudanca/SKILL.md +29 -0
- package/seedgridKB/SeedGrid/Toolkit/templates/decisao-arquitetura.md +29 -0
- package/seedgridKB/SeedGrid/Toolkit/templates/especificacao-tarefa.md +32 -0
- package/seedgridKB/SeedGrid/Toolkit/templates/relatorio-validacao.md +30 -0
- package/seedgridKB/SeedGrid/Versoes.md +64 -0
- package/seedgridKB/SeedGrid/Visao-geral.md +35 -0
- package/seedgridKB/manifest.json +142 -0
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: [seedgrid, front, component, navegacao-e-overlay]
|
|
3
|
+
fonte: front/seedgrid-fe-components/apps/showcase/src/app/components (sg-dock-menu, sg-popup, sg-dialog, sg-confirmation-dialog, sg-wizard)
|
|
4
|
+
branch: main
|
|
5
|
+
commit: ad30fc11de
|
|
6
|
+
analisado-em: 2026-10-14
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Exemplos — navegação e overlay
|
|
10
|
+
|
|
11
|
+
Visão geral: [[SeedGrid/SeedGrid-components/navegacao-e-overlay/Visao-geral|Navegação e overlay]] · API: [[SeedGrid/SeedGrid-components/navegacao-e-overlay/API|API]]
|
|
12
|
+
|
|
13
|
+
Todos os exemplos abaixo foram verificados com type-check TypeScript (`strict`) contra `packages/seedgrid-fe-components/src/index.ts` no commit `ad30fc11de` (resultado: OK). Os marcados "1:1" são cópias exatas dos arquivos `samples/*.tsx.sample` do showcase. Os do `SgDockMenu` foram **completados** (imports e componente) porque os samples do showcase desse componente são trechos sem `import`/`export` — o JSX e os dados são os do sample citado.
|
|
14
|
+
|
|
15
|
+
## SgDockMenu
|
|
16
|
+
|
|
17
|
+
### Dock básico ancorado num container
|
|
18
|
+
Baseado em `apps/showcase/src/app/components/sg-dock-menu/samples/basico.tsx.sample` (completado com imports). `style={{ position: "absolute" }}` prende o dock ao container `relative`.
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
import React from "react";
|
|
22
|
+
import { Bell, Home, Mail, Settings, User } from "lucide-react";
|
|
23
|
+
import { SgDockMenu, type SgDockMenuItem } from "@seedgrid/fe-components";
|
|
24
|
+
|
|
25
|
+
const items: SgDockMenuItem[] = [
|
|
26
|
+
{ id: "home", icon: <Home size={24} />, label: "Home" },
|
|
27
|
+
{ id: "mail", icon: <Mail size={24} />, label: "Mail", badge: 5 },
|
|
28
|
+
{ id: "notifications", icon: <Bell size={24} />, label: "Notifications", badge: 12 },
|
|
29
|
+
{ id: "settings", icon: <Settings size={24} />, label: "Settings" },
|
|
30
|
+
{ id: "profile", icon: <User size={24} />, label: "Profile" }
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
export default function Example() {
|
|
34
|
+
return (
|
|
35
|
+
<div className="relative h-64 rounded-lg border-2 border-dashed border-border bg-muted/20">
|
|
36
|
+
<SgDockMenu id="basic-dock" items={items} position="center-bottom" zIndex={10} style={{ position: "absolute" }} />
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Arraste com posição persistida + callbacks e item desabilitado
|
|
43
|
+
Combina `samples/drag-and-drop.tsx.sample` e `samples/callbacks-e-disabled.tsx.sample` (completado). Com `dragId`, a posição arrastada é salva (`localStorage` ou `SgEnvironmentProvider`) e o clique direito oferece "resetar posição".
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
import React from "react";
|
|
47
|
+
import { Home, Mail, Settings } from "lucide-react";
|
|
48
|
+
import { SgDockMenu, type SgDockMenuItem } from "@seedgrid/fe-components";
|
|
49
|
+
|
|
50
|
+
const items: SgDockMenuItem[] = [
|
|
51
|
+
{ id: "home", icon: <Home size={24} />, label: "Home" },
|
|
52
|
+
{ id: "mail", icon: <Mail size={24} />, label: "Mail", badge: 5 },
|
|
53
|
+
{ id: "settings", icon: <Settings size={24} />, label: "Settings", disabled: true }
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
export default function Example() {
|
|
57
|
+
const [eventLog, setEventLog] = React.useState<string[]>([]);
|
|
58
|
+
const callbackItems: SgDockMenuItem[] = items.map((item) => ({
|
|
59
|
+
...item,
|
|
60
|
+
onClick: () => setEventLog((prev) => [`${item.label} clicked`, ...prev].slice(0, 10))
|
|
61
|
+
}));
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<div className="space-y-4">
|
|
65
|
+
<div className="relative h-80 rounded-lg border-2 border-dashed border-border bg-muted/20">
|
|
66
|
+
<SgDockMenu
|
|
67
|
+
id="draggable-dock"
|
|
68
|
+
dragId="demo-dockmenu-draggable"
|
|
69
|
+
items={callbackItems}
|
|
70
|
+
position="center-bottom"
|
|
71
|
+
enableDragDrop
|
|
72
|
+
zIndex={10}
|
|
73
|
+
style={{ position: "absolute" }}
|
|
74
|
+
/>
|
|
75
|
+
</div>
|
|
76
|
+
<div className="h-32 overflow-y-auto rounded border border-border bg-foreground/5 p-2 font-mono text-xs">
|
|
77
|
+
{eventLog.map((entry, idx) => <div key={idx}>{entry}</div>)}
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## SgPopup
|
|
85
|
+
|
|
86
|
+
### Popup com ações (1:1)
|
|
87
|
+
`apps/showcase/src/app/components/sg-popup/samples/basico.tsx.sample` — o consumidor abre pelo botão âncora; o popup fecha por clique fora, `Esc` ou clique numa ação.
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
import React from "react";
|
|
91
|
+
import { SgButton, SgPopup } from "@seedgrid/fe-components";
|
|
92
|
+
|
|
93
|
+
export default function Example() {
|
|
94
|
+
const btnRef = React.useRef<HTMLButtonElement>(null);
|
|
95
|
+
const [open, setOpen] = React.useState(false);
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<>
|
|
99
|
+
<SgButton ref={btnRef} onClick={() => setOpen(true)}>Abrir popup</SgButton>
|
|
100
|
+
<SgPopup
|
|
101
|
+
title="Configuracao"
|
|
102
|
+
subtitle="Resumo da acao"
|
|
103
|
+
open={open}
|
|
104
|
+
onOpenChange={setOpen}
|
|
105
|
+
anchorRef={btnRef as React.RefObject<HTMLElement>}
|
|
106
|
+
placement="auto"
|
|
107
|
+
preferPlacement="right"
|
|
108
|
+
align="start"
|
|
109
|
+
actions={[
|
|
110
|
+
{ label: "Confirmar" },
|
|
111
|
+
{ label: "Cancelar" }
|
|
112
|
+
]}
|
|
113
|
+
/>
|
|
114
|
+
</>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Ações com ícone e hint (1:1)
|
|
120
|
+
`apps/showcase/src/app/components/sg-popup/samples/icone-hint.tsx.sample`
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
import React from "react";
|
|
124
|
+
import { Check, X } from "lucide-react";
|
|
125
|
+
import { SgButton, SgPopup } from "@seedgrid/fe-components";
|
|
126
|
+
|
|
127
|
+
export default function Example() {
|
|
128
|
+
const btnRef = React.useRef<HTMLButtonElement>(null);
|
|
129
|
+
const [open, setOpen] = React.useState(false);
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<>
|
|
133
|
+
<SgButton ref={btnRef} onClick={() => setOpen(true)}>Abrir popup com icones</SgButton>
|
|
134
|
+
<SgPopup
|
|
135
|
+
title="Aprovacao"
|
|
136
|
+
open={open}
|
|
137
|
+
onOpenChange={setOpen}
|
|
138
|
+
anchorRef={btnRef as React.RefObject<HTMLElement>}
|
|
139
|
+
placement="auto"
|
|
140
|
+
preferPlacement="right"
|
|
141
|
+
align="start"
|
|
142
|
+
actions={[
|
|
143
|
+
{
|
|
144
|
+
label: "Aprovar",
|
|
145
|
+
hint: "Aprova a acao atual",
|
|
146
|
+
icon: <Check className="h-4 w-4" />
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
label: "Rejeitar",
|
|
150
|
+
hint: "Cancela a acao atual",
|
|
151
|
+
icon: <X className="h-4 w-4" />
|
|
152
|
+
}
|
|
153
|
+
]}
|
|
154
|
+
/>
|
|
155
|
+
</>
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## SgDialog
|
|
161
|
+
|
|
162
|
+
### Dialog com cabeçalho, rodapé e foco inicial (1:1)
|
|
163
|
+
`apps/showcase/src/app/components/sg-dialog/samples/basico.tsx.sample` — usa `leading`/`trailing`, `customColor`, `elevation` como `box-shadow` literal e `data-sg-dialog-initial-focus`.
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
import React from "react";
|
|
167
|
+
import { SgButton, SgDialog } from "@seedgrid/fe-components";
|
|
168
|
+
|
|
169
|
+
export default function Example() {
|
|
170
|
+
const [open, setOpen] = React.useState(false);
|
|
171
|
+
|
|
172
|
+
return (
|
|
173
|
+
<>
|
|
174
|
+
<SgButton onClick={() => setOpen(true)}>Abrir dialog</SgButton>
|
|
175
|
+
<SgDialog
|
|
176
|
+
open={open}
|
|
177
|
+
onOpenChange={setOpen}
|
|
178
|
+
title="Confirmar acao"
|
|
179
|
+
subtitle="Exemplo basico"
|
|
180
|
+
customColor="#fff7ed"
|
|
181
|
+
elevation="0 0 0 1px rgba(234, 88, 12, 0.22), 0 24px 56px rgba(234, 88, 12, 0.28)"
|
|
182
|
+
style={{ border: "1px solid rgba(59, 130, 246, 0.25)" }}
|
|
183
|
+
leading={<span>O</span>}
|
|
184
|
+
trailing={<span>ID: 428</span>}
|
|
185
|
+
footer={
|
|
186
|
+
<>
|
|
187
|
+
<SgButton appearance="ghost" onClick={() => setOpen(false)}>Cancelar</SgButton>
|
|
188
|
+
<SgButton onClick={() => setOpen(false)}>Confirmar</SgButton>
|
|
189
|
+
</>
|
|
190
|
+
}
|
|
191
|
+
>
|
|
192
|
+
<div className="space-y-2 text-sm">
|
|
193
|
+
<p>Conteudo principal do dialog.</p>
|
|
194
|
+
<input
|
|
195
|
+
data-sg-dialog-initial-focus="true"
|
|
196
|
+
className="h-10 w-full rounded-lg border border-border bg-background px-3"
|
|
197
|
+
placeholder="Digite algo"
|
|
198
|
+
/>
|
|
199
|
+
</div>
|
|
200
|
+
</SgDialog>
|
|
201
|
+
</>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Modo estrito (1:1)
|
|
207
|
+
`apps/showcase/src/app/components/sg-dialog/samples/strict.tsx.sample` — sem X, sem fechar por overlay/Esc. Atenção: com `closeOnEsc={false}` o *focus trap* de `Tab` também fica desligado (ver [[SeedGrid/SeedGrid-components/navegacao-e-overlay/API#SgDialog|API › SgDialog]]).
|
|
208
|
+
|
|
209
|
+
```tsx
|
|
210
|
+
import React from "react";
|
|
211
|
+
import { SgButton, SgDialog } from "@seedgrid/fe-components";
|
|
212
|
+
|
|
213
|
+
export default function Example() {
|
|
214
|
+
const [open, setOpen] = React.useState(false);
|
|
215
|
+
|
|
216
|
+
return (
|
|
217
|
+
<>
|
|
218
|
+
<SgButton appearance="outline" onClick={() => setOpen(true)}>Abrir modo estrito</SgButton>
|
|
219
|
+
<SgDialog
|
|
220
|
+
open={open}
|
|
221
|
+
onOpenChange={setOpen}
|
|
222
|
+
closeable={false}
|
|
223
|
+
closeOnOverlayClick={false}
|
|
224
|
+
closeOnEsc={false}
|
|
225
|
+
title="Confirmacao obrigatoria"
|
|
226
|
+
subtitle="Nao fecha por ESC nem overlay"
|
|
227
|
+
footer={
|
|
228
|
+
<>
|
|
229
|
+
<SgButton appearance="ghost" onClick={() => setOpen(false)}>Cancelar</SgButton>
|
|
230
|
+
<SgButton onClick={() => setOpen(false)}>Confirmar</SgButton>
|
|
231
|
+
</>
|
|
232
|
+
}
|
|
233
|
+
>
|
|
234
|
+
<div className="text-sm text-muted-foreground">Use este modo quando o usuario precisa tomar uma decisao explicita.</div>
|
|
235
|
+
</SgDialog>
|
|
236
|
+
</>
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Auto-fechamento (1:1)
|
|
242
|
+
`apps/showcase/src/app/components/sg-dialog/samples/auto-close.tsx.sample`
|
|
243
|
+
|
|
244
|
+
```tsx
|
|
245
|
+
import React from "react";
|
|
246
|
+
import { SgButton, SgDialog } from "@seedgrid/fe-components";
|
|
247
|
+
|
|
248
|
+
export default function Example() {
|
|
249
|
+
const [open, setOpen] = React.useState(false);
|
|
250
|
+
|
|
251
|
+
return (
|
|
252
|
+
<>
|
|
253
|
+
<SgButton appearance="outline" onClick={() => setOpen(true)}>Abrir com auto close</SgButton>
|
|
254
|
+
<SgDialog
|
|
255
|
+
open={open}
|
|
256
|
+
onOpenChange={setOpen}
|
|
257
|
+
autoCloseMs={3000}
|
|
258
|
+
title="Sincronizacao concluida"
|
|
259
|
+
subtitle="O dialog fecha em 3 segundos"
|
|
260
|
+
>
|
|
261
|
+
<div className="text-sm text-muted-foreground">Esse exemplo mostra o uso de autoCloseMs.</div>
|
|
262
|
+
</SgDialog>
|
|
263
|
+
</>
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## SgConfirmationDialog
|
|
269
|
+
|
|
270
|
+
### Confirmação básica (1:1)
|
|
271
|
+
`apps/showcase/src/app/components/sg-confirmation-dialog/samples/basico.tsx.sample` — `onCancel` também dispara ao dispensar pelo overlay/Esc.
|
|
272
|
+
|
|
273
|
+
```tsx
|
|
274
|
+
import React from "react";
|
|
275
|
+
import { SgButton, SgConfirmationDialog } from "@seedgrid/fe-components";
|
|
276
|
+
|
|
277
|
+
export default function Example() {
|
|
278
|
+
const [open, setOpen] = React.useState(false);
|
|
279
|
+
const [result, setResult] = React.useState("none");
|
|
280
|
+
|
|
281
|
+
return (
|
|
282
|
+
<>
|
|
283
|
+
<SgButton onClick={() => setOpen(true)}>delete permission</SgButton>
|
|
284
|
+
<SgConfirmationDialog
|
|
285
|
+
open={open}
|
|
286
|
+
onOpenChange={setOpen}
|
|
287
|
+
title="Delete permission"
|
|
288
|
+
message="Confirm delete?"
|
|
289
|
+
severity="danger"
|
|
290
|
+
onCancel={() => setResult("cancel")}
|
|
291
|
+
onConfirm={() => setResult("confirm")}
|
|
292
|
+
/>
|
|
293
|
+
<p className="text-xs text-muted-foreground">result: {result}</p>
|
|
294
|
+
</>
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Botões customizados (1:1)
|
|
300
|
+
`apps/showcase/src/app/components/sg-confirmation-dialog/samples/botoes-customizados.tsx.sample`
|
|
301
|
+
|
|
302
|
+
```tsx
|
|
303
|
+
import React from "react";
|
|
304
|
+
import { Trash2, X } from "lucide-react";
|
|
305
|
+
import { SgButton, SgConfirmationDialog, type SgConfirmationDialogButtonConfig } from "@seedgrid/fe-components";
|
|
306
|
+
|
|
307
|
+
const cancelButton: SgConfirmationDialogButtonConfig = {
|
|
308
|
+
label: "No, keep it",
|
|
309
|
+
icon: <X className="size-4" />,
|
|
310
|
+
severity: "secondary",
|
|
311
|
+
appearance: "ghost"
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
const confirmButton: SgConfirmationDialogButtonConfig = {
|
|
315
|
+
label: "Yes, delete",
|
|
316
|
+
icon: <Trash2 className="size-4" />,
|
|
317
|
+
severity: "danger"
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
export default function Example() {
|
|
321
|
+
const [open, setOpen] = React.useState(false);
|
|
322
|
+
const [log, setLog] = React.useState("none");
|
|
323
|
+
|
|
324
|
+
return (
|
|
325
|
+
<>
|
|
326
|
+
<SgButton severity="danger" onClick={() => setOpen(true)}>delete row</SgButton>
|
|
327
|
+
<SgConfirmationDialog
|
|
328
|
+
open={open}
|
|
329
|
+
onOpenChange={setOpen}
|
|
330
|
+
title="Delete permission"
|
|
331
|
+
message="Confirm delete?"
|
|
332
|
+
severity="danger"
|
|
333
|
+
cancelButton={cancelButton}
|
|
334
|
+
confirmButton={confirmButton}
|
|
335
|
+
onCancel={() => setLog("cancel")}
|
|
336
|
+
onConfirm={() => setLog("confirm")}
|
|
337
|
+
/>
|
|
338
|
+
<p className="text-xs text-muted-foreground">last action: {log}</p>
|
|
339
|
+
</>
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## SgWizard / SgWizardPage
|
|
345
|
+
|
|
346
|
+
### Stepper numerado (1:1)
|
|
347
|
+
`apps/showcase/src/app/components/sg-wizard/samples/stepper-numerado.tsx.sample`
|
|
348
|
+
|
|
349
|
+
```tsx
|
|
350
|
+
import React from "react";
|
|
351
|
+
import { SgWizard, SgWizardPage } from "@seedgrid/fe-components";
|
|
352
|
+
|
|
353
|
+
export default function Example() {
|
|
354
|
+
return (
|
|
355
|
+
<SgWizard stepper="numbered" onFinish={() => {}}>
|
|
356
|
+
<SgWizardPage title="Introducao">
|
|
357
|
+
<div className="rounded border border-border bg-foreground/5 p-4">
|
|
358
|
+
<div className="text-sm font-semibold">1. Introducao</div>
|
|
359
|
+
<p className="mt-1 text-sm text-muted-foreground">Conteudo introdutorio.</p>
|
|
360
|
+
</div>
|
|
361
|
+
</SgWizardPage>
|
|
362
|
+
<SgWizardPage title="Detalhes">
|
|
363
|
+
<div className="rounded border border-border bg-foreground/5 p-4">
|
|
364
|
+
<div className="text-sm font-semibold">2. Detalhes</div>
|
|
365
|
+
<p className="mt-1 text-sm text-muted-foreground">Preencha os detalhes.</p>
|
|
366
|
+
</div>
|
|
367
|
+
</SgWizardPage>
|
|
368
|
+
<SgWizardPage title="Revisao">
|
|
369
|
+
<div className="rounded border border-border bg-foreground/5 p-4">
|
|
370
|
+
<div className="text-sm font-semibold">3. Revisao</div>
|
|
371
|
+
<p className="mt-1 text-sm text-muted-foreground">Revise as informacoes.</p>
|
|
372
|
+
</div>
|
|
373
|
+
</SgWizardPage>
|
|
374
|
+
<SgWizardPage title="Confirmacao">
|
|
375
|
+
<div className="rounded border border-border bg-foreground/5 p-4">
|
|
376
|
+
<div className="text-sm font-semibold">4. Confirmacao</div>
|
|
377
|
+
<p className="mt-1 text-sm text-muted-foreground">Confirme e finalize.</p>
|
|
378
|
+
</div>
|
|
379
|
+
</SgWizardPage>
|
|
380
|
+
</SgWizard>
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Validação por etapa com `validateStep` (1:1)
|
|
386
|
+
`apps/showcase/src/app/components/sg-wizard/samples/validatestep.tsx.sample`
|
|
387
|
+
|
|
388
|
+
```tsx
|
|
389
|
+
import React from "react";
|
|
390
|
+
import { SgInputEmail, SgInputText, SgWizard, SgWizardPage } from "@seedgrid/fe-components";
|
|
391
|
+
|
|
392
|
+
export default function Example() {
|
|
393
|
+
const [formValues, setFormValues] = React.useState({ name: "", email: "" });
|
|
394
|
+
|
|
395
|
+
return (
|
|
396
|
+
<SgWizard
|
|
397
|
+
validateStep={(index) => {
|
|
398
|
+
if (index === 0) {
|
|
399
|
+
return Boolean(formValues.name.trim()) && Boolean(formValues.email.trim());
|
|
400
|
+
}
|
|
401
|
+
return true;
|
|
402
|
+
}}
|
|
403
|
+
onFinish={() => {}}
|
|
404
|
+
>
|
|
405
|
+
<SgWizardPage title="Campos obrigatorios">
|
|
406
|
+
<div className="grid gap-3 sm:grid-cols-2">
|
|
407
|
+
<SgInputText
|
|
408
|
+
id="validate-step-name"
|
|
409
|
+
label="Nome"
|
|
410
|
+
inputProps={{
|
|
411
|
+
value: formValues.name,
|
|
412
|
+
onChange: (event) =>
|
|
413
|
+
setFormValues((prev) => ({ ...prev, name: event.target.value })),
|
|
414
|
+
}}
|
|
415
|
+
/>
|
|
416
|
+
<SgInputEmail
|
|
417
|
+
id="validate-step-email"
|
|
418
|
+
label="Email"
|
|
419
|
+
inputProps={{
|
|
420
|
+
value: formValues.email,
|
|
421
|
+
onChange: (event) =>
|
|
422
|
+
setFormValues((prev) => ({ ...prev, email: event.target.value })),
|
|
423
|
+
}}
|
|
424
|
+
/>
|
|
425
|
+
</div>
|
|
426
|
+
</SgWizardPage>
|
|
427
|
+
<SgWizardPage title="Etapa liberada">
|
|
428
|
+
<div className="rounded border border-border bg-foreground/5 p-4">
|
|
429
|
+
<div className="text-sm font-semibold">Etapa seguinte</div>
|
|
430
|
+
<p className="mt-1 text-sm text-muted-foreground">
|
|
431
|
+
So abre quando nome e email foram preenchidos.
|
|
432
|
+
</p>
|
|
433
|
+
</div>
|
|
434
|
+
</SgWizardPage>
|
|
435
|
+
</SgWizard>
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### Guarda assíncrona e conclusão assíncrona (1:1)
|
|
441
|
+
`apps/showcase/src/app/components/sg-wizard/samples/onbeforenext-async.tsx.sample`
|
|
442
|
+
|
|
443
|
+
```tsx
|
|
444
|
+
import React from "react";
|
|
445
|
+
import { SgWizard, SgWizardPage } from "@seedgrid/fe-components";
|
|
446
|
+
|
|
447
|
+
export default function Example() {
|
|
448
|
+
return (
|
|
449
|
+
<SgWizard
|
|
450
|
+
onBeforeNext={async () => {
|
|
451
|
+
await new Promise((resolve) => setTimeout(resolve, 600));
|
|
452
|
+
return true;
|
|
453
|
+
}}
|
|
454
|
+
onFinish={async () => {
|
|
455
|
+
await new Promise((resolve) => setTimeout(resolve, 400));
|
|
456
|
+
}}
|
|
457
|
+
>
|
|
458
|
+
<SgWizardPage>
|
|
459
|
+
<div className="rounded border border-border bg-foreground/5 p-4">
|
|
460
|
+
<div className="text-sm font-semibold">Validacao assicrona</div>
|
|
461
|
+
<p className="mt-1 text-sm text-muted-foreground">
|
|
462
|
+
Antes de avancar, o wizard aguarda uma promise.
|
|
463
|
+
</p>
|
|
464
|
+
</div>
|
|
465
|
+
</SgWizardPage>
|
|
466
|
+
<SgWizardPage>
|
|
467
|
+
<div className="rounded border border-border bg-foreground/5 p-4">
|
|
468
|
+
<div className="text-sm font-semibold">Segunda etapa</div>
|
|
469
|
+
<p className="mt-1 text-sm text-muted-foreground">
|
|
470
|
+
O submit final tambem pode ser assicrono.
|
|
471
|
+
</p>
|
|
472
|
+
</div>
|
|
473
|
+
</SgWizardPage>
|
|
474
|
+
</SgWizard>
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### Bloqueio declarativo com `nextDisabled` (1:1)
|
|
480
|
+
`apps/showcase/src/app/components/sg-wizard/samples/nextdisabled.tsx.sample`
|
|
481
|
+
|
|
482
|
+
```tsx
|
|
483
|
+
import React from "react";
|
|
484
|
+
import { SgInputText, SgWizard, SgWizardPage } from "@seedgrid/fe-components";
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* `nextDisabled` — bloqueio JA conhecido.
|
|
488
|
+
*
|
|
489
|
+
* `onBeforeNext` e `validateStep` so agem no clique: o botao continua com aparencia de habilitado
|
|
490
|
+
* e, quando eles recusam, nada acontece na tela. Quando o consumidor JA sabe que a etapa nao pode
|
|
491
|
+
* avancar — tipicamente o resultado de uma checagem assincrona que ja terminou —, `nextDisabled`
|
|
492
|
+
* deixa isso visivel: botao opaco, cursor de bloqueio e stepper sem oferecer as proximas etapas.
|
|
493
|
+
*/
|
|
494
|
+
export default function Example() {
|
|
495
|
+
const [codigo, setCodigo] = React.useState("");
|
|
496
|
+
const [checando, setChecando] = React.useState(false);
|
|
497
|
+
const [jaUsado, setJaUsado] = React.useState(false);
|
|
498
|
+
|
|
499
|
+
// Simula a consulta ao servidor ao sair do campo.
|
|
500
|
+
async function verificarCodigo() {
|
|
501
|
+
if (!codigo.trim()) return;
|
|
502
|
+
setChecando(true);
|
|
503
|
+
await new Promise((resolve) => setTimeout(resolve, 600));
|
|
504
|
+
setJaUsado(codigo.trim().toUpperCase() === "SG-123");
|
|
505
|
+
setChecando(false);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
return (
|
|
509
|
+
<SgWizard
|
|
510
|
+
// Durante a consulta o wizard ja desabilita sozinho enquanto aguarda onBeforeNext; aqui o
|
|
511
|
+
// bloqueio PERMANECE depois que a resposta chegou.
|
|
512
|
+
nextDisabled={jaUsado}
|
|
513
|
+
onFinish={() => undefined}
|
|
514
|
+
>
|
|
515
|
+
<SgWizardPage title="Convite">
|
|
516
|
+
<SgInputText
|
|
517
|
+
id="wizard-codigo-convite"
|
|
518
|
+
label="Codigo do convite"
|
|
519
|
+
error={jaUsado ? "Este codigo ja foi utilizado." : undefined}
|
|
520
|
+
onChange={(value) => {
|
|
521
|
+
setCodigo(value);
|
|
522
|
+
setJaUsado(false); // digitou de novo: reabre o avanco ate a proxima checagem
|
|
523
|
+
}}
|
|
524
|
+
onExit={() => void verificarCodigo()}
|
|
525
|
+
/>
|
|
526
|
+
<p className="mt-2 text-sm text-muted-foreground">
|
|
527
|
+
{checando
|
|
528
|
+
? "Verificando o codigo..."
|
|
529
|
+
: 'Digite "SG-123" e saia do campo: o botao Proximo fica desabilitado.'}
|
|
530
|
+
</p>
|
|
531
|
+
</SgWizardPage>
|
|
532
|
+
<SgWizardPage title="Conclusao">
|
|
533
|
+
<div className="rounded border border-border bg-foreground/5 p-4">
|
|
534
|
+
<div className="text-sm font-semibold">Codigo aceito</div>
|
|
535
|
+
<p className="mt-1 text-sm text-muted-foreground">
|
|
536
|
+
So se chega aqui com um codigo que a checagem liberou.
|
|
537
|
+
</p>
|
|
538
|
+
</div>
|
|
539
|
+
</SgWizardPage>
|
|
540
|
+
</SgWizard>
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
### Helpers puros do wizard
|
|
546
|
+
Exemplo próprio (não vem do showcase), baseado nas assinaturas de `src/wizard/logic.ts` e nos casos de `tests/wizard-logic.test.mjs`.
|
|
547
|
+
|
|
548
|
+
```tsx
|
|
549
|
+
import { canNavigateToWizardStep, canProceedWizardAction, clampWizardStep } from "@seedgrid/fe-components";
|
|
550
|
+
|
|
551
|
+
export async function demo(): Promise<boolean> {
|
|
552
|
+
const step = clampWizardStep(5, 3); // 2
|
|
553
|
+
const canGoBack = canNavigateToWizardStep({ currentStep: step, targetStep: 0, pageCount: 3, stepNavigation: "previous" });
|
|
554
|
+
const ok = await canProceedWizardAction({
|
|
555
|
+
validateCurrentPage: () => true,
|
|
556
|
+
validateStep: async (index) => index >= 0,
|
|
557
|
+
step
|
|
558
|
+
});
|
|
559
|
+
return canGoBack && ok;
|
|
560
|
+
}
|
|
561
|
+
```
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: [seedgrid, front, component, navegacao-e-overlay]
|
|
3
|
+
fonte: front/seedgrid-fe-components/packages/seedgrid-fe-components/src/menus, front/seedgrid-fe-components/packages/seedgrid-fe-components/src/overlay, front/seedgrid-fe-components/packages/seedgrid-fe-components/src/wizard
|
|
4
|
+
branch: main
|
|
5
|
+
commit: ad30fc11de
|
|
6
|
+
analisado-em: 2026-10-14
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Navegação e overlay — visão geral
|
|
10
|
+
|
|
11
|
+
Grupo de componentes do pacote `@seedgrid/fe-components` que reúne **três pastas pequenas** de `src/` numa só nota, por terem pouco conteúdo cada uma:
|
|
12
|
+
|
|
13
|
+
| Pasta de origem | Conteúdo |
|
|
14
|
+
|---|---|
|
|
15
|
+
| `src/menus/` | `SgDockMenu` (dock flutuante estilo macOS) e os helpers puros de `dock-menu-logic.ts` |
|
|
16
|
+
| `src/overlay/` | `SgPopup` (overlay ancorado, não modal), `SgDialog` (modal), `SgConfirmationDialog` (modal de confirmação construído sobre `SgDialog`) |
|
|
17
|
+
| `src/wizard/` | `SgWizard` + `SgWizardPage` (fluxo multi-etapas) e os helpers puros de `logic.ts` |
|
|
18
|
+
|
|
19
|
+
> O menu de navegação lateral/horizontal (`SgMenu`), breadcrumb, toolbar e page control ficam em `src/layout/` — ver [[SeedGrid/SeedGrid-components/layout/Visao-geral|Layout]].
|
|
20
|
+
|
|
21
|
+
- API completa: [[SeedGrid/SeedGrid-components/navegacao-e-overlay/API|API de navegação e overlay]]
|
|
22
|
+
- Exemplos: [[SeedGrid/SeedGrid-components/navegacao-e-overlay/Exemplos|Exemplos de navegação e overlay]]
|
|
23
|
+
- Fundamentos do pacote (instalação, CSS, i18n): [[SeedGrid/SeedGrid-components/fundamentos/Visao-geral|Fundamentos]]
|
|
24
|
+
|
|
25
|
+
## Componentes
|
|
26
|
+
|
|
27
|
+
| Componente | Exportado | Para que serve | Showcase |
|
|
28
|
+
|---|---|---|---|
|
|
29
|
+
| `SgDockMenu` | sim | Dock flutuante de ações com ícones, badges, efeito *magnify*, 8 posições ancoradas e arraste com posição persistida | `/components/sg-dock-menu` |
|
|
30
|
+
| `SgPopup` | sim | Overlay contextual ancorado a um elemento (`anchorRef`), com título, lista de ações e/ou conteúdo livre; fecha por clique fora/Esc | `/components/sg-popup` |
|
|
31
|
+
| `SgDialog` | sim | Modal com cabeçalho/corpo/rodapé, severidade, animação, auto-fechamento, foco inicial, *focus trap* e bloqueio de scroll | `/components/sg-dialog` |
|
|
32
|
+
| `SgConfirmationDialog` | sim | `SgDialog` especializado em confirmar/cancelar, com ícone por severidade e botões configuráveis | `/components/sg-confirmation-dialog` |
|
|
33
|
+
| `SgWizard` | sim | Fluxo em etapas com stepper opcional, validação automática dos inputs da etapa, guardas síncronas/assíncronas e conclusão assíncrona | `/components/sg-wizard` |
|
|
34
|
+
| `SgWizardPage` | sim | Etapa de um `SgWizard` (título/ícone usados no stepper) | `/components/sg-wizard` |
|
|
35
|
+
|
|
36
|
+
Exportação confirmada em `src/index.ts` (barrel; o `package.json` expõe apenas `"."` e `"./style.css"`).
|
|
37
|
+
|
|
38
|
+
### Funções e tipos públicos relacionados
|
|
39
|
+
|
|
40
|
+
| Símbolo | Origem | Exportado |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| `resolveDockMenuOrientation`, `resolveDockMenuLiftDirection`, `buildDockMenuLayout`, `buildDockMenuItemMotion`, `buildDockMenuLabelStyle`, `buildDockMenuContainerStyle`, `buildDockMenuContextMenuState` | `src/menus/dock-menu-logic.ts` | sim |
|
|
43
|
+
| `buildDockMenuStorageKey` (e `parseStoredPanelDragPosition`, compartilhado com a toolbar) | `src/layout/drag-position.ts` | sim |
|
|
44
|
+
| `clampWizardStep`, `canNavigateToWizardStep`, `canProceedWizardAction` | `src/wizard/logic.ts` | sim |
|
|
45
|
+
| Tipos `SgDockMenuProps`, `SgDockMenuItem`, `SgDockMenuPosition`, `SgDockMenuOrientation` | `SgDockMenu.tsx` | sim |
|
|
46
|
+
| Tipos `SgPopupProps`, `SgPopupAction`, `SgPopupPlacement`, `SgPopupPreferPlacement`, `SgPopupAlign`, `SgPopupSeverity` | `SgPopup.tsx` | sim |
|
|
47
|
+
| Tipos `SgDialogProps`, `SgDialogSize`, `SgDialogSeverity`, `SgDialogAnimation` | `SgDialog.tsx` | sim |
|
|
48
|
+
| Tipos `SgConfirmationDialogProps`, `SgConfirmationDialogButtonConfig` | `SgConfirmationDialog.tsx` | sim |
|
|
49
|
+
| Tipos `SgWizardProps`, `SgWizardPageProps`, `SgWizardLabels`, `SgWizardStepper`, `WizardStepNavigation`, `WizardGuardRunner` | `SgWizard.tsx`, `logic.ts` | sim |
|
|
50
|
+
|
|
51
|
+
Os helpers do dock e do wizard são funções puras usadas internamente pelos componentes e cobertas por testes; o export público permite reuso/teste, mas o uso normal é só via componente. Detalhes em [[SeedGrid/SeedGrid-components/navegacao-e-overlay/API|API]].
|
|
52
|
+
|
|
53
|
+
## Como se compõem
|
|
54
|
+
|
|
55
|
+
- Nenhum componente do grupo exige provider. Todos chamam `useComponentsI18n()` para textos padrão (ex.: `components.dialog.close`, `components.wizard.next`) — opcionalmente envolva a app em `SgComponentsI18nProvider` (ver [[SeedGrid/SeedGrid-components/fundamentos/API|API › i18n]]). **Confirmado**.
|
|
56
|
+
- `SgDockMenu` persiste a posição arrastada: com `SgEnvironmentProvider` presente usa `useSgPersistence()` (estratégia/namespace do ambiente); sem ele usa `localStorage` direto, chave `sg-dockmenu-pos:<dragId>:<viewport|parent>`. Ver [[SeedGrid/SeedGrid-components/providers/API|Providers]]. **Confirmado** (`SgDockMenu.tsx` → `loadStoredPosition`/`saveStoredPosition`).
|
|
57
|
+
- `SgPopup` e `SgDialog` renderizam via `createPortal(..., document.body)`. `SgConfirmationDialog` compõe `SgDialog` + `SgButton` (rodapé).
|
|
58
|
+
- `SgWizard` só considera filhos diretos cujo `type === SgWizardPage`; outros filhos são descartados. A validação automática procura elementos com atributo `data-sg-error` dentro da etapa — atributo emitido pelos inputs SeedGrid (ex.: `SgInputText`, `SgInputNumber`), ver [[SeedGrid/SeedGrid-components/inputs-texto/Visao-geral|Inputs de texto]]. **Confirmado** (`SgWizard.tsx` → `validateCurrentPage`).
|
|
59
|
+
|
|
60
|
+
## Dependências
|
|
61
|
+
|
|
62
|
+
- Peer: `react`, `react-dom` (portais). Nenhuma lib externa específica deste grupo. Os exemplos do showcase usam `lucide-react` (peer opcional do pacote) para ícones.
|
|
63
|
+
|
|
64
|
+
## Testes (não executados)
|
|
65
|
+
|
|
66
|
+
| Arquivo | Cobertura |
|
|
67
|
+
|---|---|
|
|
68
|
+
| `tests/overlay.test.mjs` | Contratos estáticos: textos padrão de `SgConfirmationDialog`/`SgDialog`/`SgPopup` vindos de chaves i18n; padrões `closeOnCancel/closeOnConfirm = true`; dismiss do dialog roteado para o fluxo de cancelamento; `closeOnEsc`/`closeOnOverlayClick`/`closeOnOutsideClick`/`closeOnEscape` ligados por padrão; popup usa `title` antes do aria-label i18n |
|
|
69
|
+
| `tests/wizard.test.mjs` | Render SSR: labels traduzidos, clamp de `initialStep`, override de labels, stepper `none`, navegação desabilitada, `nextDisabled` |
|
|
70
|
+
| `tests/wizard-logic.test.mjs` | `clampWizardStep`, `canNavigateToWizardStep` (modos), `canProceedWizardAction` (ordem e interrupção das guardas) |
|
|
71
|
+
| `tests/buttons-menus.test.mjs` | `SgDockMenu` com botões acessíveis/disabled; helpers `buildDockMenu*`/`resolveDockMenu*`, `buildDockMenuStorageKey` determinísticos |
|
|
72
|
+
| `tests/buttons-menus-dom.test.mjs` (jsdom) | Dock: menu de contexto de reset e persistência de arraste em `localStorage`; Wizard: avançar/voltar, clique no stepper, guardas, validação de inputs; Popup: fecha por clique fora e Esc |
|
|
73
|
+
|
|
74
|
+
## Limitações e observações
|
|
75
|
+
|
|
76
|
+
- `SgPopup` não abre sozinho ao clicar na âncora: o consumidor controla `open`/`onOpenChange` (o clique na âncora é ignorado pelo "clique fora"). **Confirmado**.
|
|
77
|
+
- No `SgDialog`, o *focus trap* de `Tab` vive no mesmo efeito do `Esc`: com `closeOnEsc={false}` o foco **não** fica preso no modal. **Confirmado** (`SgDialog.tsx`, efeito `onKeyDown`).
|
|
78
|
+
- `SgDialog.onClose` só dispara pelos fechamentos internos (botão X, overlay, Esc, `autoCloseMs`); mudar `open` para `false` de fora não chama `onClose`. **Confirmado**.
|
|
79
|
+
- `SgWizard` chama `onStepChange` num efeito com dependências `[props, step]`: além das trocas de etapa, ele dispara de novo sempre que o wizard re-renderiza com um novo objeto `props`. **Confirmado** (código); impacto prático = **Inferência**.
|
|
80
|
+
- `SgWizard` não expõe etapa controlada (não há `step`/`activeStep` como prop) nem `ref`.
|
|
81
|
+
- `SgDockMenu`: `item.badge && (...)` — badge `0` não renderiza a bolha e o React imprime `0` como texto. **Inferência** (semântica de JSX com `&&`).
|
|
82
|
+
- O grupo não tem menu de contexto genérico; o menu de contexto do dock é apenas o diálogo "resetar posição".
|