@snksergio/design-system 0.61.0 → 0.63.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/dist-lib/ai/blocos/chart/budget-breakdown.tsx +174 -0
- package/dist-lib/ai/blocos/indice.md +43 -0
- package/dist-lib/ai/blocos/paneldetail/detalhe-com-tabela.tsx +450 -0
- package/dist-lib/ai/blocos/paneldetail/detalhe-de-tarefa-com-abas.tsx +570 -0
- package/dist-lib/ai/blocos/paneldetail/detalhe-do-registro.tsx +555 -0
- package/dist-lib/ai/componentes/AlertModal.md +47 -0
- package/dist-lib/ai/componentes/AppShell.md +117 -0
- package/dist-lib/ai/componentes/Breadcrumb.md +187 -0
- package/dist-lib/ai/componentes/Button.md +116 -0
- package/dist-lib/ai/componentes/ButtonGroup.md +162 -0
- package/dist-lib/ai/componentes/CardCheckbox.md +99 -0
- package/dist-lib/ai/componentes/CardOption.md +133 -0
- package/dist-lib/ai/componentes/Chart.md +93 -0
- package/dist-lib/ai/componentes/Chip.md +68 -0
- package/dist-lib/ai/componentes/ChoroplethMap.md +118 -0
- package/dist-lib/ai/componentes/ColorPicker.md +70 -0
- package/dist-lib/ai/componentes/Combobox.md +51 -0
- package/dist-lib/ai/componentes/ConversationListItem.md +90 -0
- package/dist-lib/ai/componentes/DataList.md +111 -0
- package/dist-lib/ai/componentes/DataTable.md +867 -0
- package/dist-lib/ai/componentes/DatePicker.md +84 -0
- package/dist-lib/ai/componentes/DateSeparatorChip.md +59 -0
- package/dist-lib/ai/componentes/EmptyState.md +72 -0
- package/dist-lib/ai/componentes/FileUploadField.md +95 -0
- package/dist-lib/ai/componentes/FloatingPanel.md +118 -0
- package/dist-lib/ai/componentes/FooterTable.md +62 -0
- package/dist-lib/ai/componentes/FormField.md +110 -0
- package/dist-lib/ai/componentes/Gantt.md +552 -0
- package/dist-lib/ai/componentes/Header.md +98 -0
- package/dist-lib/ai/componentes/Icon.md +65 -0
- package/dist-lib/ai/componentes/Kanban.md +343 -0
- package/dist-lib/ai/componentes/Kpi.md +103 -0
- package/dist-lib/ai/componentes/List.md +61 -0
- package/dist-lib/ai/componentes/MarkdownText.md +59 -0
- package/dist-lib/ai/componentes/MenuSidebar.md +128 -0
- package/dist-lib/ai/componentes/MessageAck.md +53 -0
- package/dist-lib/ai/componentes/MessageBubble.md +115 -0
- package/dist-lib/ai/componentes/MessageComposer.md +80 -0
- package/dist-lib/ai/componentes/MessageVariablesPicker.md +104 -0
- package/dist-lib/ai/componentes/Modal.md +88 -0
- package/dist-lib/ai/componentes/MonthYearPicker.md +49 -0
- package/dist-lib/ai/componentes/PageHeader.md +129 -0
- package/dist-lib/ai/componentes/Panel.md +84 -0
- package/dist-lib/ai/componentes/Scheduler.md +421 -0
- package/dist-lib/ai/componentes/ScreenLoader.md +60 -0
- package/dist-lib/ai/componentes/SingleMenuSidebar.md +171 -0
- package/dist-lib/ai/componentes/Spinner.md +52 -0
- package/dist-lib/ai/componentes/Table.md +192 -0
- package/dist-lib/ai/componentes/TableToolbar.md +87 -0
- package/dist-lib/ai/componentes/TabsNavigation.md +152 -0
- package/dist-lib/ai/componentes/Toast.md +49 -0
- package/dist-lib/ai/componentes/_primitivos.md +74 -0
- package/dist-lib/ai/componentes/avatar-ig.md +181 -0
- package/dist-lib/ai/componentes/indice.json +49 -0
- package/dist-lib/ai/exemplos/app-shell/app-shell-example.tsx +140 -0
- package/dist-lib/ai/exemplos/app-shell/index.ts +3 -0
- package/dist-lib/ai/exemplos/app-shell/nav-data.ts +97 -0
- package/dist-lib/ai/exemplos/app-shell/routes.tsx +75 -0
- package/dist-lib/ai/exemplos/chat/chat-screen.tsx +152 -0
- package/dist-lib/ai/exemplos/chat/chat-v2-mocks.ts +171 -0
- package/dist-lib/ai/exemplos/chat/chat-v2.styles.ts +23 -0
- package/dist-lib/ai/exemplos/chat/chat-v2.types.ts +81 -0
- package/dist-lib/ai/exemplos/chat/components/ChannelDot/channel-dot.tsx +28 -0
- package/dist-lib/ai/exemplos/chat/components/ConversationActionsMenu/conversation-actions-menu.tsx +83 -0
- package/dist-lib/ai/exemplos/chat/components/ConversationActionsMenu/index.ts +4 -0
- package/dist-lib/ai/exemplos/chat/components/ConversationColumn/conversation-column.styles.ts +22 -0
- package/dist-lib/ai/exemplos/chat/components/ConversationColumn/conversation-column.tsx +203 -0
- package/dist-lib/ai/exemplos/chat/components/ConversationColumn/conversation-column.types.ts +10 -0
- package/dist-lib/ai/exemplos/chat/components/ConversationColumn/index.ts +2 -0
- package/dist-lib/ai/exemplos/chat/components/ConversationListItem/conversation-list-item.styles.ts +55 -0
- package/dist-lib/ai/exemplos/chat/components/ConversationListItem/conversation-list-item.tsx +52 -0
- package/dist-lib/ai/exemplos/chat/components/ConversationListItem/conversation-list-item.types.ts +7 -0
- package/dist-lib/ai/exemplos/chat/components/ConversationListItem/index.ts +2 -0
- package/dist-lib/ai/exemplos/chat/components/DateSeparator/date-separator.tsx +18 -0
- package/dist-lib/ai/exemplos/chat/components/DetailField/detail-field.tsx +23 -0
- package/dist-lib/ai/exemplos/chat/components/DetailSection/detail-section.tsx +41 -0
- package/dist-lib/ai/exemplos/chat/components/DetailSection/index.ts +1 -0
- package/dist-lib/ai/exemplos/chat/components/DetailsColumn/details-column.styles.ts +30 -0
- package/dist-lib/ai/exemplos/chat/components/DetailsColumn/details-column.tsx +142 -0
- package/dist-lib/ai/exemplos/chat/components/DetailsColumn/details-column.types.ts +16 -0
- package/dist-lib/ai/exemplos/chat/components/DetailsColumn/index.ts +5 -0
- package/dist-lib/ai/exemplos/chat/components/FilterRow/filter-row.styles.ts +37 -0
- package/dist-lib/ai/exemplos/chat/components/FilterRow/filter-row.tsx +45 -0
- package/dist-lib/ai/exemplos/chat/components/FilterRow/index.ts +1 -0
- package/dist-lib/ai/exemplos/chat/components/FiltersColumn/filters-column.styles.ts +27 -0
- package/dist-lib/ai/exemplos/chat/components/FiltersColumn/filters-column.tsx +66 -0
- package/dist-lib/ai/exemplos/chat/components/FiltersColumn/filters-column.types.ts +13 -0
- package/dist-lib/ai/exemplos/chat/components/FiltersColumn/filters-rail.tsx +38 -0
- package/dist-lib/ai/exemplos/chat/components/FiltersColumn/index.ts +6 -0
- package/dist-lib/ai/exemplos/chat/components/MessageBubble/index.ts +2 -0
- package/dist-lib/ai/exemplos/chat/components/MessageBubble/message-bubble.styles.ts +37 -0
- package/dist-lib/ai/exemplos/chat/components/MessageBubble/message-bubble.tsx +29 -0
- package/dist-lib/ai/exemplos/chat/components/MessageBubble/message-bubble.types.ts +5 -0
- package/dist-lib/ai/exemplos/chat/components/PersonAvatar/index.ts +5 -0
- package/dist-lib/ai/exemplos/chat/components/PersonAvatar/person-avatar.tsx +31 -0
- package/dist-lib/ai/exemplos/chat/components/QueueColumn/index.ts +2 -0
- package/dist-lib/ai/exemplos/chat/components/QueueColumn/queue-column.styles.ts +19 -0
- package/dist-lib/ai/exemplos/chat/components/QueueColumn/queue-column.tsx +140 -0
- package/dist-lib/ai/exemplos/chat/components/QueueColumn/queue-column.types.ts +13 -0
- package/dist-lib/ai/exemplos/chat/components/RailItem/index.ts +1 -0
- package/dist-lib/ai/exemplos/chat/components/RailItem/rail-item.styles.ts +30 -0
- package/dist-lib/ai/exemplos/chat/components/RailItem/rail-item.tsx +42 -0
- package/dist-lib/ai/exemplos/chat/hooks/use-resizable.ts +98 -0
- package/dist-lib/ai/exemplos/chat/index.ts +1 -0
- package/dist-lib/ai/exemplos/clientes/_table-data.ts +59 -0
- package/dist-lib/ai/exemplos/clientes/clientes-screen.tsx +505 -0
- package/dist-lib/ai/exemplos/clientes/clientes-showcase-mocks.ts +117 -0
- package/dist-lib/ai/exemplos/clientes/clientes-showcase.styles.ts +13 -0
- package/dist-lib/ai/exemplos/clientes/clientes-showcase.types.ts +16 -0
- package/dist-lib/ai/exemplos/clientes/components/DetailDrawer/detail-drawer.styles.ts +28 -0
- package/dist-lib/ai/exemplos/clientes/components/DetailDrawer/detail-drawer.tsx +303 -0
- package/dist-lib/ai/exemplos/clientes/components/DetailDrawer/detail-drawer.types.ts +14 -0
- package/dist-lib/ai/exemplos/clientes/components/DetailDrawer/index.ts +2 -0
- package/dist-lib/ai/exemplos/clientes/components/NovoClienteDrawer/index.ts +2 -0
- package/dist-lib/ai/exemplos/clientes/components/NovoClienteDrawer/novo-cliente-drawer.tsx +207 -0
- package/dist-lib/ai/exemplos/clientes/index.ts +1 -0
- package/dist-lib/ai/exemplos/dashboard/dashboard-brazil-map.ts +33 -0
- package/dist-lib/ai/exemplos/dashboard/dashboard-screen.tsx +1110 -0
- package/dist-lib/ai/exemplos/dashboard/index.ts +1 -0
- package/dist-lib/ai/exemplos/edit-page/components/StepNav.tsx +81 -0
- package/dist-lib/ai/exemplos/edit-page/components/section-card.tsx +85 -0
- package/dist-lib/ai/exemplos/edit-page/edit-page-screen.tsx +234 -0
- package/dist-lib/ai/exemplos/edit-page/index.ts +1 -0
- package/dist-lib/ai/exemplos/finance/_table-data.ts +57 -0
- package/dist-lib/ai/exemplos/finance/clientes-financeiro-mocks.ts +227 -0
- package/dist-lib/ai/exemplos/finance/clientes-financeiro.types.ts +75 -0
- package/dist-lib/ai/exemplos/finance/clientes-showcase-mocks.ts +117 -0
- package/dist-lib/ai/exemplos/finance/clientes-showcase.styles.ts +13 -0
- package/dist-lib/ai/exemplos/finance/clientes-showcase.types.ts +16 -0
- package/dist-lib/ai/exemplos/finance/components/EditarFinanceDrawer/editar-finance-drawer.tsx +241 -0
- package/dist-lib/ai/exemplos/finance/components/EditarFinanceDrawer/index.ts +5 -0
- package/dist-lib/ai/exemplos/finance/components/ExtratoExpansion/extrato-expansion.tsx +172 -0
- package/dist-lib/ai/exemplos/finance/components/ExtratoExpansion/index.ts +1 -0
- package/dist-lib/ai/exemplos/finance/components/FinanceDetailPanel/finance-detail-panel.tsx +241 -0
- package/dist-lib/ai/exemplos/finance/components/FinanceDetailPanel/index.ts +2 -0
- package/dist-lib/ai/exemplos/finance/components/NovoClienteDrawer/index.ts +2 -0
- package/dist-lib/ai/exemplos/finance/components/NovoClienteDrawer/novo-cliente-drawer.tsx +207 -0
- package/dist-lib/ai/exemplos/finance/components/SacarDialog/index.ts +2 -0
- package/dist-lib/ai/exemplos/finance/components/SacarDialog/sacar-dialog.tsx +346 -0
- package/dist-lib/ai/exemplos/finance/finance-screen.tsx +821 -0
- package/dist-lib/ai/exemplos/finance/index.ts +1 -0
- package/dist-lib/ai/exemplos/gantt/_gantt-data.tsx +402 -0
- package/dist-lib/ai/exemplos/gantt/gantt-screen.tsx +512 -0
- package/dist-lib/ai/exemplos/gantt/index.ts +1 -0
- package/dist-lib/ai/exemplos/login/index.ts +1 -0
- package/dist-lib/ai/exemplos/login/login-screen.tsx +246 -0
- package/dist-lib/ai/exemplos/mapa-rede/components/ConsultorDetailPanel/consultor-detail-panel.tsx +158 -0
- package/dist-lib/ai/exemplos/mapa-rede/components/ConsultorDetailPanel/index.ts +2 -0
- package/dist-lib/ai/exemplos/mapa-rede/index.ts +1 -0
- package/dist-lib/ai/exemplos/mapa-rede/mapa-de-rede-mocks.ts +655 -0
- package/dist-lib/ai/exemplos/mapa-rede/mapa-de-rede.types.ts +53 -0
- package/dist-lib/ai/exemplos/mapa-rede/mapa-rede-screen.tsx +227 -0
- package/dist-lib/ai/exemplos/order-detail/components/ActivityTab.tsx +77 -0
- package/dist-lib/ai/exemplos/order-detail/components/AttachmentsTab.tsx +45 -0
- package/dist-lib/ai/exemplos/order-detail/components/CommentsTab.tsx +111 -0
- package/dist-lib/ai/exemplos/order-detail/components/DetailsTab.tsx +189 -0
- package/dist-lib/ai/exemplos/order-detail/components/OverviewTab.tsx +200 -0
- package/dist-lib/ai/exemplos/order-detail/components/section-card.tsx +85 -0
- package/dist-lib/ai/exemplos/order-detail/index.ts +1 -0
- package/dist-lib/ai/exemplos/order-detail/order-detail-screen.tsx +119 -0
- package/dist-lib/ai/exemplos/order-detail/order-mocks.ts +186 -0
- package/dist-lib/ai/exemplos/order-detail/order.types.ts +118 -0
- package/dist-lib/ai/global/componentes.md +217 -0
- package/dist-lib/ai/global/composicao.md +182 -0
- package/dist-lib/ai/indice.json +192 -0
- package/dist-lib/ai/lint/ds-lint-patterns.mjs +115 -0
- package/dist-lib/ai/manifest.json +42 -0
- package/dist-lib/ai/regras/design.md +88 -0
- package/dist-lib/ai/regras/temas.md +192 -0
- package/dist-lib/ai/regras-por-componente.json +103 -0
- package/dist-lib/ai/roteiros/app-builder/roteiro.md +155 -0
- package/dist-lib/ai/roteiros/auth-builder/roteiro.md +42 -0
- package/dist-lib/ai/roteiros/cards/roteiro.md +34 -0
- package/dist-lib/ai/roteiros/charts/roteiro.md +32 -0
- package/dist-lib/ai/roteiros/chat/roteiro.md +31 -0
- package/dist-lib/ai/roteiros/crud-builder/blueprint.md +63 -0
- package/dist-lib/ai/roteiros/crud-builder/entrevista.md +139 -0
- package/dist-lib/ai/roteiros/crud-builder/geracao.md +113 -0
- package/dist-lib/ai/roteiros/crud-builder/roteiro.md +89 -0
- package/dist-lib/ai/roteiros/dashboard-builder/blueprint.md +47 -0
- package/dist-lib/ai/roteiros/dashboard-builder/entrevista.md +62 -0
- package/dist-lib/ai/roteiros/dashboard-builder/geracao.md +88 -0
- package/dist-lib/ai/roteiros/dashboard-builder/roteiro.md +88 -0
- package/dist-lib/ai/roteiros/drawers/roteiro.md +41 -0
- package/dist-lib/ai/roteiros/list-builder/blueprint.md +94 -0
- package/dist-lib/ai/roteiros/list-builder/entrevista.md +188 -0
- package/dist-lib/ai/roteiros/list-builder/geracao.md +63 -0
- package/dist-lib/ai/roteiros/list-builder/roteiro.md +91 -0
- package/dist-lib/ai/roteiros/module-replicator/roteiro.md +56 -0
- package/dist-lib/ai/roteiros/page-detail/roteiro.md +32 -0
- package/dist-lib/ai/roteiros/page-edit/roteiro.md +31 -0
- package/dist-lib/ai/roteiros/screen-composer/roteiro.md +95 -0
- package/package.json +4 -1
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
> **Nota de portabilidade.** Este roteiro foi extraído do pipeline do iGreen DS
|
|
2
|
+
> para Claude Code. Menções a slash command (`/ds-create-…`), a `.claude/` e a
|
|
3
|
+
> ferramentas daquele ambiente descrevem **como ele é acionado lá** — aqui o
|
|
4
|
+
> equivalente é carregar este roteiro pelo `indice.json`. O conteúdo de decisão
|
|
5
|
+
> (entrevista, blueprint, regras de composição) vale igual.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
> **Modo submódulo (`ds-link`).** Existe `.claude/ds-config.json` com `"mode": "submodule"`?
|
|
9
|
+
> Então **NÃO rode `igreen:add`** — esse script não existe no seu projeto. Os componentes e
|
|
10
|
+
> exemplos já estão no disco em `<dsPath>/src`: importe pelo `importBase` do config
|
|
11
|
+
> (compostos) e pelo `primitivesBase` (primitivos shadcn), e **leia** o exemplo direto de
|
|
12
|
+
> `<dsPath>/src/examples/`.
|
|
13
|
+
|
|
14
|
+
# List Builder — Entrevista
|
|
15
|
+
|
|
16
|
+
## ⛔ Perguntas obrigatórias (NUNCA pular, mesmo inferindo)
|
|
17
|
+
|
|
18
|
+
1. **Shape do card (Fase 2)** — mesmo inferindo, APRESENTAR o mapa de slots
|
|
19
|
+
(leading/title/subtitle/meta/...) e **confirmar em lote**. Nunca gerar com o
|
|
20
|
+
card só inferido sem o usuário ver/confirmar.
|
|
21
|
+
2. **Views (Fase 4)** — **OFERECER e explicar o valor**: _"abas com filtros
|
|
22
|
+
pré-configurados (ex.: Admins, Ativos) — troca de recorte num clique. Quer
|
|
23
|
+
alguma?"_ Default = nenhuma, mas só após perguntar.
|
|
24
|
+
|
|
25
|
+
Princípios:
|
|
26
|
+
|
|
27
|
+
- **Fases agrupadas com defaults explícitos** — cada pergunta mostra o default;
|
|
28
|
+
"ok/Enter" aceita.
|
|
29
|
+
- **Modo expresso** — o usuário pode dizer "aceita os defaults daqui pra frente".
|
|
30
|
+
- **Dados podem ser incompletos** — fonte sem payload → slots viram hipóteses a
|
|
31
|
+
confirmar (nunca gerar silenciosamente).
|
|
32
|
+
- `AskUserQuestion` quando enumerável; prosa quando aberto.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Fase 0 — Entidade + fonte de dados (obrigatória)
|
|
37
|
+
|
|
38
|
+
1. **Entidade**: singular/plural (ex: "Membro/Membros") + 1 frase de domínio.
|
|
39
|
+
2. **Fonte de dados** — uma de:
|
|
40
|
+
- **(a) Sample JSON colado** ← preferido (inferência valor+nome).
|
|
41
|
+
- **(b) Interface TypeScript** (inferência nome+tipo).
|
|
42
|
+
- **(c) Descrição de endpoint** (inferência só por nome → confiança baixa).
|
|
43
|
+
- **(d) Listagem manual** (`campo: tipo`).
|
|
44
|
+
3. **Client vs server mode**:
|
|
45
|
+
- API pagina/filtra no servidor e devolve `total`? → **server**
|
|
46
|
+
(`mode="server"` + `onQueryChange` + `total`; DataList NÃO filtra local).
|
|
47
|
+
- Dataset completo de uma vez (ou mock)? → **client** (default).
|
|
48
|
+
4. **Volume estimado** (decide proposta de escala na Fase 6). Default "< 1.000".
|
|
49
|
+
5. **Campo id único** — todo item precisa `id`. Default `id`.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Fase 1 — Página e shell (agrupada)
|
|
54
|
+
|
|
55
|
+
| Pergunta | Default |
|
|
56
|
+
| ---------------------- | ---------------------------------------------------------------------- |
|
|
57
|
+
| Título da página | plural da entidade |
|
|
58
|
+
| Descrição (1-2 frases) | gerada do domínio, confirmar |
|
|
59
|
+
| **Wrapper** | ver abaixo |
|
|
60
|
+
| Rota (kebab-case) | derivada do nome — **verificar colisão no router deste projeto** |
|
|
61
|
+
| Onde entra na nav | perguntar (menu lateral? submenu? qual grupo?) |
|
|
62
|
+
|
|
63
|
+
**Wrapper — 3 opções:**
|
|
64
|
+
|
|
65
|
+
- **(a) `ExamplePageLayout`** (default neste repo) — standalone, padrão dos
|
|
66
|
+
`List*Preview`. Props `category/title/description/code/children`. Dá altura
|
|
67
|
+
definida pro preview (pré-requisito de `fillHeight`/virtualização).
|
|
68
|
+
- **(b) `AppShell` + `PageHeader`** — tela "real". Perguntar drawer de criação /
|
|
69
|
+
DetailDrawer no item click. Forms seguem L-023 (`FormField`) + L-024 (`gap-form-gap`).
|
|
70
|
+
- **(c) Componente puro** — consumer (PAGES_DIR/REGISTRO do ambiente).
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Fase 2 — Card (shape) — confirmação em lote
|
|
75
|
+
|
|
76
|
+
O DataList passa cada item pro `List`, que monta o card por **slots** OU por
|
|
77
|
+
**`renderItem`** (card rico). Decidir qual:
|
|
78
|
+
|
|
79
|
+
### 2a. Slots (caso comum) — mapear campos → slots
|
|
80
|
+
|
|
81
|
+
Apresentar UM mapa e confirmar em lote:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
| slot | campo / conteúdo | nota |
|
|
85
|
+
|------------|-----------------------------|------|
|
|
86
|
+
| leading | <avatar/ícone> | opcional |
|
|
87
|
+
| title | <campo> | OBRIGATÓRIO |
|
|
88
|
+
| subtitle | <campo> | opcional (ex: email) |
|
|
89
|
+
| description | <campo> | opcional (line-clamp 2) |
|
|
90
|
+
| meta[] | <label:campo (align)>, ... | colunas à direita (ROLE/STATUS/VISTO) |
|
|
91
|
+
| trailing | <badge/chip/contagem> | opcional |
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Inferência de slot por nome (PT+EN): `name/nome/title` → title · `email` →
|
|
95
|
+
subtitle · `status/role/papel` → meta (com dot ou chip) · `avatar/photo/foto` →
|
|
96
|
+
leading. `meta[].value` pode ser texto ou um chip/StatusDot — confirmar.
|
|
97
|
+
|
|
98
|
+
### 2b. renderItem (card rico) — quando MUITOS campos / layout custom
|
|
99
|
+
|
|
100
|
+
Se o item tem layout próprio (ex: pedido com header+meta+footer, progresso,
|
|
101
|
+
avatar-stack) → `renderItem={(item) => <Card .../>}`. Espelhar
|
|
102
|
+
`ListRichPreview.tsx`. O wrapper (card/hover/click/menu) continua do List.
|
|
103
|
+
|
|
104
|
+
| Item | Default |
|
|
105
|
+
| ------------------------------ | --------------------------------------------- |
|
|
106
|
+
| Densidade | `comfortable` (ou `compact`) |
|
|
107
|
+
| Menu por card (`getMenuItems`) | oferecer Editar/Excluir (Excluir destructive) |
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Fase 3 — Layout (agrupada)
|
|
112
|
+
|
|
113
|
+
| Layout | Quando | Extras a perguntar |
|
|
114
|
+
| ---------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
115
|
+
| **standard** (default) | lista plana | — |
|
|
116
|
+
| **grouped** | seções por status/categoria | `groups` (id/label/color) · `enableDnD` (arrastar entre/dentro → `onMove`/`onReorder`) · `groupSurface` |
|
|
117
|
+
| **hierarchical** | árvore (pai→filho) | itens com `children` · `defaultExpandedIds` · **`branchHighlight`**: `none` (conectores) / `block` (painéis) / `active` (ramo do último aberto) · lazy `onLoadChildren` |
|
|
118
|
+
|
|
119
|
+
`branchHighlight` só em hierarchical. DnD só em standard/grouped (excludente com virtualização).
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Fase 4 — Toolbar (agrupada)
|
|
124
|
+
|
|
125
|
+
A toolbar do DataList é enxuta (reusa o TableToolbar): visões(abas)/título ·
|
|
126
|
+
refresh · busca · filtro(drawer) · ⋯. Sem colunas/toggle de visão.
|
|
127
|
+
|
|
128
|
+
> ⛔ **Anti-pattern — NUNCA gerar form/selects soltos ACIMA da lista.** Intenção de
|
|
129
|
+
> "adicionar filtro" (select de status em cima, campo de período, "filtrar por X") →
|
|
130
|
+
> **sugira o padrão certo** (o DataList já filtra reativo, com chips clicáveis/editáveis):
|
|
131
|
+
>
|
|
132
|
+
> - **Filtro por campo** (status/categoria/tipo/data…) → declare em `filterFields`. Quer
|
|
133
|
+
> abrir já filtrado? **pré-aplique** via `views` ou `filterModel` → abre com o **chip
|
|
134
|
+
> aplicado**, editável, reativo. Pode pré-setar **vários** de uma vez.
|
|
135
|
+
> - **toolbarActions é SÓ pra caso pequeno e simples que NÃO reage com campo** (ex.:
|
|
136
|
+
> data/período, escopo) — **label curta**, **máx ~2**. Se mexe com os campos, é grande,
|
|
137
|
+
> ou são muitos → **NÃO use o toolbar.**
|
|
138
|
+
> - **Muitos filtros, ou ligados a campo** → SEMPRE os nativos **pré-aplicados** (chips no
|
|
139
|
+
> load) + drawer "Filtros". Nunca empilhar selects.
|
|
140
|
+
>
|
|
141
|
+
> Regra de ouro: **filtro é recurso do DataList (reativo), não UI montada na unha.**
|
|
142
|
+
|
|
143
|
+
| Item | Pergunta | Default |
|
|
144
|
+
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
|
|
145
|
+
| Título OU views | título à esquerda, ou abas de visão? | título (plural) |
|
|
146
|
+
| Busca | `searchable` (cobre title/subtitle/description + accessors) | on |
|
|
147
|
+
| **filterFields** | quais campos filtram? cada um: `{ id, label, type, accessor, options? }` | inferir dos campos select/status; confirmar |
|
|
148
|
+
| **Views (abas)** | presets `{ id, label, query:{search, filterModel} }` — OFERECER (ver obrigatória) | nenhuma |
|
|
149
|
+
| Refresh | `onRefresh` | on |
|
|
150
|
+
| **toolbarActions** | ações custom no toolbar (`button`/`dropdown`/`input`, ex.: seletor de período/mês). Inline no desktop; **colapsam no ⋯ no mobile**. Oferecer quando o usuário pedir um seletor/botão extra na barra | off |
|
|
151
|
+
| moreActions (⋯) | itens extras? | off |
|
|
152
|
+
|
|
153
|
+
`filterFields.type` ∈ text/select/boolean/number/date. Chips de filtro aplicado
|
|
154
|
+
aparecem automaticamente (ToolbarApplied). Filtro abre o MESMO drawer da tabela.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Fase 5 — Seleção, bulk e click
|
|
159
|
+
|
|
160
|
+
| Item | Pergunta | Default |
|
|
161
|
+
| ------------- | ------------------------------------------------------------------------------ | ----------------- |
|
|
162
|
+
| `selectable` | checkbox por card + bulk bar | off |
|
|
163
|
+
| `bulkActions` | `{ label, icon?, onClick(ids), destructive? }[]` (ex: Editar/Arquivar/Excluir) | se selectable on |
|
|
164
|
+
| `onItemClick` | nada / abrir detalhe / navegar | nada (standalone) |
|
|
165
|
+
|
|
166
|
+
Excluir (destructive) em drawer/form ⇒ confirmação via `AlertModal`.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Fase 6 — Escala (excludentes)
|
|
171
|
+
|
|
172
|
+
| Opção | Quando | Props |
|
|
173
|
+
| ------------------- | -------------------------------------------- | ---------------------------------------------------------------- |
|
|
174
|
+
| Nenhuma (default) | < ~1.000 itens | — |
|
|
175
|
+
| **Virtualização** | listas grandes (só `standard`) — desliga DnD | `virtualized` (+ `estimateItemSize`) |
|
|
176
|
+
| **Infinite scroll** | paginar ao rolar | `onLoadMore` + `hasMore` + `loadingMore` (+ skeleton automático) |
|
|
177
|
+
|
|
178
|
+
Em tela dedicada (`ExamplePageLayout`), propor `fillHeight` + `className="flex-1
|
|
179
|
+
min-h-0"` (toolbar fixa, só a lista rola). Não combinar `fillHeight` com `virtualized`.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Encerramento
|
|
184
|
+
|
|
185
|
+
Consolidar TODAS as escolhas num objeto de decisões (em memória — nada em disco),
|
|
186
|
+
carregar `blueprint.md` e montar o preview do gate.
|
|
187
|
+
|
|
188
|
+
Sinal: `BLUEPRINT_PRONTO: <Entidade> (lista) — aguardando gate`
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
> **Nota de portabilidade.** Este roteiro foi extraído do pipeline do iGreen DS
|
|
2
|
+
> para Claude Code. Menções a slash command (`/ds-create-…`), a `.claude/` e a
|
|
3
|
+
> ferramentas daquele ambiente descrevem **como ele é acionado lá** — aqui o
|
|
4
|
+
> equivalente é carregar este roteiro pelo `indice.json`. O conteúdo de decisão
|
|
5
|
+
> (entrevista, blueprint, regras de composição) vale igual.
|
|
6
|
+
|
|
7
|
+
> **Modo submódulo (`ds-link`).** Existe `.claude/ds-config.json` com `"mode": "submodule"`?
|
|
8
|
+
> Então **NÃO rode `igreen:add`** — esse script não existe no seu projeto. Os componentes e
|
|
9
|
+
> exemplos já estão no disco em `<dsPath>/src`: importe pelo `importBase` do config
|
|
10
|
+
> (compostos) e pelo `primitivesBase` (primitivos shadcn), e **leia** o exemplo direto de
|
|
11
|
+
> `<dsPath>/src/examples/`.
|
|
12
|
+
|
|
13
|
+
# List Builder — Geração (consumidor)
|
|
14
|
+
|
|
15
|
+
Só entre aqui após o gate aprovado. Ordem obrigatória:
|
|
16
|
+
|
|
17
|
+
## 1. Puxar do registry (componente + exemplo canônico)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm run igreen:add -- data-list example-mapa-rede
|
|
21
|
+
# + outros componentes citados no blueprint (chip, page-header, floating-panel,
|
|
22
|
+
# alert-modal, etc — o registry resolve as deps automaticamente)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`data-list` traz junto `list`, `table-toolbar`, `data-table` (via registryDependencies).
|
|
26
|
+
|
|
27
|
+
## 2. LER antes de escrever (precedência de fontes)
|
|
28
|
+
|
|
29
|
+
1. `src/examples/mapa-rede/mapa-rede-screen.tsx` — o molde real (DataList
|
|
30
|
+
`layout="hierarchical"` + `branchHighlight` + `renderItem` do card + `fillHeight`
|
|
31
|
+
- painel de detalhe `FloatingPanel` + `AlertModal`).
|
|
32
|
+
2. `src/components/ui/DataList/USAGE.md` + `src/components/ui/List/USAGE.md` + types ao lado — API exata.
|
|
33
|
+
3. Pra card rico / outros layouts (standard/grouped/DnD): adapte a forma do exemplo.
|
|
34
|
+
|
|
35
|
+
Nunca gere props de memória — copie a forma do exemplo.
|
|
36
|
+
|
|
37
|
+
## 3. Criar a página
|
|
38
|
+
|
|
39
|
+
- Caminho/rota conforme o blueprint (`PAGES_DIR`/`REGISTRO`).
|
|
40
|
+
- Wrapper: `<div className="flex flex-col h-full min-h-0 gap-gp-2xl">` → `<PageHeader .../>`
|
|
41
|
+
→ `<DataList fillHeight className="flex-1 min-h-0" .../>`.
|
|
42
|
+
- Card via **slots** (`leading/title/subtitle/meta/trailing`) OU `renderItem` (card rico).
|
|
43
|
+
- Layout `standard`/`grouped`(+`enableDnD`)/`hierarchical`(+`branchHighlight`) conforme blueprint.
|
|
44
|
+
- `filterFields` com `accessor: (item) => valor`; views (abas); seleção/bulk; escala
|
|
45
|
+
(`virtualized` XOR `onLoadMore`) — um por vez.
|
|
46
|
+
- Painel de detalhe / modais (se houver): espelhe `ConsultorDetailPanel` (FloatingPanel) e
|
|
47
|
+
o `AlertModal` do exemplo, ligados via estado da página.
|
|
48
|
+
- Tokens/spacing/typography conforme `.claude/rules/ds-design.md` + `DESIGN.md`.
|
|
49
|
+
|
|
50
|
+
## 4. Registrar a rota
|
|
51
|
+
|
|
52
|
+
No ponto que o usuário indicou (router / App). Página órfã = incompleto.
|
|
53
|
+
|
|
54
|
+
## 5. Validar
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npx tsc --noEmit # abort se falhar — corrija antes do handoff
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 6. Handoff
|
|
61
|
+
|
|
62
|
+
`LIST_PRONTO: <Entidade>` + onde foi registrada + como rodar (`npm run dev`).
|
|
63
|
+
Sugira ao usuário abrir a tela e conferir; ofereça ajustes finos (card, filtros, layout).
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
> **Nota de portabilidade.** Este roteiro foi extraído do pipeline do iGreen DS
|
|
2
|
+
> para Claude Code. Menções a slash command (`/ds-create-…`), a `.claude/` e a
|
|
3
|
+
> ferramentas daquele ambiente descrevem **como ele é acionado lá** — aqui o
|
|
4
|
+
> equivalente é carregar este roteiro pelo `indice.json`. O conteúdo de decisão
|
|
5
|
+
> (entrevista, blueprint, regras de composição) vale igual.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# List Builder (consumidor) — Router
|
|
9
|
+
|
|
10
|
+
Você guia a criação de uma tela de **lista de cards** que consome `<DataList>`
|
|
11
|
+
**sem fugir do exemplo e da documentação**. NÃO inventa API de props, NÃO gera
|
|
12
|
+
código de memória, NÃO toca em arquivo antes do gate aprovado.
|
|
13
|
+
|
|
14
|
+
## ⚠️ Desambiguação ANTES de tudo (anti-erro)
|
|
15
|
+
|
|
16
|
+
Muita gente chama tabela de "lista". Se você chegou aqui direto sem o front-door,
|
|
17
|
+
confirme em 1 pergunta que o caso é mesmo lista de cards — senão a pessoa cria errado:
|
|
18
|
+
|
|
19
|
+
| Lista de cards (ESTA skill) | Tabela/grade (→ `crud-builder`) |
|
|
20
|
+
| ----------------------------------------------------------------------- | ------------------------------------------------------------------ |
|
|
21
|
+
| cada item é um **card**; poucos campos em destaque (avatar/título/meta) | colunas × linhas; muitos campos por registro |
|
|
22
|
+
| visual, hierarquia/agrupamento/DnD, feed, organograma | comparar/ordenar/filtrar **por coluna**, editar célula, somatórios |
|
|
23
|
+
| ex: membros, tarefas, organização (árvore), rede, atividades | ex: clientes, financeiro, pedidos com muitas colunas |
|
|
24
|
+
|
|
25
|
+
Caso for tabela → **PARAR** e usar `crud-builder` (`/ds-create-crud`).
|
|
26
|
+
|
|
27
|
+
## Ambiente (este é um projeto CONSUMIDOR, copy-in)
|
|
28
|
+
|
|
29
|
+
| Variável | Valor |
|
|
30
|
+
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
|
|
31
|
+
| `IMPORT_PATH` | `@/components/ui/DataList`, `@/components/ui/List`, etc (copy-in via alias) |
|
|
32
|
+
| `EXEMPLO_CANÔNICO` | `example-mapa-rede` → `npm run igreen:add -- example-mapa-rede` → ler `src/examples/mapa-rede/mapa-rede-screen.tsx` |
|
|
33
|
+
| `DOC` | `src/components/ui/DataList/USAGE.md` + `src/components/ui/List/USAGE.md` (após `igreen:add data-list`) + types ao lado |
|
|
34
|
+
| `PAGES_DIR` / `REGISTRO` | perguntar ao usuário (onde mora a página + como registra rota) |
|
|
35
|
+
|
|
36
|
+
Se o componente/exemplo ainda não está no disco, **puxe via `igreen:add`** antes de ler — nunca gere de memória.
|
|
37
|
+
|
|
38
|
+
> **Modo submódulo (ds-link).** Se existe `.claude/ds-config.json` com `"mode": "submodule"`,
|
|
39
|
+
> o DS é consumido como **submódulo** (não copy-in): os componentes/exemplos JÁ estão no disco
|
|
40
|
+
> em `<dsPath>/src` e **não** há registry. Use `importBase` do config (ex.: `@ds/components/ui/<Nome>`)
|
|
41
|
+
> e leia o exemplo canônico direto em `<dsPath>/src/examples/mapa-rede/mapa-rede-screen.tsx` —
|
|
42
|
+
> **NÃO** rode `igreen:add`. `PAGES_DIR`/`REGISTRO` continuam do projeto pai.
|
|
43
|
+
|
|
44
|
+
## Fluxo — 3 estágios
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
/ds-create-list (ou /ds-create-screen → desambiguação → aqui)
|
|
48
|
+
▼ interview.md
|
|
49
|
+
1. ENTREVISTA (fases 0-6) — acumula escolhas, ZERO edição em disco
|
|
50
|
+
▼ blueprint.md
|
|
51
|
+
2. BLUEPRINT [GATE] — preview consolidado + pré-validações → aguarda "aprovar"
|
|
52
|
+
▼ generate.md
|
|
53
|
+
3. GERAÇÃO — igreen:add → ler exemplo → criar página → registrar → tsc → handoff
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Carregue cada sub-arquivo só no estágio correspondente: `interview.md` agora, `blueprint.md` ao fim da entrevista, `generate.md` só após o gate.
|
|
57
|
+
|
|
58
|
+
## ⚠️ Precedência de fontes (anti-drift)
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
1. src/examples/mapa-rede/mapa-rede-screen.tsx (exemplo real, vence tudo)
|
|
62
|
+
2. src/components/ui/DataList/USAGE.md + src/components/ui/List/USAGE.md + types ao lado
|
|
63
|
+
3. Snippets desta skill
|
|
64
|
+
4. Memória da IA ← NUNCA confiar sozinha
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Se USAGE.md divergir do exemplo/types, o exemplo + types vencem.
|
|
68
|
+
|
|
69
|
+
## Guardrails (não-negociáveis)
|
|
70
|
+
|
|
71
|
+
1. `virtualized` e `enableDnD` são **mutuamente exclusivos**; `virtualized` e
|
|
72
|
+
`onLoadMore` (infinite-scroll) **não combinam** — escolha um.
|
|
73
|
+
2. `branchHighlight` (`block`/`active`) só faz efeito em `layout="hierarchical"`.
|
|
74
|
+
3. `filterFields` declara `accessor: (item) => valor` (NÃO column def); `select`
|
|
75
|
+
precisa `options`. Operador de view/filtro válido pro tipo (multiSelect⇒isAnyOf,
|
|
76
|
+
select⇒equals, text⇒contains, number⇒equals, date⇒between, boolean⇒equals).
|
|
77
|
+
4. `fillHeight` em tela dedicada ⇒ pai com altura + `className="flex-1 min-h-0"`
|
|
78
|
+
(toolbar/chips/bulk fixos, só a lista rola). Não usar com `virtualized`.
|
|
79
|
+
5. `layout="grouped"` exige `groups`; `hierarchical` exige itens com `children`.
|
|
80
|
+
6. Card via slots OU `renderItem` (não os dois). Forms (criar/editar em drawer)
|
|
81
|
+
usam `<FormField>` + `gap-form-gap`.
|
|
82
|
+
7. Classes DS antes de Tailwind literal; zero hardcode de cor/tamanho (ver `.claude/rules/ds-design.md`).
|
|
83
|
+
8. Wrapper da tela: `flex flex-col h-full min-h-0 gap-gp-2xl` (PageHeader → 16px → lista). Ver `DESIGN.md`.
|
|
84
|
+
9. Página registrada no roteador do usuário — página órfã = tarefa incompleta.
|
|
85
|
+
10. `npx tsc --noEmit` limpo antes do handoff (abort-on-error).
|
|
86
|
+
11. LER o exemplo canônico ANTES de gerar — nunca de memória.
|
|
87
|
+
|
|
88
|
+
## Handoff
|
|
89
|
+
|
|
90
|
+
- Entrevista pronta → `BLUEPRINT_PRONTO: <Entidade> (lista) — aguardando gate`
|
|
91
|
+
- Pós-geração → `LIST_PRONTO: <Entidade>` (+ onde foi registrada)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
> **Nota de portabilidade.** Este roteiro foi extraído do pipeline do iGreen DS
|
|
2
|
+
> para Claude Code. Menções a slash command (`/ds-create-…`), a `.claude/` e a
|
|
3
|
+
> ferramentas daquele ambiente descrevem **como ele é acionado lá** — aqui o
|
|
4
|
+
> equivalente é carregar este roteiro pelo `indice.json`. O conteúdo de decisão
|
|
5
|
+
> (entrevista, blueprint, regras de composição) vale igual.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
> **Modo submódulo (`ds-link`).** Existe `.claude/ds-config.json` com `"mode": "submodule"`?
|
|
9
|
+
> Então **NÃO rode `igreen:add`** — esse script não existe no seu projeto. Os componentes e
|
|
10
|
+
> exemplos já estão no disco em `<dsPath>/src`: importe pelo `importBase` do config
|
|
11
|
+
> (compostos) e pelo `primitivesBase` (primitivos shadcn), e **leia** o exemplo direto de
|
|
12
|
+
> `<dsPath>/src/examples/`.
|
|
13
|
+
|
|
14
|
+
# module-replicator — Replicar família de telas (segmento)
|
|
15
|
+
|
|
16
|
+
Quando um app tem **módulos espelhados** (ex.: várias verticais/segmentos com a
|
|
17
|
+
mesma estrutura de telas), replica a família trocando só o que varia.
|
|
18
|
+
|
|
19
|
+
## ⚠️ Antes de copiar: copiar OU parametrizar?
|
|
20
|
+
|
|
21
|
+
Copiar N vezes = N cópias pra manter (todo bug/ajuste ×N). **Se as telas são
|
|
22
|
+
idênticas em estrutura e só mudam dados/rótulos**, o melhor costuma ser
|
|
23
|
+
**parametrizar** — 1 componente dirigido por config de segmento:
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
const SEGMENTOS = { energia: {...}, telecom: {...}, seguros: {...} };
|
|
27
|
+
function SegmentoDashboard({ seg }: { seg: SegKey }) { /* lê SEGMENTOS[seg] */ }
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Ofereça as duas ao usuário: **(a) parametrizar** (recomendado se ≥3 clones ou
|
|
31
|
+
manutenção conjunta) ou **(b) replicar arquivos** (ok pra 1-2 e quando os
|
|
32
|
+
segmentos devem divergir depois). Só siga pra cópia se ele escolher (b).
|
|
33
|
+
|
|
34
|
+
## Fluxo (replicar arquivos — opção b)
|
|
35
|
+
|
|
36
|
+
1. **Identifique o módulo-fonte**: as telas/arquivos + o contexto de nav dele
|
|
37
|
+
(`nav-data`) + as rotas (`routes`).
|
|
38
|
+
2. **Separe o que VARIA** (dataset/mock, rótulos/títulos, id/ícone/cor do contexto,
|
|
39
|
+
hrefs `#/<segmento>/...`) do que é **ESTRUTURAL** (layout, colunas, componentes,
|
|
40
|
+
spacing) — o estrutural fica **idêntico**.
|
|
41
|
+
3. **Copie** as telas → novo segmento; troque só o que varia (1 arquivo de mock por
|
|
42
|
+
segmento, mesma shape/tipos).
|
|
43
|
+
4. **Registre** o novo contexto em `nav-data` + as entradas no mapa de rotas
|
|
44
|
+
(ver skill `app-builder`). Hrefs únicos por segmento.
|
|
45
|
+
5. `npx tsc --noEmit` limpo.
|
|
46
|
+
|
|
47
|
+
## Gotchas do tipo
|
|
48
|
+
|
|
49
|
+
- **Nunca altere a ESTRUTURA na cópia** — se divergir, vira manutenção ×N e perde o
|
|
50
|
+
sentido de "família". Só dados/rótulos/ícone/cor/href mudam.
|
|
51
|
+
- **Mock**: um arquivo por segmento com a MESMA shape (reuse os tipos). Não duplique tipos.
|
|
52
|
+
- **Nav/rotas**: `id`/label/icon/color do contexto únicos; hrefs `#/<segmento>/<tela>`;
|
|
53
|
+
1 linha por tela no mapa de rotas (não if-chain).
|
|
54
|
+
- Se depois um segmento precisar de tela exclusiva, aí sim diverge só aquela.
|
|
55
|
+
|
|
56
|
+
Aplique `DESIGN.md`. Handoff: `MODULO_PRONTO: <segmento> (N telas)` + rotas.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
> **Nota de portabilidade.** Este roteiro foi extraído do pipeline do iGreen DS
|
|
2
|
+
> para Claude Code. Menções a slash command (`/ds-create-…`), a `.claude/` e a
|
|
3
|
+
> ferramentas daquele ambiente descrevem **como ele é acionado lá** — aqui o
|
|
4
|
+
> equivalente é carregar este roteiro pelo `indice.json`. O conteúdo de decisão
|
|
5
|
+
> (entrevista, blueprint, regras de composição) vale igual.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# page-detail — Página de detalhamento
|
|
9
|
+
|
|
10
|
+
Página de leitura/inspeção de um registro: cabeçalho + abas + cards de seção.
|
|
11
|
+
|
|
12
|
+
## Fluxo
|
|
13
|
+
1. `npm run igreen:add -- example-order-detail` (traz a tela + `Tabs`, `Card`, `Chip`, `PageHeader`).
|
|
14
|
+
2. **Leia** `src/examples/order-detail/order-detail-screen.tsx` + USAGE dos componentes.
|
|
15
|
+
3. Adapte as abas/seções/campos ao registro do usuário.
|
|
16
|
+
4. Registre a rota. `npx tsc --noEmit` limpo.
|
|
17
|
+
|
|
18
|
+
> **Modo submódulo (ds-link).** Se existe `.claude/ds-config.json` com `"mode": "submodule"`,
|
|
19
|
+
> o DS é consumido como **submódulo** (não copy-in): os componentes/exemplos JÁ estão no disco
|
|
20
|
+
> em `<dsPath>/src` e **não** há registry. Use `importBase` do config (ex.: `@ds/components/shadcn/tabs`)
|
|
21
|
+
> e leia o exemplo direto em `<dsPath>/src/examples/order-detail/order-detail-screen.tsx` —
|
|
22
|
+
> **NÃO** rode `igreen:add`.
|
|
23
|
+
|
|
24
|
+
## Gotchas do tipo
|
|
25
|
+
- Estrutura: `PageHeader` (título + badges de status + ações) → `Tabs` (visão geral / detalhes / atividade / comentários / anexos) → cards de seção (`section-card`).
|
|
26
|
+
- `Tabs` tem a variant `line` (underline) além da default segmented — use `line` pra navegação de abas de detalhe/ficha; segmented pra alternância de conteúdo curto.
|
|
27
|
+
- Layout 2 colunas (conteúdo + painel lateral do cliente/meta) num grid responsivo; empilha no mobile.
|
|
28
|
+
- Badges de status via `Chip`/`Badge` com cor semântica (`success`/`warning`/...).
|
|
29
|
+
- Wrapper de página: `flex flex-col h-full min-h-0 gap-gp-2xl`.
|
|
30
|
+
- Campos label/valor: rótulo `text-caption` em `fg-muted`, valor `text-body`.
|
|
31
|
+
|
|
32
|
+
Se a tela também edita inline ou abre drawer de edição → ver skill `drawers`. Aplique `DESIGN.md`. Handoff: `DETAIL_PRONTO: <Entidade>` + rota.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
> **Nota de portabilidade.** Este roteiro foi extraído do pipeline do iGreen DS
|
|
2
|
+
> para Claude Code. Menções a slash command (`/ds-create-…`), a `.claude/` e a
|
|
3
|
+
> ferramentas daquele ambiente descrevem **como ele é acionado lá** — aqui o
|
|
4
|
+
> equivalente é carregar este roteiro pelo `indice.json`. O conteúdo de decisão
|
|
5
|
+
> (entrevista, blueprint, regras de composição) vale igual.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# page-edit — Tela de edição/cadastro
|
|
9
|
+
|
|
10
|
+
Tela de formulário (criar/editar). Não gere de memória — puxe e adapte o exemplo.
|
|
11
|
+
|
|
12
|
+
## Fluxo
|
|
13
|
+
1. `npm run igreen:add -- example-edit-page` (traz a tela + `FormField`, `Button`, etc).
|
|
14
|
+
2. **Leia** `src/examples/edit-page/edit-page-screen.tsx` + `src/components/ui/FormField/USAGE.md`.
|
|
15
|
+
3. Adapte os campos ao caso do usuário (mantendo a estrutura de seções/steps).
|
|
16
|
+
4. Registre a rota onde o usuário indicar. `npx tsc --noEmit` limpo.
|
|
17
|
+
|
|
18
|
+
> **Modo submódulo (ds-link).** Se existe `.claude/ds-config.json` com `"mode": "submodule"`,
|
|
19
|
+
> o DS é consumido como **submódulo** (não copy-in): os componentes/exemplos JÁ estão no disco
|
|
20
|
+
> em `<dsPath>/src` e **não** há registry. Use `importBase` do config (ex.: `@ds/components/ui/FormField`)
|
|
21
|
+
> e leia o exemplo direto em `<dsPath>/src/examples/edit-page/edit-page-screen.tsx` —
|
|
22
|
+
> **NÃO** rode `igreen:add`.
|
|
23
|
+
|
|
24
|
+
## Gotchas do tipo
|
|
25
|
+
- **Sempre `<FormField>`** (FormFieldInput/Select/Textarea/Switch) — nunca `<label>` cru (peso/cor/dark-mode divergem). Spacing entre campos = `gap-form-gap` (20px).
|
|
26
|
+
- Validação inline via `errorMessage` no FormField; helper via `helperText`.
|
|
27
|
+
- Multi-step: padrão `StepNav` lateral do example-edit-page (estado `activeStep` + refs de seção).
|
|
28
|
+
- Wrapper de página: `flex flex-col h-full min-h-0 gap-gp-2xl`; PageHeader com ações Cancelar/Salvar.
|
|
29
|
+
- Ações: Salvar = `<Button color="primary" variant="filled">`; Cancelar = `secondary outline`.
|
|
30
|
+
|
|
31
|
+
Aplique `DESIGN.md` + `.claude/rules/ds-design.md`. Handoff: `EDIT_PRONTO: <Entidade>` + rota.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
> **Nota de portabilidade.** Este roteiro foi extraído do pipeline do iGreen DS
|
|
2
|
+
> para Claude Code. Menções a slash command (`/ds-create-…`), a `.claude/` e a
|
|
3
|
+
> ferramentas daquele ambiente descrevem **como ele é acionado lá** — aqui o
|
|
4
|
+
> equivalente é carregar este roteiro pelo `indice.json`. O conteúdo de decisão
|
|
5
|
+
> (entrevista, blueprint, regras de composição) vale igual.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# screen-composer — Página composta (estado compartilhado)
|
|
9
|
+
|
|
10
|
+
Não é um tipo de peça — é a **cola** entre peças. Cada peça vem de um builder
|
|
11
|
+
(crud/list/dashboard/drawers); aqui você monta o layout e **cabeia o estado que
|
|
12
|
+
elas compartilham**. A receita completa está logo abaixo, em "Os 2 padrões".
|
|
13
|
+
|
|
14
|
+
## Quando esta skill (vs os builders diretos)
|
|
15
|
+
|
|
16
|
+
- 1 peça só (uma tabela, uma lista, um dashboard) → vá direto no builder.
|
|
17
|
+
- **2+ peças que reagem entre si** (master-detail e/ou cross-filter) → **aqui**.
|
|
18
|
+
|
|
19
|
+
## Fluxo
|
|
20
|
+
|
|
21
|
+
1. **Decomponha** a página: quais peças (tabela / lista / KPIs+gráfico / detalhe /
|
|
22
|
+
filtro global) e quais **interações** (clicar→detalhe? controle→filtra tudo?).
|
|
23
|
+
2. **Monte cada peça** pelo builder certo (crud/list/dashboard) OU puxe o exemplo
|
|
24
|
+
composto: `npm run igreen:add -- example-finance` (master-detail: tabela +
|
|
25
|
+
detail panel + drawers) / `example-order-detail`. **Leia** o exemplo.
|
|
26
|
+
3. **Cabeie o estado no nível da PÁGINA** — ver "Os 2 padrões" abaixo.
|
|
27
|
+
4. `npx tsc --noEmit` limpo.
|
|
28
|
+
|
|
29
|
+
## Os 2 padrões (cobrem quase toda página composta)
|
|
30
|
+
|
|
31
|
+
Estado que 2+ peças compartilham **não mora em cada peça**: sobe pro componente da
|
|
32
|
+
página (single source of truth) e desce por props.
|
|
33
|
+
|
|
34
|
+
### Master-detail — clicar num item abre o detalhe
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
function ClientesPage() {
|
|
38
|
+
const [selectedId, setSelectedId] = useState<string | null>(null);
|
|
39
|
+
const selected = selectedId ? findById(selectedId) : null;
|
|
40
|
+
return (
|
|
41
|
+
<div className="flex h-full min-h-0 gap-gp-2xl">
|
|
42
|
+
<DataTable
|
|
43
|
+
rows={rows}
|
|
44
|
+
columns={cols}
|
|
45
|
+
onRowClick={(row) => setSelectedId(row.id)} // grade → estado
|
|
46
|
+
className="flex-1 min-h-0"
|
|
47
|
+
/>
|
|
48
|
+
{/* ao LADO = FloatingPanel/painel fixo · POR CIMA = Drawer/Sheet */}
|
|
49
|
+
<DetailPanel item={selected} onClose={() => setSelectedId(null)} />
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Nunca duplique a linha no detalhe — passe só o `id`/objeto selecionado.
|
|
56
|
+
|
|
57
|
+
### Cross-filter — um controle alimenta várias peças
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
function PainelPage() {
|
|
61
|
+
const [periodo, setPeriodo] = useState<Periodo>("mes");
|
|
62
|
+
const data = useMemo(() => filtrar(base, periodo), [periodo]); // 1 fonte
|
|
63
|
+
return (
|
|
64
|
+
<div className="flex flex-col gap-gp-2xl">
|
|
65
|
+
<PageHeader actions={<PeriodSelector value={periodo} onChange={setPeriodo} />} />
|
|
66
|
+
<KpiGroup>{/* lê `data` */}</KpiGroup>
|
|
67
|
+
<ChartCard data={data} />
|
|
68
|
+
<DataTable rows={data.rows} columns={cols} />
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
- **Um** `useMemo` deriva o dataset; todas as peças leem dele (não refazem fetch).
|
|
75
|
+
- Filtro por **coluna** continua nativo/pré-aplicado (chips) — ver `ds-components.md`.
|
|
76
|
+
O cross-filter aqui é o **escopo global** (período/segmento), no `PageHeader.actions`.
|
|
77
|
+
- Os dois combinam: `selectedId` e `periodo` convivem no mesmo nível.
|
|
78
|
+
|
|
79
|
+
> **Modo submódulo (ds-link).** Se existe `.claude/ds-config.json` com `"mode": "submodule"`,
|
|
80
|
+
> NÃO rode `igreen:add` — leia os exemplos em `<dsPath>/src/examples/` e importe via `importBase`.
|
|
81
|
+
|
|
82
|
+
## Gotchas do tipo
|
|
83
|
+
|
|
84
|
+
- **Single source of truth**: estado que 2+ peças compartilham SOBE pra página, não
|
|
85
|
+
fica duplicado em cada peça. Peça isolada mantém o seu.
|
|
86
|
+
- **Master-detail**: passe só `id`/objeto seleto pro detalhe (nunca remonte a linha).
|
|
87
|
+
Ao lado = `FloatingPanel`/painel fixo; por cima = `Drawer`/`Sheet`.
|
|
88
|
+
- **Cross-filter**: um `useMemo(filtrar(base, filtro))` alimenta KPIs+gráfico+tabela;
|
|
89
|
+
não refaça fetch por peça. Filtro por COLUNA continua nativo/pré-aplicado (L-051);
|
|
90
|
+
o cross-filter é o escopo global (período/segmento), no `PageHeader.actions`.
|
|
91
|
+
- **Layout**: shell `flex flex-col gap-gp-2xl` (ou `flex gap` p/ master-detail lado a lado);
|
|
92
|
+
`fillHeight`/`flex-1 min-h-0` nas peças que rolam.
|
|
93
|
+
- Conteúdo/estilo de cada peça = responsabilidade do builder dela; aqui é só layout + estado.
|
|
94
|
+
|
|
95
|
+
Aplique `DESIGN.md`. Handoff: `SCREEN_PRONTO: <página>` + rota.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@snksergio/design-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.63.0",
|
|
4
4
|
"//distribuicao": "Canal PRIMARIO = registry shadcn (copy-in) + CLI @snksergio/create-design-system; sobe sozinho no merge (Vercel). Canal SECUNDARIO = este pacote npm (@snksergio/design-system), publicado por passo MANUAL do mantenedor, entao costuma ficar atras do registry. SECUNDARIO descreve a ORDEM DE PUBLICACAO, nao o nivel de suporte: NAO e depreciado, e desde a 0.37.0 entrega 41 dos 42 componentes ui/ no barrel raiz + os 41 primitivos shadcn no subpath ./shadcn (so TabelaTeste, demo interno, fica de fora). Publish so pelo Passo 7 do .claude/skills/ds-dev/release.md (valida com `npm run lib:verify`, pede o token, publica, revoga). Ver DISTRIBUICAO.md.",
|
|
5
5
|
"description": "iGreen Design System — internal library for SaaS CRM, admin panels and dashboards. React 19 + Tailwind v4 + Shadcn + Radix.",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -19,8 +19,10 @@
|
|
|
19
19
|
"dist-lib/chunks/**",
|
|
20
20
|
"dist-lib/src/**",
|
|
21
21
|
"dist-lib/tokens/**",
|
|
22
|
+
"dist-lib/ai/**",
|
|
22
23
|
"README.md"
|
|
23
24
|
],
|
|
25
|
+
"//ai-bundle": "dist-lib/ai/ é o pacote de conteúdo pra IA fora do Claude Code (roteiros, regras, exemplos, guias, manifesto com versão+commit). É LIDO POR CAMINHO, não importado — por isso só o manifest.json tem entrada em exports, como âncora resolvível e verificada pelo lib-verify; os outros 60+ arquivos seguem o precedente de dist-lib/fonts/**, que está em files sem export e o gate aprova. Enumerar 60 markdowns em exports seria ruído, e wildcard não é verificado (ver //exports-theme-marcas). Gerado no closeBundle do vite.lib.config.ts.",
|
|
24
26
|
"engines": {
|
|
25
27
|
"node": ">=20.0.0"
|
|
26
28
|
},
|
|
@@ -44,6 +46,7 @@
|
|
|
44
46
|
"import": "./dist-lib/shadcn.mjs",
|
|
45
47
|
"require": "./dist-lib/shadcn.cjs"
|
|
46
48
|
},
|
|
49
|
+
"./ai/manifest.json": "./dist-lib/ai/manifest.json",
|
|
47
50
|
"./theme.css": "./dist-lib/theme.css",
|
|
48
51
|
"./theme/brand-blue.css": "./dist-lib/theme/brand-blue.css",
|
|
49
52
|
"./theme/brand-green.css": "./dist-lib/theme/brand-green.css",
|