@praxisui/dynamic-fields 9.0.0-beta.90 → 9.0.0-rc.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@praxisui/dynamic-fields",
3
- "version": "9.0.0-beta.90",
3
+ "version": "9.0.0-rc.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.90",
15
- "@praxisui/cron-builder": "^9.0.0-beta.90"
14
+ "@praxisui/core": "^9.0.0-rc.2",
15
+ "@praxisui/cron-builder": "^9.0.0-rc.2"
16
16
  },
17
17
  "dependencies": {
18
18
  "libphonenumber-js": "^1.12.41",
@@ -266,7 +266,7 @@ Em conflito entre alias legado e path canonico, priorizar path canonico e regist
266
266
  ## Detailed API reference
267
267
  ### Preserved technical reference (normalized from previous revision)
268
268
 
269
- `pdx-material-async-select` e um select config-first para catalogos remotos grandes, com busca no painel, carregamento incremental e suporte opcional a cursor. Nao e um select local com fetch pontual; e um runtime metadata-driven para cenarios corporativos de alto volume.
269
+ `pdx-material-async-select` e um controle config-first para catalogos remotos grandes, com combobox pesquisavel, carregamento incremental e suporte opcional a cursor. Nao e um select local com fetch pontual; e um runtime metadata-driven para cenarios corporativos de alto volume.
270
270
 
271
271
  ### Prova em 20 segundos
272
272
 
@@ -276,7 +276,7 @@ Em conflito entre alias legado e path canonico, priorizar path canonico e regist
276
276
  "metadata": {
277
277
  "name": "supplier",
278
278
  "label": "Fornecedor",
279
- "controlType": "select",
279
+ "controlType": "async-select",
280
280
  "resourcePath": "suppliers/options",
281
281
  "optionLabelKey": "label",
282
282
  "optionValueKey": "id",
@@ -285,7 +285,8 @@ Em conflito entre alias legado e path canonico, priorizar path canonico e regist
285
285
  }
286
286
  ```
287
287
 
288
- - O runtime abre o painel com busca e carga progressiva de opcoes.
288
+ - No modo simples pesquisavel, o runtime oferece um unico combobox com busca e
289
+ carga progressiva de opcoes.
289
290
  - O mesmo contrato escala para multi-selecao com `multiple`, `selectAll` e `maxSelections`.
290
291
  - A estrategia de carga pode alternar entre pagina tradicional e cursor sem trocar componente.
291
292
 
@@ -308,7 +309,7 @@ Em conflito entre alias legado e path canonico, priorizar path canonico e regist
308
309
 
309
310
  #### Promessa e limites
310
311
 
311
- **O que isso habilita:** select remoto com busca inline, pagina incremental e alternancia entre fluxo page/cursor.
312
+ **O que isso habilita:** combobox remoto com busca inline, pagina incremental e alternancia entre fluxo page/cursor.
312
313
 
313
314
  **Quando usar:** catálogos remotos grandes com custo de carga alto e necessidade de UX progressiva.
314
315
 
@@ -316,18 +317,28 @@ Em conflito entre alias legado e path canonico, priorizar path canonico e regist
316
317
 
317
318
  Garantias:
318
319
 
319
- - input de busca e carga incremental estao habilitados no painel.
320
+ - `searchable=true` e `multiple=false` materializam um unico combobox: o texto
321
+ pesquisado nunca substitui o valor canonico do `FormControl`.
322
+ - selecionar uma opcao persiste `option.value`; abandonar a pesquisa restaura o
323
+ label da selecao vigente.
320
324
  - `loadOn` controla a primeira carga (`open`, `init`, `none`).
321
325
  - Uma falha na carga inicial nao marca o campo como carregado: com `loadOn='open'`, reabrir o painel tenta novamente; somente uma resposta processada com sucesso conclui a carga inicial.
322
326
  - `useCursor` pode trocar estrategia de pagina quando backend suporta cursor.
323
327
  - Com `resourcePath` e `loadOn='open'`, o painel abre mesmo antes da primeira pagina remota para disparar a carga inicial; a opcao sentinela usada para isso e interna, invisivel e nao compoe contrato visual publico.
324
- - `Carregar mais` so aparece depois de uma primeira pagina remota carregada com sucesso e com proxima pagina disponivel; durante a paginacao permanece visivel, ocupado e desabilitado para evitar requisicoes duplicadas e salto de layout. A acao usa o rodape compartilhado, materializado como irmao do `listbox` no overlay, tem alvo minimo de 44 px, recebe foco por `Tab` a partir da busca e nao participa da semantica de opcoes.
328
+ - no combobox simples pesquisavel, a proxima pagina e carregada
329
+ automaticamente quando o scroll se aproxima do fim da lista; nao existe
330
+ botao interativo dentro do `listbox`.
331
+ - no caminho `MatSelect`, a acao opcional de carregar mais permanece irma
332
+ declarativa do select e fora do overlay.
325
333
  - fontes locais (`selectOptions`/`options`) e `loadOn='none'` antes da primeira carga nao exibem acao de paginacao.
326
334
  - em paginacao numerada, o fim usa `totalPages`/`totalElements` quando fornecidos pelo backend; se ausentes, usa `content.length < pageSize` como fallback.
327
335
 
328
336
  Limites:
329
337
 
330
338
  - debounce de busca interno permanece fixo em `300ms`.
339
+ - selecao multipla permanece no caminho `MatSelect`; um composite multi-select
340
+ pesquisavel exige arquitetura propria de chips/listbox e nao reutiliza o
341
+ combobox simples.
331
342
  - ordenacao nao possui contrato dedicado nesta camada.
332
343
  - `loadOn` e `useCursor` dependem da capacidade do backend e da configuracao global.
333
344
 
@@ -356,6 +367,8 @@ Precedencia de comportamento:
356
367
  #### Checklist corporativo
357
368
 
358
369
  - alinhe backend para pesquisa por termo e include de selecionados.
370
+ - valide que texto digitado, blur sem selecao e resposta remota tardia nao
371
+ contaminam o ID persistido.
359
372
  - retorne `totalPages` e `totalElements` consistentes para evitar chamadas extras de paginacao.
360
373
  - padronize `optionLabelKey`/`optionValueKey` entre dominios.
361
374
  - defina `dependencyLoadOnChange` conforme UX esperada em cascata.
@@ -382,7 +395,7 @@ Precedencia de comportamento:
382
395
 
383
396
  | Caminho JSON | Tipo | Status | Comportamento em runtime |
384
397
  | --- | --- | --- | --- |
385
- | `metadata.controlType` | `'select' \| 'multiSelect'` | Active | Contrato aceito para single/multiple. |
398
+ | `metadata.controlType` | `'async-select'` | Active | Contrato canonico para opcoes remotas single/multiple. |
386
399
  | `metadata.selectOptions` | `Array<{ value; text; label?; disabled? }>` | Active | Fonte principal de opcoes locais. |
387
400
  | `metadata.options` | `Array<any>` | Runtime-extension | Alias legado quando `selectOptions` nao e informado. |
388
401
  | `metadata.multiple` | `boolean` | Active | Define branch single/multiple no template. |
@@ -393,7 +406,7 @@ Precedencia de comportamento:
393
406
  | `metadata.filterCriteria` | `Record<string, any>` | Active | Filtros base para consulta remota. |
394
407
  | `metadata.optionLabelKey` | `string` | Active | Chave de label no payload remoto. |
395
408
  | `metadata.optionValueKey` | `string` | Active | Chave de value no payload remoto. |
396
- | `metadata.searchable` | `boolean` | Partial | Campo existe no contrato, mas busca permanece habilitada neste componente. |
409
+ | `metadata.searchable` | `boolean` | Active | Em single, escolhe entre combobox pesquisavel e `MatSelect`; em multiple, habilita a busca auxiliar do caminho multiplo. |
397
410
  | `metadata.loadOn` | `'open' \| 'init' \| 'none'` | Runtime-extension | Estrategia de primeira carga remota. |
398
411
  | `metadata.dependencyLoadOnChange` | `'respectLoadOn' \| 'immediate' \| 'manual'` | Runtime-extension | Regras de recarga por dependencia. |
399
412
 
@@ -493,7 +506,7 @@ Correcao: use `dependencyLoadOnChange='immediate'` ou dispare recarga no host.
493
506
  "metadata": {
494
507
  "name": "supplier",
495
508
  "label": "Fornecedor",
496
- "controlType": "select",
509
+ "controlType": "async-select",
497
510
  "resourcePath": "suppliers/options",
498
511
  "optionLabelKey": "label",
499
512
  "optionValueKey": "id",
@@ -11,8 +11,8 @@ import * as _angular_material_core from '@angular/material/core';
11
11
  import { MatOptionSelectionChange, ErrorStateMatcher } from '@angular/material/core';
12
12
  import { MatDatepickerInputEvent, MatDateRangePicker, MatDatepicker } from '@angular/material/datepicker';
13
13
  import { ConnectedPosition } from '@angular/cdk/overlay';
14
+ import { MatAutocompleteSelectedEvent, MatAutocompleteTrigger } from '@angular/material/autocomplete';
14
15
  import * as _praxisui_dynamic_fields from '@praxisui/dynamic-fields';
15
- import { MatAutocompleteTrigger } from '@angular/material/autocomplete';
16
16
  import { MatMenuTrigger } from '@angular/material/menu';
17
17
  import { NestedTreeControl } from '@angular/cdk/tree';
18
18
  import { MatTreeNestedDataSource } from '@angular/material/tree';
@@ -2625,6 +2625,7 @@ declare class MaterialSearchableSelectComponent extends SimpleBaseSelectComponen
2625
2625
  loadNextPage(): void;
2626
2626
  showLoadMore(): boolean;
2627
2627
  onPanelSearchKeydown(event: KeyboardEvent): void;
2628
+ panelActionsVisible(): boolean;
2628
2629
  shouldRenderOpenSentinel(): boolean;
2629
2630
  private isLastPage;
2630
2631
  onLoadMoreInteraction(event: Event): void;
@@ -2660,6 +2661,7 @@ declare class InlineSearchableSelectComponent extends MaterialSearchableSelectCo
2660
2661
  onSearchInputEvent(event: Event): void;
2661
2662
  showLoadMore(): boolean;
2662
2663
  onPanelSearchKeydown(event: KeyboardEvent): void;
2664
+ panelActionsVisible(): boolean;
2663
2665
  showEndReachedMessage(): boolean;
2664
2666
  onLoadMoreClick(event: MouseEvent): void;
2665
2667
  placeholderText(): string;
@@ -2712,6 +2714,7 @@ interface AsyncSelectMetadata {
2712
2714
  dependencyLoadOnChange?: DependencyLoadMode;
2713
2715
  }
2714
2716
  declare class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
2717
+ private readonly renderer;
2715
2718
  private lastConfiguredPath?;
2716
2719
  private initialLoadStrategy;
2717
2720
  private hasPerformedInitialLoad;
@@ -2720,12 +2723,17 @@ declare class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
2720
2723
  visible: boolean;
2721
2724
  presentationMode: boolean;
2722
2725
  private searchInput?;
2723
- readonly termControl: FormControl<string | null>;
2726
+ private autocomplete?;
2727
+ readonly termControl: FormControl<unknown>;
2724
2728
  readonly activeLookupFilters: _angular_core.WritableSignal<LookupFilterRequest[]>;
2725
2729
  readonly selectedLookupSortKey: _angular_core.WritableSignal<string | null>;
2726
2730
  protected readonly remoteTotalElements: _angular_core.WritableSignal<number | null>;
2731
+ private readonly queryTerm;
2727
2732
  private readonly store;
2728
2733
  readonly endReached: _angular_core.WritableSignal<boolean>;
2734
+ private queryGeneration;
2735
+ private activeControlValueSubscription;
2736
+ private removeAutocompleteScrollListener;
2729
2737
  private cursorAfter;
2730
2738
  private cursorPageIndex;
2731
2739
  private dataVersion?;
@@ -2737,6 +2745,17 @@ declare class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
2737
2745
  searchInputAriaLabel(): string;
2738
2746
  ngOnInit(): void;
2739
2747
  onOpened(opened: boolean): void;
2748
+ usesSearchCombobox(): boolean;
2749
+ comboboxInputAriaLabel(): string;
2750
+ autocompletePanelClass(): string;
2751
+ readonly displayComboboxOption: (value: unknown) => string;
2752
+ onComboboxFocus(): void;
2753
+ onComboboxBlur(): void;
2754
+ onComboboxOpened(): void;
2755
+ onComboboxClosed(): void;
2756
+ onComboboxOptionSelected(event: MatAutocompleteSelectedEvent): void;
2757
+ onClearClick(): void;
2758
+ panelActionsVisible(): boolean;
2740
2759
  protected hasCompletedInitialLoad(): boolean;
2741
2760
  private getSelectedIds;
2742
2761
  private preloadSelected;
@@ -2757,6 +2776,15 @@ declare class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
2757
2776
  clearLookupFilters(field?: string): void;
2758
2777
  replaceLookupFilters(filters: LookupFilterRequest[]): void;
2759
2778
  protected refreshLookupQueryState(): void;
2779
+ private bindActiveControlValue;
2780
+ protected onActiveControlChanged(previousControl: FormControl, currentControl: FormControl): void;
2781
+ private syncComboboxDisplay;
2782
+ private syncBusinessControlDisabledState;
2783
+ private selectedComboboxOption;
2784
+ private isRenderedOption;
2785
+ private resetSearchSession;
2786
+ private attachAutocompleteScrollListener;
2787
+ private detachAutocompleteScrollListener;
2760
2788
  private runQuery;
2761
2789
  loadMore(): void;
2762
2790
  showLoadMore(): boolean;
@@ -2764,7 +2792,6 @@ declare class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
2764
2792
  private isLastPage;
2765
2793
  onLoadMoreInteraction(event: Event): void;
2766
2794
  retry(): void;
2767
- handleKey(event: KeyboardEvent): void;
2768
2795
  protected registerMatSelect(select: MatSelect): void;
2769
2796
  private refocusSearchInput;
2770
2797
  reload(reset: boolean): void;
@@ -2779,6 +2806,7 @@ declare class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
2779
2806
  protected areOptionValuesEqual(left: unknown, right: unknown): boolean;
2780
2807
  private normalizeRemoteOptionValue;
2781
2808
  protected hasRemoteOptionsContract(): boolean;
2809
+ ngOnDestroy(): void;
2782
2810
  private clearRemoteConfiguration;
2783
2811
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<MaterialAsyncSelectComponent, never>;
2784
2812
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<MaterialAsyncSelectComponent, "pdx-material-async-select", never, { "readonlyMode": { "alias": "readonlyMode"; "required": false; }; "disabledMode": { "alias": "disabledMode"; "required": false; }; "visible": { "alias": "visible"; "required": false; }; "presentationMode": { "alias": "presentationMode"; "required": false; }; }, {}, never, never, true, never>;
@@ -2829,6 +2857,7 @@ declare class InlineAsyncSelectComponent extends MaterialAsyncSelectComponent {
2829
2857
  onSearchInput(term: string): void;
2830
2858
  showLoadMore(): boolean;
2831
2859
  onPanelSearchKeydown(event: KeyboardEvent): void;
2860
+ panelActionsVisible(): boolean;
2832
2861
  showEndReachedMessage(): boolean;
2833
2862
  onLoadMoreClick(event: MouseEvent): void;
2834
2863
  placeholderText(): string;
@@ -2924,6 +2953,10 @@ declare class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
2924
2953
  private lastSelectMetadataSignature;
2925
2954
  private readonly metadataFunctionIds;
2926
2955
  private nextMetadataFunctionId;
2956
+ private readonly inlineSelectPanelClasses;
2957
+ private readonly fullFieldSelectPanelClasses;
2958
+ private placeholderTextCacheSignature;
2959
+ private placeholderTextCache;
2927
2960
  set initialMetadata(metadata: MaterialEntityLookupMetadata | null | undefined);
2928
2961
  private currentMetadata;
2929
2962
  setSelectMetadata(metadata: EntityLookupMetadata): void;
@@ -2936,8 +2969,8 @@ declare class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
2936
2969
  selectPanelClasses(): string[];
2937
2970
  hasSelection(): boolean;
2938
2971
  selectedCount(): number;
2972
+ panelActionsVisible(): boolean;
2939
2973
  displayText(): string;
2940
- private hasPendingLocalSelection;
2941
2974
  richLayoutEnabled(): boolean;
2942
2975
  selectedCardLayout(): boolean;
2943
2976
  selectedCompactLayout(): boolean;
@@ -3014,8 +3047,6 @@ declare class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
3014
3047
  onTriggerIconMouseDown(event: MouseEvent): void;
3015
3048
  onQuickClear(event: MouseEvent): void;
3016
3049
  onOpenedChange(opened: boolean): void;
3017
- onSearchInputEvent(event: Event): void;
3018
- onSearchInputKeydown(event: KeyboardEvent): void;
3019
3050
  onSearchInput(term: string): void;
3020
3051
  showLoadMore(): boolean;
3021
3052
  showEndReachedMessage(): boolean;