@praxisui/manual-form 1.0.0-beta.30 → 1.0.0-beta.40
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/README.md +125 -13
- package/fesm2022/praxisui-manual-form.mjs +3634 -184
- package/fesm2022/praxisui-manual-form.mjs.map +1 -1
- package/index.d.ts +235 -12
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -42,6 +42,74 @@ O exemplo `/cargos/manual-form` demonstra uso declarativo:
|
|
|
42
42
|
</praxis-manual-form>
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
+
### Padrão didático para exemplos renderizados
|
|
46
|
+
|
|
47
|
+
Para páginas de documentação que precisam mostrar o componente antes de blocos longos de texto,
|
|
48
|
+
use o wrapper `praxis-manual-form-doc-example`. Ele já entrega:
|
|
49
|
+
|
|
50
|
+
- Banner curto com foco no exemplo live.
|
|
51
|
+
- Tabs para alternar entre `Live`, `Template`, `TS` e `Config`.
|
|
52
|
+
- Toggle de modo de customização (liga/desliga) com evento.
|
|
53
|
+
- Botão de cópia do snippet ativo.
|
|
54
|
+
- Callouts opcionais de `IMPORTANTE`, `NOTA` e `DICA`.
|
|
55
|
+
|
|
56
|
+
```html
|
|
57
|
+
<praxis-manual-form-doc-example
|
|
58
|
+
title="Cadastro de cargo"
|
|
59
|
+
subtitle="Preview primeiro, explicações depois."
|
|
60
|
+
level="Intermediario"
|
|
61
|
+
bannerTitle="Veja o componente em ação"
|
|
62
|
+
bannerDescription="Explore o live e abra código apenas quando necessário."
|
|
63
|
+
[templateCode]="templateSnippet"
|
|
64
|
+
[tsCode]="tsSnippet"
|
|
65
|
+
[configCode]="configSnippet"
|
|
66
|
+
[customizationEnabled]="editMode()"
|
|
67
|
+
(customizationEnabledChange)="editMode.set($event)"
|
|
68
|
+
important="Persista o draft no submit."
|
|
69
|
+
note="A aba Live abre por padrão."
|
|
70
|
+
tip="Use a aba Config para explicar contratos JSON."
|
|
71
|
+
>
|
|
72
|
+
<div exampleLive>
|
|
73
|
+
<praxis-manual-form
|
|
74
|
+
[formGroup]="form"
|
|
75
|
+
formId="cargo-manual-form"
|
|
76
|
+
[editModeEnabled]="editMode()"
|
|
77
|
+
>
|
|
78
|
+
<pdx-text-input formControlName="nome" label="Nome"></pdx-text-input>
|
|
79
|
+
</praxis-manual-form>
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<div exampleDiagram>
|
|
83
|
+
<!-- Mermaid, SVG ou fluxo simplificado -->
|
|
84
|
+
</div>
|
|
85
|
+
</praxis-manual-form-doc-example>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Também existe um showcase pronto para consumo direto:
|
|
89
|
+
|
|
90
|
+
```html
|
|
91
|
+
<praxis-manual-form-doc-example-showcase></praxis-manual-form-doc-example-showcase>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Esse showcase já inclui providers locais de `API_URL` e `ASYNC_CONFIG_STORAGE`, evitando erro de injeção em páginas de documentação.
|
|
95
|
+
|
|
96
|
+
### Diagrama de funcionamento (alto nível)
|
|
97
|
+
|
|
98
|
+
```mermaid
|
|
99
|
+
flowchart LR
|
|
100
|
+
Host[Template com <pdx-*>] --> ManualForm[praxis-manual-form]
|
|
101
|
+
ManualForm --> Detect[Detecta campos]
|
|
102
|
+
Detect --> Meta[Infere FieldMetadata]
|
|
103
|
+
Meta --> Group[Cria/Adota FormGroup]
|
|
104
|
+
Group --> Render[Renderiza campos + validações]
|
|
105
|
+
ManualForm --> Instance[ManualFormInstance]
|
|
106
|
+
Instance --> Storage[ConfigStorage]
|
|
107
|
+
ManualForm -->|editMode| Editor[Metadata Editor]
|
|
108
|
+
Editor --> Patch[Aplica patch]
|
|
109
|
+
Patch --> Instance
|
|
110
|
+
Instance --> Persist[saveDraft / resetToSeed]
|
|
111
|
+
```
|
|
112
|
+
|
|
45
113
|
### Editor de metadados integrado
|
|
46
114
|
|
|
47
115
|
Use o `ManualFieldMetadataBridgeService` para abrir o editor visual a partir de qualquer campo detectado pelo container. O serviço carrega o módulo sob demanda, aplica o patch retornado e chama `saveDraft()` para persistir as alterações no runtime.
|
|
@@ -65,6 +133,24 @@ export class CargoManualFormComponent {
|
|
|
65
133
|
}
|
|
66
134
|
```
|
|
67
135
|
|
|
136
|
+
### Toolbar de campo (modo de edicao)
|
|
137
|
+
|
|
138
|
+
Quando `editModeEnabled` estiver ativo, o manual-form exibe uma toolbar flutuante ao clicar
|
|
139
|
+
no campo. Ela permite alternar `required`, `readOnly`, `hidden` e `disabled`, e abrir o editor
|
|
140
|
+
completo de metadados.
|
|
141
|
+
|
|
142
|
+
Atalhos de teclado (quando o campo esta focado):
|
|
143
|
+
- `F2` ou `Alt+F10` abre a toolbar e move o foco para o primeiro botao.
|
|
144
|
+
- `ESC` fecha a toolbar.
|
|
145
|
+
|
|
146
|
+
Observacao: se um componente de campo interromper o clique (stopPropagation), a toolbar nao
|
|
147
|
+
abrira via mouse. Use os atalhos de teclado ou evite bloquear o click no host do campo.
|
|
148
|
+
|
|
149
|
+
Token de z-index:
|
|
150
|
+
- `--pdx-manual-toolbar-z` (default: `2001`).
|
|
151
|
+
Classe de overlay (para temas corporativos):
|
|
152
|
+
- `.pdx-manual-toolbar-panel` (aplicada no CDK Overlay para customizacoes).
|
|
153
|
+
|
|
68
154
|
## Motivações
|
|
69
155
|
|
|
70
156
|
- DX coerente para formulários manuais (sem JSON).
|
|
@@ -100,7 +186,7 @@ Essa base permite que hosts manualmente criem formulários com componentes Praxi
|
|
|
100
186
|
## Padrão corporativo recomendado
|
|
101
187
|
|
|
102
188
|
- Host tipado: o host deve criar um `FormGroup` tipado e passá‑lo via `[formGroup]`. O container adota esse grupo, aplica metadados/validators e evita interceptações internas. Isso habilita o Angular Language Service a validar `formControlName` e melhora a DX.
|
|
103
|
-
- Modo dinâmico:
|
|
189
|
+
- Modo dinâmico: opção para PoCs e exemplos rápidos; veja os detalhes na seção “Guia rápido”.
|
|
104
190
|
|
|
105
191
|
## Configurações avançadas
|
|
106
192
|
|
|
@@ -111,37 +197,44 @@ Essa base permite que hosts manualmente criem formulários com componentes Praxi
|
|
|
111
197
|
- Autosave
|
|
112
198
|
- `@Input() enableAutoSave: boolean` (padrão: `true`) e `@Input() autoSaveDebounceMs: number` (padrão: `800`).
|
|
113
199
|
|
|
114
|
-
|
|
200
|
+
### API pública adicional
|
|
115
201
|
|
|
116
|
-
|
|
202
|
+
- `ManualFormInstance.metadataChanges()`
|
|
203
|
+
- Emite sempre que o mapa de `FieldMetadata` é atualizado no runtime.
|
|
204
|
+
- Timing: após `patchFieldMetadata()`, `replaceConfig()`, `resetToSeed()` e cargas de config persistida.
|
|
205
|
+
|
|
206
|
+
## SSR (AsyncConfigStorage sem localStorage)
|
|
207
|
+
|
|
208
|
+
Em SSR, `localStorage` não existe. Como `praxis-manual-form` depende do token `ASYNC_CONFIG_STORAGE`, você pode prover uma implementação segura no servidor (ex.: in‑memory) e manter `LocalStorageAsyncAdapter` no browser.
|
|
117
209
|
|
|
118
210
|
Exemplo (Angular com `app.config.server.ts`):
|
|
119
211
|
|
|
120
212
|
```ts
|
|
121
213
|
// app.config.server.ts
|
|
122
214
|
import { ApplicationConfig, PLATFORM_ID, inject, isPlatformServer } from '@angular/core';
|
|
123
|
-
import {
|
|
215
|
+
import { ASYNC_CONFIG_STORAGE, LocalStorageAsyncAdapter, type AsyncConfigStorage } from '@praxisui/core';
|
|
216
|
+
import { EMPTY, of } from 'rxjs';
|
|
124
217
|
|
|
125
|
-
class
|
|
218
|
+
class MemoryAsyncStorage implements AsyncConfigStorage {
|
|
126
219
|
private readonly map = new Map<string, any>();
|
|
127
|
-
loadConfig<T>(key: string)
|
|
128
|
-
saveConfig<T>(key: string, config: T)
|
|
129
|
-
clearConfig(key: string)
|
|
220
|
+
loadConfig<T>(key: string) { return of((this.map.get(key) as T) ?? null); }
|
|
221
|
+
saveConfig<T>(key: string, config: T) { this.map.set(key, config); return EMPTY; }
|
|
222
|
+
clearConfig(key: string) { this.map.delete(key); return EMPTY; }
|
|
130
223
|
}
|
|
131
224
|
|
|
132
225
|
export const appConfig: ApplicationConfig = {
|
|
133
226
|
providers: [
|
|
134
227
|
{
|
|
135
|
-
provide:
|
|
228
|
+
provide: ASYNC_CONFIG_STORAGE,
|
|
136
229
|
useFactory: () => isPlatformServer(inject(PLATFORM_ID))
|
|
137
|
-
? new
|
|
138
|
-
: inject(
|
|
230
|
+
? new MemoryAsyncStorage()
|
|
231
|
+
: inject(LocalStorageAsyncAdapter),
|
|
139
232
|
},
|
|
140
233
|
],
|
|
141
234
|
};
|
|
142
235
|
```
|
|
143
236
|
|
|
144
|
-
Alternativas no servidor: usar cookies, cache distribuído (ex.: Redis) ou persistir por sessão do usuário. Basta implementar a interface `
|
|
237
|
+
Alternativas no servidor: usar cookies, cache distribuído (ex.: Redis) ou persistir por sessão do usuário. Basta implementar a interface `AsyncConfigStorage`.
|
|
145
238
|
|
|
146
239
|
### Exemplo (nested form)
|
|
147
240
|
|
|
@@ -270,6 +363,20 @@ Exemplo de uso no host:
|
|
|
270
363
|
</praxis-manual-form>
|
|
271
364
|
```
|
|
272
365
|
|
|
366
|
+
#### O que o editor cobre (tabs)
|
|
367
|
+
|
|
368
|
+
O editor do formulario (Settings Panel) expõe:
|
|
369
|
+
- **Campos**: visibilidade, obrigatorio, somente leitura, desabilitado.
|
|
370
|
+
- **Acoes**: layout da barra, botoes padrao e acoes customizadas.
|
|
371
|
+
- **Mensagens**: feedbacks de sucesso/erro, loading e confirmacoes.
|
|
372
|
+
- **Comportamento**: flags de UX (ex.: focusFirstError, scrollToErrors).
|
|
373
|
+
- **Dicas**: textos auxiliares para modos de tela (i18n/UX).
|
|
374
|
+
- **Hooks**: JSON com hooks de lifecycle (antes/depois de init/submit).
|
|
375
|
+
- **Regras**: regras de layout/visibilidade (JSON).
|
|
376
|
+
- **Cascatas**: dependencias entre campos via metadados.
|
|
377
|
+
|
|
378
|
+
Obs.: a execucao de hooks/regras depende do host registrar os providers correspondentes.
|
|
379
|
+
|
|
273
380
|
## Extensibilidade por DI
|
|
274
381
|
|
|
275
382
|
- Customize a inferência de `FieldControlType` via tokens:
|
|
@@ -300,7 +407,7 @@ Exemplo de uso no host:
|
|
|
300
407
|
- Preferir host tipado e `usePathNames=true` para nested forms.
|
|
301
408
|
- Habilitar autosave com debounce adequado.
|
|
302
409
|
- Evitar lógica pesada em templates; delegar inferências ao container.
|
|
303
|
-
- No SSR, sempre prover `
|
|
410
|
+
- No SSR, sempre prover `ASYNC_CONFIG_STORAGE` compatível (sem localStorage).
|
|
304
411
|
|
|
305
412
|
## Licença
|
|
306
413
|
|
|
@@ -312,6 +419,11 @@ Apache-2.0 — consulte `LICENSE` neste pacote ou no repositório raiz.
|
|
|
312
419
|
- Layout é responsabilidade do host; não há reordenação automática por metadados.
|
|
313
420
|
- Modo dinâmico sem `[formGroup]` não habilita validação estática de `formControlName` no IDE.
|
|
314
421
|
|
|
422
|
+
## Notas adicionais
|
|
423
|
+
|
|
424
|
+
- Quando `editModeEnabled` estiver ativo, o container renderiza o assistente AI (Praxis AI) no header do formulario.
|
|
425
|
+
- `componentInstanceId` ajuda a compor a chave de persistencia (com `formId` e `persistenceOptions`), evitando conflito entre instancias da mesma tela.
|
|
426
|
+
|
|
315
427
|
## Comparativo — Manual vs Dinâmico (JSON)
|
|
316
428
|
|
|
317
429
|
- Manual: controle máximo do HTML; evolui por metadados incrementais; ótimo para telas estáveis com design específico.
|