@praxisui/dynamic-fields 8.0.0-beta.27 → 8.0.0-beta.29

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/index.d.ts CHANGED
@@ -400,6 +400,10 @@ interface PraxisDynamicFieldsI18nOverrides {
400
400
  };
401
401
  multiSelect?: {
402
402
  selectAllLabel?: PraxisDynamicFieldText;
403
+ selectedTokensAriaLabel?: PraxisDynamicFieldText;
404
+ removeSelectionAriaLabel?: PraxisDynamicFieldText;
405
+ selectedPanelTitle?: PraxisDynamicFieldText;
406
+ selectedPanelRemoveHint?: PraxisDynamicFieldText;
403
407
  };
404
408
  transferList?: {
405
409
  availableLabel?: PraxisDynamicFieldText;
@@ -1454,6 +1458,11 @@ declare class DynamicFieldLoaderDirective implements OnInit, OnDestroy, OnChange
1454
1458
  field: FieldMetadata;
1455
1459
  element: HTMLElement;
1456
1460
  }>;
1461
+ /** @internal Emits when a field receives focus in canvas mode */
1462
+ canvasFocus: EventEmitter<{
1463
+ field: FieldMetadata;
1464
+ element: HTMLElement;
1465
+ }>;
1457
1466
  /** Mapa interno de componentes criados */
1458
1467
  private componentRefs;
1459
1468
  /** Mapa de shells criados */
@@ -1584,7 +1593,7 @@ declare class DynamicFieldLoaderDirective implements OnInit, OnDestroy, OnChange
1584
1593
  */
1585
1594
  private inferControlTypeFromField;
1586
1595
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<DynamicFieldLoaderDirective, never>;
1587
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DynamicFieldLoaderDirective, "[dynamicFieldLoader]", never, { "fields": { "alias": "fields"; "required": true; }; "formGroup": { "alias": "formGroup"; "required": true; }; "enableExternalControlBinding": { "alias": "enableExternalControlBinding"; "required": false; }; "itemTemplate": { "alias": "itemTemplate"; "required": false; }; "debugTrace": { "alias": "debugTrace"; "required": false; }; "debugTraceLabel": { "alias": "debugTraceLabel"; "required": false; }; "readonlyMode": { "alias": "readonlyMode"; "required": false; }; "disabledMode": { "alias": "disabledMode"; "required": false; }; "presentationMode": { "alias": "presentationMode"; "required": false; }; "visible": { "alias": "visible"; "required": false; }; "canvasMode": { "alias": "canvasMode"; "required": false; }; }, { "componentsCreated": "componentsCreated"; "fieldCreated": "fieldCreated"; "fieldDestroyed": "fieldDestroyed"; "renderError": "renderError"; "canvasMouseEnter": "canvasMouseEnter"; "canvasMouseLeave": "canvasMouseLeave"; "canvasClick": "canvasClick"; }, never, never, true, never>;
1596
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DynamicFieldLoaderDirective, "[dynamicFieldLoader]", never, { "fields": { "alias": "fields"; "required": true; }; "formGroup": { "alias": "formGroup"; "required": true; }; "enableExternalControlBinding": { "alias": "enableExternalControlBinding"; "required": false; }; "itemTemplate": { "alias": "itemTemplate"; "required": false; }; "debugTrace": { "alias": "debugTrace"; "required": false; }; "debugTraceLabel": { "alias": "debugTraceLabel"; "required": false; }; "readonlyMode": { "alias": "readonlyMode"; "required": false; }; "disabledMode": { "alias": "disabledMode"; "required": false; }; "presentationMode": { "alias": "presentationMode"; "required": false; }; "visible": { "alias": "visible"; "required": false; }; "canvasMode": { "alias": "canvasMode"; "required": false; }; }, { "componentsCreated": "componentsCreated"; "fieldCreated": "fieldCreated"; "fieldDestroyed": "fieldDestroyed"; "renderError": "renderError"; "canvasMouseEnter": "canvasMouseEnter"; "canvasMouseLeave": "canvasMouseLeave"; "canvasClick": "canvasClick"; "canvasFocus": "canvasFocus"; }, never, never, true, never>;
1588
1597
  }
1589
1598
 
1590
1599
  declare class MaterialButtonComponent extends SimpleBaseButtonComponent implements OnDestroy {
@@ -2543,6 +2552,7 @@ declare class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
2543
2552
  readonly termControl: FormControl<string | null>;
2544
2553
  readonly activeLookupFilters: _angular_core.WritableSignal<LookupFilterRequest[]>;
2545
2554
  readonly selectedLookupSortKey: _angular_core.WritableSignal<string | null>;
2555
+ protected readonly remoteTotalElements: _angular_core.WritableSignal<number | null>;
2546
2556
  private readonly store;
2547
2557
  readonly endReached: _angular_core.WritableSignal<boolean>;
2548
2558
  private cursorAfter;
@@ -2676,6 +2686,15 @@ interface EntityLookupViewModel {
2676
2686
  detailHref: string;
2677
2687
  detailRoute: string;
2678
2688
  badges: string[];
2689
+ richFields: EntityLookupRichFieldViewModel[];
2690
+ }
2691
+ interface EntityLookupRichFieldViewModel {
2692
+ key: string;
2693
+ label: string;
2694
+ value: string;
2695
+ icon: string;
2696
+ presentation: string;
2697
+ tone: LookupStatusTone | 'info';
2679
2698
  }
2680
2699
  interface LookupClearButtonConfig {
2681
2700
  enabled?: boolean;
@@ -2715,6 +2734,9 @@ type EntityLookupMetadata = MaterialEntityLookupMetadata & {
2715
2734
  };
2716
2735
  declare class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
2717
2736
  private readonly dialog;
2737
+ private readonly globalActions;
2738
+ private readonly resourceDiscovery;
2739
+ private readonly surfaceOpenAdapter;
2718
2740
  inlineMinWidthPx: number;
2719
2741
  inlineMaxWidthPx: number;
2720
2742
  private fieldLabelText;
@@ -2727,11 +2749,13 @@ declare class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
2727
2749
  onViewportResize(): void;
2728
2750
  errorStateMatcher(): _angular_material_error_options_d_CGdTZUYk.E;
2729
2751
  protected getSpecificCssClasses(): string[];
2752
+ selectPanelClasses(): string[];
2730
2753
  hasSelection(): boolean;
2731
2754
  selectedCount(): number;
2732
2755
  displayText(): string;
2733
2756
  richLayoutEnabled(): boolean;
2734
2757
  selectedCardLayout(): boolean;
2758
+ selectedCompactLayout(): boolean;
2735
2759
  fullFieldLayout(): boolean;
2736
2760
  showFieldDependencyHint(): boolean;
2737
2761
  showFieldSearchHint(): boolean;
@@ -2742,6 +2766,7 @@ declare class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
2742
2766
  selectedLookupViews(): EntityLookupViewModel[];
2743
2767
  visibleSelectedLookupTokens(): SelectedLookupTokenViewModel[];
2744
2768
  hiddenSelectedLookupTokenCount(): number;
2769
+ isSelected(option: LookupOption): boolean;
2745
2770
  showSelectedTokenRemove(): boolean;
2746
2771
  selectedTokenRemoveAriaLabel(text: string): string;
2747
2772
  onRemoveSelectedToken(event: MouseEvent, identity: string): void;
@@ -2759,6 +2784,7 @@ declare class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
2759
2784
  statusBadgeClass(item: EntityLookupViewModel): string;
2760
2785
  lookupInitials(item: EntityLookupViewModel): string;
2761
2786
  showDetailAction(item: EntityLookupViewModel): boolean;
2787
+ private hasGovernedDetailSurface;
2762
2788
  showChangeAction(): boolean;
2763
2789
  showCopyCodeAction(item: EntityLookupViewModel): boolean;
2764
2790
  showCopyIdAction(item: EntityLookupViewModel): boolean;
@@ -2771,6 +2797,12 @@ declare class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
2771
2797
  clearActionText(): string;
2772
2798
  selectionLimitReachedText(maxSelections: number | null | undefined): string;
2773
2799
  onDetailAction(event: MouseEvent, item: EntityLookupViewModel): void;
2800
+ private openDetailSurface;
2801
+ private tryOpenGovernedDetailSurface;
2802
+ private itemSurfacesHref;
2803
+ private selectDetailSurface;
2804
+ private lookupDetailPresentation;
2805
+ private detailSurfaceTitle;
2774
2806
  onChangeAction(event: MouseEvent): void;
2775
2807
  onCopyCodeAction(event: MouseEvent, item: EntityLookupViewModel): void;
2776
2808
  onCopyIdAction(event: MouseEvent, item: EntityLookupViewModel): void;
@@ -2865,6 +2897,12 @@ declare class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
2865
2897
  private lookupStatusKeys;
2866
2898
  private resolveLookupSelectable;
2867
2899
  private lookupBadges;
2900
+ richFieldToneClass(field: EntityLookupRichFieldViewModel): string;
2901
+ private lookupRichFields;
2902
+ private lookupRichFieldFromDescriptor;
2903
+ private asRichFieldArray;
2904
+ private formatLookupRichFieldValue;
2905
+ private normalizeLookupTone;
2868
2906
  private classifyLookupSelectionState;
2869
2907
  private resolveStatusTone;
2870
2908
  private lookupSeparator;
@@ -2876,6 +2914,11 @@ declare class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
2876
2914
  private uniqueLookupKeys;
2877
2915
  private equalsOptionValue;
2878
2916
  private resolveLookupIdentity;
2917
+ displayPreset(): string;
2918
+ private displayDensity;
2919
+ private lookupDisplayConfig;
2920
+ private lookupDisplayBoolean;
2921
+ private readLookupPath;
2879
2922
  private isPrimitiveLookupValue;
2880
2923
  private asRecord;
2881
2924
  private lookupOptionSource;
@@ -3018,6 +3061,12 @@ declare class EntityLookupDialogComponent implements AfterViewInit {
3018
3061
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<EntityLookupDialogComponent, "pdx-entity-lookup-dialog", never, {}, {}, never, never, true, never>;
3019
3062
  }
3020
3063
 
3064
+ interface InlineMultiSelectTokenViewModel {
3065
+ value: unknown;
3066
+ text: string;
3067
+ title: string;
3068
+ trackKey: string;
3069
+ }
3021
3070
  declare class InlineMultiSelectComponent extends SimpleBaseSelectComponent {
3022
3071
  readonlyMode: boolean;
3023
3072
  disabledMode: boolean;
@@ -3037,9 +3086,18 @@ declare class InlineMultiSelectComponent extends SimpleBaseSelectComponent {
3037
3086
  hasSelection(): boolean;
3038
3087
  selectedCount(): number;
3039
3088
  displayText(): string;
3089
+ selectedTokens(): InlineMultiSelectTokenViewModel[];
3090
+ visibleSelectedTokens(): InlineMultiSelectTokenViewModel[];
3091
+ hiddenSelectedTokenCount(): number;
3092
+ hiddenSelectedTokenTitle(): string;
3093
+ selectedTokensAriaLabel(): string;
3094
+ selectedTokenRemoveAriaLabel(text: string): string;
3095
+ selectedPanelTitle(): string;
3096
+ selectedPanelRemoveHint(): string;
3040
3097
  showQuickClear(): boolean;
3041
3098
  onTriggerIconMouseDown(event: MouseEvent): void;
3042
3099
  onQuickClear(event: MouseEvent): void;
3100
+ onRemoveSelectedToken(event: MouseEvent, value: unknown): void;
3043
3101
  onOpenedChange(opened: boolean): void;
3044
3102
  onSearchInput(term: string): void;
3045
3103
  onSearchInputEvent(event: Event): void;
@@ -3051,6 +3109,8 @@ declare class InlineMultiSelectComponent extends SimpleBaseSelectComponent {
3051
3109
  private currentValues;
3052
3110
  private resolveOptionLabel;
3053
3111
  private equalsOptionValue;
3112
+ private maxVisibleSelectedTokens;
3113
+ private stringifyTokenValue;
3054
3114
  private resolveFieldLabelFromMetadata;
3055
3115
  private humanizeFieldName;
3056
3116
  private recalculateInlineSizeBounds;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@praxisui/dynamic-fields",
3
- "version": "8.0.0-beta.27",
3
+ "version": "8.0.0-beta.29",
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": "^20.1.0",
@@ -11,8 +11,8 @@
11
11
  "@angular/platform-browser": "^20.1.0",
12
12
  "@angular/router": "^20.1.0",
13
13
  "rxjs": "^7.8.0",
14
- "@praxisui/core": "^8.0.0-beta.27",
15
- "@praxisui/cron-builder": "^8.0.0-beta.27"
14
+ "@praxisui/core": "^8.0.0-beta.29",
15
+ "@praxisui/cron-builder": "^8.0.0-beta.29"
16
16
  },
17
17
  "dependencies": {
18
18
  "libphonenumber-js": "^1.12.41",
@@ -22,8 +22,8 @@ source_of_truth:
22
22
  - "projects/praxis-dynamic-fields/src/lib/utils/field-state.util.ts"
23
23
  - "projects/praxis-dynamic-fields/src/lib/utils/format-display.util.ts"
24
24
  - "projects/praxis-core/src/lib/models/component-metadata.interface.ts"
25
- source_of_truth_last_verified: "2026-03-06"
26
- last_updated: "2026-03-06"
25
+ source_of_truth_last_verified: "2026-05-18"
26
+ last_updated: "2026-05-18"
27
27
  toc: true
28
28
  sidebar: true
29
29
  tags:
@@ -175,6 +175,7 @@ Nao ha paths experimentais confirmados no contrato publico desta revisao.
175
175
  | `canvasMouseEnter` | unknown | runtime-event | Experimental | Validate payload shape against source_of_truth. |
176
176
  | `canvasMouseLeave` | unknown | runtime-event | Experimental | Validate payload shape against source_of_truth. |
177
177
  | `canvasClick` | unknown | runtime-event | Experimental | Validate payload shape against source_of_truth. |
178
+ | `canvasFocus` | unknown | focusin runtime-event | Experimental | Emitted when a projected field receives focus in canvas mode so `praxis-dynamic-form` can select the field and show the canonical canvas toolbar. |
178
179
 
179
180
  ### External side channels
180
181
 
@@ -197,7 +198,7 @@ Nao ha paths experimentais confirmados no contrato publico desta revisao.
197
198
 
198
199
  | Surface | Verified | Coverage status | Evidence | Notes |
199
200
  | --- | --- | --- | --- | --- |
200
- | Runtime | `true` | Active | `projects/praxis-dynamic-fields/src/lib/components/field-shell/field-shell.component.ts`, `projects/praxis-dynamic-fields/src/lib/utils/field-state.util.ts` | Core runtime flows verified via focused component specs on 2026-03-06; editor/tooling coverage remains independent. |
201
+ | Runtime | `true` | Active | `projects/praxis-dynamic-fields/src/lib/components/field-shell/field-shell.component.ts`, `projects/praxis-dynamic-fields/src/lib/utils/field-state.util.ts` | Core runtime flows verified via focused component specs on 2026-05-18, including canvas focus selection; editor/tooling coverage remains independent. |
201
202
  | Schema/Types | `true` | Active | source_of_truth + Detailed API reference | Reconcile schema/types with canonical paths during follow-up when needed. |
202
203
  | Editor/Tooling | `false` | Not-covered | `projects/praxis-core/src/lib/metadata/field-selector-control-type.constants.ts`, `projects/praxis-core/src/lib/utils/inline-filter-controls.util.ts` | `praxis-field-shell` nao aparece no selector map default nem no alias map inline; cobertura de editor/tooling permanece nao confirmada. |
203
204
 
@@ -121,6 +121,13 @@ Este documento e a referencia canonica da API JSON de pdx-inline-entity-lookup.
121
121
  | `metadata.optionSource.codePropertyPath` | string | false | n/a | Active | Campo canonico de codigo curto exibido antes do label. |
122
122
  | `metadata.optionSource.descriptionPropertyPaths` | string[] | false | n/a | Active | Campos concatenados na linha secundaria do lookup. |
123
123
  | `metadata.optionSource.statusPropertyPath` | string | false | n/a | Active | Campo canonico de status exibido na linha secundaria. |
124
+ | `metadata.optionSource.display` | object | false | n/a | Active | Intencao canonica de UX para a entidade referenciada. |
125
+ | `metadata.optionSource.display.preset` | string | false | `rich` para formulario, `compact` para inline | Active | Preset semantico: `compact`, `rich`, `directory`, `status`, `reference` ou `hierarchical`. |
126
+ | `metadata.optionSource.display.usage` | string | false | n/a | Active | Contexto preferencial de uso: `form`, `filter`, `table-cell`, `dashboard`, `wizard` ou `review`. |
127
+ | `metadata.optionSource.display.density` | string | false | n/a | Active | Densidade preferencial: `compact`, `comfortable` ou `rich`. |
128
+ | `metadata.optionSource.display.secondaryPropertyPaths` | string[] | false | n/a | Active | Campos de subtitulo usados para diferenciar entidades parecidas. |
129
+ | `metadata.optionSource.display.fields` | object[] | false | n/a | Active | Campos ricos semanticos exibidos na lista e no valor selecionado. Cada item aceita `key`, `propertyPath`, `label`, `icon`, `presentation`, `tone` e `format`. |
130
+ | `metadata.optionSource.display.badgePropertyPaths` | string[] | false | n/a | Active | Campos publicados como badges/chips quando o backend tambem os materializa no payload de option. |
124
131
 
125
132
  ### Path audit
126
133
 
@@ -159,6 +166,7 @@ Nao ha paths experimentais confirmados no contrato publico desta revisao.
159
166
  | `metadata.optionValueKey` | string | false | n/a | component-defined | Partial; verify per source_of_truth. |
160
167
  | `metadata.optionLabelKey` | string | false | n/a | component-defined | Partial; verify per source_of_truth. |
161
168
  | `metadata.optionSource` | object | false | n/a | `RESOURCE_ENTITY` recomendado para entidades de negocio | Fonte canonica para resourcePath, identidade, label, codigo, descricao, status e detalhe. |
169
+ | `metadata.optionSource.display` | object | false | n/a | contrato semantico de UX, nao CSS | Governanca de preset, uso, densidade, campos ricos, secundarios e badges do resultado. |
162
170
  | `metadata.resourcePath` | string | false | n/a | component-defined | Partial; verify per source_of_truth. |
163
171
  | `metadata.inlineAutoSize.*` | object | false | n/a | component-defined | Partial; verify per source_of_truth. |
164
172
  | `metadata.searchable` | boolean | false | n/a | component-defined | Partial; verify per source_of_truth. |
@@ -312,10 +320,20 @@ Use quando precisar:
312
320
  | `metadata.optionSource.codePropertyPath` | `string` | Ativo | Resolve codigo curto exibido como parte primaria do lookup. |
313
321
  | `metadata.optionSource.descriptionPropertyPaths` | `string[]` | Ativo | Resolve descricao rica concatenando campos de dominio na linha secundaria. |
314
322
  | `metadata.optionSource.statusPropertyPath` | `string` | Ativo | Resolve status exibido depois da descricao. |
315
- | `metadata.optionSource.detail.hrefTemplate` / `metadata.optionSource.detail.routeTemplate` | `string` | Ativo | Gera links/rotas de detalhe quando o payload remoto nao trouxer `detailHref`/`detailRoute` em `extra`. |
323
+ | `metadata.optionSource.detail.kind` | `"surface" | "route" | "href"` | Ativo | `surface` e o contrato canonico para detalhe de entidade: o runtime descobre `/{resource}/{id}/surfaces` e abre a surface por `GlobalActionService`/`surface.open`. `route`/`href` ficam como fallback legado. |
324
+ | `metadata.optionSource.detail.surfaceId` | `string` | Ativo | Id da surface item-level preferida para o detalhe. Quando ausente, o runtime escolhe `detail`, `view` ou a primeira surface item-level de leitura disponivel. |
325
+ | `metadata.optionSource.detail.presentation` | `"drawer" | "modal"` | Ativo | Apresentacao desejada para `surface.open`. Default vem do preset/host de surface. |
326
+ | `metadata.optionSource.detail.preferredWidget` / `metadata.optionSource.detail.mode` | `string` | Documental | Hints semanticos para autoria/discovery. A materializacao final vem da surface descoberta e do `ResourceSurfaceOpenAdapterService`. |
327
+ | `metadata.optionSource.detail.hrefTemplate` / `metadata.optionSource.detail.routeTemplate` | `string` | Legado | Fallback para abrir detalhe por link quando nao houver contrato de surface ou servico global disponivel. Nao deve ser a fonte primaria em novos lookups de plataforma. |
328
+ | `metadata.optionSource.display.preset` | `"compact" | "rich" | "directory" | "status" | "reference" | "hierarchical"` | Ativo | Define a intencao visual canonica. `directory` e recomendado para pessoas/equipes; `reference` para codigo + descricao; `status` para entidades com estado operacional forte. |
329
+ | `metadata.optionSource.display.usage` | `"form" | "filter" | "table-cell" | "dashboard" | "wizard" | "review"` | Ativo | Indica onde a option-source costuma aparecer. O runtime pode ajustar densidade e acoes sem duplicar regra por host. |
330
+ | `metadata.optionSource.display.density` | `"compact" | "comfortable" | "rich"` | Ativo | Densidade preferencial. Campos de formulario usam `comfortable`; filtros inline e celulas de tabela tendem a `compact`; revisoes podem usar `rich`. |
331
+ | `metadata.optionSource.display.secondaryPropertyPaths` | `string[]` | Ativo | Campos usados como subtitulo quando o payload local ou remoto preserva essas propriedades. O runtime tambem aceita `descriptionPropertyPaths` como fallback. |
332
+ | `metadata.optionSource.display.fields` | `object[]` | Ativo | Subinformacoes ricas com `propertyPath`, `label`, `icon`, `presentation` (`text`, `chip`, `badge`, `date`, `currency`, `metric`), `tone` e `format`. Quando o endpoint materializa `OptionDTO.extra.richFields[]`, esses valores sao usados diretamente. |
333
+ | `metadata.optionSource.display.badgePropertyPaths` | `string[]` | Ativo | Campos usados para badges/chips quando materializados no payload da option-source. |
316
334
  | `metadata.resourcePath` | `string` | Ativo | Caminho operacional herdado. Para Entity Lookup de plataforma, preferir `metadata.optionSource.resourcePath`. |
317
335
  | `metadata.inlineAutoSize.*` | `object` | Ativo | Largura responsiva da pill lookup. |
318
- | `metadata.selectedLayout` | `"card" | "inline" | "compact" | "token"` | Ativo | Para `controlType: "entityLookup"`, `card` e o default renderizam valor selecionado como cartao rico. `token` preserva leitura compacta. |
336
+ | `metadata.selectedLayout` | `"compact" | "inline" | "card" | "token"` | Ativo | Para `controlType: "entityLookup"`, `compact` e o default preservam altura de campo de formulario. `card` renderiza valor selecionado como cartao rico quando a superficie pedir revisao/detalhe. `token` preserva leitura compacta herdada. |
319
337
  | `metadata.resultLayout` | `"list" | "denseList" | "table" | "card"` | Ativo | Para `controlType: "entityLookup"`, `list` e o default renderizam linhas ricas; `denseList` preserva leitura compacta. |
320
338
  | `metadata.showCode` | `boolean` | Ativo | Controla exibicao do codigo curto na linha e no cartao. Default: `true`. |
321
339
  | `metadata.showDescription` | `boolean` | Ativo | Controla exibicao da descricao composta. Default: `true`. |
@@ -323,11 +341,11 @@ Use quando precisar:
323
341
  | `metadata.showAvatar` | `boolean` | Ativo | Controla exibicao de avatar por iniciais. Default: `true`. |
324
342
  | `metadata.showBadges` | `boolean` | Ativo | Controla exibicao de badges auxiliares vindos de `badges`, `tags`, `riskLevel`, `homologationStatus` ou `badgeKeys`. Default: `true`. |
325
343
  | `metadata.showDisabledReason` | `boolean` | Ativo | Controla exibicao do motivo de bloqueio quando `selectable=false`. Default: `true`. |
326
- | `metadata.showResultCount` | `boolean` | Ativo | Controla contador de resultados no painel de busca. Default: `true`. |
344
+ | `metadata.showResultCount` | `boolean` | Ativo | Controla contador de resultados no painel de busca. Quando o backend pagina com `totalElements`, mostra o total remoto; em fontes locais/cursor, mostra o total carregado. Default: `true`. |
327
345
  | `metadata.statusToneMap` | `Record<string, "success" | "warning" | "danger" | "neutral">` | Ativo | Permite mapear status de dominio para tom visual governado. |
328
346
  | `metadata.badgeKeys` | `string[]` | Ativo | Chaves adicionais lidas do valor de entidade para compor badges auxiliares. |
329
347
  | `metadata.maxVisibleBadges` | `number` | Ativo | Limita quantidade de badges auxiliares exibidos. Default: `3`. |
330
- | `metadata.actions.showDetail` | `boolean` | Ativo | Controla acao de detalhe quando houver `detailHref` ou `detailRoute`. Default: `true`. |
348
+ | `metadata.actions.showDetail` | `boolean` | Ativo | Controla acao de detalhe quando houver surface canonica ou fallback `detailHref`/`detailRoute`. Default: `true`. |
331
349
  | `metadata.actions.showChange` | `boolean` | Ativo | Controla acao de troca no cartao selecionado. Default: `true`. |
332
350
  | `metadata.actions.showCopyCode` | `boolean` | Ativo | Controla acao de copiar codigo/id. Default: `true`. |
333
351
  | `metadata.actions.showClear` | `boolean` | Ativo | Controla acao de limpar em conjunto com `clearButton`/clearable herdado. |
@@ -344,8 +362,9 @@ Resumo de composicao deste componente:
344
362
 
345
363
  ### 4. Mapeamento de Comportamento
346
364
  - Para `controlType: "inlineEntityLookup"`, o trigger preserva valor compacto composto por `buildLookupPrimaryText(id,label)`.
347
- - Para `controlType: "entityLookup"`, o trigger pode renderizar cartao de entidade com avatar, codigo, label, descricao, status, badges e acoes.
348
- - Opcoes podem mostrar linha secundaria (`subtitle`) para desambiguacao; em `entityLookup`, a linha rica tambem mostra avatar, status visual, badges e motivo de bloqueio.
365
+ - Para `controlType: "entityLookup"`, o host publica `data-field-type="entityLookup"`, ocupa `width: 100%` e deve respeitar a coluna do `praxis-dynamic-form`; o trigger pode renderizar campo compacto ou cartao de revisao com avatar, codigo, label, descricao, status, badges e acoes.
366
+ - `metadata.optionSource.display` e a fonte preferencial de UX para a entidade; campos top-level como `selectedLayout`, `density`, `showAvatar` e `showStatus` funcionam como override local de host.
367
+ - Opcoes podem mostrar linha secundaria (`subtitle`) para desambiguacao; em `entityLookup`, a linha rica tambem mostra avatar, campos ricos com icones/chips/datas, status visual, badges e motivo de bloqueio.
349
368
  - Com `metadata.optionSource.resourcePath`, busca emite termo no pipeline remoto de option-source; sem endpoint, filtra local.
350
369
  - `metadata.resourcePath` continua aceito como configuracao operacional herdada, mas nao substitui a semantica canonica de entidade publicada em `metadata.optionSource`.
351
370
  - Opcao de reset limpa filtro sem fechar contexto de trabalho.
@@ -388,7 +407,27 @@ Uso: lookup simples em lista local.
388
407
  "descriptionPropertyPaths": ["departamento"],
389
408
  "statusPropertyPath": "status",
390
409
  "detail": {
391
- "routeTemplate": "/employees/:id"
410
+ "kind": "surface",
411
+ "surfaceId": "view",
412
+ "presentation": "drawer",
413
+ "preferredWidget": "praxis-dynamic-form",
414
+ "mode": "view"
415
+ },
416
+ "display": {
417
+ "preset": "directory",
418
+ "usage": "form",
419
+ "density": "comfortable",
420
+ "selectedLayout": "compact",
421
+ "resultLayout": "list",
422
+ "primaryPropertyPath": "nome",
423
+ "secondaryPropertyPaths": ["cargo", "departamento"],
424
+ "badgePropertyPaths": ["departamento"],
425
+ "showAvatar": true,
426
+ "showCode": false,
427
+ "showDescription": true,
428
+ "showStatus": true,
429
+ "showBadges": true,
430
+ "showResultCount": true
392
431
  }
393
432
  },
394
433
  "lookupSeparator": " | ",