@polymorphism-tech/morph-spec 2.2.0 → 2.4.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/CLAUDE.md +314 -1673
- package/LICENSE +72 -72
- package/README.md +515 -516
- package/bin/detect-agents.js +225 -225
- package/bin/morph-spec.js +358 -173
- package/bin/render-template.js +302 -302
- package/bin/semantic-detect-agents.js +246 -246
- package/bin/task-manager.js +429 -0
- package/bin/validate-agents-skills.js +251 -251
- package/bin/validate-agents.js +69 -69
- package/bin/validate-phase.js +263 -263
- package/bin/validate.js +369 -0
- package/content/.azure/README.md +293 -293
- package/content/.azure/docs/azure-devops-setup.md +454 -454
- package/content/.azure/docs/branch-strategy.md +398 -398
- package/content/.azure/docs/local-development.md +515 -515
- package/content/.azure/pipelines/pipeline-variables.yml +34 -34
- package/content/.azure/pipelines/prod-pipeline.yml +319 -319
- package/content/.azure/pipelines/staging-pipeline.yml +234 -234
- package/content/.azure/pipelines/templates/build-dotnet.yml +75 -75
- package/content/.azure/pipelines/templates/deploy-app-service.yml +94 -94
- package/content/.azure/pipelines/templates/deploy-container-app.yml +120 -120
- package/content/.azure/pipelines/templates/infra-deploy.yml +90 -90
- package/content/.claude/commands/morph-apply.md +221 -158
- package/content/.claude/commands/morph-archive.md +79 -79
- package/content/.claude/commands/morph-infra.md +209 -209
- package/content/.claude/commands/morph-preflight.md +227 -0
- package/content/.claude/commands/morph-proposal.md +122 -101
- package/content/.claude/commands/morph-status.md +86 -86
- package/content/.claude/commands/morph-troubleshoot.md +122 -0
- package/content/.claude/settings.local.json +15 -15
- package/content/.claude/skills/checklists/code-review.md +226 -0
- package/content/.claude/skills/checklists/morph-checklist.md +117 -0
- package/content/.claude/skills/checklists/simulation-checklist.md +77 -0
- package/content/.claude/skills/infra/bicep-architect.md +126 -419
- package/content/.claude/skills/infra/container-specialist.md +131 -437
- package/content/.claude/skills/infra/devops-engineer.md +119 -405
- package/content/.claude/skills/integrations/asaas-financial.md +130 -333
- package/content/.claude/skills/integrations/azure-identity.md +142 -309
- package/content/.claude/skills/integrations/clerk-auth.md +108 -290
- package/content/.claude/skills/integrations/resend-email.md +119 -0
- package/content/.claude/skills/specialists/ai-system-architect.md +192 -604
- package/content/.claude/skills/specialists/azure-architect.md +142 -142
- package/content/.claude/skills/specialists/code-analyzer.md +235 -0
- package/content/.claude/skills/specialists/dotnet-senior.md +287 -0
- package/content/.claude/skills/specialists/ef-modeler.md +113 -200
- package/content/.claude/skills/specialists/hangfire-orchestrator.md +126 -245
- package/content/.claude/skills/specialists/ms-agent-expert.md +109 -263
- package/content/.claude/skills/specialists/po-pm-advisor.md +197 -197
- package/content/.claude/skills/specialists/standards-architect.md +156 -78
- package/content/.claude/skills/specialists/testing-specialist.md +126 -0
- package/content/.claude/skills/specialists/ui-ux-designer.md +191 -1060
- package/content/.claude/skills/stacks/dotnet-blazor.md +210 -588
- package/content/.claude/skills/stacks/dotnet-nextjs.md +154 -402
- package/content/.claude/skills/workflows/morph-replicate.md +213 -0
- package/content/.claude/{commands/morph-clarify.md → skills/workflows/phase-clarify.md} +5 -58
- package/content/.claude/{commands/morph-design.md → skills/workflows/phase-design.md} +16 -86
- package/content/.claude/{commands/morph-setup.md → skills/workflows/phase-setup.md} +9 -17
- package/content/.claude/skills/workflows/phase-tasks.md +164 -0
- package/content/.claude/{commands/morph-uiux.md → skills/workflows/phase-uiux.md} +15 -88
- package/content/.morph/.morphversion +5 -5
- package/content/.morph/archive/.gitkeep +25 -25
- package/content/.morph/config/agents.json +378 -242
- package/content/.morph/config/config.template.json +89 -108
- package/content/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +392 -392
- package/content/.morph/docs/workflows/design-impl.md +37 -0
- package/content/.morph/docs/workflows/fast-track.md +29 -0
- package/content/.morph/docs/workflows/full-morph.md +76 -0
- package/content/.morph/docs/workflows/standard.md +44 -0
- package/content/.morph/docs/workflows/ui-refresh.md +39 -0
- package/content/.morph/examples/api-nextjs/README.md +241 -241
- package/content/.morph/examples/api-nextjs/contracts.ts +307 -307
- package/content/.morph/examples/api-nextjs/spec.md +399 -399
- package/content/.morph/examples/api-nextjs/tasks.md +168 -168
- package/content/.morph/examples/micro-saas/README.md +125 -125
- package/content/.morph/examples/micro-saas/contracts.cs +358 -358
- package/content/.morph/examples/micro-saas/decisions.md +246 -246
- package/content/.morph/examples/micro-saas/spec.md +236 -236
- package/content/.morph/examples/micro-saas/tasks.md +150 -150
- package/content/.morph/examples/multi-agent/README.md +309 -309
- package/content/.morph/examples/multi-agent/contracts.cs +433 -433
- package/content/.morph/examples/multi-agent/spec.md +479 -479
- package/content/.morph/examples/multi-agent/tasks.md +185 -185
- package/content/.morph/examples/scheduled-reports/decisions.md +158 -0
- package/content/.morph/examples/scheduled-reports/proposal.md +95 -0
- package/content/.morph/examples/scheduled-reports/spec.md +267 -0
- package/content/.morph/examples/state-v3.json +188 -0
- package/content/.morph/features/.gitkeep +25 -25
- package/content/.morph/hooks/README.md +190 -239
- package/content/.morph/hooks/pre-commit-agents.sh +24 -24
- package/content/.morph/hooks/pre-commit-all.sh +48 -48
- package/content/.morph/hooks/pre-commit-specs.sh +49 -49
- package/content/.morph/hooks/pre-commit-tests.sh +60 -60
- package/content/.morph/project.md +160 -160
- package/content/.morph/schemas/agent.schema.json +296 -296
- package/content/.morph/schemas/tasks.schema.json +220 -0
- package/content/.morph/specs/.gitkeep +20 -20
- package/content/.morph/standards/agent-framework-blazor-ui.md +359 -0
- package/content/.morph/standards/agent-framework-production.md +410 -0
- package/content/.morph/standards/agent-framework-setup.md +413 -453
- package/content/.morph/standards/agent-framework-workflows.md +349 -0
- package/content/.morph/standards/architecture.md +325 -325
- package/content/.morph/standards/azure.md +605 -379
- package/content/.morph/standards/coding.md +377 -377
- package/content/.morph/standards/dotnet10-migration.md +520 -494
- package/content/.morph/standards/fluent-ui-setup.md +590 -590
- package/content/.morph/standards/migration-guide.md +514 -514
- package/content/.morph/standards/passkeys-auth.md +423 -423
- package/content/.morph/standards/vector-search-rag.md +536 -536
- package/content/.morph/state.json +17 -17
- package/content/.morph/templates/FluentDesignTheme.cs +149 -149
- package/content/.morph/templates/MudTheme.cs +281 -281
- package/content/.morph/templates/agent.cs +163 -172
- package/content/.morph/templates/clarify-questions.md +159 -0
- package/content/.morph/templates/component.razor +239 -239
- package/content/.morph/templates/contracts/Commands.cs +74 -0
- package/content/.morph/templates/contracts/Entities.cs +25 -0
- package/content/.morph/templates/contracts/Queries.cs +74 -0
- package/content/.morph/templates/contracts/README.md +74 -0
- package/content/.morph/templates/contracts.cs +217 -217
- package/content/.morph/templates/decisions.md +123 -106
- package/content/.morph/templates/design-system.css +226 -226
- package/content/.morph/templates/infra/.dockerignore.example +89 -89
- package/content/.morph/templates/infra/Dockerfile.example +82 -82
- package/content/.morph/templates/infra/README.md +286 -286
- package/content/.morph/templates/infra/app-insights.bicep +63 -63
- package/content/.morph/templates/infra/app-service.bicep +164 -164
- package/content/.morph/templates/infra/container-app-env.bicep +49 -49
- package/content/.morph/templates/infra/container-app.bicep +156 -156
- package/content/.morph/templates/infra/deploy-checklist.md +426 -0
- package/content/.morph/templates/infra/deploy.ps1 +229 -229
- package/content/.morph/templates/infra/deploy.sh +208 -208
- package/content/.morph/templates/infra/key-vault.bicep +91 -91
- package/content/.morph/templates/infra/main.bicep +189 -189
- package/content/.morph/templates/infra/parameters.dev.json +29 -29
- package/content/.morph/templates/infra/parameters.prod.json +29 -29
- package/content/.morph/templates/infra/parameters.staging.json +29 -29
- package/content/.morph/templates/infra/sql-database.bicep +103 -103
- package/content/.morph/templates/infra/storage.bicep +106 -106
- package/content/.morph/templates/integrations/asaas-client.cs +387 -387
- package/content/.morph/templates/integrations/asaas-webhook.cs +351 -351
- package/content/.morph/templates/integrations/azure-identity-config.cs +288 -288
- package/content/.morph/templates/integrations/clerk-config.cs +258 -258
- package/content/.morph/templates/job.cs +171 -171
- package/content/.morph/templates/migration.cs +83 -83
- package/content/.morph/templates/proposal.md +141 -155
- package/content/.morph/templates/recap.md +94 -105
- package/content/.morph/templates/repository.cs +141 -141
- package/content/.morph/templates/saas/subscription.cs +347 -347
- package/content/.morph/templates/saas/tenant.cs +338 -338
- package/content/.morph/templates/service.cs +139 -139
- package/content/.morph/templates/simulation.md +353 -0
- package/content/.morph/templates/spec.md +149 -148
- package/content/.morph/templates/sprint-status.yaml +68 -68
- package/content/.morph/templates/state.template.json +222 -222
- package/content/.morph/templates/story.md +143 -143
- package/content/.morph/templates/tasks.md +257 -235
- package/content/.morph/templates/test.cs +239 -239
- package/content/.morph/templates/ui-components.md +362 -276
- package/content/.morph/templates/ui-design-system.md +286 -286
- package/content/.morph/templates/ui-flows.md +336 -336
- package/content/.morph/templates/ui-mockups.md +133 -133
- package/content/.morph/test-infra/example.bicep +59 -59
- package/content/CLAUDE.md +150 -442
- package/content/README.md +79 -79
- package/detectors/config-detector.js +223 -223
- package/detectors/conversation-analyzer.js +163 -163
- package/detectors/index.js +84 -84
- package/detectors/standards-generator.js +275 -275
- package/detectors/structure-detector.js +245 -250
- package/docs/README.md +144 -149
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +977 -977
- package/docs/api/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1048 -1048
- package/docs/api/scripts/collapse.js +38 -38
- package/docs/api/scripts/commonNav.js +28 -28
- package/docs/api/scripts/linenumber.js +25 -25
- package/docs/api/scripts/nav.js +12 -12
- package/docs/api/scripts/polyfill.js +3 -3
- package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -202
- package/docs/api/scripts/prettify/lang-css.js +2 -2
- package/docs/api/scripts/prettify/prettify.js +28 -28
- package/docs/api/scripts/search.js +98 -98
- package/docs/api/styles/jsdoc.css +776 -776
- package/docs/api/styles/prettify.css +80 -80
- package/docs/examples.md +328 -328
- package/docs/getting-started.md +301 -302
- package/docs/installation.md +361 -361
- package/docs/templates.md +418 -418
- package/docs/validation-checklist.md +265 -266
- package/package.json +80 -80
- package/scripts/postinstall.js +132 -132
- package/src/commands/advance-phase.js +183 -0
- package/src/commands/analyze-blazor-concurrency.js +193 -0
- package/src/commands/create-story.js +351 -351
- package/src/commands/detect-agents.js +139 -0
- package/src/commands/detect.js +104 -104
- package/src/commands/doctor.js +356 -280
- package/src/commands/generate.js +149 -149
- package/src/commands/init.js +258 -245
- package/src/commands/lint-fluent.js +352 -0
- package/src/commands/rollback-phase.js +185 -0
- package/src/commands/session-summary.js +291 -0
- package/src/commands/shard-spec.js +224 -224
- package/src/commands/sprint-status.js +250 -250
- package/src/commands/state.js +333 -333
- package/src/commands/sync.js +167 -167
- package/src/commands/task.js +78 -0
- package/src/commands/troubleshoot.js +222 -0
- package/src/commands/update.js +192 -159
- package/src/commands/validate-blazor-state.js +210 -0
- package/src/commands/validate-blazor.js +156 -0
- package/src/commands/validate-css.js +84 -0
- package/src/commands/validate-phase.js +221 -0
- package/src/lib/blazor-concurrency-analyzer.js +288 -0
- package/src/lib/blazor-state-validator.js +291 -0
- package/src/lib/blazor-validator.js +374 -0
- package/src/lib/complexity-analyzer.js +441 -292
- package/src/lib/continuous-validator.js +421 -0
- package/src/lib/css-validator.js +352 -0
- package/src/lib/decision-constraint-loader.js +109 -0
- package/src/lib/design-system-generator.js +298 -298
- package/src/lib/learning-system.js +520 -0
- package/src/lib/mockup-generator.js +366 -0
- package/src/lib/recap-generator.js +205 -0
- package/src/lib/state-manager.js +397 -340
- package/src/lib/troubleshoot-grep.js +194 -0
- package/src/lib/troubleshoot-index.js +144 -0
- package/src/lib/ui-detector.js +350 -0
- package/src/lib/validation-runner.js +231 -0
- package/src/lib/validators/architecture-validator.js +387 -0
- package/src/lib/validators/contract-compliance-validator.js +273 -0
- package/src/lib/validators/package-validator.js +360 -0
- package/src/lib/validators/ui-contrast-validator.js +422 -0
- package/src/utils/file-copier.js +179 -139
- package/src/utils/logger.js +32 -32
- package/src/utils/version-checker.js +175 -175
- package/content/.claude/commands/morph-costs.md +0 -206
- package/content/.claude/commands/morph-tasks.md +0 -319
- package/content/.claude/skills/specialists/cost-guardian.md +0 -110
- package/content/.claude/skills/stacks/shopify.md +0 -445
- package/content/.morph/config/azure-pricing.json +0 -70
- package/content/.morph/config/azure-pricing.schema.json +0 -50
- package/content/.morph/hooks/pre-commit-costs.sh +0 -91
- package/docs/api/cost-calculator.js.html +0 -513
- package/docs/api/design-system-generator.js.html +0 -382
- package/docs/api/global.html +0 -5263
- package/docs/api/index.html +0 -96
- package/docs/api/state-manager.js.html +0 -423
- package/src/commands/cost.js +0 -181
- package/src/commands/update-pricing.js +0 -206
- package/src/lib/cost-calculator.js +0 -429
|
@@ -1,276 +1,362 @@
|
|
|
1
|
-
# UI Components - {{FEATURE_NAME_TITLE}}
|
|
2
|
-
|
|
3
|
-
> Especificação dos componentes Fluent UI / MudBlazor utilizados nesta feature.
|
|
4
|
-
> Mapeia cada elemento visual para um componente concreto da biblioteca escolhida.
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Decisão de Biblioteca UI
|
|
9
|
-
|
|
10
|
-
### Biblioteca Escolhida: {Fluent UI Blazor | MudBlazor | Híbrida}
|
|
11
|
-
|
|
12
|
-
**Justificativa:**
|
|
13
|
-
{Por que esta biblioteca foi escolhida para ESTA feature específica?}
|
|
14
|
-
|
|
15
|
-
**Critérios de decisão:**
|
|
16
|
-
- ✅ **{Critério 1}**: {Explicação}
|
|
17
|
-
- ✅ **{Critério 2}**: {Explicação}
|
|
18
|
-
- ⚠️ **{Trade-off}**: {O que foi sacrificado e por quê}
|
|
19
|
-
|
|
20
|
-
**Referência ADR**: Ver `decisions.md` - ADR-{número}: {Título da decisão}
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## Componentes Mapeados
|
|
25
|
-
|
|
26
|
-
### {Nome do Elemento Visual}
|
|
27
|
-
|
|
28
|
-
**Biblioteca**: {Fluent UI | MudBlazor}
|
|
29
|
-
**Componente**: `{ComponentName}`
|
|
30
|
-
|
|
31
|
-
#### Props Principais
|
|
32
|
-
```csharp
|
|
33
|
-
<{ComponentName}
|
|
34
|
-
Prop1="{valor ou @binding}"
|
|
35
|
-
Prop2="{valor ou @binding}"
|
|
36
|
-
Prop3="{valor ou @binding}"
|
|
37
|
-
OnClick="@{Handler}" />
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
#### Propriedades Detalhadas
|
|
41
|
-
| Prop | Tipo | Valor | Descrição |
|
|
42
|
-
|------|------|-------|-----------|
|
|
43
|
-
| `Prop1` | `string` | `"{valor}"` | {Para que serve} |
|
|
44
|
-
| `Prop2` | `bool` | `true` | {Para que serve} |
|
|
45
|
-
| `Prop3` | `EventCallback` | `@Handler` | {Quando dispara} |
|
|
46
|
-
|
|
47
|
-
#### Estados
|
|
48
|
-
|
|
49
|
-
**1. Default (Estado Inicial)**
|
|
50
|
-
```razor
|
|
51
|
-
<{ComponentName}
|
|
52
|
-
Appearance="Appearance.Neutral"
|
|
53
|
-
Disabled="false">
|
|
54
|
-
{Conteúdo padrão}
|
|
55
|
-
</{ComponentName}>
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
**2. Loading**
|
|
59
|
-
```razor
|
|
60
|
-
@if (_isLoading)
|
|
61
|
-
{
|
|
62
|
-
<FluentSkeleton Width="100%" Height="40px" />
|
|
63
|
-
<!-- OU -->
|
|
64
|
-
<FluentProgress />
|
|
65
|
-
}
|
|
66
|
-
else
|
|
67
|
-
{
|
|
68
|
-
<{ComponentName} ... />
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
**3. Error**
|
|
73
|
-
```razor
|
|
74
|
-
@if (!string.IsNullOrEmpty(_error))
|
|
75
|
-
{
|
|
76
|
-
<FluentMessageBar Intent="MessageIntent.Error">
|
|
77
|
-
@_error
|
|
78
|
-
</FluentMessageBar>
|
|
79
|
-
}
|
|
80
|
-
<{ComponentName} ... />
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
**4. Empty (Sem Dados)**
|
|
84
|
-
```razor
|
|
85
|
-
@if (!_items.Any())
|
|
86
|
-
{
|
|
87
|
-
<FluentStack Orientation="Orientation.Vertical" HorizontalAlignment="HorizontalAlignment.Center">
|
|
88
|
-
<FluentLabel>Nenhum item encontrado</FluentLabel>
|
|
89
|
-
<FluentButton Appearance="Appearance.Accent" OnClick="@Create">
|
|
90
|
-
Criar Novo
|
|
91
|
-
</FluentButton>
|
|
92
|
-
</FluentStack>
|
|
93
|
-
}
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
**5. Success (Feedback Positivo)**
|
|
97
|
-
```razor
|
|
98
|
-
<FluentToast Intent="ToastIntent.Success" Timeout="3000">
|
|
99
|
-
Operação realizada com sucesso!
|
|
100
|
-
</FluentToast>
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
#### Eventos
|
|
104
|
-
|
|
105
|
-
| Evento | Handler | Ação |
|
|
106
|
-
|--------|---------|------|
|
|
107
|
-
| `OnClick` | `HandleClick` | {O que acontece ao clicar} |
|
|
108
|
-
| `OnChange` | `HandleChange` | {O que acontece ao mudar valor} |
|
|
109
|
-
| `OnSubmit` | `HandleSubmit` | {O que acontece ao submeter} |
|
|
110
|
-
|
|
111
|
-
#### Exemplo de Código Completo
|
|
112
|
-
|
|
113
|
-
```razor
|
|
114
|
-
<!-- {Nome do Componente}.razor -->
|
|
115
|
-
<{ComponentName}
|
|
116
|
-
Items="@_items"
|
|
117
|
-
Loading="@_isLoading"
|
|
118
|
-
OnClick="@HandleClick">
|
|
119
|
-
|
|
120
|
-
@if (_isLoading)
|
|
121
|
-
{
|
|
122
|
-
<FluentProgress />
|
|
123
|
-
}
|
|
124
|
-
else
|
|
125
|
-
{
|
|
126
|
-
@foreach (var item in _items)
|
|
127
|
-
{
|
|
128
|
-
<{ChildComponent} Data="@item" />
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
</{ComponentName}>
|
|
132
|
-
|
|
133
|
-
@code {
|
|
134
|
-
[Parameter] public List<ItemType> Items { get; set; } = new();
|
|
135
|
-
|
|
136
|
-
private bool _isLoading;
|
|
137
|
-
private string? _error;
|
|
138
|
-
|
|
139
|
-
protected override async Task OnInitializedAsync()
|
|
140
|
-
{
|
|
141
|
-
await LoadDataAsync();
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
private async Task LoadDataAsync()
|
|
145
|
-
{
|
|
146
|
-
_isLoading = true;
|
|
147
|
-
try
|
|
148
|
-
{
|
|
149
|
-
_items = await _service.GetItemsAsync();
|
|
150
|
-
}
|
|
151
|
-
catch (Exception ex)
|
|
152
|
-
{
|
|
153
|
-
_error = ex.Message;
|
|
154
|
-
}
|
|
155
|
-
finally
|
|
156
|
-
{
|
|
157
|
-
_isLoading = false;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
private async Task HandleClick(ItemType item)
|
|
162
|
-
{
|
|
163
|
-
// Ação ao clicar
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
#### Acessibilidade
|
|
169
|
-
|
|
170
|
-
**ARIA Attributes:**
|
|
171
|
-
- `role="{role}"`: {Propósito}
|
|
172
|
-
- `aria-label="{label}"`: {Descrição para screen readers}
|
|
173
|
-
- `aria-describedby="{id}"`: {Descrição adicional}
|
|
174
|
-
|
|
175
|
-
**Keyboard Navigation:**
|
|
176
|
-
- `Tab`: {Foca no elemento}
|
|
177
|
-
- `Enter/Space`: {Ativa o elemento}
|
|
178
|
-
- `Escape`: {Cancela/fecha}
|
|
179
|
-
- `Arrow Keys`: {Navega entre opções}
|
|
180
|
-
|
|
181
|
-
**Focus Management:**
|
|
182
|
-
- **Foco inicial**: {Onde o foco deve ir quando o componente aparece}
|
|
183
|
-
- **Focus trap**: {Se aplicável, como manter o foco dentro do componente (modals)}
|
|
184
|
-
|
|
185
|
-
---
|
|
186
|
-
|
|
187
|
-
## {Próximo Componente}
|
|
188
|
-
|
|
189
|
-
{Repita a estrutura acima para cada componente}
|
|
190
|
-
|
|
191
|
-
---
|
|
192
|
-
|
|
193
|
-
## Componentes Customizados
|
|
194
|
-
|
|
195
|
-
### {Nome do Componente Custom}
|
|
196
|
-
|
|
197
|
-
Se você precisar criar um componente que NÃO existe em Fluent UI ou MudBlazor:
|
|
198
|
-
|
|
199
|
-
**Composição:**
|
|
200
|
-
```razor
|
|
201
|
-
<!-- Components/{ComponentName}.razor -->
|
|
202
|
-
<div class="custom-component">
|
|
203
|
-
<FluentCard>
|
|
204
|
-
<FluentStack Orientation="Orientation.Vertical">
|
|
205
|
-
<!-- Composição de componentes existentes -->
|
|
206
|
-
</FluentStack>
|
|
207
|
-
</FluentCard>
|
|
208
|
-
</div>
|
|
209
|
-
|
|
210
|
-
@code {
|
|
211
|
-
// Lógica do componente
|
|
212
|
-
}
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
**Quando usar:**
|
|
216
|
-
- {Situação 1 que justifica componente custom}
|
|
217
|
-
- {Situação 2}
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
## Packages Necessários
|
|
222
|
-
|
|
223
|
-
### Fluent UI Blazor
|
|
224
|
-
```xml
|
|
225
|
-
<PackageReference Include="Microsoft.FluentUI.AspNetCore.Components" Version="4.0.0" />
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
```csharp
|
|
229
|
-
// Program.cs
|
|
230
|
-
builder.Services.AddFluentUIComponents();
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
```razor
|
|
234
|
-
// _Imports.razor
|
|
235
|
-
@using Microsoft.FluentUI.AspNetCore.Components
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
### MudBlazor (se híbrido)
|
|
239
|
-
```xml
|
|
240
|
-
<PackageReference Include="MudBlazor" Version="6.11.0" />
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
```csharp
|
|
244
|
-
// Program.cs
|
|
245
|
-
builder.Services.AddMudServices();
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
```razor
|
|
249
|
-
// _Imports.razor
|
|
250
|
-
@using MudBlazor
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
---
|
|
254
|
-
|
|
255
|
-
## Mapa de Componentes
|
|
256
|
-
|
|
257
|
-
Resumo visual de quais componentes são usados onde:
|
|
258
|
-
|
|
259
|
-
| Tela/Feature | Componente | Biblioteca | Complexidade |
|
|
260
|
-
|--------------|------------|------------|--------------|
|
|
261
|
-
| {Tela 1} | FluentDataGrid | Fluent UI | Média |
|
|
262
|
-
| {Tela 1} | FluentCard | Fluent UI | Baixa |
|
|
263
|
-
| {Tela 2} | MudChart | MudBlazor | Alta |
|
|
264
|
-
| {Tela 2} | FluentDialog | Fluent UI | Média |
|
|
265
|
-
|
|
266
|
-
---
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
1
|
+
# UI Components - {{FEATURE_NAME_TITLE}}
|
|
2
|
+
|
|
3
|
+
> Especificação dos componentes Fluent UI / MudBlazor utilizados nesta feature.
|
|
4
|
+
> Mapeia cada elemento visual para um componente concreto da biblioteca escolhida.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Decisão de Biblioteca UI
|
|
9
|
+
|
|
10
|
+
### Biblioteca Escolhida: {Fluent UI Blazor | MudBlazor | Híbrida}
|
|
11
|
+
|
|
12
|
+
**Justificativa:**
|
|
13
|
+
{Por que esta biblioteca foi escolhida para ESTA feature específica?}
|
|
14
|
+
|
|
15
|
+
**Critérios de decisão:**
|
|
16
|
+
- ✅ **{Critério 1}**: {Explicação}
|
|
17
|
+
- ✅ **{Critério 2}**: {Explicação}
|
|
18
|
+
- ⚠️ **{Trade-off}**: {O que foi sacrificado e por quê}
|
|
19
|
+
|
|
20
|
+
**Referência ADR**: Ver `decisions.md` - ADR-{número}: {Título da decisão}
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Componentes Mapeados
|
|
25
|
+
|
|
26
|
+
### {Nome do Elemento Visual}
|
|
27
|
+
|
|
28
|
+
**Biblioteca**: {Fluent UI | MudBlazor}
|
|
29
|
+
**Componente**: `{ComponentName}`
|
|
30
|
+
|
|
31
|
+
#### Props Principais
|
|
32
|
+
```csharp
|
|
33
|
+
<{ComponentName}
|
|
34
|
+
Prop1="{valor ou @binding}"
|
|
35
|
+
Prop2="{valor ou @binding}"
|
|
36
|
+
Prop3="{valor ou @binding}"
|
|
37
|
+
OnClick="@{Handler}" />
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
#### Propriedades Detalhadas
|
|
41
|
+
| Prop | Tipo | Valor | Descrição |
|
|
42
|
+
|------|------|-------|-----------|
|
|
43
|
+
| `Prop1` | `string` | `"{valor}"` | {Para que serve} |
|
|
44
|
+
| `Prop2` | `bool` | `true` | {Para que serve} |
|
|
45
|
+
| `Prop3` | `EventCallback` | `@Handler` | {Quando dispara} |
|
|
46
|
+
|
|
47
|
+
#### Estados
|
|
48
|
+
|
|
49
|
+
**1. Default (Estado Inicial)**
|
|
50
|
+
```razor
|
|
51
|
+
<{ComponentName}
|
|
52
|
+
Appearance="Appearance.Neutral"
|
|
53
|
+
Disabled="false">
|
|
54
|
+
{Conteúdo padrão}
|
|
55
|
+
</{ComponentName}>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**2. Loading**
|
|
59
|
+
```razor
|
|
60
|
+
@if (_isLoading)
|
|
61
|
+
{
|
|
62
|
+
<FluentSkeleton Width="100%" Height="40px" />
|
|
63
|
+
<!-- OU -->
|
|
64
|
+
<FluentProgress />
|
|
65
|
+
}
|
|
66
|
+
else
|
|
67
|
+
{
|
|
68
|
+
<{ComponentName} ... />
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**3. Error**
|
|
73
|
+
```razor
|
|
74
|
+
@if (!string.IsNullOrEmpty(_error))
|
|
75
|
+
{
|
|
76
|
+
<FluentMessageBar Intent="MessageIntent.Error">
|
|
77
|
+
@_error
|
|
78
|
+
</FluentMessageBar>
|
|
79
|
+
}
|
|
80
|
+
<{ComponentName} ... />
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**4. Empty (Sem Dados)**
|
|
84
|
+
```razor
|
|
85
|
+
@if (!_items.Any())
|
|
86
|
+
{
|
|
87
|
+
<FluentStack Orientation="Orientation.Vertical" HorizontalAlignment="HorizontalAlignment.Center">
|
|
88
|
+
<FluentLabel>Nenhum item encontrado</FluentLabel>
|
|
89
|
+
<FluentButton Appearance="Appearance.Accent" OnClick="@Create">
|
|
90
|
+
Criar Novo
|
|
91
|
+
</FluentButton>
|
|
92
|
+
</FluentStack>
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**5. Success (Feedback Positivo)**
|
|
97
|
+
```razor
|
|
98
|
+
<FluentToast Intent="ToastIntent.Success" Timeout="3000">
|
|
99
|
+
Operação realizada com sucesso!
|
|
100
|
+
</FluentToast>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
#### Eventos
|
|
104
|
+
|
|
105
|
+
| Evento | Handler | Ação |
|
|
106
|
+
|--------|---------|------|
|
|
107
|
+
| `OnClick` | `HandleClick` | {O que acontece ao clicar} |
|
|
108
|
+
| `OnChange` | `HandleChange` | {O que acontece ao mudar valor} |
|
|
109
|
+
| `OnSubmit` | `HandleSubmit` | {O que acontece ao submeter} |
|
|
110
|
+
|
|
111
|
+
#### Exemplo de Código Completo
|
|
112
|
+
|
|
113
|
+
```razor
|
|
114
|
+
<!-- {Nome do Componente}.razor -->
|
|
115
|
+
<{ComponentName}
|
|
116
|
+
Items="@_items"
|
|
117
|
+
Loading="@_isLoading"
|
|
118
|
+
OnClick="@HandleClick">
|
|
119
|
+
|
|
120
|
+
@if (_isLoading)
|
|
121
|
+
{
|
|
122
|
+
<FluentProgress />
|
|
123
|
+
}
|
|
124
|
+
else
|
|
125
|
+
{
|
|
126
|
+
@foreach (var item in _items)
|
|
127
|
+
{
|
|
128
|
+
<{ChildComponent} Data="@item" />
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
</{ComponentName}>
|
|
132
|
+
|
|
133
|
+
@code {
|
|
134
|
+
[Parameter] public List<ItemType> Items { get; set; } = new();
|
|
135
|
+
|
|
136
|
+
private bool _isLoading;
|
|
137
|
+
private string? _error;
|
|
138
|
+
|
|
139
|
+
protected override async Task OnInitializedAsync()
|
|
140
|
+
{
|
|
141
|
+
await LoadDataAsync();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private async Task LoadDataAsync()
|
|
145
|
+
{
|
|
146
|
+
_isLoading = true;
|
|
147
|
+
try
|
|
148
|
+
{
|
|
149
|
+
_items = await _service.GetItemsAsync();
|
|
150
|
+
}
|
|
151
|
+
catch (Exception ex)
|
|
152
|
+
{
|
|
153
|
+
_error = ex.Message;
|
|
154
|
+
}
|
|
155
|
+
finally
|
|
156
|
+
{
|
|
157
|
+
_isLoading = false;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
private async Task HandleClick(ItemType item)
|
|
162
|
+
{
|
|
163
|
+
// Ação ao clicar
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
#### Acessibilidade
|
|
169
|
+
|
|
170
|
+
**ARIA Attributes:**
|
|
171
|
+
- `role="{role}"`: {Propósito}
|
|
172
|
+
- `aria-label="{label}"`: {Descrição para screen readers}
|
|
173
|
+
- `aria-describedby="{id}"`: {Descrição adicional}
|
|
174
|
+
|
|
175
|
+
**Keyboard Navigation:**
|
|
176
|
+
- `Tab`: {Foca no elemento}
|
|
177
|
+
- `Enter/Space`: {Ativa o elemento}
|
|
178
|
+
- `Escape`: {Cancela/fecha}
|
|
179
|
+
- `Arrow Keys`: {Navega entre opções}
|
|
180
|
+
|
|
181
|
+
**Focus Management:**
|
|
182
|
+
- **Foco inicial**: {Onde o foco deve ir quando o componente aparece}
|
|
183
|
+
- **Focus trap**: {Se aplicável, como manter o foco dentro do componente (modals)}
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## {Próximo Componente}
|
|
188
|
+
|
|
189
|
+
{Repita a estrutura acima para cada componente}
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Componentes Customizados
|
|
194
|
+
|
|
195
|
+
### {Nome do Componente Custom}
|
|
196
|
+
|
|
197
|
+
Se você precisar criar um componente que NÃO existe em Fluent UI ou MudBlazor:
|
|
198
|
+
|
|
199
|
+
**Composição:**
|
|
200
|
+
```razor
|
|
201
|
+
<!-- Components/{ComponentName}.razor -->
|
|
202
|
+
<div class="custom-component">
|
|
203
|
+
<FluentCard>
|
|
204
|
+
<FluentStack Orientation="Orientation.Vertical">
|
|
205
|
+
<!-- Composição de componentes existentes -->
|
|
206
|
+
</FluentStack>
|
|
207
|
+
</FluentCard>
|
|
208
|
+
</div>
|
|
209
|
+
|
|
210
|
+
@code {
|
|
211
|
+
// Lógica do componente
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Quando usar:**
|
|
216
|
+
- {Situação 1 que justifica componente custom}
|
|
217
|
+
- {Situação 2}
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Packages Necessários
|
|
222
|
+
|
|
223
|
+
### Fluent UI Blazor
|
|
224
|
+
```xml
|
|
225
|
+
<PackageReference Include="Microsoft.FluentUI.AspNetCore.Components" Version="4.0.0" />
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
```csharp
|
|
229
|
+
// Program.cs
|
|
230
|
+
builder.Services.AddFluentUIComponents();
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
```razor
|
|
234
|
+
// _Imports.razor
|
|
235
|
+
@using Microsoft.FluentUI.AspNetCore.Components
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### MudBlazor (se híbrido)
|
|
239
|
+
```xml
|
|
240
|
+
<PackageReference Include="MudBlazor" Version="6.11.0" />
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
```csharp
|
|
244
|
+
// Program.cs
|
|
245
|
+
builder.Services.AddMudServices();
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
```razor
|
|
249
|
+
// _Imports.razor
|
|
250
|
+
@using MudBlazor
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Mapa de Componentes
|
|
256
|
+
|
|
257
|
+
Resumo visual de quais componentes são usados onde:
|
|
258
|
+
|
|
259
|
+
| Tela/Feature | Componente | Biblioteca | Complexidade |
|
|
260
|
+
|--------------|------------|------------|--------------|
|
|
261
|
+
| {Tela 1} | FluentDataGrid | Fluent UI | Média |
|
|
262
|
+
| {Tela 1} | FluentCard | Fluent UI | Baixa |
|
|
263
|
+
| {Tela 2} | MudChart | MudBlazor | Alta |
|
|
264
|
+
| {Tela 2} | FluentDialog | Fluent UI | Média |
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Checklist de Componentes CSS
|
|
271
|
+
|
|
272
|
+
> **IMPORTANTE:** Liste TODOS os componentes CSS necessarios ANTES de implementar.
|
|
273
|
+
> Use `morph-spec validate-css` para validar que todas as classes existem.
|
|
274
|
+
|
|
275
|
+
### Componentes CSS Novos (a criar)
|
|
276
|
+
|
|
277
|
+
Classes CSS customizadas que precisam ser criadas no `design-system.css`:
|
|
278
|
+
|
|
279
|
+
- [ ] `.{page-prefix}-{component}` - {Descricao do componente}
|
|
280
|
+
- [ ] `.{page-prefix}-{element}` - {Descricao do elemento}
|
|
281
|
+
|
|
282
|
+
**Exemplo:**
|
|
283
|
+
```markdown
|
|
284
|
+
- [ ] `.home-hero` - Container do hero section da home
|
|
285
|
+
- [ ] `.home-features` - Grid de features
|
|
286
|
+
- [ ] `.checkout-form` - Container do formulario de checkout
|
|
287
|
+
- [ ] `.checkout-summary` - Card de resumo do pedido
|
|
288
|
+
- [ ] `.modal-overlay` - Overlay escuro para modais customizados
|
|
289
|
+
- [ ] `.modal-container` - Container do modal com animacao
|
|
290
|
+
- [ ] `.card-premium` - Card com glow e borda especial
|
|
291
|
+
- [ ] `.button-shimmer` - Botao com efeito shimmer
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Componentes CSS Existentes (reutilizar)
|
|
295
|
+
|
|
296
|
+
Classes que ja existem no projeto (design-system.css ou bibliotecas):
|
|
297
|
+
|
|
298
|
+
- [x] `.{existing-class}` - {Onde esta definida}
|
|
299
|
+
|
|
300
|
+
**Exemplo:**
|
|
301
|
+
```markdown
|
|
302
|
+
- [x] `.page-layout` - design-system.css (estrutura padrao)
|
|
303
|
+
- [x] `.tip-box` - design-system.css (caixa de dica)
|
|
304
|
+
- [x] `FluentCard` - Fluent UI Blazor (componente)
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Variaveis CSS Novas
|
|
308
|
+
|
|
309
|
+
Variaveis CSS customizadas necessarias:
|
|
310
|
+
|
|
311
|
+
- [ ] `--{project}-{variable-name}` - {Descricao e valor}
|
|
312
|
+
|
|
313
|
+
**Exemplo:**
|
|
314
|
+
```markdown
|
|
315
|
+
- [ ] `--fishart-primary` - Cor primaria (#FF6B35)
|
|
316
|
+
- [ ] `--fishart-shadow-glow` - Sombra com glow (0 0 20px rgba(255, 107, 53, 0.3))
|
|
317
|
+
- [ ] `--fishart-gradient-hero` - Gradiente do hero (linear-gradient(...))
|
|
318
|
+
- [ ] `--fishart-transition-bounce` - Transicao com bounce (cubic-bezier(...))
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Animacoes CSS Novas
|
|
322
|
+
|
|
323
|
+
Keyframes e classes de animacao necessarias:
|
|
324
|
+
|
|
325
|
+
- [ ] `@keyframes {animation-name}` - {Descricao}
|
|
326
|
+
- [ ] `.animate-{name}` - Classe que aplica a animacao
|
|
327
|
+
|
|
328
|
+
**Exemplo:**
|
|
329
|
+
```markdown
|
|
330
|
+
- [ ] `@keyframes slideInUp` - Entrada de baixo para cima
|
|
331
|
+
- [ ] `.animate-slideInUp` - Aplica slideInUp com 0.5s ease
|
|
332
|
+
- [ ] `@keyframes scaleIn` - Zoom in suave
|
|
333
|
+
- [ ] `.animate-scaleIn` - Aplica scaleIn com 0.3s ease
|
|
334
|
+
- [ ] `.stagger-1` a `.stagger-5` - Delays para animacoes em sequencia
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Validacao Pre-Implementacao
|
|
338
|
+
|
|
339
|
+
Antes de iniciar FASE 5 (IMPLEMENT), validar:
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
# Criar todas as classes listadas acima no design-system.css
|
|
343
|
+
|
|
344
|
+
# Validar que nenhuma classe esta faltando
|
|
345
|
+
morph-spec validate-css src/MyApp.Web
|
|
346
|
+
|
|
347
|
+
# Output esperado: "All CSS classes are properly defined!"
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## Referências
|
|
353
|
+
|
|
354
|
+
- [Fluent UI Components](https://www.fluentui-blazor.net/Components)
|
|
355
|
+
- [MudBlazor Components](https://mudblazor.com/components/list)
|
|
356
|
+
- [Guia Fluent UI Blazor](../../framework/standards/fluent-ui-blazor.md)
|
|
357
|
+
- [CSS Naming Convention](../../framework/standards/css-naming.md)
|
|
358
|
+
- [CSS Animations](../../framework/standards/css-animations.md)
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
*Template MORPH-SPEC v2.2.0 by Polymorphism Tech*
|