@praxisui/dynamic-fields 9.0.0-beta.0 → 9.0.0-beta.2
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 +116 -563
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,302 +1,54 @@
|
|
|
1
|
-
|
|
2
|
-
title: "Dynamic Fields"
|
|
3
|
-
slug: "dynamic-fields-overview"
|
|
4
|
-
description: "Visao geral do @praxisui/dynamic-fields com renderizacao metadata-driven, registro lazy de componentes, tokens M3 e campos enterprise."
|
|
5
|
-
doc_type: "reference"
|
|
6
|
-
document_kind: "component-overview"
|
|
7
|
-
component: "dynamic-fields"
|
|
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-fields"
|
|
18
|
-
- "metadata"
|
|
19
|
-
- "forms"
|
|
20
|
-
- "runtime"
|
|
21
|
-
- "material"
|
|
22
|
-
order: 32
|
|
23
|
-
icon: "toc"
|
|
24
|
-
toc: true
|
|
25
|
-
sidebar: true
|
|
26
|
-
search_boost: 1.0
|
|
27
|
-
reading_time: 16
|
|
28
|
-
estimated_setup_time: 25
|
|
29
|
-
version: "1.0"
|
|
30
|
-
related_docs:
|
|
31
|
-
- "dynamic-fields-field-catalog"
|
|
32
|
-
- "dynamic-fields-field-selection-guide"
|
|
33
|
-
- "dynamic-fields-host-custom-field-guide"
|
|
34
|
-
- "dynamic-fields-host-custom-field-troubleshooting"
|
|
35
|
-
- "dynamic-fields-inline-filter-catalog"
|
|
36
|
-
- "dynamic-fields-inline-components-guide"
|
|
37
|
-
- "host-integration-guide"
|
|
38
|
-
- "consumer-integration-quickstart"
|
|
39
|
-
keywords:
|
|
40
|
-
- "dynamic field loader"
|
|
41
|
-
- "metadata-driven fields"
|
|
42
|
-
- "material controls"
|
|
43
|
-
- "runtime registry"
|
|
44
|
-
last_updated: "2026-03-07"
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
# @praxisui/dynamic-fields — Dynamic Form Fields
|
|
48
|
-
|
|
49
|
-
## Documentation
|
|
50
|
-
|
|
51
|
-
- Official documentation: https://praxisui.dev
|
|
52
|
-
- Quickstart reference app: https://github.com/codexrodrigues/praxis-ui-quickstart
|
|
53
|
-
- Recommended for: metadata-driven forms that need lazy field registration, Angular Material integration and enterprise field catalogs
|
|
54
|
-
|
|
55
|
-
## When to use
|
|
56
|
-
|
|
57
|
-
- Render field components from metadata at runtime
|
|
58
|
-
- Standardize field behavior and theming across multiple forms
|
|
59
|
-
- Extend the field catalog without hardwiring every component into the host app
|
|
60
|
-
|
|
61
|
-
## Concept Usage
|
|
62
|
-
|
|
63
|
-
- Dynamic component rendering
|
|
64
|
-
- Headless UI and design systems
|
|
65
|
-
- Data-driven forms
|
|
1
|
+
# @praxisui/dynamic-fields
|
|
66
2
|
|
|
67
|
-
|
|
3
|
+
Metadata-driven Angular field runtime for Praxis UI.
|
|
68
4
|
|
|
69
|
-
|
|
5
|
+
Use this package when forms, filters, or authoring tools must render field controls from `FieldMetadata` and `FieldControlType` instead of hardcoding Angular components in every host screen.
|
|
70
6
|
|
|
71
|
-
|
|
72
|
-
- use `valuePresentation` para valores escalares de display, como `currency`, `number`, `date`, `datetime`, `time`, `percentage` e `boolean`
|
|
73
|
-
- mantenha `format`, `numericFormat`, `currency`, `numberFormat` e `locale` apenas como bridge legado quando necessário
|
|
74
|
-
- `valuePresentation` não é o contrato certo para ranges, selections e IDs semânticos
|
|
75
|
-
- precedência prática: `field.valuePresentation` -> hints legados mapeáveis -> `localization` da superfície/campo -> `LOCALE_ID`
|
|
76
|
-
- `controlType` ajuda o runtime a inferir fallback quando o metadata antigo ainda é usado, mas não substitui a semântica de apresentação
|
|
77
|
-
- em `presentationMode` puro, o runtime renderiza o valor formatado no shell e evita instanciar o componente interativo escondido, reduzindo side effects e deriva de valor
|
|
7
|
+
## Official Links
|
|
78
8
|
|
|
79
|
-
|
|
9
|
+
- Documentation: https://praxisui.dev/docs/components
|
|
10
|
+
- Live demo: https://praxis-ui-4e602.web.app
|
|
11
|
+
- Quickstart app: https://github.com/codexrodrigues/praxis-ui-quickstart
|
|
12
|
+
- API quickstart: https://github.com/codexrodrigues/praxis-api-quickstart-public
|
|
13
|
+
- Source: https://github.com/codexrodrigues/praxis-ui-angular/tree/main/projects/praxis-dynamic-fields
|
|
14
|
+
- Issues: https://github.com/codexrodrigues/praxis-ui-angular/issues
|
|
80
15
|
|
|
81
|
-
##
|
|
16
|
+
## Install
|
|
82
17
|
|
|
83
18
|
```bash
|
|
84
|
-
npm
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### Estilos e tokens (opcional)
|
|
88
|
-
|
|
89
|
-
- Largura dos campos: quando o host usa `providePraxisDynamicFields()`, a lib injeta um estilo escopado que garante `mat-form-field { width: 100% }` dentro dos componentes. Não é necessário repetir no app.
|
|
90
|
-
- Gradiente de marca (se desejar): o host pode definir um gradiente para detalhes visuais da lib (ex.: toolbar de edição):
|
|
91
|
-
|
|
92
|
-
```scss
|
|
93
|
-
:root {
|
|
94
|
-
--p-primary-gradient: linear-gradient(90deg, #1f8a8a, #6c63ff);
|
|
95
|
-
}
|
|
19
|
+
npm i @praxisui/dynamic-fields@latest
|
|
96
20
|
```
|
|
97
21
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
Tema e escopo (host)
|
|
101
|
-
- A classe de tema é decisão do host (`.dark-theme` ou `.theme-dark`/`.theme-light`); mantenha tokens e componentes no mesmo escopo.
|
|
102
|
-
|
|
103
|
-
### Tokens M3 obrigatórios (host)
|
|
104
|
-
|
|
105
|
-
Para que os componentes reflitam corretamente o tema do app host, garanta no mínimo:
|
|
106
|
-
|
|
107
|
-
- Superfícies: `--md-sys-color-surface`, `--md-sys-color-surface-variant`, `--md-sys-color-surface-container-*`
|
|
108
|
-
- Texto/contorno: `--md-sys-color-on-surface`, `--md-sys-color-on-surface-variant`, `--md-sys-color-outline`, `--md-sys-color-outline-variant`
|
|
109
|
-
- Semânticos: `--md-sys-color-primary`, `--md-sys-color-on-primary`, `--md-sys-color-secondary`, `--md-sys-color-on-secondary`, `--md-sys-color-tertiary`, `--md-sys-color-on-tertiary`, `--md-sys-color-error`, `--md-sys-color-on-error`
|
|
110
|
-
- Containers: `--md-sys-color-primary-container`, `--md-sys-color-on-primary-container`, `--md-sys-color-secondary-container`, `--md-sys-color-on-secondary-container`, `--md-sys-color-tertiary-container`, `--md-sys-color-on-tertiary-container`, `--md-sys-color-error-container`, `--md-sys-color-on-error-container`
|
|
111
|
-
- Elevação: `--md-sys-elevation-level1`–`--md-sys-elevation-level3`
|
|
22
|
+
Peer dependencies:
|
|
112
23
|
|
|
113
|
-
|
|
114
|
-
-
|
|
115
|
-
- A classe de tema é decisão do host (`.dark-theme` ou `.theme-dark`/`.theme-light`); mantenha tokens e componentes no mesmo escopo.
|
|
116
|
-
- Datepicker usa `panelClass="pdx-datepicker-panel"`; personalize o overlay via essa classe no tema do host.
|
|
117
|
-
|
|
118
|
-
### Prefixos Material e labels flutuantes
|
|
119
|
-
|
|
120
|
-
O Angular Material documenta uma limitação real em `mat-form-field` com aparência `fill` ou `outline`: prefixos/sufixos de texto não alinham bem com o label em repouso, e a recomendação oficial atual é usar `floatLabel="always"` nesses casos. A plataforma segue essa recomendação para adornos estruturais permanentes, como swatches de cor e símbolos que fazem parte do valor visual.
|
|
121
|
-
|
|
122
|
-
Não substitua essa política por offsets CSS locais. Offsets dependem de densidade, fonte, idioma, aparência Material e do tamanho do prefixo, e tendem a quebrar quando o Angular Material muda a estrutura MDC interna. Se o Angular Material passar a oferecer suporte nativo melhor para prefixos em `fill`/`outline`, reavalie esta decisão de plataforma e prefira voltar a delegar o alinhamento ao Material.
|
|
123
|
-
|
|
124
|
-
Peers (instale no app host):
|
|
125
|
-
- `@angular/core` `^20.1.0`, `@angular/common` `^20.1.0`, `@angular/forms` `^20.1.0`
|
|
126
|
-
- `@angular/material` `^20.1.0`, `@angular/cdk` `^20.1.0`, `@angular/router` `^20.1.0`
|
|
24
|
+
- `@angular/common`, `@angular/core`, `@angular/forms`, `@angular/material`, `@angular/cdk`, `@angular/platform-browser`, `@angular/router` `^21.0.0`
|
|
25
|
+
- `@praxisui/core`, `@praxisui/cron-builder` `^9.0.0-beta.1`
|
|
127
26
|
- `rxjs` `^7.8.0`
|
|
128
|
-
- `@praxisui/core`
|
|
129
|
-
- Opcional conforme uso: `@praxisui/dialog`, `@praxisui/cron-builder`
|
|
130
|
-
|
|
131
|
-
## ✨ Características
|
|
132
|
-
|
|
133
|
-
- **Registro Simplificado**: Sistema de registro de componentes focado no essencial
|
|
134
|
-
- **Lazy Loading**: Carregamento sob demanda com cache inteligente
|
|
135
|
-
- **Material Design**: Componentes baseados no Angular Material
|
|
136
|
-
- **Color Picker**: Novo componente de seleção de cores com suporte a paleta e canvas
|
|
137
|
-
- **Novos Componentes**: Toggle, Slider, Time Picker e Rating
|
|
138
|
-
- **Material Select Modular**: Fragmentado em subcomponentes (SearchInput, OptionsList e Chips)
|
|
139
|
-
- **TypeScript**: Totalmente tipado com integração do `@praxisui/core`
|
|
140
|
-
- **Corporativo**: Adequado para cenários empresariais
|
|
141
|
-
|
|
142
|
-
## 🏗️ Arquitetura
|
|
143
|
-
|
|
144
|
-
### Sistema de Registro
|
|
145
|
-
|
|
146
|
-
```typescript
|
|
147
|
-
import { ComponentRegistryService } from "@praxisui/dynamic-fields";
|
|
148
|
-
import { FieldControlType } from "@praxisui/core";
|
|
149
|
-
|
|
150
|
-
// Obter componente usando constantes
|
|
151
|
-
const component = await registry.getComponent(FieldControlType.INPUT);
|
|
152
|
-
|
|
153
|
-
// Verificar registro
|
|
154
|
-
const isRegistered = registry.isRegistered(FieldControlType.INPUT);
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## 📄 Documentacao Tecnica da Lib
|
|
158
|
-
|
|
159
|
-
- `projects/praxis-dynamic-fields/docs/dynamic-fields-inventory.md`
|
|
160
|
-
- `projects/praxis-dynamic-fields/docs/dynamic-fields-field-catalog.md`
|
|
161
|
-
- `projects/praxis-dynamic-fields/docs/dynamic-fields-field-selection-guide.md`
|
|
162
|
-
- `projects/praxis-dynamic-fields/docs/dynamic-fields-host-custom-field-guide.md`
|
|
163
|
-
- `projects/praxis-dynamic-fields/docs/dynamic-fields-host-custom-field-troubleshooting.md`
|
|
164
|
-
- `projects/praxis-dynamic-fields/docs/dynamic-fields-inline-filter-inventory.md`
|
|
165
|
-
- `projects/praxis-dynamic-fields/docs/dynamic-fields-inline-filter-catalog.md`
|
|
166
|
-
- `projects/praxis-dynamic-fields/docs/dynamic-fields-inline-filter-selection-guide.md`
|
|
167
|
-
- `projects/praxis-dynamic-fields/docs/dynamic-fields-inline-filter-runtime-contract.md`
|
|
168
|
-
- `projects/praxis-dynamic-fields/docs/dynamic-fields-inline-filter-custom-component-guide.md`
|
|
169
|
-
- `projects/praxis-dynamic-fields/docs/dynamic-fields-inline-filter-troubleshooting.md`
|
|
170
|
-
- `projects/praxis-dynamic-fields/docs/dynamic-fields-inline-components-guide.md` (slug: `dynamic-fields-inline-components-guide`)
|
|
171
|
-
- `projects/praxis-dynamic-fields/docs/generic-crud-service.md`
|
|
172
|
-
|
|
173
|
-
## Editorial governance
|
|
174
|
-
|
|
175
|
-
Para fields mantidos pela propria lib, a semantica editorial canonica nasce em `src/lib/editorial/**`.
|
|
176
|
-
|
|
177
|
-
Fronteira oficial:
|
|
178
|
-
|
|
179
|
-
- `ComponentMetadataEditorialDescriptor`: fonte canonica de `friendlyName`, `description`, `tooltip`, `icon`, bindings e i18n para familias governadas.
|
|
180
|
-
- `ComponentDocMeta`: artefato derivado para builders, discovery e compatibilidade de runtime; nao deve redefinir copy editorial da mesma familia governada.
|
|
181
|
-
- `dynamic-fields-playground.catalog.ts`: camada derivada para showcase/discovery; pode adicionar `recommendedWhen`, `avoidWhen`, estados e snippets, mas nao deve reinventar copy canonica.
|
|
182
|
-
- `@praxisui/dynamic-form`: consumidor; resolve nome/icone/descricao via `ComponentMetadataRegistry.resolveEditorial(..., { namespace: 'dynamicFields' })`.
|
|
183
|
-
|
|
184
|
-
Estado atual da trilha:
|
|
185
|
-
|
|
186
|
-
- a governanca editorial canonica cobre a wave 1 registrada em `dynamic-fields-wave-1.registry.ts`;
|
|
187
|
-
- familias fora da wave 1 ainda podem expor `ComponentDocMeta` proprio, mas isso nao as transforma em nova fonte canonica;
|
|
188
|
-
- ao promover uma nova familia para a trilha canonica, a ordem correta e: descriptor editorial -> metadata derivado -> catalogo derivado -> consumo no `dynamic-form`.
|
|
189
|
-
|
|
190
|
-
## Agentic Authoring & Manifest
|
|
191
|
-
|
|
192
|
-
`@praxisui/dynamic-fields` publica `PRAXIS_DYNAMIC_FIELDS_AUTHORING_MANIFEST` como contrato executavel de authoring para a familia de controles. Diferente de componentes com um unico config editor, este manifesto governa a cadeia runtime/editorial/tooling.
|
|
193
|
-
|
|
194
|
-
- **Component family:** `praxis-dynamic-fields`
|
|
195
|
-
- **Config Schema:** `FieldMetadata`
|
|
196
|
-
- **Editable targets:** 7 target kinds: `controlType`, `controlAlias`, `editorialDescriptor`, `selectorMapping`, `fieldMetadataPath`, `runtimeCoverage`, `editorCoverage`.
|
|
197
|
-
- **Operation families:** 8 operations: `controlType.register`, `controlType.alias.add`, `controlType.alias.remove`, `descriptor.update`, `selector.mapping.set`, `metadata.mapping.set`, `editorCoverage.validate`, `runtimeCoverage.validate`.
|
|
198
|
-
- **Validation:** 14 validators separam cobertura runtime de cobertura editorial/tooling, protegem aliases e selector mappings deterministas, alinham capabilities de `FieldMetadata` e exigem evidencia de cobertura.
|
|
199
|
-
- **Control profiles:** 18 perfis (`text-input`, `numeric`, `currency`, `select`, `entity-lookup`, `tree-select`, `list-transfer`, `date`, `date-range`, `time-range`, `toggle`, `color`, `regional-document`, `file-upload`, `collection`, `avatar`, `display-action`, `field-shell`) adicionam operacoes, validators e examples granulares por classe de controle sem duplicar 1 manifesto completo por componente.
|
|
200
|
-
- **Registry projection:** o manifesto e projetado na entrada agregada `praxis-dynamic-fields` e tambem nos componentes de `@praxisui/dynamic-fields` no `ai_registry`; cada componente projetado recebe `authoringManifestProfiles` com o perfil aplicavel, e runtime render sozinho nao e evidencia suficiente de suporte editorial.
|
|
201
|
-
- **Selector mappings:** `selector.mapping.set` governa entradas do `FieldSelectorRegistry`; selectors de host precisam ser registrados explicitamente em vez de depender de convencao textual ou fallback por nome parecido.
|
|
202
|
-
|
|
203
|
-
### Componentes Suportados
|
|
204
|
-
|
|
205
|
-
A fonte de verdade do suporte default e o `ComponentRegistryService`.
|
|
206
|
-
|
|
207
|
-
Use os documentos governados abaixo em vez de manter listas textuais soltas:
|
|
208
|
-
|
|
209
|
-
- inventario auditavel do runtime: `dynamic-fields-inventory.md`
|
|
210
|
-
- catalogo principal de fields de formulario: `dynamic-fields-field-catalog.md`
|
|
211
|
-
- guia de escolha do field correto: `dynamic-fields-field-selection-guide.md`
|
|
212
|
-
- extensao do host: `dynamic-fields-host-custom-field-guide.md`
|
|
213
|
-
- troubleshooting de extensao: `dynamic-fields-host-custom-field-troubleshooting.md`
|
|
214
|
-
- trilha especializada de filtros compactos: `dynamic-fields-inline-filter-catalog.md`
|
|
215
27
|
|
|
216
|
-
##
|
|
217
|
-
|
|
218
|
-
O `MaterialSelectComponent` agora está dividido em subcomponentes menores para facilitar manutenção e testes:
|
|
219
|
-
|
|
220
|
-
- **SelectSearchInputComponent** - Campo de busca opcional exibido dentro do painel.
|
|
221
|
-
- **SelectOptionsListComponent** - Lista de opções com suporte a grupos e virtualização.
|
|
222
|
-
- **SelectChipsComponent** - Exibe as opções selecionadas como chips quando `multipleDisplay` é `"chips"`.
|
|
223
|
-
|
|
224
|
-
Esses subcomponentes são utilizados internamente pelo select e não exigem alterações na utilização normal do componente.
|
|
225
|
-
|
|
226
|
-
## 🧩 MaterialCheckboxGroupComponent
|
|
227
|
-
|
|
228
|
-
Renderiza uma lista de checkboxes conectada ao `@angular/forms`, permitindo a seleção de múltiplos valores.
|
|
229
|
-
|
|
230
|
-
- **Select All**: opção para marcar todas as entradas habilitadas.
|
|
231
|
-
- **maxSelections**: limita o número de escolhas possíveis.
|
|
232
|
-
- **Carregamento Remoto**: aceita `resourcePath`, `optionLabelKey` e `optionValueKey` para popular opções via API.
|
|
233
|
-
- **Layout**: suporta `labelPosition` e `color` conforme [documentação do Angular Material](https://material.angular.dev/components/checkbox/overview).
|
|
234
|
-
|
|
235
|
-
## 🧩 MaterialRadioGroupComponent
|
|
236
|
-
|
|
237
|
-
Grupo de botões de rádio que consome metadados ou dados remotos para criar seleções exclusivas.
|
|
238
|
-
|
|
239
|
-
- **Seleção Única**: utiliza `MatRadioGroup` para garantir apenas um valor ativo.
|
|
240
|
-
- **Carregamento Dinâmico**: mesmas chaves de configuração de `MaterialSelectComponent` para buscar opções.
|
|
241
|
-
- **Layout Flexível**: configuração de orientação, `labelPosition` e `color` segundo a [documentação oficial](https://material.angular.dev/components/radio/overview).
|
|
242
|
-
|
|
243
|
-
## 🧩 Avatar Field
|
|
244
|
-
|
|
245
|
-
Componente visual para exibir representação de usuário/entidade/estado, com prioridade de conteúdo:
|
|
246
|
-
|
|
247
|
-
- imageSrc > icon > initials > ng-content
|
|
248
|
-
|
|
249
|
-
Propriedades principais: `themeColor`, `rounded`, `size`, `fillMode`, `border`, `tooltip`, `ariaLabel`.
|
|
250
|
-
|
|
251
|
-
Exemplos:
|
|
252
|
-
|
|
253
|
-
```html
|
|
254
|
-
<pdx-material-avatar [imageSrc]="user.img" size="large" themeColor="tertiary"></pdx-material-avatar>
|
|
255
|
-
<pdx-material-avatar initials="MB" themeColor="secondary"></pdx-material-avatar>
|
|
256
|
-
<pdx-material-avatar icon="person" fillMode="outline"></pdx-material-avatar>
|
|
257
|
-
<pdx-material-avatar><app-status-badge></app-status-badge></pdx-material-avatar>
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
Uso em formulários dinâmicos (via metadata):
|
|
28
|
+
## Provide Defaults
|
|
261
29
|
|
|
262
30
|
```ts
|
|
263
|
-
import {
|
|
264
|
-
|
|
265
|
-
const fields: FieldMetadata[] = [
|
|
266
|
-
{
|
|
267
|
-
name: 'avatar',
|
|
268
|
-
label: 'Avatar',
|
|
269
|
-
controlType: FieldControlType.AVATAR,
|
|
270
|
-
// opções específicas via `extra` (quando aplicável)
|
|
271
|
-
extra: { imageSrc: 'https://example.com/u/42.png', size: 'large' }
|
|
272
|
-
}
|
|
273
|
-
];
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
Tokens M3 aplicados:
|
|
277
|
-
|
|
278
|
-
- `--pfx-avatar-bg`, `--pfx-avatar-fg`, `--pfx-avatar-border-color`, `--pfx-avatar-border-w`
|
|
279
|
-
- `--pfx-avatar-size`, `--pfx-avatar-radius-[full|lg|md|sm]`
|
|
31
|
+
import { ApplicationConfig } from '@angular/core';
|
|
32
|
+
import { providePraxisDynamicFields } from '@praxisui/dynamic-fields';
|
|
280
33
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
npm install @praxisui/dynamic-fields@beta
|
|
34
|
+
export const appConfig: ApplicationConfig = {
|
|
35
|
+
providers: [providePraxisDynamicFields()],
|
|
36
|
+
};
|
|
285
37
|
```
|
|
286
38
|
|
|
287
|
-
|
|
39
|
+
Use `providePraxisDynamicFieldsNoDefaults()` only when the host intentionally wants to register its own runtime catalog.
|
|
288
40
|
|
|
289
|
-
|
|
41
|
+
## Quick Start
|
|
290
42
|
|
|
291
43
|
```ts
|
|
292
|
-
import { Component,
|
|
293
|
-
import {
|
|
44
|
+
import { Component, inject } from '@angular/core';
|
|
45
|
+
import { NonNullableFormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
|
46
|
+
import { FieldControlType, FieldMetadata } from '@praxisui/core';
|
|
294
47
|
import { DynamicFieldLoaderDirective } from '@praxisui/dynamic-fields';
|
|
295
|
-
import { FieldMetadata, FieldControlType } from '@praxisui/core';
|
|
296
48
|
|
|
297
49
|
@Component({
|
|
298
|
-
selector: 'app-dynamic-form',
|
|
299
50
|
standalone: true,
|
|
51
|
+
selector: 'app-dynamic-fields-example',
|
|
300
52
|
imports: [ReactiveFormsModule, DynamicFieldLoaderDirective],
|
|
301
53
|
template: `
|
|
302
54
|
<form [formGroup]="form">
|
|
@@ -304,347 +56,148 @@ import { FieldMetadata, FieldControlType } from '@praxisui/core';
|
|
|
304
56
|
dynamicFieldLoader
|
|
305
57
|
[fields]="fields"
|
|
306
58
|
[formGroup]="form"
|
|
307
|
-
|
|
59
|
+
[presentationMode]="false"
|
|
60
|
+
(componentsCreated)="created = $event">
|
|
308
61
|
</ng-container>
|
|
309
62
|
</form>
|
|
310
63
|
`,
|
|
311
64
|
})
|
|
312
|
-
export class
|
|
65
|
+
export class DynamicFieldsExampleComponent {
|
|
313
66
|
private readonly fb = inject(NonNullableFormBuilder);
|
|
314
67
|
|
|
68
|
+
created = new Map<string, unknown>();
|
|
69
|
+
|
|
315
70
|
form = this.fb.group({
|
|
316
|
-
|
|
317
|
-
|
|
71
|
+
name: this.fb.control('', { validators: [Validators.required] }),
|
|
72
|
+
status: this.fb.control('active'),
|
|
318
73
|
});
|
|
319
74
|
|
|
320
75
|
fields: FieldMetadata[] = [
|
|
321
76
|
{
|
|
322
|
-
name: '
|
|
323
|
-
label: '
|
|
77
|
+
name: 'name',
|
|
78
|
+
label: 'Name',
|
|
324
79
|
controlType: FieldControlType.INPUT,
|
|
325
|
-
placeholder: 'Seu nome completo',
|
|
326
80
|
required: true,
|
|
327
81
|
},
|
|
328
82
|
{
|
|
329
|
-
name: '
|
|
330
|
-
label: '
|
|
83
|
+
name: 'status',
|
|
84
|
+
label: 'Status',
|
|
331
85
|
controlType: FieldControlType.SELECT,
|
|
332
86
|
options: [
|
|
333
|
-
{ label: '
|
|
334
|
-
{ label: '
|
|
87
|
+
{ label: 'Active', value: 'active' },
|
|
88
|
+
{ label: 'Inactive', value: 'inactive' },
|
|
335
89
|
],
|
|
336
|
-
multiple: false,
|
|
337
|
-
searchable: true,
|
|
338
90
|
},
|
|
339
91
|
];
|
|
340
|
-
|
|
341
|
-
onReady(map: Map<string, any>) {
|
|
342
|
-
// Recebe referências dos componentes criados (opcional)
|
|
343
|
-
console.log('components', Array.from(map.keys()));
|
|
344
|
-
}
|
|
345
92
|
}
|
|
346
93
|
```
|
|
347
94
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
```html
|
|
351
|
-
<ng-container dynamicFieldLoader [fields]="fields" [formGroup]="form"></ng-container>
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
```typescript
|
|
355
|
-
import { ComponentRegistryService } from "@praxisui/dynamic-fields";
|
|
356
|
-
import { FieldControlType } from "@praxisui/core";
|
|
95
|
+
## Runtime Registry
|
|
357
96
|
|
|
358
|
-
|
|
359
|
-
selector: "app-dynamic-form",
|
|
360
|
-
template: `<ng-container #dynamicContainer></ng-container>`,
|
|
361
|
-
})
|
|
362
|
-
export class DynamicFormComponent {
|
|
363
|
-
@ViewChild("dynamicContainer", { read: ViewContainerRef })
|
|
364
|
-
container!: ViewContainerRef;
|
|
365
|
-
|
|
366
|
-
constructor(private registry: ComponentRegistryService) {}
|
|
367
|
-
|
|
368
|
-
async loadField(type: FieldControlType) {
|
|
369
|
-
const component = await this.registry.getComponent(type);
|
|
370
|
-
if (component) {
|
|
371
|
-
this.container.createComponent(component);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
// Exemplo prático
|
|
376
|
-
async loadInputField() {
|
|
377
|
-
await this.loadField(FieldControlType.INPUT);
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
async loadDatePicker() {
|
|
381
|
-
await this.loadField(FieldControlType.DATE_PICKER);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
async loadColorPicker() {
|
|
385
|
-
await this.loadField(FieldControlType.COLOR_PICKER);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
## 🔧 Registrar Componente Customizado
|
|
391
|
-
|
|
392
|
-
```typescript
|
|
393
|
-
import { FieldControlType } from "@praxisui/core";
|
|
394
|
-
|
|
395
|
-
// Registrar componente customizado - SUPER SIMPLES!
|
|
396
|
-
registry.register("customField" as FieldControlType, () => import("./custom-field.component").then((m) => m.CustomFieldComponent));
|
|
397
|
-
|
|
398
|
-
// Uso posterior
|
|
399
|
-
const customComponent = await registry.getComponent("customField" as FieldControlType);
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
## 📊 Estatísticas
|
|
403
|
-
|
|
404
|
-
```typescript
|
|
405
|
-
const stats = registry.getStats();
|
|
406
|
-
console.log(stats);
|
|
407
|
-
// {
|
|
408
|
-
// registeredComponents: 7,
|
|
409
|
-
// cachedComponents: 3,
|
|
410
|
-
// registeredTypes: ['input', 'select', ...]
|
|
411
|
-
// }
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
## 🛠️ API (Pontos de Entrada)
|
|
415
|
-
|
|
416
|
-
Exportados principais:
|
|
417
|
-
- Diretivas: `DynamicFieldLoaderDirective`
|
|
418
|
-
- Serviços: `ComponentRegistryService`
|
|
419
|
-
- Base: `SimpleBaseInputComponent`, `SimpleBaseSelectComponent`, `SimpleBaseButtonComponent`
|
|
420
|
-
- Componentes Material (exemplos): `MaterialSelectComponent`, `MaterialRadioGroupComponent`, `MaterialCheckboxGroupComponent`, `MaterialDatepickerComponent`, `MaterialSliderComponent`, `MaterialTimepickerComponent`, `MaterialTextareaComponent`, `MaterialAutocompleteComponent`, `MaterialChipsComponent`, `MaterialButtonComponent`, `MaterialFileUploadComponent`
|
|
421
|
-
|
|
422
|
-
Referencie `src/public-api.ts` do pacote para a lista completa de símbolos exportados.
|
|
423
|
-
|
|
424
|
-
### ComponentRegistryService
|
|
425
|
-
|
|
426
|
-
#### Métodos Principais
|
|
427
|
-
|
|
428
|
-
- `register<T>(type, factory)` - Registra componente (ultra-simples!)
|
|
429
|
-
- `getComponent<T>(type)` - Obtém componente (async)
|
|
430
|
-
- `isRegistered(type)` - Verifica se está registrado
|
|
431
|
-
- `getRegisteredTypes()` - Lista tipos registrados
|
|
432
|
-
|
|
433
|
-
#### Métodos Utilitários
|
|
434
|
-
|
|
435
|
-
- `getStats()` - Estatísticas do registro
|
|
436
|
-
- `clearCache(type?)` - Limpa cache
|
|
437
|
-
- `unregister(type)` - Remove componente
|
|
438
|
-
- `preload(types[])` - Pré-carrega componentes
|
|
439
|
-
|
|
440
|
-
### Interfaces
|
|
441
|
-
|
|
442
|
-
```typescript
|
|
443
|
-
interface RegistryStats {
|
|
444
|
-
registeredComponents: number;
|
|
445
|
-
cachedComponents: number;
|
|
446
|
-
registeredTypes: FieldControlType[];
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
interface ComponentRegistration {
|
|
450
|
-
factory: () => Promise<Type<any>>;
|
|
451
|
-
cached?: Type<any>;
|
|
452
|
-
}
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
## 🎯 Integração com @praxisui/core
|
|
456
|
-
|
|
457
|
-
Esta biblioteca usa os tipos e metadados do `@praxisui/core`:
|
|
458
|
-
|
|
459
|
-
- `FieldControlType` - Tipos de controle unificados
|
|
460
|
-
- `UnifiedFieldMetadata` - Sistema de metadados corporativo
|
|
461
|
-
- `MaterialInputMetadata`, `MaterialSelectMetadata`, etc. - Metadados específicos
|
|
462
|
-
|
|
463
|
-
## 📋 Desenvolvimento
|
|
464
|
-
|
|
465
|
-
```bash
|
|
466
|
-
# Build da biblioteca
|
|
467
|
-
ng build praxis-dynamic-fields
|
|
468
|
-
|
|
469
|
-
# Testes
|
|
470
|
-
ng test praxis-dynamic-fields
|
|
471
|
-
|
|
472
|
-
# Lint
|
|
473
|
-
ng lint praxis-dynamic-fields
|
|
474
|
-
```
|
|
475
|
-
|
|
476
|
-
## 🏷️ Versão
|
|
477
|
-
|
|
478
|
-
**Versão atual**: Sistema simplificado pós-refatoração
|
|
479
|
-
**Dependências**: `@praxisui/core`, `@angular/material`
|
|
480
|
-
**Angular**: 20+
|
|
481
|
-
**TypeScript**: 5.8+
|
|
482
|
-
|
|
483
|
-
---
|
|
484
|
-
|
|
485
|
-
_Sistema desenvolvido seguindo diretrizes de simplicidade e foco no essencial._
|
|
486
|
-
|
|
487
|
-
## 🔌 Extensão pelo App Host (registrando seu próprio componente)
|
|
488
|
-
|
|
489
|
-
Resumo executivo:
|
|
490
|
-
|
|
491
|
-
- `ComponentRegistryService.register(...)`: registra o componente que o runtime carrega.
|
|
492
|
-
- `ComponentMetadataRegistry.register(...)`: registra nome/ícone/superfície editorial.
|
|
493
|
-
- `controlType` do contrato deve bater com `ComponentDocMeta.id`.
|
|
494
|
-
- Hot metadata funciona melhor quando o componente expõe `setInputMetadata(...)` e/ou signal de metadata.
|
|
495
|
-
|
|
496
|
-
Para o guia governado completo, consulte:
|
|
497
|
-
|
|
498
|
-
- `projects/praxis-dynamic-fields/docs/dynamic-fields-host-custom-field-guide.md`
|
|
499
|
-
- `projects/praxis-dynamic-fields/docs/dynamic-fields-host-custom-field-troubleshooting.md`
|
|
500
|
-
|
|
501
|
-
Aplicações host podem registrar componentes próprios para uso no DynamicFieldLoader e expor metadados para título/ícone amigáveis no editor.
|
|
502
|
-
|
|
503
|
-
### 1) Registrar o componente no runtime (DynamicFieldLoader)
|
|
504
|
-
|
|
505
|
-
Use `ENVIRONMENT_INITIALIZER` para registrar o componente no `ComponentRegistryService` durante o bootstrap do app:
|
|
97
|
+
`ComponentRegistryService` resolves a `controlType` to the Angular component used by the runtime.
|
|
506
98
|
|
|
507
99
|
```ts
|
|
508
|
-
import { ApplicationConfig, ENVIRONMENT_INITIALIZER } from '@angular/core';
|
|
509
100
|
import { ComponentRegistryService } from '@praxisui/dynamic-fields';
|
|
510
101
|
import { FieldControlType } from '@praxisui/core';
|
|
511
102
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
{
|
|
515
|
-
provide: ENVIRONMENT_INITIALIZER,
|
|
516
|
-
multi: true,
|
|
517
|
-
useFactory: (registry: ComponentRegistryService) => () => {
|
|
518
|
-
// "my-custom" será usado como controlType no metadata do formulário
|
|
519
|
-
registry.register('my-custom' as FieldControlType, () =>
|
|
520
|
-
import('./components/my-custom.component').then((m) => m.MyCustomComponent),
|
|
521
|
-
);
|
|
522
|
-
},
|
|
523
|
-
deps: [ComponentRegistryService],
|
|
524
|
-
},
|
|
525
|
-
],
|
|
526
|
-
};
|
|
103
|
+
const inputComponent = await registry.getComponent(FieldControlType.INPUT);
|
|
104
|
+
const registered = registry.isRegistered(FieldControlType.SELECT);
|
|
527
105
|
```
|
|
528
106
|
|
|
529
|
-
|
|
530
|
-
- Metadados: implemente `setInputMetadata(metadata)` ou exponha um signal `metadata` (WritableSignal) e use `.set(metadata)`.
|
|
531
|
-
- FormControl: exponha um signal `formControl` com `.set(control)` ou implemente `setExternalControl(control)`; alternativamente implemente corretamente `ControlValueAccessor` e faça `[formControl]` no template para evitar NG01203.
|
|
532
|
-
- Flags globais (opcional): suporte `[readonlyMode]`, `[disabledMode]`, `[visible]`, `[presentationMode]` para integração com o shell/canvas.
|
|
533
|
-
|
|
534
|
-
### 2) Registrar metadados para título/ícone amigáveis (ComponentMetadataRegistry)
|
|
535
|
-
|
|
536
|
-
Registre `ComponentDocMeta` para que o editor de campos use nome/ícone do seu componente:
|
|
107
|
+
For host-owned custom fields, register both runtime and editorial metadata:
|
|
537
108
|
|
|
538
109
|
```ts
|
|
539
|
-
import {
|
|
110
|
+
import { ENVIRONMENT_INITIALIZER } from '@angular/core';
|
|
540
111
|
import { ComponentDocMeta, ComponentMetadataRegistry } from '@praxisui/core';
|
|
541
|
-
import {
|
|
542
|
-
|
|
543
|
-
const
|
|
544
|
-
id: 'my-custom',
|
|
545
|
-
selector: 'my-custom',
|
|
546
|
-
component:
|
|
547
|
-
friendlyName: '
|
|
548
|
-
description: '
|
|
112
|
+
import { ComponentRegistryService } from '@praxisui/dynamic-fields';
|
|
113
|
+
|
|
114
|
+
const MY_FIELD_META: ComponentDocMeta = {
|
|
115
|
+
id: 'my-custom-field',
|
|
116
|
+
selector: 'app-my-custom-field',
|
|
117
|
+
component: MyCustomFieldComponent,
|
|
118
|
+
friendlyName: 'My custom field',
|
|
119
|
+
description: 'Host-owned field rendered by DynamicFieldLoader.',
|
|
549
120
|
icon: 'bolt',
|
|
550
121
|
lib: 'app-host',
|
|
551
122
|
};
|
|
552
123
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
124
|
+
providers: [
|
|
125
|
+
{
|
|
126
|
+
provide: ENVIRONMENT_INITIALIZER,
|
|
127
|
+
multi: true,
|
|
128
|
+
useFactory: (
|
|
129
|
+
runtime: ComponentRegistryService,
|
|
130
|
+
metadata: ComponentMetadataRegistry,
|
|
131
|
+
) => () => {
|
|
132
|
+
runtime.register('my-custom-field' as never, () =>
|
|
133
|
+
import('./my-custom-field.component').then((m) => m.MyCustomFieldComponent),
|
|
134
|
+
);
|
|
135
|
+
metadata.register(MY_FIELD_META);
|
|
562
136
|
},
|
|
563
|
-
|
|
564
|
-
}
|
|
137
|
+
deps: [ComponentRegistryService, ComponentMetadataRegistry],
|
|
138
|
+
},
|
|
139
|
+
];
|
|
565
140
|
```
|
|
566
141
|
|
|
567
|
-
|
|
568
|
-
- O editor “Configurar campo” compõe o título como `"<Friendly Type> — <Label>"` e resolve o ícone via `ComponentMetadataRegistry`. Se `controlType` do seu campo for igual ao `id` do metadata (ex.: `'my-custom'`), o Dynamic Form usará diretamente os valores do registry.
|
|
142
|
+
Package-owned controls must be added through the library's canonical chain: editorial descriptor, derived metadata, derived catalog, runtime registration, and downstream tooling checks.
|
|
569
143
|
|
|
570
|
-
|
|
144
|
+
## Metadata Boundaries
|
|
571
145
|
|
|
572
|
-
|
|
146
|
+
Dynamic Fields has four related but distinct layers:
|
|
573
147
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
controlType: 'my-custom', // corresponde ao id do metadata e ao registro do runtime
|
|
579
|
-
};
|
|
580
|
-
```
|
|
148
|
+
- runtime rendering through `ComponentRegistryService`
|
|
149
|
+
- form integration through `DynamicFieldLoaderDirective` and Angular forms
|
|
150
|
+
- editorial discovery through `ComponentMetadataRegistry` and package descriptors
|
|
151
|
+
- tooling and AI authoring through catalogs, manifests, and profiles
|
|
581
152
|
|
|
582
|
-
|
|
583
|
-
- Implementa `ControlValueAccessor` ou liga `[formControl]` a um controle nativo (evita NG01203).
|
|
584
|
-
- Suporta `setInputMetadata` ou signal `metadata` com `.set(...)` para hot updates.
|
|
585
|
-
- Opcional: aceita `[readonlyMode]`, `[disabledMode]`, `[visible]`, `[presentationMode]`.
|
|
586
|
-
- O `controlType` do campo coincide com o `id` do `ComponentDocMeta` (para resolver título/ícone no editor).
|
|
153
|
+
Runtime support alone does not prove editor/tooling support. When adding or documenting a control, verify the layer being claimed.
|
|
587
154
|
|
|
588
|
-
|
|
155
|
+
## Value Presentation
|
|
589
156
|
|
|
590
|
-
|
|
157
|
+
Read-only and display states prefer the canonical `field.valuePresentation` contract when available.
|
|
591
158
|
|
|
592
|
-
|
|
159
|
+
Use `valuePresentation` for scalar display values such as currency, number, date, datetime, time, percentage, and boolean. Keep legacy hints such as `format`, `numericFormat`, `currency`, `numberFormat`, and `locale` only as compatibility inputs when needed.
|
|
593
160
|
|
|
594
|
-
|
|
595
|
-
const field: FieldMetadata = {
|
|
596
|
-
name: 'search',
|
|
597
|
-
label: 'Buscar',
|
|
598
|
-
controlType: FieldControlType.INPUT,
|
|
599
|
-
clearButton: {
|
|
600
|
-
enabled: true,
|
|
601
|
-
icon: 'mi:clear',
|
|
602
|
-
iconColor: 'primary', // ou cor CSS (#496ddb, rgb(73,109,219), red)
|
|
603
|
-
tooltip: 'Limpar',
|
|
604
|
-
ariaLabel: 'Limpar busca',
|
|
605
|
-
showOnlyWhenFilled: true,
|
|
606
|
-
},
|
|
607
|
-
};
|
|
608
|
-
```
|
|
161
|
+
## Inline Filters
|
|
609
162
|
|
|
610
|
-
|
|
611
|
-
- `iconColor` aceita tokens de tema (`primary`, `accent`, `warn`) ou cores CSS.
|
|
612
|
-
- Em campos com comportamentos especializados (ex.: currency), o clear também limpa o valor visual.
|
|
613
|
-
- `clearButton` também aceita boolean (`true/false`) por compatibilidade retroativa.
|
|
614
|
-
- No `pdx-color-picker`, o clear é exibido no menu interno, mas aceita `clearButton` como boolean ou objeto (ícone/cor/tooltip).
|
|
163
|
+
The package also exports inline field components for compact filter and toolbar experiences, including inline text, select, async select, entity lookup, numeric, currency, date, date range, time, rating, and specialized business filters.
|
|
615
164
|
|
|
616
|
-
|
|
165
|
+
Inline filter support has its own runtime and discovery contract. Use the official docs and catalog when choosing a compact filter control.
|
|
617
166
|
|
|
618
|
-
|
|
167
|
+
## AI Authoring
|
|
619
168
|
|
|
620
|
-
|
|
621
|
-
- `null` => sem filtro aplicado
|
|
622
|
-
- `{ start: number | null, end: number | null }` => faixa de avaliação
|
|
169
|
+
`PRAXIS_DYNAMIC_FIELDS_AUTHORING_MANIFEST` governs the field-control family. It separates:
|
|
623
170
|
|
|
624
|
-
|
|
171
|
+
- `controlType` registration
|
|
172
|
+
- aliases
|
|
173
|
+
- editorial descriptors
|
|
174
|
+
- selector mappings
|
|
175
|
+
- metadata paths
|
|
176
|
+
- runtime coverage
|
|
177
|
+
- editor/tooling coverage
|
|
625
178
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
179
|
+
Component-level authoring profiles add control-specific hints without duplicating a full manifest per control.
|
|
180
|
+
|
|
181
|
+
## Public API
|
|
182
|
+
|
|
183
|
+
Main exports:
|
|
184
|
+
|
|
185
|
+
- `DynamicFieldLoaderDirective`
|
|
186
|
+
- `ComponentRegistryService`
|
|
187
|
+
- `providePraxisDynamicFields`
|
|
188
|
+
- `providePraxisDynamicFieldsCore`
|
|
189
|
+
- `providePraxisDynamicFieldsNoDefaults`
|
|
190
|
+
- base components such as `SimpleBaseInputComponent`, `SimpleBaseSelectComponent`, `SimpleBaseButtonComponent`
|
|
191
|
+
- Material and inline field components
|
|
192
|
+
- component metadata exports
|
|
193
|
+
- `DYNAMIC_FIELDS_PLAYGROUND_CATALOG`
|
|
194
|
+
- `PRAXIS_DYNAMIC_FIELDS_AUTHORING_MANIFEST`
|
|
195
|
+
- dynamic-field AI capability catalogs and profiles
|
|
196
|
+
- utilities such as JSON schema mapping, clear-button helpers, logging, and error-state matchers
|
|
197
|
+
|
|
198
|
+
## Notes
|
|
641
199
|
|
|
642
|
-
|
|
643
|
-
-
|
|
644
|
-
-
|
|
645
|
-
-
|
|
646
|
-
- Cores das estrelas no popover podem ser definidas por:
|
|
647
|
-
- `ratingToneLowColor`
|
|
648
|
-
- `ratingToneMidColor`
|
|
649
|
-
- `ratingToneHighColor`
|
|
650
|
-
- `ratingBadgeColor`
|
|
200
|
+
- Keep host custom fields explicit: runtime registration and editorial metadata are both required for a complete experience.
|
|
201
|
+
- Do not patch package-owned controls only in a consuming host; fix the canonical registry/editorial chain.
|
|
202
|
+
- Use Material Design 3 tokens from the host theme for surfaces, text, outline, semantic colors, and overlay contrast.
|
|
203
|
+
- Use the official documentation for field catalogs, selection guidance, inline filter contracts, and custom-field troubleshooting.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisui/dynamic-fields",
|
|
3
|
-
"version": "9.0.0-beta.
|
|
3
|
+
"version": "9.0.0-beta.2",
|
|
4
4
|
"description": "Angular Material-based dynamic form fields for Praxis UI with lazy loading and metadata-driven rendering.",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"@angular/common": "^21.0.0",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"@angular/platform-browser": "^21.0.0",
|
|
12
12
|
"@angular/router": "^21.0.0",
|
|
13
13
|
"rxjs": "^7.8.0",
|
|
14
|
-
"@praxisui/core": "^9.0.0-beta.
|
|
15
|
-
"@praxisui/cron-builder": "^9.0.0-beta.
|
|
14
|
+
"@praxisui/core": "^9.0.0-beta.2",
|
|
15
|
+
"@praxisui/cron-builder": "^9.0.0-beta.2"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"libphonenumber-js": "^1.12.41",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"repository": {
|
|
26
26
|
"type": "git",
|
|
27
|
-
"url": "https://github.com/codexrodrigues/praxis-ui-angular"
|
|
27
|
+
"url": "git+https://github.com/codexrodrigues/praxis-ui-angular.git"
|
|
28
28
|
},
|
|
29
29
|
"homepage": "https://praxisui.dev",
|
|
30
30
|
"bugs": {
|