@praxisui/dynamic-form 1.0.0-beta.5 → 1.0.0-beta.53
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 +204 -7
- package/fesm2022/praxisui-dynamic-form.mjs +16815 -9953
- package/fesm2022/praxisui-dynamic-form.mjs.map +1 -1
- package/index.d.ts +473 -57
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -1,7 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Dynamic Form"
|
|
3
|
+
slug: "dynamic-form-overview"
|
|
4
|
+
description: "Visao geral do @praxisui/dynamic-form com schema-driven UI, editor embutido, layout runtime e integracao orientada a contrato."
|
|
5
|
+
doc_type: "reference"
|
|
6
|
+
document_kind: "component-overview"
|
|
7
|
+
component: "dynamic-form"
|
|
8
|
+
category: "components"
|
|
9
|
+
audience:
|
|
10
|
+
- "frontend"
|
|
11
|
+
- "host"
|
|
12
|
+
- "architect"
|
|
13
|
+
level: "intermediate"
|
|
14
|
+
status: "active"
|
|
15
|
+
owner: "praxis-ui"
|
|
16
|
+
tags:
|
|
17
|
+
- "dynamic-form"
|
|
18
|
+
- "schema-driven"
|
|
19
|
+
- "runtime"
|
|
20
|
+
- "layout"
|
|
21
|
+
- "config-editor"
|
|
22
|
+
order: 30
|
|
23
|
+
icon: "dynamic_form"
|
|
24
|
+
toc: true
|
|
25
|
+
sidebar: true
|
|
26
|
+
search_boost: 1.0
|
|
27
|
+
reading_time: 12
|
|
28
|
+
estimated_setup_time: 20
|
|
29
|
+
version: "1.0"
|
|
30
|
+
related_docs:
|
|
31
|
+
- "dynamic-form-hot-metadata-updates"
|
|
32
|
+
- "praxis-dynamic-form-json-api"
|
|
33
|
+
- "host-integration-guide"
|
|
34
|
+
- "consumer-integration-quickstart"
|
|
35
|
+
keywords:
|
|
36
|
+
- "FormConfig"
|
|
37
|
+
- "schema-driven"
|
|
38
|
+
- "layout editor"
|
|
39
|
+
- "settings integration"
|
|
40
|
+
last_updated: "2026-03-07"
|
|
41
|
+
---
|
|
42
|
+
|
|
1
43
|
# @praxisui/dynamic-form
|
|
2
44
|
|
|
3
45
|
> Standalone dynamic form component with schema-driven UI, native field cascades, settings integration, and a built-in configuration editor.
|
|
4
46
|
|
|
47
|
+
## 🔰 Exemplos / Quickstart
|
|
48
|
+
|
|
49
|
+
Para ver esta biblioteca em funcionamento em uma aplicação completa, utilize o projeto de exemplo (Quickstart):
|
|
50
|
+
|
|
51
|
+
- Repositório: https://github.com/codexrodrigues/praxis-ui-quickstart
|
|
52
|
+
- O Quickstart demonstra a integração das bibliotecas `@praxisui/*` em um app Angular, incluindo instalação, configuração e uso em telas reais.
|
|
53
|
+
|
|
5
54
|
## Install
|
|
6
55
|
|
|
7
56
|
```bash
|
|
@@ -50,7 +99,7 @@ export class FormDemoComponent {
|
|
|
50
99
|
rows: [
|
|
51
100
|
{
|
|
52
101
|
columns: [
|
|
53
|
-
{ fields: [{ name: 'fullName', label: 'Full Name', controlType: '
|
|
102
|
+
{ fields: [{ name: 'fullName', label: 'Full Name', controlType: 'input' }] },
|
|
54
103
|
{ fields: [{ name: 'email', label: 'E-mail', controlType: 'email' }] },
|
|
55
104
|
],
|
|
56
105
|
},
|
|
@@ -101,11 +150,153 @@ Alternatively, when `editModeEnabled` is true, `praxis-dynamic-form` renders a g
|
|
|
101
150
|
|
|
102
151
|
- Components: `PraxisDynamicForm`, `PraxisDynamicFormConfigEditor`, `JsonConfigEditorComponent`, `LayoutEditorComponent`
|
|
103
152
|
- Services: `FormConfigService`, `FormLayoutService`, `DynamicFormLayoutService`, `FormContextService`
|
|
104
|
-
- Utilities: form rule converters, normalize date arrays
|
|
153
|
+
- Utilities: form rule converters, normalize date arrays, **FormRulesService** (aplica regras de propriedades)
|
|
105
154
|
- Metadata helpers: `providePraxisDynamicFormMetadata`
|
|
106
155
|
|
|
107
156
|
See public exports: `projects/praxis-dynamic-form/src/public-api.ts`.
|
|
108
157
|
|
|
158
|
+
## Documentacao Tecnica da Lib
|
|
159
|
+
|
|
160
|
+
- `projects/praxis-dynamic-form/src/lib/praxis-dynamic-form.json-api.md`
|
|
161
|
+
- `projects/praxis-dynamic-form/docs/hot-metadata-updates.md`
|
|
162
|
+
|
|
163
|
+
## IA — catálogo de capacidades (composição)
|
|
164
|
+
|
|
165
|
+
O assistente usa um catálogo agregado de capabilities para gerar patches seguros:
|
|
166
|
+
|
|
167
|
+
- **Macro (FormConfig)**: layout, regras, ações, hooks e mensagens (`form-ai-capabilities`).
|
|
168
|
+
- **Base (FieldMetadata)**: propriedades comuns de campos (`field-metadata-ai-capabilities`).
|
|
169
|
+
- **Micro (por controlType)**: overlay específico de cada input (`@praxisui/dynamic-fields`).
|
|
170
|
+
|
|
171
|
+
Os paths micro são normalizados para `fieldMetadata[].<prop>` para garantir que os patches apontem para a raiz correta do formulário.
|
|
172
|
+
|
|
173
|
+
## Regras de formulário (novo contrato)
|
|
174
|
+
|
|
175
|
+
- Formato: cada regra tem `targetType` (`field | section | action | row | column`), `targets: string[]` (IDs canônicos, sem prefixo), e `effect` com `condition` (DSL ou Specification), `properties` e `propertiesWhenFalse`.
|
|
176
|
+
- Compatibilidade: regras antigas (`context/targetField`) são migradas para `properties/targets` automaticamente; prefixos `section:/action:/row:/column:` são removidos e `targetType` é inferido se não vier explicitado.
|
|
177
|
+
- Semântica de limpeza: valores `null` em `properties/propertiesWhenFalse` removem o override e retornam ao valor base do layout; ausência mantém o valor base.
|
|
178
|
+
- Whitelist por tipo (somente propriedades a seguir são aplicadas; demais são descartadas e logadas em dev):
|
|
179
|
+
- `field`: `visible`, `required`, `readonly`, `disabled`, `className`, `style`, `label`, `description`, `placeholder`, `hint`, `tooltip`, `prefixIcon`, `suffixIcon`, `prefixText`, `suffixText`, `defaultValue`, `options` (array `{label,value,disabled?}`), `appearance` (`fill|outline`), `color` (`primary|accent|warn`), `floatLabel` (`auto|always|never`), `hintPosition` (`start|end`), `validators` (primitivos por chave).
|
|
180
|
+
- `section`: `visible`, `title`, `description`, `icon`, `className`, `style`, `collapsible`, `collapsed`, `headerTooltip`, `headerAlign` (`start|center`), gaps (`gapBottom`, `titleGapBottom`, `descriptionGapBottom`), cores/tipografia (`titleColor`, `descriptionColor`, `titleStyle`, `descriptionStyle`).
|
|
181
|
+
- `action`: `visible`, `disabled`, `loading`, `label`, `icon`, `tooltip`, `color` (`primary|accent|warn|basic`), `variant` (`raised|stroked|flat|fab`), `size` (`small|medium|large`), `className`, `style`.
|
|
182
|
+
- `row`: `visible`, `gap`, `rowGap`, `className`, `style`.
|
|
183
|
+
- `column`: `visible`, `span`, `offset`, `order`, `hidden`, `align` (`start|center|end|stretch`), `padding`, `className`, `style`.
|
|
184
|
+
- Runtime (FormRulesService): filtra por whitelist, converte tipos (enum/number/boolean/string), saneia objetos (`options/validators/style`), aplica remoção de chaves com `null` e retorna mapas `fieldProps/sectionProps/actionProps/rowProps/columnProps`.
|
|
185
|
+
- Renderização: `PraxisDynamicForm` aplica overrides em campos/seções/ações/linhas/colunas (visibilidade, gaps, padding, classes, estilos, labels, etc.); colunas respeitam `align/span/offset/order/hidden/padding` vindo das regras.
|
|
186
|
+
|
|
187
|
+
### Builder integrado
|
|
188
|
+
|
|
189
|
+
- No editor visual, use a aba “Propriedades” (integrada ao builder) para selecionar o alvo (`targetType` + autocomplete de IDs de campos/seções/ações/linhas/colunas), escolher propriedades whitelisted e definir valores para `properties` (branch true) e `propertiesWhenFalse` (branch false). Botão “Limpar override” remove a propriedade (equivalente a `null`).
|
|
190
|
+
- A aba de Propriedades usa inputs tipados (enum/number/boolean/string/JSON) conforme o schema injetado; valores inválidos são ignorados.
|
|
191
|
+
- O config editor fornece `targetSchemas` (campos/seções/ações/linhas/colunas) e `targetPropertySchemas` para o builder; `formRules` são salvas no formato canônico (sem `context/targetField`).
|
|
192
|
+
|
|
193
|
+
## Layout padrão (sem FormConfig)
|
|
194
|
+
|
|
195
|
+
Quando o componente não recebe uma `FormConfig` prévia (primeira execução), ele gera um layout padrão a partir do metadata do backend:
|
|
196
|
+
|
|
197
|
+
- Linhas/colunas: 2 campos por linha (padrão). Em telas pequenas (xs/sm) os campos empilham (1 por linha), e a partir de md ficam lado a lado.
|
|
198
|
+
- Responsividade do grid (12 colunas):
|
|
199
|
+
- xs: 12, sm: 12, md: 6, lg: 6, xl: 6 (para 2 por linha). Para outros valores, a regra é `base = floor(12 / fieldsPerRow)`.
|
|
200
|
+
- Largura dos campos: `mat-form-field { width: 100% }` e um **allow‑list** de tipos “input‑like” em `data-field-type` recebem `width: 100%`. Controles compactos (ex.: checkbox/radio/toggle/rating/slider) **não** são forçados a preencher a coluna.
|
|
201
|
+
- Editor de Configuração: ao abrir a aba “Layout”, o editor reflete esse layout padrão; ao aplicar/salvar, persiste a `FormConfig` no storage do host.
|
|
202
|
+
- Personalização: você pode ajustar o layout pelo Editor (arrastar/seções/linhas/colunas, alterar spans) ou fornecer uma `FormConfig` completa via `[config]`.
|
|
203
|
+
|
|
204
|
+
## Form Actions — Layout & Styling
|
|
205
|
+
|
|
206
|
+
A barra de ações (onde ficam "ENVIAR", "Cancelar", etc.) é configurável via `config.actions` e pelo Editor (aba "Ações").
|
|
207
|
+
|
|
208
|
+
Defaults
|
|
209
|
+
- Rótulo do botão principal: `ENVIAR`.
|
|
210
|
+
- Posição estrutural: `afterSections` (renderiza abaixo da última seção).
|
|
211
|
+
- Alinhamento: `right`.
|
|
212
|
+
- Orientação: `horizontal`.
|
|
213
|
+
- Espaçamento: `normal`.
|
|
214
|
+
- Background: sem cor por padrão (herda da superfície). Configure via `containerStyles` ou `containerClassName` se desejar uma superfície própria.
|
|
215
|
+
|
|
216
|
+
Estrutura (parcial)
|
|
217
|
+
```ts
|
|
218
|
+
interface FormActionsLayout {
|
|
219
|
+
submit: FormActionButton; // id, label, color, type, variant, shortcut, etc.
|
|
220
|
+
cancel: FormActionButton;
|
|
221
|
+
reset: FormActionButton;
|
|
222
|
+
custom?: FormActionButton[]; // botões extras
|
|
223
|
+
|
|
224
|
+
// Layout/posicionamento
|
|
225
|
+
placement?: 'afterSections' | 'insideLastSection' | 'top';
|
|
226
|
+
position?: 'left' | 'center' | 'right' | 'justified' | 'split';
|
|
227
|
+
orientation?: 'horizontal' | 'vertical';
|
|
228
|
+
spacing?: 'compact' | 'normal' | 'spacious';
|
|
229
|
+
sticky?: boolean; // fixa a barra (bottom)
|
|
230
|
+
|
|
231
|
+
// Estilização do container
|
|
232
|
+
containerClassName?: string; // adiciona classe ao container
|
|
233
|
+
containerStyles?: { [k: string]: any }; // estilos inline (camelCase)
|
|
234
|
+
|
|
235
|
+
// Mobile
|
|
236
|
+
mobile?: { position?: 'left'|'center'|'right'|'justified'; orientation?: 'horizontal'|'vertical'; collapseToMenu?: boolean };
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Exemplo (config)
|
|
241
|
+
```ts
|
|
242
|
+
config.actions = {
|
|
243
|
+
submit: { visible: true, label: 'ENVIAR', type: 'submit', color: 'primary', variant: 'raised', shortcut: 'ctrl+s' },
|
|
244
|
+
cancel: { visible: true, label: 'Cancelar', type: 'button', color: 'basic' },
|
|
245
|
+
reset: { visible: false, label: 'Reset' },
|
|
246
|
+
placement: 'afterSections',
|
|
247
|
+
position: 'right',
|
|
248
|
+
orientation: 'horizontal',
|
|
249
|
+
spacing: 'normal',
|
|
250
|
+
sticky: false,
|
|
251
|
+
containerClassName: 'my-form-actions',
|
|
252
|
+
containerStyles: {
|
|
253
|
+
background: 'var(--md-sys-color-surface-container)',
|
|
254
|
+
border: '1px solid var(--md-sys-color-outline-variant)',
|
|
255
|
+
borderRadius: '12px',
|
|
256
|
+
padding: '12px 16px'
|
|
257
|
+
},
|
|
258
|
+
mobile: { collapseToMenu: true }
|
|
259
|
+
};
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
CSS por classe (opcional)
|
|
263
|
+
```scss
|
|
264
|
+
.my-form-actions {
|
|
265
|
+
background: var(--md-sys-color-surface-container);
|
|
266
|
+
border: 1px solid var(--md-sys-color-outline-variant);
|
|
267
|
+
border-radius: 12px;
|
|
268
|
+
padding: 12px 16px;
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Dicas
|
|
273
|
+
- Cores do botão: use `color` = `primary|accent|warn|basic` (respeitam o tema Material).
|
|
274
|
+
- Tokens M3: prefira `--md-sys-*` para cores/superfícies.
|
|
275
|
+
- Mobile: ative `collapseToMenu` para colapsar botões extras em menu nas telas pequenas.
|
|
276
|
+
- A classe de tema é decisão do host (`.dark-theme` ou `.theme-dark`/`.theme-light`); mantenha tokens e componentes no mesmo escopo.
|
|
277
|
+
|
|
278
|
+
### Tokens M3 obrigatórios (host)
|
|
279
|
+
|
|
280
|
+
Para que o builder e os editores respeitem o tema do app host:
|
|
281
|
+
|
|
282
|
+
- Superfícies: `--md-sys-color-surface`, `--md-sys-color-surface-variant`, `--md-sys-color-surface-container-*`
|
|
283
|
+
- Texto/contorno: `--md-sys-color-on-surface`, `--md-sys-color-on-surface-variant`, `--md-sys-color-outline`, `--md-sys-color-outline-variant`
|
|
284
|
+
- Semânticos: `--md-sys-color-primary`, `--md-sys-color-secondary`, `--md-sys-color-tertiary`, `--md-sys-color-error`
|
|
285
|
+
- Containers: `--md-sys-color-primary-container`, `--md-sys-color-secondary-container`, `--md-sys-color-tertiary-container`, `--md-sys-color-error-container`
|
|
286
|
+
- Elevação: `--md-sys-elevation-level1`–`--md-sys-elevation-level3`
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
## Section titles — espaçamento global
|
|
290
|
+
|
|
291
|
+
O título de seção usa por padrão `margin: 0 0 6px 0`. Você pode ajustar globalmente via CSS var:
|
|
292
|
+
|
|
293
|
+
```scss
|
|
294
|
+
/* Global (app host) */
|
|
295
|
+
:root { --pfx-section-title-mb: 10px; } // ex.: 10px abaixo do título
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Ou por seção, via metadado `titleGapBottom` (em pixels), que aplica inline somente naquela seção.
|
|
299
|
+
|
|
109
300
|
## Compatibility
|
|
110
301
|
|
|
111
302
|
- `@praxisui/dynamic-form` `0.0.x` → Angular `20.x`
|
|
@@ -119,9 +310,9 @@ Apache-2.0 – see the `LICENSE` packaged with this library or the repository ro
|
|
|
119
310
|
|
|
120
311
|
### Concept Usage
|
|
121
312
|
|
|
122
|
-
-
|
|
123
|
-
-
|
|
124
|
-
-
|
|
313
|
+
- Data-driven forms
|
|
314
|
+
- Declarative UI
|
|
315
|
+
- Schema-driven UI
|
|
125
316
|
|
|
126
317
|
## Quando usar cada mecanismo
|
|
127
318
|
|
|
@@ -142,9 +333,9 @@ Apache-2.0 – see the `LICENSE` packaged with this library or the repository ro
|
|
|
142
333
|
|
|
143
334
|
## Links úteis
|
|
144
335
|
|
|
145
|
-
- Fluxo de Schema (ETag/304, schemaId, reconciliação): `docs/schemas/fluxo-schema.md`
|
|
336
|
+
- Fluxo de Schema (ETag/304, schemaId, reconciliação): `projects/praxis-core/docs/schema-flow.md` (canônico) e `docs/schemas/fluxo-schema.md` (resumo operacional)
|
|
146
337
|
- Guia de implementação e metadados da cascata: `docs/CASCADE-NATIVA.md`
|
|
147
|
-
- Padrões de endpoints (Options vs Filter) para selects: `docs/DEVS-GENERIC-CRUD-SERVICE.md`
|
|
338
|
+
- Padrões de endpoints (Options vs Filter) para selects: `projects/praxis-dynamic-fields/docs/generic-crud-service.md` (canônico) e `docs/DEVS-GENERIC-CRUD-SERVICE.md` (resumo operacional)
|
|
148
339
|
|
|
149
340
|
## Verificação de Schema (ETag/If-None-Match)
|
|
150
341
|
|
|
@@ -164,3 +355,9 @@ Apache-2.0 – see the `LICENSE` packaged with this library or the repository ro
|
|
|
164
355
|
- 200 → atualiza `serverHash/lastVerifiedAt`, define `schemaOutdated = editModeEnabled && hadBase`, emite `schemaStatusChange`. Não aplica schema automaticamente.
|
|
165
356
|
- Primeira vez (sem base): baixa o corpo do schema para gerar o layout; persiste `form-schema-meta:{formId}`.
|
|
166
357
|
- Notificações respeitam preferências e são one‑shot por hash; o banner/snackbar oferecem ações para Reconciliar, Lembrar depois (snooze) e Ignorar.
|
|
358
|
+
|
|
359
|
+
### URL da API (absoluto vs relativo)
|
|
360
|
+
|
|
361
|
+
- Quando `API_URL.default.baseUrl` for relativo (ex.: `'/api'`), a lib resolve a origem a partir de `location.origin` no browser. Isso cobre o cenário comum com proxy de dev (`/api`, `/schemas`).
|
|
362
|
+
- Em SSR (sem `location.origin`), configure `baseUrl` absoluto (ex.: `https://api.acme.com/api`) para evitar erros do tipo “Invalid URL” ao construir chamadas de `/schemas/filtered`.
|
|
363
|
+
- O `GenericCrudService.getSchemasFilteredBaseUrl()` retorna sempre uma URL absoluta; o `SchemaMetadataClient` também aceita `baseUrl` relativo quando há origin disponível.
|