@praxisui/dynamic-fields 0.0.1
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/LICENSE +6 -0
- package/README.md +397 -0
- package/fesm2022/praxisui-dynamic-fields-index-C9IUU4lo.mjs +2 -0
- package/fesm2022/praxisui-dynamic-fields-index-C9IUU4lo.mjs.map +1 -0
- package/fesm2022/praxisui-dynamic-fields-index-GJtthzkD.mjs +2 -0
- package/fesm2022/praxisui-dynamic-fields-index-GJtthzkD.mjs.map +1 -0
- package/fesm2022/praxisui-dynamic-fields.mjs +19338 -0
- package/fesm2022/praxisui-dynamic-fields.mjs.map +1 -0
- package/index.d.ts +3399 -0
- package/package.json +44 -0
package/LICENSE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
# @praxis/dynamic-fields — Dynamic Form Fields
|
|
2
|
+
|
|
3
|
+
### Concept Usage
|
|
4
|
+
|
|
5
|
+
- [Dynamic Component Rendering](../../../../docs/concepts/dynamic-component-rendering.md)
|
|
6
|
+
- [Headless UI & Design Systems](../../../../docs/concepts/headless-ui-and-design-systems.md)
|
|
7
|
+
- [Data Driven Forms](../../../../docs/concepts/data-driven-forms.md)
|
|
8
|
+
|
|
9
|
+
Biblioteca de campos dinâmicos para aplicações Angular (v20+) com Material Design. Renderiza campos a partir de metadados, com carregamento lazy e integração com Reactive Forms.
|
|
10
|
+
|
|
11
|
+
## Instalação
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @praxis/dynamic-fields
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Peers (instale no app host):
|
|
18
|
+
- `@angular/core` `^20.1.0`, `@angular/common` `^20.1.0`, `@angular/forms` `^20.1.0`
|
|
19
|
+
- `@angular/material` `^20.1.0`, `@angular/cdk` `^20.1.0`, `@angular/router` `^20.1.0`
|
|
20
|
+
- `rxjs` `^7.8.0`
|
|
21
|
+
- `@praxis/core` `^0.0.1`, `@praxis/specification-core` `^0.0.1`
|
|
22
|
+
- Opcional conforme uso: `@praxis/dialog`, `@praxis/cron-builder`
|
|
23
|
+
|
|
24
|
+
## ✨ Características
|
|
25
|
+
|
|
26
|
+
- **Registro Simplificado**: Sistema de registro de componentes focado no essencial
|
|
27
|
+
- **Lazy Loading**: Carregamento sob demanda com cache inteligente
|
|
28
|
+
- **Material Design**: Componentes baseados no Angular Material
|
|
29
|
+
- **Color Picker**: Novo componente de seleção de cores com suporte a paleta e canvas
|
|
30
|
+
- **Novos Componentes**: Toggle, Slider, Time Picker e Rating
|
|
31
|
+
- **Material Select Modular**: Fragmentado em subcomponentes (SearchInput, OptionsList e Chips)
|
|
32
|
+
- **TypeScript**: Totalmente tipado com integração do `@praxis/core`
|
|
33
|
+
- **Corporativo**: Adequado para cenários empresariais
|
|
34
|
+
|
|
35
|
+
## 🏗️ Arquitetura
|
|
36
|
+
|
|
37
|
+
### Sistema de Registro
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { ComponentRegistryService } from "@praxisui/dynamic-fields";
|
|
41
|
+
import { FieldControlType } from "@praxisui/core";
|
|
42
|
+
|
|
43
|
+
// Obter componente usando constantes
|
|
44
|
+
const component = await registry.getComponent(FieldControlType.INPUT);
|
|
45
|
+
|
|
46
|
+
// Verificar registro
|
|
47
|
+
const isRegistered = registry.isRegistered(FieldControlType.INPUT);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Componentes Suportados
|
|
51
|
+
|
|
52
|
+
O sistema usa as constantes do `@praxis/core` para garantir consistência:
|
|
53
|
+
|
|
54
|
+
- `FieldControlType.INPUT` - Campo de texto Material Design
|
|
55
|
+
- `FieldControlType.TEXTAREA` - Área de texto Material Design
|
|
56
|
+
- `FieldControlType.SELECT` - Campo de seleção Material Design
|
|
57
|
+
- `FieldControlType.CHECKBOX` - Caixa de seleção Material Design
|
|
58
|
+
- `FieldControlType.RADIO` - Botão de rádio Material Design
|
|
59
|
+
- `FieldControlType.DATE_PICKER` - Seletor de data Material Design
|
|
60
|
+
- `FieldControlType.EMAIL_INPUT` - Campo de email
|
|
61
|
+
- `FieldControlType.PASSWORD` - Campo de senha
|
|
62
|
+
- `FieldControlType.CURRENCY_INPUT` - Campo monetário
|
|
63
|
+
- `FieldControlType.NUMERIC_TEXT_BOX` - Campo numérico
|
|
64
|
+
- `FieldControlType.MULTI_SELECT` - Seleção múltipla
|
|
65
|
+
- `FieldControlType.AUTO_COMPLETE` - Auto completar (busca habilitada por padrão)
|
|
66
|
+
- `FieldControlType.DATE_TIME_PICKER` - Data e hora
|
|
67
|
+
- `FieldControlType.DATE_RANGE` - Intervalo de datas
|
|
68
|
+
- `FieldControlType.FILE_UPLOAD` - Upload de arquivos
|
|
69
|
+
- `FieldControlType.TOGGLE` - Interruptor Material Design
|
|
70
|
+
- `FieldControlType.SLIDER` - Slider Material Design
|
|
71
|
+
- `FieldControlType.TIME_PICKER` - Seletor de horário
|
|
72
|
+
- `FieldControlType.RATING` - Classificação por estrelas
|
|
73
|
+
- `FieldControlType.COLOR_PICKER` - Seletor de cores
|
|
74
|
+
|
|
75
|
+
Campos com `FieldControlType.AUTO_COMPLETE` utilizam internamente o `MaterialSearchableSelectComponent`, habilitando busca automaticamente.
|
|
76
|
+
|
|
77
|
+
## 🧩 MaterialSelectComponent
|
|
78
|
+
|
|
79
|
+
O `MaterialSelectComponent` agora está dividido em subcomponentes menores para facilitar manutenção e testes:
|
|
80
|
+
|
|
81
|
+
- **SelectSearchInputComponent** - Campo de busca opcional exibido dentro do painel.
|
|
82
|
+
- **SelectOptionsListComponent** - Lista de opções com suporte a grupos e virtualização.
|
|
83
|
+
- **SelectChipsComponent** - Exibe as opções selecionadas como chips quando `multipleDisplay` é `"chips"`.
|
|
84
|
+
|
|
85
|
+
Esses subcomponentes são utilizados internamente pelo select e não exigem alterações na utilização normal do componente.
|
|
86
|
+
|
|
87
|
+
## 🧩 MaterialCheckboxGroupComponent
|
|
88
|
+
|
|
89
|
+
Renderiza uma lista de checkboxes conectada ao `@angular/forms`, permitindo a seleção de múltiplos valores.
|
|
90
|
+
|
|
91
|
+
- **Select All**: opção para marcar todas as entradas habilitadas.
|
|
92
|
+
- **maxSelections**: limita o número de escolhas possíveis.
|
|
93
|
+
- **Carregamento Remoto**: aceita `resourcePath`, `optionLabelKey` e `optionValueKey` para popular opções via API.
|
|
94
|
+
- **Layout**: suporta `labelPosition` e `color` conforme [documentação do Angular Material](https://material.angular.dev/components/checkbox/overview).
|
|
95
|
+
|
|
96
|
+
## 🧩 MaterialRadioGroupComponent
|
|
97
|
+
|
|
98
|
+
Grupo de botões de rádio que consome metadados ou dados remotos para criar seleções exclusivas.
|
|
99
|
+
|
|
100
|
+
- **Seleção Única**: utiliza `MatRadioGroup` para garantir apenas um valor ativo.
|
|
101
|
+
- **Carregamento Dinâmico**: mesmas chaves de configuração de `MaterialSelectComponent` para buscar opções.
|
|
102
|
+
- **Layout Flexível**: configuração de orientação, `labelPosition` e `color` segundo a [documentação oficial](https://material.angular.dev/components/radio/overview).
|
|
103
|
+
|
|
104
|
+
## 📦 Instalação
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
npm install @praxis/dynamic-fields
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## 🚀 Uso Básico (DynamicFieldLoaderDirective)
|
|
111
|
+
|
|
112
|
+
Exemplo mínimo usando a diretiva `dynamicFieldLoader` para criar campos Material a partir de metadados.
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
import { Component, signal, inject } from '@angular/core';
|
|
116
|
+
import { ReactiveFormsModule, NonNullableFormBuilder, Validators } from '@angular/forms';
|
|
117
|
+
import { DynamicFieldLoaderDirective } from '@praxis/dynamic-fields';
|
|
118
|
+
import { FieldMetadata, FieldControlType } from '@praxis/core';
|
|
119
|
+
|
|
120
|
+
@Component({
|
|
121
|
+
selector: 'app-dynamic-form',
|
|
122
|
+
standalone: true,
|
|
123
|
+
imports: [ReactiveFormsModule, DynamicFieldLoaderDirective],
|
|
124
|
+
template: `
|
|
125
|
+
<form [formGroup]="form">
|
|
126
|
+
<ng-container
|
|
127
|
+
dynamicFieldLoader
|
|
128
|
+
[fields]="fields"
|
|
129
|
+
[formGroup]="form"
|
|
130
|
+
(componentsCreated)="onReady($event)">
|
|
131
|
+
</ng-container>
|
|
132
|
+
</form>
|
|
133
|
+
`,
|
|
134
|
+
})
|
|
135
|
+
export class DynamicFormComponent {
|
|
136
|
+
private readonly fb = inject(NonNullableFormBuilder);
|
|
137
|
+
|
|
138
|
+
form = this.fb.group({
|
|
139
|
+
fullName: this.fb.control('', { validators: [Validators.required] }),
|
|
140
|
+
category: this.fb.control(null),
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
fields: FieldMetadata[] = [
|
|
144
|
+
{
|
|
145
|
+
name: 'fullName',
|
|
146
|
+
label: 'Nome',
|
|
147
|
+
controlType: FieldControlType.INPUT,
|
|
148
|
+
placeholder: 'Seu nome completo',
|
|
149
|
+
required: true,
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: 'category',
|
|
153
|
+
label: 'Categoria',
|
|
154
|
+
controlType: FieldControlType.SELECT,
|
|
155
|
+
options: [
|
|
156
|
+
{ label: 'A', value: 'A' },
|
|
157
|
+
{ label: 'B', value: 'B' },
|
|
158
|
+
],
|
|
159
|
+
multiple: false,
|
|
160
|
+
searchable: true,
|
|
161
|
+
},
|
|
162
|
+
];
|
|
163
|
+
|
|
164
|
+
onReady(map: Map<string, any>) {
|
|
165
|
+
// Recebe referências dos componentes criados (opcional)
|
|
166
|
+
console.log('components', Array.from(map.keys()));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Template-only:
|
|
172
|
+
|
|
173
|
+
```html
|
|
174
|
+
<ng-container dynamicFieldLoader [fields]="fields" [formGroup]="form"></ng-container>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
import { ComponentRegistryService } from "@praxis/dynamic-fields";
|
|
179
|
+
import { FieldControlType } from "@praxisui/core";
|
|
180
|
+
|
|
181
|
+
@Component({
|
|
182
|
+
selector: "app-dynamic-form",
|
|
183
|
+
template: `<ng-container #dynamicContainer></ng-container>`,
|
|
184
|
+
})
|
|
185
|
+
export class DynamicFormComponent {
|
|
186
|
+
@ViewChild("dynamicContainer", { read: ViewContainerRef })
|
|
187
|
+
container!: ViewContainerRef;
|
|
188
|
+
|
|
189
|
+
constructor(private registry: ComponentRegistryService) {}
|
|
190
|
+
|
|
191
|
+
async loadField(type: FieldControlType) {
|
|
192
|
+
const component = await this.registry.getComponent(type);
|
|
193
|
+
if (component) {
|
|
194
|
+
this.container.createComponent(component);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Exemplo prático
|
|
199
|
+
async loadInputField() {
|
|
200
|
+
await this.loadField(FieldControlType.INPUT);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async loadDatePicker() {
|
|
204
|
+
await this.loadField(FieldControlType.DATE_PICKER);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
async loadColorPicker() {
|
|
208
|
+
await this.loadField(FieldControlType.COLOR_PICKER);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## 🔧 Registrar Componente Customizado
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
import { FieldControlType } from "@praxis/core";
|
|
217
|
+
|
|
218
|
+
// Registrar componente customizado - SUPER SIMPLES!
|
|
219
|
+
registry.register("customField" as FieldControlType, () => import("./custom-field.component").then((m) => m.CustomFieldComponent));
|
|
220
|
+
|
|
221
|
+
// Uso posterior
|
|
222
|
+
const customComponent = await registry.getComponent("customField" as FieldControlType);
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## 📊 Estatísticas
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
const stats = registry.getStats();
|
|
229
|
+
console.log(stats);
|
|
230
|
+
// {
|
|
231
|
+
// registeredComponents: 7,
|
|
232
|
+
// cachedComponents: 3,
|
|
233
|
+
// registeredTypes: ['input', 'select', ...]
|
|
234
|
+
// }
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## 🛠️ API (Pontos de Entrada)
|
|
238
|
+
|
|
239
|
+
Exportados principais:
|
|
240
|
+
- Diretivas: `DynamicFieldLoaderDirective`
|
|
241
|
+
- Serviços: `ComponentRegistryService`
|
|
242
|
+
- Base: `SimpleBaseInputComponent`, `SimpleBaseSelectComponent`, `SimpleBaseButtonComponent`
|
|
243
|
+
- Componentes Material (exemplos): `MaterialSelectComponent`, `MaterialRadioGroupComponent`, `MaterialCheckboxGroupComponent`, `MaterialDatepickerComponent`, `MaterialSliderComponent`, `MaterialTimepickerComponent`, `MaterialTextareaComponent`, `MaterialAutocompleteComponent`, `MaterialChipsComponent`, `MaterialButtonComponent`, `MaterialFileUploadComponent`
|
|
244
|
+
|
|
245
|
+
Referencie `src/public-api.ts` do pacote para a lista completa de símbolos exportados.
|
|
246
|
+
|
|
247
|
+
### ComponentRegistryService
|
|
248
|
+
|
|
249
|
+
#### Métodos Principais
|
|
250
|
+
|
|
251
|
+
- `register<T>(type, factory)` - Registra componente (ultra-simples!)
|
|
252
|
+
- `getComponent<T>(type)` - Obtém componente (async)
|
|
253
|
+
- `isRegistered(type)` - Verifica se está registrado
|
|
254
|
+
- `getRegisteredTypes()` - Lista tipos registrados
|
|
255
|
+
|
|
256
|
+
#### Métodos Utilitários
|
|
257
|
+
|
|
258
|
+
- `getStats()` - Estatísticas do registro
|
|
259
|
+
- `clearCache(type?)` - Limpa cache
|
|
260
|
+
- `unregister(type)` - Remove componente
|
|
261
|
+
- `preload(types[])` - Pré-carrega componentes
|
|
262
|
+
|
|
263
|
+
### Interfaces
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
interface RegistryStats {
|
|
267
|
+
registeredComponents: number;
|
|
268
|
+
cachedComponents: number;
|
|
269
|
+
registeredTypes: FieldControlType[];
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
interface ComponentRegistration {
|
|
273
|
+
factory: () => Promise<Type<any>>;
|
|
274
|
+
cached?: Type<any>;
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## 🎯 Integração com @praxisui/core
|
|
279
|
+
|
|
280
|
+
Esta biblioteca usa os tipos e metadados do `@praxisui/core`:
|
|
281
|
+
|
|
282
|
+
- `FieldControlType` - Tipos de controle unificados
|
|
283
|
+
- `UnifiedFieldMetadata` - Sistema de metadados corporativo
|
|
284
|
+
- `MaterialInputMetadata`, `MaterialSelectMetadata`, etc. - Metadados específicos
|
|
285
|
+
|
|
286
|
+
## 📋 Desenvolvimento
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
# Build da biblioteca
|
|
290
|
+
ng build praxis-dynamic-fields
|
|
291
|
+
|
|
292
|
+
# Testes
|
|
293
|
+
ng test praxis-dynamic-fields
|
|
294
|
+
|
|
295
|
+
# Lint
|
|
296
|
+
ng lint praxis-dynamic-fields
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## 🏷️ Versão
|
|
300
|
+
|
|
301
|
+
**Versão atual**: Sistema simplificado pós-refatoração
|
|
302
|
+
**Dependências**: `@praxisui/core`, `@angular/material`
|
|
303
|
+
**Angular**: 20+
|
|
304
|
+
**TypeScript**: 5.8+
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
_Sistema desenvolvido seguindo diretrizes de simplicidade e foco no essencial._
|
|
309
|
+
|
|
310
|
+
## 🔌 Extensão pelo App Host (registrando seu próprio componente)
|
|
311
|
+
|
|
312
|
+
Aplicações host podem registrar componentes próprios para uso no DynamicFieldLoader e expor metadados para título/ícone amigáveis no editor.
|
|
313
|
+
|
|
314
|
+
### 1) Registrar o componente no runtime (DynamicFieldLoader)
|
|
315
|
+
|
|
316
|
+
Use `ENVIRONMENT_INITIALIZER` para registrar o componente no `ComponentRegistryService` durante o bootstrap do app:
|
|
317
|
+
|
|
318
|
+
```ts
|
|
319
|
+
import { ApplicationConfig, ENVIRONMENT_INITIALIZER } from '@angular/core';
|
|
320
|
+
import { ComponentRegistryService } from '@praxisui/dynamic-fields';
|
|
321
|
+
import { FieldControlType } from '@praxisui/core';
|
|
322
|
+
|
|
323
|
+
export const appConfig: ApplicationConfig = {
|
|
324
|
+
providers: [
|
|
325
|
+
{
|
|
326
|
+
provide: ENVIRONMENT_INITIALIZER,
|
|
327
|
+
multi: true,
|
|
328
|
+
useFactory: (registry: ComponentRegistryService) => () => {
|
|
329
|
+
// "my-custom" será usado como controlType no metadata do formulário
|
|
330
|
+
registry.register('my-custom' as FieldControlType, () =>
|
|
331
|
+
import('./components/my-custom.component').then((m) => m.MyCustomComponent),
|
|
332
|
+
);
|
|
333
|
+
},
|
|
334
|
+
deps: [ComponentRegistryService],
|
|
335
|
+
},
|
|
336
|
+
],
|
|
337
|
+
};
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Observações de integração com o DynamicFieldLoader:
|
|
341
|
+
- Metadados: implemente `setInputMetadata(metadata)` ou exponha um signal `metadata` (WritableSignal) e use `.set(metadata)`.
|
|
342
|
+
- 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.
|
|
343
|
+
- Flags globais (opcional): suporte `[readonlyMode]`, `[disabledMode]`, `[visible]`, `[presentationMode]` para integração com o shell/canvas.
|
|
344
|
+
|
|
345
|
+
### 2) Registrar metadados para título/ícone amigáveis (ComponentMetadataRegistry)
|
|
346
|
+
|
|
347
|
+
Registre `ComponentDocMeta` para que o editor de campos use nome/ícone do seu componente:
|
|
348
|
+
|
|
349
|
+
```ts
|
|
350
|
+
import { ApplicationConfig, ENVIRONMENT_INITIALIZER } from '@angular/core';
|
|
351
|
+
import { ComponentDocMeta, ComponentMetadataRegistry } from '@praxisui/core';
|
|
352
|
+
import { MyCustomComponent } from './components/my-custom.component';
|
|
353
|
+
|
|
354
|
+
const MY_CUSTOM_METADATA: ComponentDocMeta = {
|
|
355
|
+
id: 'my-custom',
|
|
356
|
+
selector: 'my-custom',
|
|
357
|
+
component: MyCustomComponent,
|
|
358
|
+
friendlyName: 'Meu Componente',
|
|
359
|
+
description: 'Componente custom do app host',
|
|
360
|
+
icon: 'bolt',
|
|
361
|
+
lib: 'app-host',
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
export const appConfig: ApplicationConfig = {
|
|
365
|
+
providers: [
|
|
366
|
+
{
|
|
367
|
+
provide: ENVIRONMENT_INITIALIZER,
|
|
368
|
+
multi: true,
|
|
369
|
+
useFactory: (registry: ComponentMetadataRegistry) => () => {
|
|
370
|
+
registry.register(MY_CUSTOM_METADATA);
|
|
371
|
+
},
|
|
372
|
+
deps: [ComponentMetadataRegistry],
|
|
373
|
+
},
|
|
374
|
+
],
|
|
375
|
+
};
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Por que isso importa?
|
|
379
|
+
- 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.
|
|
380
|
+
|
|
381
|
+
### 3) Usar no formulário dinâmico
|
|
382
|
+
|
|
383
|
+
Defina o `controlType` do campo como o id registrado:
|
|
384
|
+
|
|
385
|
+
```ts
|
|
386
|
+
const field: FieldMetadata = {
|
|
387
|
+
name: 'customField',
|
|
388
|
+
label: 'Meu Campo',
|
|
389
|
+
controlType: 'my-custom', // corresponde ao id do metadata e ao registro do runtime
|
|
390
|
+
};
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
### ✅ Checklist de Compatibilidade
|
|
394
|
+
- Implementa `ControlValueAccessor` ou liga `[formControl]` a um controle nativo (evita NG01203).
|
|
395
|
+
- Suporta `setInputMetadata` ou signal `metadata` com `.set(...)` para hot updates.
|
|
396
|
+
- Opcional: aceita `[readonlyMode]`, `[disabledMode]`, `[visible]`, `[presentationMode]`.
|
|
397
|
+
- O `controlType` do campo coincide com o `id` do `ComponentDocMeta` (para resolver título/ícone no editor).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"praxisui-dynamic-fields-index-C9IUU4lo.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"praxisui-dynamic-fields-index-GJtthzkD.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|