@praxisui/dynamic-fields 4.0.0-beta.0 → 5.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -119,7 +119,7 @@ Peers (instale no app host):
119
119
  - `@angular/core` `^20.1.0`, `@angular/common` `^20.1.0`, `@angular/forms` `^20.1.0`
120
120
  - `@angular/material` `^20.1.0`, `@angular/cdk` `^20.1.0`, `@angular/router` `^20.1.0`
121
121
  - `rxjs` `^7.8.0`
122
- - `@praxisui/core`, `@praxisui/specification-core`
122
+ - `@praxisui/core`
123
123
  - Opcional conforme uso: `@praxisui/dialog`, `@praxisui/cron-builder`
124
124
 
125
125
  ## ✨ Características
@@ -2625,6 +2625,12 @@ class SimpleBaseSelectComponent extends SimpleBaseInputComponent {
2625
2625
  ? this.options().filter((o) => o.label.toLowerCase().includes(term))
2626
2626
  : this.options();
2627
2627
  }, ...(ngDevMode ? [{ debugName: "filteredOptions" }] : []));
2628
+ /**
2629
+ * Applies typed metadata to the select component.
2630
+ */
2631
+ setInputMetadata(metadata) {
2632
+ this.setSelectMetadata(metadata);
2633
+ }
2628
2634
  /**
2629
2635
  * Applies typed metadata to the select component.
2630
2636
  */
@@ -2726,6 +2732,12 @@ class SimpleBaseSelectComponent extends SimpleBaseInputComponent {
2726
2732
  });
2727
2733
  return st.readonly;
2728
2734
  }
2735
+ isInteractionDisabled() {
2736
+ return (!!this.disabledMode ||
2737
+ this.control().disabled ||
2738
+ this.isReadonlyEffective() ||
2739
+ !!this.presentationMode);
2740
+ }
2729
2741
  /** Whether to show the clear button (if enabled in metadata) */
2730
2742
  showClear() {
2731
2743
  const cfg = this.metadata()?.clearButton;
@@ -6444,7 +6456,7 @@ class MaterialSelectComponent extends SimpleBaseSelectComponent {
6444
6456
  };
6445
6457
  }
6446
6458
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: MaterialSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
6447
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: MaterialSelectComponent, isStandalone: true, selector: "pdx-material-select", inputs: { readonlyMode: "readonlyMode", disabledMode: "disabledMode", visible: "visible", presentationMode: "presentationMode" }, host: { properties: { "class": "componentCssClasses()", "class.praxis-disabled": "disabledMode", "style.display": "visible ? \"block\" : \"none\"", "attr.aria-hidden": "visible ? null : \"true\"", "style.width": "\"100%\"", "attr.data-field-type": "\"select\"", "attr.data-field-name": "metadata()?.name", "attr.data-component-id": "componentId()" } }, providers: [
6459
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: MaterialSelectComponent, isStandalone: true, selector: "pdx-material-select", inputs: { readonlyMode: "readonlyMode", disabledMode: "disabledMode", visible: "visible", presentationMode: "presentationMode" }, host: { properties: { "class": "componentCssClasses()", "class.praxis-disabled": "isInteractionDisabled()", "style.display": "visible ? \"block\" : \"none\"", "attr.aria-hidden": "visible ? null : \"true\"", "style.width": "\"100%\"", "attr.data-field-type": "\"select\"", "attr.data-field-name": "metadata()?.name", "attr.data-component-id": "componentId()" } }, providers: [
6448
6460
  GenericCrudService,
6449
6461
  {
6450
6462
  provide: NG_VALUE_ACCESSOR,
@@ -6473,6 +6485,7 @@ class MaterialSelectComponent extends SimpleBaseSelectComponent {
6473
6485
  <mat-select
6474
6486
  [errorStateMatcher]="errorStateMatcher()"
6475
6487
  [formControl]="control()"
6488
+ [disabled]="isInteractionDisabled()"
6476
6489
  [required]="metadata()?.required || false"
6477
6490
  [matTooltip]="tooltipEnabled() ? errorMessage() : null"
6478
6491
  [matTooltipDisabled]="!(tooltipEnabled() && !!errorMessage())"
@@ -6519,7 +6532,7 @@ class MaterialSelectComponent extends SimpleBaseSelectComponent {
6519
6532
  matSuffix
6520
6533
  type="button"
6521
6534
  (click)="onClearClick()"
6522
- [disabled]="disabledMode || isReadonlyEffective() || presentationMode"
6535
+ [disabled]="isInteractionDisabled()"
6523
6536
  [matTooltip]="clearActionTooltip()"
6524
6537
  [attr.aria-label]="clearActionAriaLabel()"
6525
6538
  >
@@ -6577,6 +6590,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
6577
6590
  <mat-select
6578
6591
  [errorStateMatcher]="errorStateMatcher()"
6579
6592
  [formControl]="control()"
6593
+ [disabled]="isInteractionDisabled()"
6580
6594
  [required]="metadata()?.required || false"
6581
6595
  [matTooltip]="tooltipEnabled() ? errorMessage() : null"
6582
6596
  [matTooltipDisabled]="!(tooltipEnabled() && !!errorMessage())"
@@ -6623,7 +6637,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
6623
6637
  matSuffix
6624
6638
  type="button"
6625
6639
  (click)="onClearClick()"
6626
- [disabled]="disabledMode || isReadonlyEffective() || presentationMode"
6640
+ [disabled]="isInteractionDisabled()"
6627
6641
  [matTooltip]="clearActionTooltip()"
6628
6642
  [attr.aria-label]="clearActionAriaLabel()"
6629
6643
  >
@@ -6652,7 +6666,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
6652
6666
  ],
6653
6667
  host: {
6654
6668
  '[class]': 'componentCssClasses()',
6655
- '[class.praxis-disabled]': 'disabledMode',
6669
+ '[class.praxis-disabled]': 'isInteractionDisabled()',
6656
6670
  '[style.display]': 'visible ? "block" : "none"',
6657
6671
  '[attr.aria-hidden]': 'visible ? null : "true"',
6658
6672
  '[style.width]': '"100%"',
@@ -10536,6 +10550,7 @@ class DynamicFieldLoaderDirective {
10536
10550
  if (!metadataAssigned) {
10537
10551
  logger.warn(`[DynamicFieldLoader] Component for field '${field.name}' does not support metadata assignment`);
10538
10552
  }
10553
+ this.applyShellEffectiveStatesToComponent(instance, shellRef.instance);
10539
10554
  // Associar FormControl
10540
10555
  const control = this.formGroup?.get(field.name) ?? null;
10541
10556
  if (control) {
@@ -10587,6 +10602,7 @@ class DynamicFieldLoaderDirective {
10587
10602
  instance.metadata.set(fieldWithId);
10588
10603
  }
10589
10604
  this.dbg('[DFL] step: reapply metadata done', { name: field.name });
10605
+ this.applyShellEffectiveStatesToComponent(instance, shellRef.instance);
10590
10606
  }
10591
10607
  catch (e) {
10592
10608
  logger.warn(`[DynamicFieldLoader] Failed to reapply metadata after control binding for '${field.name}':`, e);
@@ -10646,8 +10662,33 @@ class DynamicFieldLoaderDirective {
10646
10662
  shellRef.instance.visible = this.visible !== false ? true : false;
10647
10663
  }
10648
10664
  shellRef.changeDetectorRef.detectChanges();
10665
+ const compRef = this.componentRefs.get(shellRef.instance.field?.name);
10666
+ if (compRef) {
10667
+ this.applyShellEffectiveStatesToComponent(compRef.instance, shellRef.instance);
10668
+ try {
10669
+ compRef.changeDetectorRef.detectChanges();
10670
+ }
10671
+ catch { }
10672
+ }
10649
10673
  });
10650
10674
  }
10675
+ applyShellEffectiveStatesToComponent(instance, shell) {
10676
+ if (!instance || !shell) {
10677
+ return;
10678
+ }
10679
+ if ('readonlyMode' in instance) {
10680
+ instance.readonlyMode = shell.effectiveReadonlyMode;
10681
+ }
10682
+ if ('disabledMode' in instance) {
10683
+ instance.disabledMode = shell.effectiveDisabledMode;
10684
+ }
10685
+ if ('presentationMode' in instance) {
10686
+ instance.presentationMode = shell.effectivePresentationMode;
10687
+ }
10688
+ if ('visible' in instance) {
10689
+ instance.visible = shell.effectiveVisible;
10690
+ }
10691
+ }
10651
10692
  // =============================================================================
10652
10693
  // PRIVATE METHODS - FIELD INFERENCE (fallback mínimo)
10653
10694
  // =============================================================================
@@ -17380,7 +17421,7 @@ class MaterialSearchableSelectComponent extends SimpleBaseSelectComponent {
17380
17421
  this.reload(true);
17381
17422
  }
17382
17423
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: MaterialSearchableSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
17383
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: MaterialSearchableSelectComponent, isStandalone: true, selector: "pdx-material-searchable-select", inputs: { readonlyMode: "readonlyMode", disabledMode: "disabledMode", visible: "visible", presentationMode: "presentationMode" }, host: { properties: { "class": "componentCssClasses()", "class.praxis-disabled": "disabledMode", "style.display": "visible ? null : \"none\"", "attr.aria-hidden": "visible ? null : \"true\"", "attr.data-field-type": "\"searchable-select\"", "attr.data-field-name": "metadata()?.name", "attr.data-component-id": "componentId()" } }, providers: [
17424
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: MaterialSearchableSelectComponent, isStandalone: true, selector: "pdx-material-searchable-select", inputs: { readonlyMode: "readonlyMode", disabledMode: "disabledMode", visible: "visible", presentationMode: "presentationMode" }, host: { properties: { "class": "componentCssClasses()", "class.praxis-disabled": "isInteractionDisabled()", "style.display": "visible ? null : \"none\"", "attr.aria-hidden": "visible ? null : \"true\"", "attr.data-field-type": "\"searchable-select\"", "attr.data-field-name": "metadata()?.name", "attr.data-component-id": "componentId()" } }, providers: [
17384
17425
  GenericCrudService,
17385
17426
  {
17386
17427
  provide: NG_VALUE_ACCESSOR,
@@ -17401,6 +17442,7 @@ class MaterialSearchableSelectComponent extends SimpleBaseSelectComponent {
17401
17442
  <mat-select
17402
17443
  multiple
17403
17444
  [formControl]="control()"
17445
+ [disabled]="isInteractionDisabled()"
17404
17446
  [required]="metadata()?.required || false"
17405
17447
  (openedChange)="onOpened($event)"
17406
17448
  [matTooltip]="tooltipEnabled() ? errorMessage() : null"
@@ -17441,6 +17483,7 @@ class MaterialSearchableSelectComponent extends SimpleBaseSelectComponent {
17441
17483
  } @else {
17442
17484
  <mat-select
17443
17485
  [formControl]="control()"
17486
+ [disabled]="isInteractionDisabled()"
17444
17487
  [required]="metadata()?.required || false"
17445
17488
  (openedChange)="onOpened($event)"
17446
17489
  [matTooltip]="tooltipEnabled() ? errorMessage() : null"
@@ -17503,7 +17546,7 @@ class MaterialSearchableSelectComponent extends SimpleBaseSelectComponent {
17503
17546
  matSuffix
17504
17547
  type="button"
17505
17548
  (click)="onClearClick()"
17506
- [disabled]="disabledMode || isReadonlyEffective() || presentationMode"
17549
+ [disabled]="isInteractionDisabled()"
17507
17550
  [matTooltip]="clearActionTooltip()"
17508
17551
  [attr.aria-label]="clearActionAriaLabel()"
17509
17552
  >
@@ -17555,6 +17598,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
17555
17598
  <mat-select
17556
17599
  multiple
17557
17600
  [formControl]="control()"
17601
+ [disabled]="isInteractionDisabled()"
17558
17602
  [required]="metadata()?.required || false"
17559
17603
  (openedChange)="onOpened($event)"
17560
17604
  [matTooltip]="tooltipEnabled() ? errorMessage() : null"
@@ -17595,6 +17639,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
17595
17639
  } @else {
17596
17640
  <mat-select
17597
17641
  [formControl]="control()"
17642
+ [disabled]="isInteractionDisabled()"
17598
17643
  [required]="metadata()?.required || false"
17599
17644
  (openedChange)="onOpened($event)"
17600
17645
  [matTooltip]="tooltipEnabled() ? errorMessage() : null"
@@ -17657,7 +17702,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
17657
17702
  matSuffix
17658
17703
  type="button"
17659
17704
  (click)="onClearClick()"
17660
- [disabled]="disabledMode || isReadonlyEffective() || presentationMode"
17705
+ [disabled]="isInteractionDisabled()"
17661
17706
  [matTooltip]="clearActionTooltip()"
17662
17707
  [attr.aria-label]="clearActionAriaLabel()"
17663
17708
  >
@@ -17687,7 +17732,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
17687
17732
  ],
17688
17733
  host: {
17689
17734
  '[class]': 'componentCssClasses()',
17690
- '[class.praxis-disabled]': 'disabledMode',
17735
+ '[class.praxis-disabled]': 'isInteractionDisabled()',
17691
17736
  '[style.display]': 'visible ? null : "none"',
17692
17737
  '[attr.aria-hidden]': 'visible ? null : "true"',
17693
17738
  '[attr.data-field-type]': '"searchable-select"',
@@ -18541,7 +18586,7 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
18541
18586
  return this.tDynamicFields('select.loadOptionsError', '');
18542
18587
  }
18543
18588
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: MaterialAsyncSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
18544
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: MaterialAsyncSelectComponent, isStandalone: true, selector: "pdx-material-async-select", inputs: { readonlyMode: "readonlyMode", disabledMode: "disabledMode", visible: "visible", presentationMode: "presentationMode" }, host: { properties: { "class": "componentCssClasses()", "class.praxis-disabled": "disabledMode", "style.display": "visible ? null : \"none\"", "attr.aria-hidden": "visible ? null : \"true\"", "attr.data-field-type": "\"async-select\"", "attr.data-field-name": "metadata()?.name", "attr.data-component-id": "componentId()" } }, providers: [
18589
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: MaterialAsyncSelectComponent, isStandalone: true, selector: "pdx-material-async-select", inputs: { readonlyMode: "readonlyMode", disabledMode: "disabledMode", visible: "visible", presentationMode: "presentationMode" }, host: { properties: { "class": "componentCssClasses()", "class.praxis-disabled": "isInteractionDisabled()", "style.display": "visible ? null : \"none\"", "attr.aria-hidden": "visible ? null : \"true\"", "attr.data-field-type": "\"async-select\"", "attr.data-field-name": "metadata()?.name", "attr.data-component-id": "componentId()" } }, providers: [
18545
18590
  GenericCrudService,
18546
18591
  {
18547
18592
  provide: NG_VALUE_ACCESSOR,
@@ -18561,6 +18606,7 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
18561
18606
  <mat-select
18562
18607
  [errorStateMatcher]="errorStateMatcher()"
18563
18608
  [formControl]="control()"
18609
+ [disabled]="isInteractionDisabled()"
18564
18610
  [multiple]="multiple()"
18565
18611
  [required]="metadata()?.required || false"
18566
18612
  (openedChange)="onOpened($event)"
@@ -18624,7 +18670,7 @@ class MaterialAsyncSelectComponent extends SimpleBaseSelectComponent {
18624
18670
  matSuffix
18625
18671
  type="button"
18626
18672
  (click)="onClearClick()"
18627
- [disabled]="disabledMode || isReadonlyEffective() || presentationMode"
18673
+ [disabled]="isInteractionDisabled()"
18628
18674
  [matTooltip]="clearActionTooltip()"
18629
18675
  [attr.aria-label]="clearActionAriaLabel()"
18630
18676
  >
@@ -18675,6 +18721,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
18675
18721
  <mat-select
18676
18722
  [errorStateMatcher]="errorStateMatcher()"
18677
18723
  [formControl]="control()"
18724
+ [disabled]="isInteractionDisabled()"
18678
18725
  [multiple]="multiple()"
18679
18726
  [required]="metadata()?.required || false"
18680
18727
  (openedChange)="onOpened($event)"
@@ -18738,7 +18785,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
18738
18785
  matSuffix
18739
18786
  type="button"
18740
18787
  (click)="onClearClick()"
18741
- [disabled]="disabledMode || isReadonlyEffective() || presentationMode"
18788
+ [disabled]="isInteractionDisabled()"
18742
18789
  [matTooltip]="clearActionTooltip()"
18743
18790
  [attr.aria-label]="clearActionAriaLabel()"
18744
18791
  >
@@ -18768,7 +18815,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
18768
18815
  ],
18769
18816
  host: {
18770
18817
  '[class]': 'componentCssClasses()',
18771
- '[class.praxis-disabled]': 'disabledMode',
18818
+ '[class.praxis-disabled]': 'isInteractionDisabled()',
18772
18819
  '[style.display]': 'visible ? null : "none"',
18773
18820
  '[attr.aria-hidden]': 'visible ? null : "true"',
18774
18821
  '[attr.data-field-type]': '"async-select"',
@@ -24802,6 +24849,12 @@ class InlineToggleComponent extends SimpleBaseInputComponent {
24802
24849
  const fromMeta = this.resolveFieldLabelFromMetadata(this.metadata() || {});
24803
24850
  return fromMeta || this.fieldLabelText || 'Filtro';
24804
24851
  }
24852
+ toggleLabelText() {
24853
+ const label = this.placeholderText();
24854
+ if (!this.hasSelection())
24855
+ return label;
24856
+ return `${label}: ${this.isTrue() ? 'On' : 'Off'}`;
24857
+ }
24805
24858
  ariaLabel() {
24806
24859
  const label = this.placeholderText();
24807
24860
  if (!this.hasSelection())
@@ -24880,7 +24933,7 @@ class InlineToggleComponent extends SimpleBaseInputComponent {
24880
24933
  </mat-slide-toggle>
24881
24934
 
24882
24935
  @if (showTextLabel()) {
24883
- <span class="pdx-inline-toggle-label">{{ placeholderText() }}</span>
24936
+ <span class="pdx-inline-toggle-label">{{ toggleLabelText() }}</span>
24884
24937
  }
24885
24938
 
24886
24939
  @if (showQuickClear()) {
@@ -24931,7 +24984,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
24931
24984
  </mat-slide-toggle>
24932
24985
 
24933
24986
  @if (showTextLabel()) {
24934
- <span class="pdx-inline-toggle-label">{{ placeholderText() }}</span>
24987
+ <span class="pdx-inline-toggle-label">{{ toggleLabelText() }}</span>
24935
24988
  }
24936
24989
 
24937
24990
  @if (showQuickClear()) {
@@ -32658,6 +32711,10 @@ class InlineTreeSelectComponent extends SimpleBaseSelectComponent {
32658
32711
  });
32659
32712
  this.recalculateInlineSizeBounds();
32660
32713
  }
32714
+ writeValue(value) {
32715
+ super.writeValue(value);
32716
+ this.syncSelectedState(value);
32717
+ }
32661
32718
  setInputMetadata(metadata) {
32662
32719
  this.setTreeMetadata(metadata);
32663
32720
  }
@@ -32838,21 +32895,22 @@ class InlineTreeSelectComponent extends SimpleBaseSelectComponent {
32838
32895
  return this.tDynamicFields('inlineTreeSelect.emptyDefault', '');
32839
32896
  }
32840
32897
  displayText() {
32841
- if (!this.hasSelection()) {
32898
+ const lookup = this.currentSelectionLookup();
32899
+ if (!lookup) {
32842
32900
  return this.placeholderText();
32843
32901
  }
32844
- const pathLabels = this.selectedPathLabels();
32902
+ const pathLabels = lookup.path.map((item) => item.label);
32845
32903
  if (this.returnPath() && pathLabels.length > 0) {
32846
32904
  return pathLabels.join(' / ');
32847
32905
  }
32848
- const node = this.selectedNode();
32906
+ const node = lookup.node;
32849
32907
  if (node?.label) {
32850
32908
  return node.label;
32851
32909
  }
32852
32910
  return this.placeholderText();
32853
32911
  }
32854
32912
  hasSelection() {
32855
- return !!this.selectedNode();
32913
+ return !!this.currentSelectionLookup();
32856
32914
  }
32857
32915
  placeholderText() {
32858
32916
  const fromMeta = this.resolveFieldLabelFromMetadata(this.currentMetadata());
@@ -32973,6 +33031,9 @@ class InlineTreeSelectComponent extends SimpleBaseSelectComponent {
32973
33031
  this.selectedNode.set(lookup?.node ?? null);
32974
33032
  this.selectedPathLabels.set(lookup?.path?.map((item) => item.label) ?? []);
32975
33033
  }
33034
+ currentSelectionLookup() {
33035
+ return this.findNodeByCurrentValue(this.control().value, this.allNodes, []);
33036
+ }
32976
33037
  findNodeByCurrentValue(currentValue, nodes, path) {
32977
33038
  for (const node of nodes) {
32978
33039
  const nextPath = [...path, node];
@@ -34401,6 +34462,21 @@ class InlineDistanceRadiusComponent extends InlineRangeSliderComponent {
34401
34462
  if (mode === 'single') {
34402
34463
  return false;
34403
34464
  }
34465
+ const rawValue = this.currentRawDistanceValue();
34466
+ if (rawValue && typeof rawValue === 'object' && !Array.isArray(rawValue)) {
34467
+ const valueRecord = rawValue;
34468
+ const hasRangeShape = 'start' in valueRecord ||
34469
+ 'end' in valueRecord ||
34470
+ 'from' in valueRecord ||
34471
+ 'to' in valueRecord ||
34472
+ 'min' in valueRecord ||
34473
+ 'max' in valueRecord ||
34474
+ 'minPrice' in valueRecord ||
34475
+ 'maxPrice' in valueRecord;
34476
+ if (hasRangeShape) {
34477
+ return true;
34478
+ }
34479
+ }
34404
34480
  return super.isRangeMode();
34405
34481
  }
34406
34482
  chipLeadingIcon() {
@@ -34437,6 +34513,15 @@ class InlineDistanceRadiusComponent extends InlineRangeSliderComponent {
34437
34513
  }
34438
34514
  return this.distanceSingleLabel(value);
34439
34515
  }
34516
+ displayText() {
34517
+ return this.currentSelectionText();
34518
+ }
34519
+ hasSelection() {
34520
+ if (this.isRangeMode()) {
34521
+ return !!this.currentRangeBaseValue();
34522
+ }
34523
+ return this.currentBaseValue() !== null;
34524
+ }
34440
34525
  ariaLabel() {
34441
34526
  if (!this.hasSelection())
34442
34527
  return this.placeholderText();
@@ -34743,7 +34828,7 @@ class InlineDistanceRadiusComponent extends InlineRangeSliderComponent {
34743
34828
  return Math.max(0, Math.min(1, Number(candidate.toFixed(3))));
34744
34829
  }
34745
34830
  currentBaseValue() {
34746
- const raw = this.control().value;
34831
+ const raw = this.currentRawDistanceValue();
34747
34832
  if (raw === null || raw === undefined || raw === '')
34748
34833
  return null;
34749
34834
  const parsed = Number(raw);
@@ -34753,7 +34838,7 @@ class InlineDistanceRadiusComponent extends InlineRangeSliderComponent {
34753
34838
  }
34754
34839
  currentRangeBaseValue() {
34755
34840
  const md = this.currentDistanceMetadata();
34756
- const raw = this.control().value;
34841
+ const raw = this.currentRawDistanceValue();
34757
34842
  if (!raw || typeof raw !== 'object')
34758
34843
  return null;
34759
34844
  const rawValue = raw;
@@ -34764,6 +34849,17 @@ class InlineDistanceRadiusComponent extends InlineRangeSliderComponent {
34764
34849
  end: this.toDistanceNumberOrNull(endRaw),
34765
34850
  });
34766
34851
  }
34852
+ currentRawDistanceValue() {
34853
+ const controlValue = this.control().value;
34854
+ if (controlValue !== null && controlValue !== undefined && controlValue !== '') {
34855
+ return controlValue;
34856
+ }
34857
+ const fieldValue = this.fieldState().value;
34858
+ if (fieldValue !== null && fieldValue !== undefined && fieldValue !== '') {
34859
+ return fieldValue;
34860
+ }
34861
+ return controlValue;
34862
+ }
34767
34863
  currentRadialBaseValue() {
34768
34864
  if (this.isRangeMode()) {
34769
34865
  const range = this.currentRangeBaseValue();
@@ -39001,7 +39097,7 @@ class InlineSentimentComponent extends SimpleBaseSelectComponent {
39001
39097
  return this.displayText();
39002
39098
  }
39003
39099
  hasSelection() {
39004
- const value = this.control().value;
39100
+ const value = this.currentRawSelectionValue();
39005
39101
  if (this.multipleMode()) {
39006
39102
  return Array.isArray(value) && value.length > 0;
39007
39103
  }
@@ -39011,7 +39107,7 @@ class InlineSentimentComponent extends SimpleBaseSelectComponent {
39011
39107
  if (!this.hasSelection()) {
39012
39108
  return this.placeholderText();
39013
39109
  }
39014
- const selected = this.selectedOptions();
39110
+ const selected = this.currentSelectionVisuals();
39015
39111
  if (!selected.length) {
39016
39112
  return this.placeholderText();
39017
39113
  }
@@ -39124,7 +39220,7 @@ class InlineSentimentComponent extends SimpleBaseSelectComponent {
39124
39220
  return optionPool.map((option, index) => this.toVisualOption(option, index, optionPool.length));
39125
39221
  }
39126
39222
  selectedOptions() {
39127
- return this.sentimentOptions().filter((option) => option.selected);
39223
+ return this.currentSelectionVisuals();
39128
39224
  }
39129
39225
  showSelectionPills() {
39130
39226
  const md = this.currentMetadata();
@@ -39299,7 +39395,7 @@ class InlineSentimentComponent extends SimpleBaseSelectComponent {
39299
39395
  .filter((entry) => entry.length > 0);
39300
39396
  }
39301
39397
  selectedValues() {
39302
- const value = this.control().value;
39398
+ const value = this.currentRawSelectionValue();
39303
39399
  if (this.multipleMode()) {
39304
39400
  return Array.isArray(value) ? value : [];
39305
39401
  }
@@ -39308,6 +39404,58 @@ class InlineSentimentComponent extends SimpleBaseSelectComponent {
39308
39404
  }
39309
39405
  return [value];
39310
39406
  }
39407
+ currentRawSelectionValue() {
39408
+ const controlValue = this.control().value;
39409
+ if (controlValue !== null && controlValue !== undefined && controlValue !== '') {
39410
+ return controlValue;
39411
+ }
39412
+ const fieldValue = this.fieldState().value;
39413
+ if (fieldValue !== null && fieldValue !== undefined && fieldValue !== '') {
39414
+ return fieldValue;
39415
+ }
39416
+ return controlValue;
39417
+ }
39418
+ currentSelectionVisuals() {
39419
+ const selectedValues = this.selectedValues();
39420
+ if (!selectedValues.length) {
39421
+ return [];
39422
+ }
39423
+ const optionPool = this.sentimentOptions();
39424
+ const visuals = [];
39425
+ for (const selectedValue of selectedValues) {
39426
+ const matched = optionPool.find((option) => this.equalsOptionValue(option.value, selectedValue));
39427
+ if (matched) {
39428
+ visuals.push(matched);
39429
+ continue;
39430
+ }
39431
+ visuals.push(this.fallbackVisualFromValue(selectedValue, optionPool.length + visuals.length));
39432
+ }
39433
+ return visuals;
39434
+ }
39435
+ fallbackVisualFromValue(value, index) {
39436
+ const rawOptions = this.parseOptionsSource(this.currentMetadata().sentimentOptions) ??
39437
+ this.parseOptionsSource(this.currentMetadata().options) ??
39438
+ DEFAULT_SENTIMENT_OPTIONS;
39439
+ const optionRecord = rawOptions
39440
+ .map((entry) => this.asRecord(entry))
39441
+ .find((entry) => entry && this.equalsOptionValue(entry.value ?? entry.id ?? entry.key ?? entry.code, value));
39442
+ const label = String(optionRecord?.label ??
39443
+ optionRecord?.text ??
39444
+ optionRecord?.name ??
39445
+ optionRecord?.title ??
39446
+ value ??
39447
+ '').trim();
39448
+ return {
39449
+ id: String(optionRecord?.id ?? optionRecord?.key ?? `sentiment-selected-${index}`),
39450
+ label: label || String(value ?? this.placeholderText()).trim() || this.placeholderText(),
39451
+ subtitle: String(optionRecord?.subtitle ?? optionRecord?.description ?? '').trim(),
39452
+ emoji: this.resolveOptionEmoji(optionRecord ?? {}),
39453
+ color: this.resolveOptionColor(optionRecord ?? {}, index, Math.max(rawOptions.length, index + 1)),
39454
+ value,
39455
+ disabled: false,
39456
+ selected: true,
39457
+ };
39458
+ }
39311
39459
  resolveCloseOnSelect() {
39312
39460
  const md = this.currentMetadata();
39313
39461
  if (typeof md.sentimentCloseOnSelect === 'boolean') {
@@ -40915,7 +41063,7 @@ class MaterialMultiSelectComponent extends SimpleBaseSelectComponent {
40915
41063
  };
40916
41064
  }
40917
41065
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: MaterialMultiSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
40918
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: MaterialMultiSelectComponent, isStandalone: true, selector: "pdx-material-multi-select", inputs: { readonlyMode: "readonlyMode", disabledMode: "disabledMode", visible: "visible", presentationMode: "presentationMode" }, host: { properties: { "class": "componentCssClasses()", "class.praxis-disabled": "disabledMode", "style.display": "visible ? null : \"none\"", "attr.aria-hidden": "visible ? null : \"true\"", "attr.data-field-type": "\"multi-select\"", "attr.data-field-name": "metadata()?.name", "attr.data-component-id": "componentId()" } }, providers: [
41066
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: MaterialMultiSelectComponent, isStandalone: true, selector: "pdx-material-multi-select", inputs: { readonlyMode: "readonlyMode", disabledMode: "disabledMode", visible: "visible", presentationMode: "presentationMode" }, host: { properties: { "class": "componentCssClasses()", "class.praxis-disabled": "isInteractionDisabled()", "style.display": "visible ? null : \"none\"", "attr.aria-hidden": "visible ? null : \"true\"", "attr.data-field-type": "\"multi-select\"", "attr.data-field-name": "metadata()?.name", "attr.data-component-id": "componentId()" } }, providers: [
40919
41067
  GenericCrudService,
40920
41068
  {
40921
41069
  provide: NG_VALUE_ACCESSOR,
@@ -40944,6 +41092,7 @@ class MaterialMultiSelectComponent extends SimpleBaseSelectComponent {
40944
41092
  [errorStateMatcher]="errorStateMatcher()"
40945
41093
  multiple
40946
41094
  [formControl]="control()"
41095
+ [disabled]="isInteractionDisabled()"
40947
41096
  [required]="metadata()?.required || false"
40948
41097
  [matTooltip]="tooltipEnabled() ? errorMessage() : null"
40949
41098
  [matTooltipDisabled]="!(tooltipEnabled() && !!errorMessage())"
@@ -40991,7 +41140,7 @@ class MaterialMultiSelectComponent extends SimpleBaseSelectComponent {
40991
41140
  matSuffix
40992
41141
  type="button"
40993
41142
  (click)="onClearClick()"
40994
- [disabled]="disabledMode || isReadonlyEffective() || presentationMode"
41143
+ [disabled]="isInteractionDisabled()"
40995
41144
  [matTooltip]="clearActionTooltip()"
40996
41145
  [attr.aria-label]="clearActionAriaLabel()"
40997
41146
  >
@@ -41049,6 +41198,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
41049
41198
  [errorStateMatcher]="errorStateMatcher()"
41050
41199
  multiple
41051
41200
  [formControl]="control()"
41201
+ [disabled]="isInteractionDisabled()"
41052
41202
  [required]="metadata()?.required || false"
41053
41203
  [matTooltip]="tooltipEnabled() ? errorMessage() : null"
41054
41204
  [matTooltipDisabled]="!(tooltipEnabled() && !!errorMessage())"
@@ -41096,7 +41246,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
41096
41246
  matSuffix
41097
41247
  type="button"
41098
41248
  (click)="onClearClick()"
41099
- [disabled]="disabledMode || isReadonlyEffective() || presentationMode"
41249
+ [disabled]="isInteractionDisabled()"
41100
41250
  [matTooltip]="clearActionTooltip()"
41101
41251
  [attr.aria-label]="clearActionAriaLabel()"
41102
41252
  >
@@ -41125,7 +41275,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
41125
41275
  ],
41126
41276
  host: {
41127
41277
  '[class]': 'componentCssClasses()',
41128
- '[class.praxis-disabled]': 'disabledMode',
41278
+ '[class.praxis-disabled]': 'isInteractionDisabled()',
41129
41279
  '[style.display]': 'visible ? null : "none"',
41130
41280
  '[attr.aria-hidden]': 'visible ? null : "true"',
41131
41281
  '[attr.data-field-type]': '"multi-select"',
@@ -49346,6 +49496,108 @@ function createDefaultSeedRecipe(initialValue, note) {
49346
49496
  note,
49347
49497
  };
49348
49498
  }
49499
+ function createFilledSeedRecipe(initialValue, note, metadataPatch) {
49500
+ return {
49501
+ state: 'filled',
49502
+ label: 'Filled',
49503
+ supported: true,
49504
+ initialValue,
49505
+ note,
49506
+ metadataPatch,
49507
+ };
49508
+ }
49509
+ const INLINE_ASYNC_SELECT_PREVIEW_METADATA = {
49510
+ searchable: true,
49511
+ options: [
49512
+ { label: 'Tony Stark', value: 'TONY', subtitle: 'Stark Industries' },
49513
+ { label: 'Carol Danvers', value: 'CAROL', subtitle: 'Deep-space response' },
49514
+ { label: 'Natasha Romanoff', value: 'NATASHA', subtitle: 'Intelligence desk' },
49515
+ ],
49516
+ };
49517
+ const INLINE_TREE_SELECT_PREVIEW_METADATA = {
49518
+ searchable: true,
49519
+ nodes: [
49520
+ {
49521
+ label: 'Command center',
49522
+ value: 'command-center',
49523
+ children: [
49524
+ { label: 'Operations board', value: 'operations-board' },
49525
+ { label: 'Audit trail', value: 'audit-trail' },
49526
+ ],
49527
+ },
49528
+ {
49529
+ label: 'Field squads',
49530
+ value: 'field-squads',
49531
+ children: [
49532
+ { label: 'Rapid response', value: 'rapid-response' },
49533
+ { label: 'Evidence team', value: 'evidence-team' },
49534
+ ],
49535
+ },
49536
+ ],
49537
+ };
49538
+ const INLINE_PIPELINE_STATUS_PREVIEW_METADATA = {
49539
+ multiple: true,
49540
+ options: [
49541
+ { label: 'Qualified', value: 'QUALIFIED', subtitle: 'Ready for analyst review', color: '#38bdf8', weight: 2 },
49542
+ { label: 'Investigating', value: 'INVESTIGATING', subtitle: 'Evidence collection active', color: '#a855f7', weight: 3 },
49543
+ { label: 'Approved', value: 'APPROVED', subtitle: 'Cleared for execution', color: '#22c55e', weight: 2 },
49544
+ { label: 'Escalated', value: 'ESCALATED', subtitle: 'Needs leadership action', color: '#f97316', weight: 1 },
49545
+ ],
49546
+ };
49547
+ const INLINE_RELATIVE_PERIOD_PREVIEW_METADATA = {
49548
+ relativePeriodShowProgress: true,
49549
+ relativePeriodColumns: 2,
49550
+ };
49551
+ const INLINE_COLOR_LABEL_PREVIEW_METADATA = {
49552
+ multiple: true,
49553
+ options: [
49554
+ { id: 'critical', label: 'Critical', value: 'critical', color: '#ef4444', subtitle: 'Immediate escalation' },
49555
+ { id: 'watch', label: 'Watchlist', value: 'watch', color: '#f59e0b', subtitle: 'Track closely this week' },
49556
+ { id: 'stable', label: 'Stable', value: 'stable', color: '#22c55e', subtitle: 'Healthy operating state' },
49557
+ { id: 'info', label: 'Informational', value: 'info', color: '#3b82f6', subtitle: 'Low urgency context' },
49558
+ ],
49559
+ };
49560
+ const INLINE_SCORE_PRIORITY_PREVIEW_METADATA = {
49561
+ min: 0,
49562
+ max: 100,
49563
+ unit: 'pts',
49564
+ bands: [
49565
+ { id: 'low', label: 'Low', start: 0, end: 34, color: '#22c55e' },
49566
+ { id: 'medium', label: 'Medium', start: 35, end: 69, color: '#f59e0b' },
49567
+ { id: 'high', label: 'High', start: 70, end: 100, color: '#ef4444' },
49568
+ ],
49569
+ };
49570
+ const INLINE_RATING_PREVIEW_METADATA = {
49571
+ min: 1,
49572
+ max: 5,
49573
+ step: 1,
49574
+ discrete: true,
49575
+ };
49576
+ const INLINE_RANGE_PREVIEW_METADATA = {
49577
+ mode: 'range',
49578
+ min: 0,
49579
+ max: 100,
49580
+ quickPresetsAuto: true,
49581
+ distribution: [6, 12, 18, 24, 34, 48, 42, 30, 18, 10],
49582
+ };
49583
+ const INLINE_DISTANCE_RADIUS_PREVIEW_METADATA = {
49584
+ mode: 'range',
49585
+ min: 1,
49586
+ max: 150,
49587
+ step: 1,
49588
+ distanceUnit: 'km',
49589
+ distanceBaseUnit: 'km',
49590
+ distanceAllowUnitToggle: true,
49591
+ distanceSubtitle: 'Visualizacao radial com controle de raio e unidade',
49592
+ distanceRadialRings: 5,
49593
+ distanceAccentColor: '#3f5be6',
49594
+ inlineAutoSize: {
49595
+ minWidth: 188,
49596
+ maxWidth: 360,
49597
+ panelMinWidth: 340,
49598
+ panelMaxWidth: 560,
49599
+ },
49600
+ };
49349
49601
  const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
49350
49602
  createWave1Entry({
49351
49603
  id: 'text-input',
@@ -50225,6 +50477,7 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50225
50477
  apiPath: jsonApiPath('inline-select/pdx-inline-select.json-api.md'),
50226
50478
  stateRecipes: [
50227
50479
  createDefaultSeedRecipe('ALPHA', 'Seeded default preview to expose compact selected-pill rendering.'),
50480
+ createFilledSeedRecipe('GAMMA', 'Filled preview switches to a second local option so the compact pill demonstrates state transition clearly.'),
50228
50481
  ],
50229
50482
  }),
50230
50483
  createEntry({
@@ -50240,6 +50493,9 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50240
50493
  avoidWhen: ['a simple select is enough'],
50241
50494
  dataSourceKind: 'mixed',
50242
50495
  apiPath: jsonApiPath('inline-searchable-select/pdx-inline-searchable-select.json-api.md'),
50496
+ stateRecipes: [
50497
+ createDefaultSeedRecipe('BETA', 'Seeded default preview to expose compact search-backed inline selection.'),
50498
+ ],
50243
50499
  }),
50244
50500
  createEntry({
50245
50501
  id: 'inline-async-select',
@@ -50254,6 +50510,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50254
50510
  avoidWhen: ['small local list'],
50255
50511
  dataSourceKind: 'remote',
50256
50512
  apiPath: jsonApiPath('inline-async-select/pdx-inline-async-select.json-api.md'),
50513
+ metadata: INLINE_ASYNC_SELECT_PREVIEW_METADATA,
50514
+ stateRecipes: [
50515
+ createDefaultSeedRecipe('TONY', 'Seeded default preview to expose remote-label resolution instead of an empty toolbar shell.'),
50516
+ createFilledSeedRecipe('CAROL', 'Filled preview uses a representative async label so the chip demonstrates selected-value rendering.'),
50517
+ ],
50257
50518
  }),
50258
50519
  createEntry({
50259
50520
  id: 'inline-entity-lookup',
@@ -50268,6 +50529,10 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50268
50529
  avoidWhen: ['simple local select'],
50269
50530
  dataSourceKind: 'remote',
50270
50531
  apiPath: jsonApiPath('inline-entity-lookup/pdx-inline-entity-lookup.json-api.md'),
50532
+ stateRecipes: [
50533
+ createDefaultSeedRecipe('BETA', 'Seeded default preview to expose entity label hydration instead of an empty lookup shell.'),
50534
+ createFilledSeedRecipe('GAMMA', 'Filled preview resolves a second entity so remote identity rendering stays explicit in the toolbar.'),
50535
+ ],
50271
50536
  }),
50272
50537
  createEntry({
50273
50538
  id: 'inline-autocomplete',
@@ -50282,6 +50547,10 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50282
50547
  avoidWhen: ['a simple select is enough'],
50283
50548
  dataSourceKind: 'mixed',
50284
50549
  apiPath: jsonApiPath('inline-autocomplete/pdx-inline-autocomplete.json-api.md'),
50550
+ stateRecipes: [
50551
+ createDefaultSeedRecipe('ALPHA', 'Seeded default preview to expose compact autocomplete selection immediately.'),
50552
+ createFilledSeedRecipe('GAMMA', 'Filled preview switches to another suggestion-backed option so the inline chip does not appear frozen.'),
50553
+ ],
50285
50554
  }),
50286
50555
  createEntry({
50287
50556
  id: 'inline-multi-select',
@@ -50296,6 +50565,10 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50296
50565
  avoidWhen: ['need to read every selected item in full'],
50297
50566
  dataSourceKind: 'mixed',
50298
50567
  apiPath: jsonApiPath('inline-multi-select/pdx-inline-multi-select.json-api.md'),
50568
+ stateRecipes: [
50569
+ createDefaultSeedRecipe(['ALPHA', 'BETA'], 'Seeded default preview to expose the multi-selection summary chip.'),
50570
+ createFilledSeedRecipe(['BETA', 'GAMMA'], 'Filled preview rotates the selected set so the compact multi-summary reflects a real state change.'),
50571
+ ],
50299
50572
  }),
50300
50573
  createEntry({
50301
50574
  id: 'inline-number',
@@ -50310,6 +50583,10 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50310
50583
  avoidWhen: ['range'],
50311
50584
  dataSourceKind: 'local',
50312
50585
  apiPath: jsonApiPath('inline-number/pdx-inline-number.json-api.md'),
50586
+ stateRecipes: [
50587
+ createDefaultSeedRecipe(42, 'Seeded default preview to expose numeric value rendering from first paint.'),
50588
+ createFilledSeedRecipe(84, 'Filled preview doubles the seeded value so the toolbar example communicates a concrete numeric change.'),
50589
+ ],
50313
50590
  }),
50314
50591
  createEntry({
50315
50592
  id: 'inline-currency',
@@ -50324,6 +50601,10 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50324
50601
  avoidWhen: ['currency range'],
50325
50602
  dataSourceKind: 'local',
50326
50603
  apiPath: jsonApiPath('inline-currency/pdx-inline-currency.json-api.md'),
50604
+ stateRecipes: [
50605
+ createDefaultSeedRecipe(18450.75, 'Seeded default preview to expose compact currency formatting instead of an empty monetary shell.'),
50606
+ createFilledSeedRecipe(98240.5, 'Filled preview uses a second monetary value so the formatted chip clearly changes between states.'),
50607
+ ],
50327
50608
  }),
50328
50609
  createEntry({
50329
50610
  id: 'inline-currency-range',
@@ -50338,6 +50619,10 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50338
50619
  avoidWhen: ['single value'],
50339
50620
  dataSourceKind: 'specialized',
50340
50621
  apiPath: jsonApiPath('inline-currency-range/pdx-inline-currency-range.json-api.md'),
50622
+ stateRecipes: [
50623
+ createDefaultSeedRecipe({ minPrice: 1200, maxPrice: 5800, currency: 'BRL' }, 'Seeded default preview to expose the compact monetary band immediately.'),
50624
+ createFilledSeedRecipe({ minPrice: 2400, maxPrice: 9800, currency: 'BRL' }, 'Filled preview broadens the monetary band so the inline summary changes with a realistic price window.'),
50625
+ ],
50341
50626
  }),
50342
50627
  createEntry({
50343
50628
  id: 'inline-range',
@@ -50353,6 +50638,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50353
50638
  dataSourceKind: 'specialized',
50354
50639
  apiPath: jsonApiPath('inline-currency-range/pdx-inline-currency-range.json-api.md'),
50355
50640
  detailFragment: 'inline-range',
50641
+ metadata: INLINE_RANGE_PREVIEW_METADATA,
50642
+ stateRecipes: [
50643
+ createDefaultSeedRecipe({ start: 18, end: 42 }, 'Seeded default preview to show a compact numeric band instead of an empty range trigger.'),
50644
+ createFilledSeedRecipe({ start: 24, end: 68 }, 'Filled preview uses a broader resolved band so the inline chip communicates the selected range clearly.'),
50645
+ ],
50356
50646
  }),
50357
50647
  createEntry({
50358
50648
  id: 'inline-rating',
@@ -50367,6 +50657,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50367
50657
  avoidWhen: ['when a raw number is enough'],
50368
50658
  dataSourceKind: 'specialized',
50369
50659
  apiPath: jsonApiPath('inline-rating/pdx-inline-rating.json-api.md'),
50660
+ metadata: INLINE_RATING_PREVIEW_METADATA,
50661
+ stateRecipes: [
50662
+ createDefaultSeedRecipe({ start: 3, end: 5 }, 'Seeded default preview to make the rating band visible from the first render.'),
50663
+ createFilledSeedRecipe({ start: 4, end: 5 }, 'Filled preview demonstrates a higher rating band so the chip and stars remain communicative.'),
50664
+ ],
50370
50665
  }),
50371
50666
  createEntry({
50372
50667
  id: 'inline-distance-radius',
@@ -50382,6 +50677,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50382
50677
  dataSourceKind: 'specialized',
50383
50678
  interactionPattern: 'range',
50384
50679
  apiPath: jsonApiPath('inline-distance-radius/pdx-inline-distance-radius.json-api.md'),
50680
+ metadata: INLINE_DISTANCE_RADIUS_PREVIEW_METADATA,
50681
+ stateRecipes: [
50682
+ createDefaultSeedRecipe({ start: 5, end: 25 }, 'Seeded default preview to expose a representative proximity band instead of an empty radial shell.'),
50683
+ createFilledSeedRecipe({ start: 15, end: 60 }, 'Filled preview expands the distance window so the semantic radius visibly evolves between states.'),
50684
+ ],
50385
50685
  }),
50386
50686
  createEntry({
50387
50687
  id: 'inline-score-priority',
@@ -50398,6 +50698,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50398
50698
  icon: { key: 'visual', tone: 'amber' },
50399
50699
  interactionPattern: 'visual',
50400
50700
  apiPath: jsonApiPath('inline-score-priority/pdx-inline-score-priority.json-api.md'),
50701
+ metadata: INLINE_SCORE_PRIORITY_PREVIEW_METADATA,
50702
+ stateRecipes: [
50703
+ createDefaultSeedRecipe({ start: 55, end: 78 }, 'Seeded default preview to expose semantic score bands instead of a neutral shell.'),
50704
+ createFilledSeedRecipe({ start: 70, end: 92 }, 'Filled preview demonstrates a high-priority band with explicit score semantics.'),
50705
+ ],
50401
50706
  }),
50402
50707
  createEntry({
50403
50708
  id: 'inline-date',
@@ -50412,6 +50717,10 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50412
50717
  avoidWhen: ['full period'],
50413
50718
  dataSourceKind: 'specialized',
50414
50719
  apiPath: jsonApiPath('inline-date/pdx-inline-date.json-api.md'),
50720
+ stateRecipes: [
50721
+ createDefaultSeedRecipe('2026-03-18', 'Seeded default preview to expose compact date rendering from the first frame.'),
50722
+ createFilledSeedRecipe('2026-03-23', 'Filled preview advances the selected date so the inline field reflects a clear temporal change.'),
50723
+ ],
50415
50724
  }),
50416
50725
  createEntry({
50417
50726
  id: 'inline-date-range',
@@ -50428,6 +50737,7 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50428
50737
  apiPath: jsonApiPath('inline-date-range/pdx-inline-date-range.json-api.md'),
50429
50738
  stateRecipes: [
50430
50739
  createDefaultSeedRecipe({ startDate: '2026-03-01', endDate: '2026-03-23' }, 'Seeded default preview to show a resolved inline range immediately.'),
50740
+ createFilledSeedRecipe({ startDate: '2026-03-08', endDate: '2026-03-28' }, 'Filled preview moves the selected period forward so the inline date window changes in a visible way.'),
50431
50741
  ],
50432
50742
  }),
50433
50743
  createEntry({
@@ -50443,6 +50753,10 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50443
50753
  avoidWhen: ['relative period or range'],
50444
50754
  dataSourceKind: 'specialized',
50445
50755
  apiPath: jsonApiPath('inline-time/pdx-inline-time.json-api.md'),
50756
+ stateRecipes: [
50757
+ createDefaultSeedRecipe('08:30', 'Seeded default preview to expose compact time rendering instead of an empty trigger.'),
50758
+ createFilledSeedRecipe('14:45', 'Filled preview switches to an afternoon slot so the time example reflects a real state change.'),
50759
+ ],
50446
50760
  }),
50447
50761
  createEntry({
50448
50762
  id: 'inline-time-range',
@@ -50457,6 +50771,10 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50457
50771
  avoidWhen: ['single time'],
50458
50772
  dataSourceKind: 'specialized',
50459
50773
  apiPath: jsonApiPath('inline-time-range/pdx-inline-time-range.json-api.md'),
50774
+ stateRecipes: [
50775
+ createDefaultSeedRecipe({ start: '08:30', end: '17:30' }, 'Seeded default preview to show an operational window immediately.'),
50776
+ createFilledSeedRecipe({ start: '13:15', end: '21:45' }, 'Filled preview shifts the operational window so the range state does not remain visually static.'),
50777
+ ],
50460
50778
  }),
50461
50779
  createEntry({
50462
50780
  id: 'inline-tree-select',
@@ -50471,6 +50789,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50471
50789
  avoidWhen: ['tree that is too deep'],
50472
50790
  dataSourceKind: 'mixed',
50473
50791
  apiPath: jsonApiPath('inline-tree-select/pdx-inline-tree-select.json-api.md'),
50792
+ metadata: INLINE_TREE_SELECT_PREVIEW_METADATA,
50793
+ stateRecipes: [
50794
+ createDefaultSeedRecipe('audit-trail', 'Seeded default preview to expose resolved tree-label rendering in the inline trigger.'),
50795
+ createFilledSeedRecipe('rapid-response', 'Filled preview resolves a second branch so the tree example communicates hierarchical selection clearly.'),
50796
+ ],
50474
50797
  }),
50475
50798
  createEntry({
50476
50799
  id: 'inline-pipeline-status',
@@ -50487,6 +50810,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50487
50810
  icon: { key: 'visual', tone: 'violet' },
50488
50811
  interactionPattern: 'visual',
50489
50812
  apiPath: jsonApiPath('inline-pipeline-status/pdx-inline-pipeline-status.json-api.md'),
50813
+ metadata: INLINE_PIPELINE_STATUS_PREVIEW_METADATA,
50814
+ stateRecipes: [
50815
+ createDefaultSeedRecipe(['QUALIFIED', 'INVESTIGATING'], 'Seeded default preview to expose semantic pipeline pills and segmented status rendering.'),
50816
+ createFilledSeedRecipe(['APPROVED', 'ESCALATED'], 'Filled preview demonstrates a more operational combination so the chip summary stays meaningful.'),
50817
+ ],
50490
50818
  }),
50491
50819
  createEntry({
50492
50820
  id: 'inline-relative-period',
@@ -50501,6 +50829,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50501
50829
  avoidWhen: ['API outside the canonical track that does not normalize presets'],
50502
50830
  dataSourceKind: 'specialized',
50503
50831
  apiPath: jsonApiPath('inline-relative-period/pdx-inline-relative-period.json-api.md'),
50832
+ metadata: INLINE_RELATIVE_PERIOD_PREVIEW_METADATA,
50833
+ stateRecipes: [
50834
+ createDefaultSeedRecipe('last7', 'Seeded default preview to expose a normalized relative-period preset in the inline trigger.'),
50835
+ createFilledSeedRecipe('thisMonth', 'Filled preview uses a second preset so the example communicates semantic period switching.'),
50836
+ ],
50504
50837
  }),
50505
50838
  createEntry({
50506
50839
  id: 'inline-sentiment',
@@ -50517,6 +50850,10 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50517
50850
  icon: { key: 'visual', tone: 'rose' },
50518
50851
  interactionPattern: 'visual',
50519
50852
  apiPath: jsonApiPath('inline-sentiment/pdx-inline-sentiment.json-api.md'),
50853
+ stateRecipes: [
50854
+ createDefaultSeedRecipe('neutral', 'Seeded default preview to expose a sentiment selection immediately instead of an empty semantic shell.'),
50855
+ createFilledSeedRecipe('great', 'Filled preview moves the sentiment to a stronger positive state so the semantic filter clearly changes.'),
50856
+ ],
50520
50857
  }),
50521
50858
  createEntry({
50522
50859
  id: 'inline-color-label',
@@ -50533,6 +50870,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50533
50870
  icon: { key: 'visual', tone: 'teal' },
50534
50871
  interactionPattern: 'visual',
50535
50872
  apiPath: jsonApiPath('inline-color-label/pdx-inline-color-label.json-api.md'),
50873
+ metadata: INLINE_COLOR_LABEL_PREVIEW_METADATA,
50874
+ stateRecipes: [
50875
+ createDefaultSeedRecipe(['critical', 'watch'], 'Seeded default preview to expose semantic color-label chips instead of a neutral pill.'),
50876
+ createFilledSeedRecipe(['stable', 'info'], 'Filled preview demonstrates a lower-urgency combination while preserving textual meaning beyond color.'),
50877
+ ],
50536
50878
  a11yNotes: [
50537
50879
  'Nunca dependa apenas de cor para comunicar estado ou significado.',
50538
50880
  'Garanta contraste AA e rotulagem textual no resumo da pill e no painel.',
@@ -50553,6 +50895,7 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
50553
50895
  apiPath: jsonApiPath('inline-toggle/pdx-inline-toggle.json-api.md'),
50554
50896
  stateRecipes: [
50555
50897
  createDefaultSeedRecipe(true, 'Seeded default preview to show the compact boolean state in toolbar scenarios.'),
50898
+ createFilledSeedRecipe(false, 'Filled preview toggles to the explicit false state so the toolbar example demonstrates both boolean outcomes.'),
50556
50899
  ],
50557
50900
  }),
50558
50901
  ];
package/index.d.ts CHANGED
@@ -977,6 +977,10 @@ declare abstract class SimpleBaseSelectComponent<T = any> extends SimpleBaseInpu
977
977
  private hasLoadedOnce;
978
978
  /** Options filtered according to the current `searchTerm` */
979
979
  readonly filteredOptions: _angular_core.Signal<SelectOption<T>[]>;
980
+ /**
981
+ * Applies typed metadata to the select component.
982
+ */
983
+ setInputMetadata(metadata: ComponentMetadata): void;
980
984
  /**
981
985
  * Applies typed metadata to the select component.
982
986
  */
@@ -985,6 +989,7 @@ declare abstract class SimpleBaseSelectComponent<T = any> extends SimpleBaseInpu
985
989
  protected registerMatSelect(select: MatSelect): void;
986
990
  protected applySelectAttributes(): void;
987
991
  protected isReadonlyEffective(): boolean;
992
+ protected isInteractionDisabled(): boolean;
988
993
  /** Whether to show the clear button (if enabled in metadata) */
989
994
  showClear(): boolean;
990
995
  /** Clears the selection according to single/multiple mode */
@@ -1528,6 +1533,7 @@ declare class DynamicFieldLoaderDirective implements OnInit, OnDestroy, OnChange
1528
1533
  * Aplica os estados globais aos shells já criados, sem re-render completo.
1529
1534
  */
1530
1535
  private applyGlobalStates;
1536
+ private applyShellEffectiveStatesToComponent;
1531
1537
  /**
1532
1538
  * Tenta inferir o controlType a partir do próprio field.
1533
1539
  * Retorna null quando não é possível inferir, mantendo a validação original.
@@ -3041,6 +3047,7 @@ declare class InlineToggleComponent extends SimpleBaseInputComponent {
3041
3047
  onTriggerIconMouseDown(event: MouseEvent): void;
3042
3048
  onQuickClear(event: MouseEvent): void;
3043
3049
  placeholderText(): string;
3050
+ toggleLabelText(): string;
3044
3051
  ariaLabel(): string;
3045
3052
  isReadonlyEffective(): boolean;
3046
3053
  showTextLabel(): boolean;
@@ -3765,7 +3772,8 @@ declare class InlineTreeSelectComponent extends SimpleBaseSelectComponent {
3765
3772
  private asRecord;
3766
3773
  hasChild: (_: number, node: MaterialTreeNode) => boolean;
3767
3774
  onComponentInit(): void;
3768
- setInputMetadata(metadata: MaterialTreeSelectMetadata): void;
3775
+ writeValue(value: unknown): void;
3776
+ setInputMetadata(metadata: ComponentMetadata): void;
3769
3777
  setTreeMetadata(metadata: MaterialTreeSelectMetadata): void;
3770
3778
  onViewportResize(): void;
3771
3779
  protected getSpecificCssClasses(): string[];
@@ -3799,6 +3807,7 @@ declare class InlineTreeSelectComponent extends SimpleBaseSelectComponent {
3799
3807
  private filterNodes;
3800
3808
  private countNodes;
3801
3809
  private syncSelectedState;
3810
+ private currentSelectionLookup;
3802
3811
  private findNodeByCurrentValue;
3803
3812
  private matchesCurrentValue;
3804
3813
  private normalizeNodes;
@@ -3892,6 +3901,8 @@ declare class InlineDistanceRadiusComponent extends InlineRangeSliderComponent {
3892
3901
  chipLeadingIcon(): string;
3893
3902
  placeholderText(): string;
3894
3903
  currentSelectionText(): string;
3904
+ displayText(): string;
3905
+ hasSelection(): boolean;
3895
3906
  ariaLabel(): string;
3896
3907
  protected getSpecificCssClasses(): string[];
3897
3908
  protected resolveInlineContextTooltipValue(): string;
@@ -3939,6 +3950,7 @@ declare class InlineDistanceRadiusComponent extends InlineRangeSliderComponent {
3939
3950
  private distanceRangeBandOpacityOverride;
3940
3951
  private currentBaseValue;
3941
3952
  private currentRangeBaseValue;
3953
+ private currentRawDistanceValue;
3942
3954
  private currentRadialBaseValue;
3943
3955
  private currentNormalizedRangeRatios;
3944
3956
  private clampBaseValue;
@@ -4347,6 +4359,9 @@ declare class InlineSentimentComponent extends SimpleBaseSelectComponent {
4347
4359
  private sentimentGradientColorByRatio;
4348
4360
  private parseColorList;
4349
4361
  private selectedValues;
4362
+ private currentRawSelectionValue;
4363
+ private currentSelectionVisuals;
4364
+ private fallbackVisualFromValue;
4350
4365
  private resolveCloseOnSelect;
4351
4366
  private resolveMultipleMode;
4352
4367
  private equalsOptionValue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@praxisui/dynamic-fields",
3
- "version": "4.0.0-beta.0",
3
+ "version": "5.0.0-beta.0",
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",
@@ -10,10 +10,9 @@
10
10
  "@angular/cdk": "^20.1.0",
11
11
  "@angular/router": "^20.1.0",
12
12
  "rxjs": "^7.8.0",
13
- "@praxisui/specification-core": "^4.0.0-beta.0",
14
- "@praxisui/core": "^4.0.0-beta.0",
15
- "@praxisui/cron-builder": "^4.0.0-beta.0",
16
- "@praxisui/dialog": "^4.0.0-beta.0"
13
+ "@praxisui/core": "^5.0.0-beta.0",
14
+ "@praxisui/cron-builder": "^5.0.0-beta.0",
15
+ "@praxisui/dialog": "^5.0.0-beta.0"
17
16
  },
18
17
  "dependencies": {
19
18
  "tslib": "^2.3.0"