@praxisui/dynamic-fields 9.0.0-beta.44 → 9.0.0-beta.46

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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-07-07T20:03:42.325Z",
3
+ "generatedAt": "2026-07-08T00:30:08.464Z",
4
4
  "packageName": "@praxisui/dynamic-fields",
5
- "packageVersion": "9.0.0-beta.44",
5
+ "packageVersion": "9.0.0-beta.46",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 76,
@@ -418,6 +418,7 @@ No modo percentual (`numericFormat` ou `format` com valor `percent`), mantém o
418
418
  `inlineCurrency` segue envelope adaptativo (`inlineAutoSize`) com máscara de moeda e símbolo antes/depois conforme metadata (`currencyPosition`).
419
419
  `inlineCurrencyRange` segue envelope adaptativo (`inlineAutoSize`) no chip e popover, com escala e resumo monetário formatados. No painel, o resumo completo é a leitura principal da faixa selecionada; os valores junto ao slider são usados apenas como orientação quando não duplicam a seleção ativa. `marks` materializa até três labels compactos e ativa ticks; `semanticBands` projeta faixas de significado no trilho; `distribution/rangeDistribution/histogram` continua sendo a camada para comparação com população real. Por padrão, alterações feitas no painel ficam em rascunho até `Aplicar`; `Cancelar`, `Esc` ou fechamento externo descartam o rascunho, e `Limpar` remove o filtro explicitamente. Labels, aria, `appearance`, `colorRole` e ícones dessas ações devem vir de `inlineOverlay.actions.*` e materializar tokens do tema. Quando `inlineOverlay.applyMode: "auto"` for explicitado, o slider comita durante a interação e a ação de cancelar deixa de ser exibida.
420
420
  `inlineEntityLookup` usa envelope adaptativo (`inlineAutoSize`) com faixa padrão maior para comportar `id + descrição`.
421
+ Em shells corporativos autenticados, como seletores globais de empresa, tenant ou órgão, `pdx-inline-entity-lookup` pode ser usado fora de `PraxisDynamicForm` com um `FormControl` externo e `initialMetadata` estático. Para fontes locais, informe `options`, `optionValueKey`, `optionLabelKey` e `loadOn: "open"`; o valor inicial do `FormControl` deve ser preservado sem disparar recarga remota nem reprocessamento contínuo de metadata. Hosts devem preferir uma referência estável de metadata, mas o runtime tolera recriação semântica equivalente para evitar loops de change detection em topbars.
421
422
  `inlineRange` usa envelope adaptativo de largura (`inlineAutoSize`) no chip e no popover para evitar bloco fixo largo quando usado na barra compacta. Por padrao, altera em modo `auto` para preservar filtros rápidos; com `inlineOverlay.applyMode: "explicit"`, slider, inputs e presets ficam em rascunho até `Aplicar`, enquanto `Cancelar`, `Esc` ou fechamento externo descartam o rascunho. Labels, aria, `appearance` e `colorRole` dos botoes devem vir de `inlineOverlay.actions.*` e materializar tokens do tema, nao CSS ad hoc.
422
423
  `inlineRating` usa o mesmo contrato `inlineOverlay` para fluxos em que explorar estrelas, inputs ou presets nao deve alterar o filtro aplicado imediatamente. Em `applyMode: "explicit"`, o painel exibe `Aplicar`, `Cancelar` e `Limpar`; a escala visual acompanha o rascunho e o valor final so muda no commit.
423
424
  `inlineDistanceRadius` usa o mesmo contrato `inlineOverlay` quando a decisao de UX exigir confirmacao: em `applyMode: "explicit"`, slider radial e presets ficam em rascunho ate `Aplicar`; `Cancelar`, `Esc` e fechamento externo descartam a alteracao. O modo default continua imediato para preservar filtros de raio rapidos.
@@ -13225,6 +13225,10 @@ class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
13225
13225
  inlineMaxWidthPx = 420;
13226
13226
  fieldLabelText = 'Lookup';
13227
13227
  staticOptions = [];
13228
+ lastAppliedSelectMetadata = null;
13229
+ lastSelectMetadataSignature = '';
13230
+ metadataFunctionIds = new WeakMap();
13231
+ nextMetadataFunctionId = 0;
13228
13232
  set initialMetadata(metadata) {
13229
13233
  if (metadata) {
13230
13234
  this.setSelectMetadata(metadata);
@@ -13234,6 +13238,14 @@ class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
13234
13238
  return (this.metadata() || {});
13235
13239
  }
13236
13240
  setSelectMetadata(metadata) {
13241
+ if (metadata === this.lastAppliedSelectMetadata) {
13242
+ return;
13243
+ }
13244
+ const metadataSignature = this.buildMetadataSignature(metadata);
13245
+ if (metadataSignature && metadataSignature === this.lastSelectMetadataSignature) {
13246
+ this.lastAppliedSelectMetadata = metadata;
13247
+ return;
13248
+ }
13237
13249
  super.setSelectMetadata(metadata);
13238
13250
  this.fieldLabelText = this.resolveFieldLabelFromMetadata(metadata);
13239
13251
  this.staticOptions = this.options().map((option) => ({ ...option }));
@@ -13241,6 +13253,8 @@ class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
13241
13253
  this.applyStaticOptionsFilter(this.currentSearchTerm());
13242
13254
  }
13243
13255
  this.recalculateInlineSizeBounds();
13256
+ this.lastAppliedSelectMetadata = metadata;
13257
+ this.lastSelectMetadataSignature = metadataSignature;
13244
13258
  }
13245
13259
  setMetadata(metadata) {
13246
13260
  super.setMetadata(metadata);
@@ -14703,6 +14717,64 @@ class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
14703
14717
  lookupOptionSource() {
14704
14718
  return (this.metadata()?.optionSource ?? this.optionSource()) || null;
14705
14719
  }
14720
+ buildMetadataSignature(metadata) {
14721
+ return this.stableMetadataHash(metadata, new WeakSet());
14722
+ }
14723
+ stableMetadataHash(value, seen) {
14724
+ if (value === null) {
14725
+ return 'null';
14726
+ }
14727
+ if (value === undefined) {
14728
+ return 'undefined';
14729
+ }
14730
+ const valueType = typeof value;
14731
+ if (valueType === 'function') {
14732
+ return `function:${this.metadataFunctionId(value)}`;
14733
+ }
14734
+ if (valueType !== 'object') {
14735
+ return `${valueType}:${this.hashText(String(value))}`;
14736
+ }
14737
+ const objectValue = value;
14738
+ if (seen.has(objectValue)) {
14739
+ return 'cycle';
14740
+ }
14741
+ seen.add(objectValue);
14742
+ if (Array.isArray(value)) {
14743
+ return this.hashParts([
14744
+ 'array',
14745
+ String(value.length),
14746
+ ...value.map((item) => this.stableMetadataHash(item, seen)),
14747
+ ]);
14748
+ }
14749
+ const record = value;
14750
+ return this.hashParts(Object.keys(record)
14751
+ .sort()
14752
+ .map((key) => `${key}:${this.stableMetadataHash(record[key], seen)}`));
14753
+ }
14754
+ metadataFunctionId(value) {
14755
+ const existing = this.metadataFunctionIds.get(value);
14756
+ if (existing !== undefined) {
14757
+ return existing;
14758
+ }
14759
+ const next = ++this.nextMetadataFunctionId;
14760
+ this.metadataFunctionIds.set(value, next);
14761
+ return next;
14762
+ }
14763
+ hashParts(parts) {
14764
+ let hash = 2166136261;
14765
+ for (const part of parts) {
14766
+ hash = this.hashText(part, hash);
14767
+ }
14768
+ return hash.toString(36);
14769
+ }
14770
+ hashText(value, seed = 2166136261) {
14771
+ let hash = seed;
14772
+ for (let index = 0; index < value.length; index += 1) {
14773
+ hash ^= value.charCodeAt(index);
14774
+ hash = Math.imul(hash, 16777619);
14775
+ }
14776
+ return hash >>> 0;
14777
+ }
14706
14778
  resolveDetailHref(id) {
14707
14779
  return this.applyLookupTemplate(this.lookupOptionSource()?.detail?.hrefTemplate, id);
14708
14780
  }
@@ -26795,11 +26867,23 @@ class MaterialSearchableSelectComponent extends SimpleBaseSelectComponent {
26795
26867
  @if (hasValidationError()) {
26796
26868
  <mat-error>{{ errorMessage() }}</mat-error>
26797
26869
  }
26798
- @if (metadata()?.hint && !hasValidationError()) {
26799
- <mat-hint>{{ metadata()!.hint }}</mat-hint>
26870
+ @if (fieldHelpPopoverText()) {
26871
+ <mat-icon
26872
+ matSuffix
26873
+ class="pdx-field-help-icon"
26874
+ [matTooltip]="fieldHelpPopoverText()"
26875
+ matTooltipPosition="above"
26876
+ [matTooltipDisabled]="fieldHelpPopoverDisabled()"
26877
+ [attr.aria-label]="fieldHelpAriaLabel()"
26878
+ tabindex="0"
26879
+ [praxisIcon]="'help_outline'"
26880
+ ></mat-icon>
26881
+ }
26882
+ @if (hasInlineFieldHelp()) {
26883
+ <mat-hint>{{ fieldHelpInlineText() }}</mat-hint>
26800
26884
  }
26801
26885
  </mat-form-field>
26802
- `, isInline: true, styles: ["::ng-deep .cdk-overlay-connected-position-bounding-box:has(.pdx-material-searchable-select-panel){z-index:var(--praxis-layer-popup, 1400)!important}::ng-deep .cdk-overlay-pane:has(.pdx-material-searchable-select-panel){z-index:var(--praxis-layer-popup, 1400)!important}::ng-deep .cdk-overlay-pane .mat-mdc-select-panel.pdx-material-searchable-select-panel{max-height:min(360px,calc(100vh - 96px));overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;padding:8px 0 6px;scrollbar-gutter:auto;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--pdx-overlay-on-surface, currentColor) 42%,transparent) transparent}::ng-deep .pdx-material-searchable-select-panel::-webkit-scrollbar{width:10px}::ng-deep .pdx-material-searchable-select-panel::-webkit-scrollbar-track{border-radius:999px;background:color-mix(in srgb,var(--pdx-overlay-on-surface, currentColor) 10%,transparent)}::ng-deep .pdx-material-searchable-select-panel::-webkit-scrollbar-thumb{min-height:36px;border:3px solid transparent;border-radius:999px;background-clip:content-box;background-color:color-mix(in srgb,var(--pdx-overlay-on-surface, currentColor) 56%,transparent)}::ng-deep .pdx-material-searchable-select-panel::-webkit-scrollbar-thumb:hover{background-color:color-mix(in srgb,var(--pdx-overlay-on-surface, currentColor) 70%,transparent)}::ng-deep .pdx-material-searchable-select-panel .pdx-select-search-option{background:var( --pdx-overlay-surface, var(--md-sys-color-surface-container-highest, var(--mat-select-panel-background-color)) );border-bottom:1px solid var(--pdx-overlay-border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .28)));box-sizing:border-box;display:block;padding:7px 12px;position:sticky;top:-8px;z-index:1}::ng-deep .pdx-material-searchable-select-panel .pdx-select-search-option input{background:var( --pdx-field-surface, color-mix( in srgb, var(--pdx-overlay-surface, var(--md-sys-color-surface-container-highest)) 82%, var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface)) 8% ) );border:1px solid var( --pdx-field-border, color-mix( in srgb, var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface)) 22%, transparent ) );border-radius:12px;box-sizing:border-box;color:var(--pdx-field-text, var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface)));min-height:38px;padding:0 12px;width:100%}::ng-deep .pdx-material-searchable-select-panel .pdx-select-search-option input::placeholder{color:color-mix(in srgb,var(--pdx-field-text, var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface))) 68%,transparent)}::ng-deep .pdx-material-searchable-select-panel .pdx-select-search-option input:focus{border-color:var(--pdx-field-focus-border, var(--md-sys-color-primary, var(--mat-select-focused-arrow-color)));outline:1px solid var( --pdx-field-focus-ring, color-mix(in srgb, var(--md-sys-color-primary, currentColor) 32%, transparent) );outline-offset:0}::ng-deep .pdx-material-searchable-select-panel .pdx-select-load-more-action{display:flex;align-items:center;min-height:48px;padding:0 16px;color:var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface));cursor:pointer;outline:none;-webkit-user-select:none;user-select:none}::ng-deep .pdx-material-searchable-select-panel .pdx-select-load-more-action:hover,::ng-deep .pdx-material-searchable-select-panel .pdx-select-load-more-action:focus-visible{background:var(--pdx-overlay-state-layer, var(--md-sys-color-surface-container-high))}::ng-deep .pdx-material-searchable-select-panel .pdx-select-load-more-action[aria-disabled=true]{cursor:default;opacity:.48;pointer-events:none}::ng-deep .pdx-material-searchable-select-panel .pdx-select-open-sentinel{min-height:0;height:0;padding:0;overflow:hidden;visibility:hidden}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i3$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i3$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
26886
+ `, isInline: true, styles: [".pdx-field-help-icon{border-radius:999px;color:var(--md-sys-color-on-surface-variant);cursor:help}.pdx-field-help-icon:focus{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}::ng-deep .cdk-overlay-connected-position-bounding-box:has(.pdx-material-searchable-select-panel){z-index:var(--praxis-layer-popup, 1400)!important}::ng-deep .cdk-overlay-pane:has(.pdx-material-searchable-select-panel){z-index:var(--praxis-layer-popup, 1400)!important}::ng-deep .cdk-overlay-pane .mat-mdc-select-panel.pdx-material-searchable-select-panel{max-height:min(360px,calc(100vh - 96px));overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;padding:8px 0 6px;scrollbar-gutter:auto;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--pdx-overlay-on-surface, currentColor) 42%,transparent) transparent}::ng-deep .pdx-material-searchable-select-panel::-webkit-scrollbar{width:10px}::ng-deep .pdx-material-searchable-select-panel::-webkit-scrollbar-track{border-radius:999px;background:color-mix(in srgb,var(--pdx-overlay-on-surface, currentColor) 10%,transparent)}::ng-deep .pdx-material-searchable-select-panel::-webkit-scrollbar-thumb{min-height:36px;border:3px solid transparent;border-radius:999px;background-clip:content-box;background-color:color-mix(in srgb,var(--pdx-overlay-on-surface, currentColor) 56%,transparent)}::ng-deep .pdx-material-searchable-select-panel::-webkit-scrollbar-thumb:hover{background-color:color-mix(in srgb,var(--pdx-overlay-on-surface, currentColor) 70%,transparent)}::ng-deep .pdx-material-searchable-select-panel .pdx-select-search-option{background:var( --pdx-overlay-surface, var(--md-sys-color-surface-container-highest, var(--mat-select-panel-background-color)) );border-bottom:1px solid var(--pdx-overlay-border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .28)));box-sizing:border-box;display:block;padding:7px 12px;position:sticky;top:-8px;z-index:1}::ng-deep .pdx-material-searchable-select-panel .pdx-select-search-option input{background:var( --pdx-field-surface, color-mix( in srgb, var(--pdx-overlay-surface, var(--md-sys-color-surface-container-highest)) 82%, var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface)) 8% ) );border:1px solid var( --pdx-field-border, color-mix( in srgb, var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface)) 22%, transparent ) );border-radius:12px;box-sizing:border-box;color:var(--pdx-field-text, var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface)));min-height:38px;padding:0 12px;width:100%}::ng-deep .pdx-material-searchable-select-panel .pdx-select-search-option input::placeholder{color:color-mix(in srgb,var(--pdx-field-text, var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface))) 68%,transparent)}::ng-deep .pdx-material-searchable-select-panel .pdx-select-search-option input:focus{border-color:var(--pdx-field-focus-border, var(--md-sys-color-primary, var(--mat-select-focused-arrow-color)));outline:1px solid var( --pdx-field-focus-ring, color-mix(in srgb, var(--md-sys-color-primary, currentColor) 32%, transparent) );outline-offset:0}::ng-deep .pdx-material-searchable-select-panel .pdx-select-load-more-action{display:flex;align-items:center;min-height:48px;padding:0 16px;color:var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface));cursor:pointer;outline:none;-webkit-user-select:none;user-select:none}::ng-deep .pdx-material-searchable-select-panel .pdx-select-load-more-action:hover,::ng-deep .pdx-material-searchable-select-panel .pdx-select-load-more-action:focus-visible{background:var(--pdx-overlay-state-layer, var(--md-sys-color-surface-container-high))}::ng-deep .pdx-material-searchable-select-panel .pdx-select-load-more-action[aria-disabled=true]{cursor:default;opacity:.48;pointer-events:none}::ng-deep .pdx-material-searchable-select-panel .pdx-select-open-sentinel{min-height:0;height:0;padding:0;overflow:hidden;visibility:hidden}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i3$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i3$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
26803
26887
  }
26804
26888
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MaterialSearchableSelectComponent, decorators: [{
26805
26889
  type: Component,
@@ -27007,8 +27091,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
27007
27091
  @if (hasValidationError()) {
27008
27092
  <mat-error>{{ errorMessage() }}</mat-error>
27009
27093
  }
27010
- @if (metadata()?.hint && !hasValidationError()) {
27011
- <mat-hint>{{ metadata()!.hint }}</mat-hint>
27094
+ @if (fieldHelpPopoverText()) {
27095
+ <mat-icon
27096
+ matSuffix
27097
+ class="pdx-field-help-icon"
27098
+ [matTooltip]="fieldHelpPopoverText()"
27099
+ matTooltipPosition="above"
27100
+ [matTooltipDisabled]="fieldHelpPopoverDisabled()"
27101
+ [attr.aria-label]="fieldHelpAriaLabel()"
27102
+ tabindex="0"
27103
+ [praxisIcon]="'help_outline'"
27104
+ ></mat-icon>
27105
+ }
27106
+ @if (hasInlineFieldHelp()) {
27107
+ <mat-hint>{{ fieldHelpInlineText() }}</mat-hint>
27012
27108
  }
27013
27109
  </mat-form-field>
27014
27110
  `, providers: [
@@ -27028,7 +27124,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
27028
27124
  '[attr.data-field-type]': '"searchable-select"',
27029
27125
  '[attr.data-field-name]': 'metadata()?.name',
27030
27126
  '[attr.data-component-id]': 'componentId()',
27031
- }, styles: ["::ng-deep .cdk-overlay-connected-position-bounding-box:has(.pdx-material-searchable-select-panel){z-index:var(--praxis-layer-popup, 1400)!important}::ng-deep .cdk-overlay-pane:has(.pdx-material-searchable-select-panel){z-index:var(--praxis-layer-popup, 1400)!important}::ng-deep .cdk-overlay-pane .mat-mdc-select-panel.pdx-material-searchable-select-panel{max-height:min(360px,calc(100vh - 96px));overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;padding:8px 0 6px;scrollbar-gutter:auto;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--pdx-overlay-on-surface, currentColor) 42%,transparent) transparent}::ng-deep .pdx-material-searchable-select-panel::-webkit-scrollbar{width:10px}::ng-deep .pdx-material-searchable-select-panel::-webkit-scrollbar-track{border-radius:999px;background:color-mix(in srgb,var(--pdx-overlay-on-surface, currentColor) 10%,transparent)}::ng-deep .pdx-material-searchable-select-panel::-webkit-scrollbar-thumb{min-height:36px;border:3px solid transparent;border-radius:999px;background-clip:content-box;background-color:color-mix(in srgb,var(--pdx-overlay-on-surface, currentColor) 56%,transparent)}::ng-deep .pdx-material-searchable-select-panel::-webkit-scrollbar-thumb:hover{background-color:color-mix(in srgb,var(--pdx-overlay-on-surface, currentColor) 70%,transparent)}::ng-deep .pdx-material-searchable-select-panel .pdx-select-search-option{background:var( --pdx-overlay-surface, var(--md-sys-color-surface-container-highest, var(--mat-select-panel-background-color)) );border-bottom:1px solid var(--pdx-overlay-border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .28)));box-sizing:border-box;display:block;padding:7px 12px;position:sticky;top:-8px;z-index:1}::ng-deep .pdx-material-searchable-select-panel .pdx-select-search-option input{background:var( --pdx-field-surface, color-mix( in srgb, var(--pdx-overlay-surface, var(--md-sys-color-surface-container-highest)) 82%, var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface)) 8% ) );border:1px solid var( --pdx-field-border, color-mix( in srgb, var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface)) 22%, transparent ) );border-radius:12px;box-sizing:border-box;color:var(--pdx-field-text, var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface)));min-height:38px;padding:0 12px;width:100%}::ng-deep .pdx-material-searchable-select-panel .pdx-select-search-option input::placeholder{color:color-mix(in srgb,var(--pdx-field-text, var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface))) 68%,transparent)}::ng-deep .pdx-material-searchable-select-panel .pdx-select-search-option input:focus{border-color:var(--pdx-field-focus-border, var(--md-sys-color-primary, var(--mat-select-focused-arrow-color)));outline:1px solid var( --pdx-field-focus-ring, color-mix(in srgb, var(--md-sys-color-primary, currentColor) 32%, transparent) );outline-offset:0}::ng-deep .pdx-material-searchable-select-panel .pdx-select-load-more-action{display:flex;align-items:center;min-height:48px;padding:0 16px;color:var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface));cursor:pointer;outline:none;-webkit-user-select:none;user-select:none}::ng-deep .pdx-material-searchable-select-panel .pdx-select-load-more-action:hover,::ng-deep .pdx-material-searchable-select-panel .pdx-select-load-more-action:focus-visible{background:var(--pdx-overlay-state-layer, var(--md-sys-color-surface-container-high))}::ng-deep .pdx-material-searchable-select-panel .pdx-select-load-more-action[aria-disabled=true]{cursor:default;opacity:.48;pointer-events:none}::ng-deep .pdx-material-searchable-select-panel .pdx-select-open-sentinel{min-height:0;height:0;padding:0;overflow:hidden;visibility:hidden}\n"] }]
27127
+ }, styles: [".pdx-field-help-icon{border-radius:999px;color:var(--md-sys-color-on-surface-variant);cursor:help}.pdx-field-help-icon:focus{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}::ng-deep .cdk-overlay-connected-position-bounding-box:has(.pdx-material-searchable-select-panel){z-index:var(--praxis-layer-popup, 1400)!important}::ng-deep .cdk-overlay-pane:has(.pdx-material-searchable-select-panel){z-index:var(--praxis-layer-popup, 1400)!important}::ng-deep .cdk-overlay-pane .mat-mdc-select-panel.pdx-material-searchable-select-panel{max-height:min(360px,calc(100vh - 96px));overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;padding:8px 0 6px;scrollbar-gutter:auto;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--pdx-overlay-on-surface, currentColor) 42%,transparent) transparent}::ng-deep .pdx-material-searchable-select-panel::-webkit-scrollbar{width:10px}::ng-deep .pdx-material-searchable-select-panel::-webkit-scrollbar-track{border-radius:999px;background:color-mix(in srgb,var(--pdx-overlay-on-surface, currentColor) 10%,transparent)}::ng-deep .pdx-material-searchable-select-panel::-webkit-scrollbar-thumb{min-height:36px;border:3px solid transparent;border-radius:999px;background-clip:content-box;background-color:color-mix(in srgb,var(--pdx-overlay-on-surface, currentColor) 56%,transparent)}::ng-deep .pdx-material-searchable-select-panel::-webkit-scrollbar-thumb:hover{background-color:color-mix(in srgb,var(--pdx-overlay-on-surface, currentColor) 70%,transparent)}::ng-deep .pdx-material-searchable-select-panel .pdx-select-search-option{background:var( --pdx-overlay-surface, var(--md-sys-color-surface-container-highest, var(--mat-select-panel-background-color)) );border-bottom:1px solid var(--pdx-overlay-border, var(--md-sys-color-outline-variant, rgba(148, 163, 184, .28)));box-sizing:border-box;display:block;padding:7px 12px;position:sticky;top:-8px;z-index:1}::ng-deep .pdx-material-searchable-select-panel .pdx-select-search-option input{background:var( --pdx-field-surface, color-mix( in srgb, var(--pdx-overlay-surface, var(--md-sys-color-surface-container-highest)) 82%, var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface)) 8% ) );border:1px solid var( --pdx-field-border, color-mix( in srgb, var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface)) 22%, transparent ) );border-radius:12px;box-sizing:border-box;color:var(--pdx-field-text, var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface)));min-height:38px;padding:0 12px;width:100%}::ng-deep .pdx-material-searchable-select-panel .pdx-select-search-option input::placeholder{color:color-mix(in srgb,var(--pdx-field-text, var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface))) 68%,transparent)}::ng-deep .pdx-material-searchable-select-panel .pdx-select-search-option input:focus{border-color:var(--pdx-field-focus-border, var(--md-sys-color-primary, var(--mat-select-focused-arrow-color)));outline:1px solid var( --pdx-field-focus-ring, color-mix(in srgb, var(--md-sys-color-primary, currentColor) 32%, transparent) );outline-offset:0}::ng-deep .pdx-material-searchable-select-panel .pdx-select-load-more-action{display:flex;align-items:center;min-height:48px;padding:0 16px;color:var(--pdx-overlay-on-surface, var(--md-sys-color-on-surface));cursor:pointer;outline:none;-webkit-user-select:none;user-select:none}::ng-deep .pdx-material-searchable-select-panel .pdx-select-load-more-action:hover,::ng-deep .pdx-material-searchable-select-panel .pdx-select-load-more-action:focus-visible{background:var(--pdx-overlay-state-layer, var(--md-sys-color-surface-container-high))}::ng-deep .pdx-material-searchable-select-panel .pdx-select-load-more-action[aria-disabled=true]{cursor:default;opacity:.48;pointer-events:none}::ng-deep .pdx-material-searchable-select-panel .pdx-select-open-sentinel{min-height:0;height:0;padding:0;overflow:hidden;visibility:hidden}\n"] }]
27032
27128
  }], propDecorators: { readonlyMode: [{
27033
27129
  type: Input
27034
27130
  }], disabledMode: [{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@praxisui/dynamic-fields",
3
- "version": "9.0.0-beta.44",
3
+ "version": "9.0.0-beta.46",
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.44",
15
- "@praxisui/cron-builder": "^9.0.0-beta.44"
14
+ "@praxisui/core": "^9.0.0-beta.46",
15
+ "@praxisui/cron-builder": "^9.0.0-beta.46"
16
16
  },
17
17
  "dependencies": {
18
18
  "libphonenumber-js": "^1.12.41",
@@ -366,6 +366,7 @@ Resumo de composicao deste componente:
366
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
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.
368
368
  - Com `metadata.optionSource.resourcePath`, busca emite termo no pipeline remoto de option-source; sem endpoint, filtra local.
369
+ - Em uso standalone de shell/topbar autenticado, o componente aceita `FormControl` externo com `initialMetadata` estático e `options` locais. Um valor inicial já selecionado no controle deve materializar o texto da opção local sem bloquear a montagem da rota nem realimentar change detection quando a metadata recebida for semanticamente equivalente.
369
370
  - `metadata.resourcePath` continua aceito como configuracao operacional herdada, mas nao substitui a semantica canonica de entidade publicada em `metadata.optionSource`.
370
371
  - Opcao de reset limpa filtro sem fechar contexto de trabalho.
371
372
  - `OptionDTO.extra.selectable === false` desabilita a opcao e permite exibir `disabledReason` sem remover a entidade da lista ou da reidratacao.
@@ -2895,6 +2895,10 @@ declare class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
2895
2895
  inlineMaxWidthPx: number;
2896
2896
  private fieldLabelText;
2897
2897
  private staticOptions;
2898
+ private lastAppliedSelectMetadata;
2899
+ private lastSelectMetadataSignature;
2900
+ private readonly metadataFunctionIds;
2901
+ private nextMetadataFunctionId;
2898
2902
  set initialMetadata(metadata: MaterialEntityLookupMetadata | null | undefined);
2899
2903
  private currentMetadata;
2900
2904
  setSelectMetadata(metadata: EntityLookupMetadata): void;
@@ -3086,6 +3090,11 @@ declare class InlineEntityLookupComponent extends MaterialAsyncSelectComponent {
3086
3090
  private isPrimitiveLookupValue;
3087
3091
  private asRecord;
3088
3092
  private lookupOptionSource;
3093
+ private buildMetadataSignature;
3094
+ private stableMetadataHash;
3095
+ private metadataFunctionId;
3096
+ private hashParts;
3097
+ private hashText;
3089
3098
  private resolveDetailHref;
3090
3099
  private resolveDetailRoute;
3091
3100
  private applyLookupTemplate;