@tsi-developpement/tsi-shared-ui 1.9.2 → 1.9.3

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.
@@ -8,8 +8,16 @@ import * as i4 from "../../../tsi-directives/auto-select.directive";
8
8
  export class TsiRateInputComponent extends TsiInputBase {
9
9
  constructor() {
10
10
  super(...arguments);
11
- // isFraction = true : 2% est enregistré 0.02
12
- // isFraction = false : 2% est enregistré 2
11
+ /**
12
+ * Governs how the percentage the user sees/edits relates to the value stored in the model.
13
+ * The user always reads and types a percentage; this flag only changes what is persisted.
14
+ *
15
+ * - false (default): "2 %" on screen is stored as the whole percent `2`.
16
+ * - true : "2 %" on screen is stored as the fraction `0.02`.
17
+ *
18
+ * Must match the `isFraction` given to the mirror `Tsi-Rate-Display` so the pair
19
+ * interprets a stored value identically.
20
+ */
13
21
  this.isFraction = false;
14
22
  this.numOfDecimal = 2;
15
23
  //#endregion
@@ -19,16 +27,17 @@ export class TsiRateInputComponent extends TsiInputBase {
19
27
  //#endregion
20
28
  this.isValueChanged = false;
21
29
  }
22
- ngOnInit() {
23
- super.ngOnInit();
24
- // if (this.inputField === undefined || this.inputField === null) {
25
- // this.inputField = 0;
26
- // this.inputFieldChange.emit(this.inputField);
27
- // }
30
+ /**
31
+ * The percentage shown in / typed into the p-inputNumber. It is a view-only
32
+ * projection of the stored model value (`inputField`), converted according to
33
+ * `isFraction`. The model remains the single source of truth.
34
+ */
35
+ get displayValue() {
36
+ return this.toDisplay(this.inputField);
28
37
  }
29
38
  valueChanged(event) {
30
39
  this.isValueChanged = true;
31
- this.inputField = event;
40
+ this.inputField = this.toModel(event);
32
41
  this.isDirty = true;
33
42
  }
34
43
  onChangeofOptions() {
@@ -38,12 +47,32 @@ export class TsiRateInputComponent extends TsiInputBase {
38
47
  this.isValueChanged = false;
39
48
  }
40
49
  }
50
+ /** stored model value -> on-screen percentage */
51
+ toDisplay(model) {
52
+ if (model == null) {
53
+ return model;
54
+ }
55
+ return this.isFraction ? this.round(model * 100, this.numOfDecimal ?? 0) : model;
56
+ }
57
+ /** on-screen percentage -> stored model value */
58
+ toModel(displayValue) {
59
+ if (displayValue == null) {
60
+ return displayValue;
61
+ }
62
+ // A fraction needs two more decimals than the percentage the user typed.
63
+ return this.isFraction ? this.round(displayValue / 100, (this.numOfDecimal ?? 0) + 2) : displayValue;
64
+ }
65
+ /** Rounds to a fixed number of decimals, guarding against binary-float drift introduced by the x100 conversion. */
66
+ round(value, decimals) {
67
+ const factor = Math.pow(10, decimals);
68
+ return Math.round((value + Number.EPSILON) * factor) / factor;
69
+ }
41
70
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TsiRateInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
42
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TsiRateInputComponent, selector: "Tsi-Rate-Input", inputs: { required: "required", isFraction: "isFraction", numOfDecimal: "numOfDecimal" }, outputs: { newItemEvent: "newItemEvent", inputFieldChange: "inputFieldChange" }, usesInheritance: true, ngImport: i0, template: "<div class=\"flex h-2rem\">\r\n <p-inputNumber autoSelect class=\"{{myStyleClass}}\" \r\n styleClass=\"{{myStyleClass}} border-radius-7\" \r\n inputStyleClass=\"{{myStyleClass}} {{validationStatusCssClass}}\"\r\n [disabled]=\"disabled\" [ngModel]=\"inputField\" \r\n (ngModelChange)=\"valueChanged($event)\"\r\n [required]=\"isRequired\"\r\n (onBlur)=\"onChangeofOptions()\" name=\"{{inputName}}\"\r\n id=\"{{inputId}}\" suffix=\"%\" [minFractionDigits]=\"numOfDecimal ?? 0\" [maxFractionDigits]=\"numOfDecimal ?? 0\"\r\n [locale]=\"locale\">\r\n </p-inputNumber>\r\n <Tsi-Bubble-Info [infoText]=\"infoText\"></Tsi-Bubble-Info>\r\n</div>", styles: [".ColorClass{background-color:#f0f;text-align:right}\n"], dependencies: [{ kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.InputNumber, selector: "p-inputNumber", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabelledBy", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "variant", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus", "disabled"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "component", type: i3.TsiBubbleInfoComponent, selector: "Tsi-Bubble-Info", inputs: ["infoText"] }, { kind: "directive", type: i4.AutoSelectDirective, selector: "[autoSelect]" }] }); }
71
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TsiRateInputComponent, selector: "Tsi-Rate-Input", inputs: { required: "required", isFraction: "isFraction", numOfDecimal: "numOfDecimal" }, outputs: { newItemEvent: "newItemEvent", inputFieldChange: "inputFieldChange" }, usesInheritance: true, ngImport: i0, template: "<div class=\"flex h-2rem\">\r\n <p-inputNumber autoSelect class=\"{{myStyleClass}}\" \r\n styleClass=\"{{myStyleClass}} border-radius-7\" \r\n inputStyleClass=\"{{myStyleClass}} {{validationStatusCssClass}}\"\r\n [disabled]=\"disabled\" [ngModel]=\"displayValue\"\r\n (ngModelChange)=\"valueChanged($event)\"\r\n [required]=\"isRequired\"\r\n (onBlur)=\"onChangeofOptions()\" name=\"{{inputName}}\"\r\n id=\"{{inputId}}\" suffix=\"%\" [minFractionDigits]=\"numOfDecimal ?? 0\" [maxFractionDigits]=\"numOfDecimal ?? 0\"\r\n [locale]=\"locale\">\r\n </p-inputNumber>\r\n <Tsi-Bubble-Info [infoText]=\"infoText\"></Tsi-Bubble-Info>\r\n</div>", styles: [".ColorClass{background-color:#f0f;text-align:right}\n"], dependencies: [{ kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.InputNumber, selector: "p-inputNumber", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabelledBy", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "variant", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus", "disabled"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "component", type: i3.TsiBubbleInfoComponent, selector: "Tsi-Bubble-Info", inputs: ["infoText"] }, { kind: "directive", type: i4.AutoSelectDirective, selector: "[autoSelect]" }] }); }
43
72
  }
44
73
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TsiRateInputComponent, decorators: [{
45
74
  type: Component,
46
- args: [{ selector: 'Tsi-Rate-Input', template: "<div class=\"flex h-2rem\">\r\n <p-inputNumber autoSelect class=\"{{myStyleClass}}\" \r\n styleClass=\"{{myStyleClass}} border-radius-7\" \r\n inputStyleClass=\"{{myStyleClass}} {{validationStatusCssClass}}\"\r\n [disabled]=\"disabled\" [ngModel]=\"inputField\" \r\n (ngModelChange)=\"valueChanged($event)\"\r\n [required]=\"isRequired\"\r\n (onBlur)=\"onChangeofOptions()\" name=\"{{inputName}}\"\r\n id=\"{{inputId}}\" suffix=\"%\" [minFractionDigits]=\"numOfDecimal ?? 0\" [maxFractionDigits]=\"numOfDecimal ?? 0\"\r\n [locale]=\"locale\">\r\n </p-inputNumber>\r\n <Tsi-Bubble-Info [infoText]=\"infoText\"></Tsi-Bubble-Info>\r\n</div>", styles: [".ColorClass{background-color:#f0f;text-align:right}\n"] }]
75
+ args: [{ selector: 'Tsi-Rate-Input', template: "<div class=\"flex h-2rem\">\r\n <p-inputNumber autoSelect class=\"{{myStyleClass}}\" \r\n styleClass=\"{{myStyleClass}} border-radius-7\" \r\n inputStyleClass=\"{{myStyleClass}} {{validationStatusCssClass}}\"\r\n [disabled]=\"disabled\" [ngModel]=\"displayValue\"\r\n (ngModelChange)=\"valueChanged($event)\"\r\n [required]=\"isRequired\"\r\n (onBlur)=\"onChangeofOptions()\" name=\"{{inputName}}\"\r\n id=\"{{inputId}}\" suffix=\"%\" [minFractionDigits]=\"numOfDecimal ?? 0\" [maxFractionDigits]=\"numOfDecimal ?? 0\"\r\n [locale]=\"locale\">\r\n </p-inputNumber>\r\n <Tsi-Bubble-Info [infoText]=\"infoText\"></Tsi-Bubble-Info>\r\n</div>", styles: [".ColorClass{background-color:#f0f;text-align:right}\n"] }]
47
76
  }], propDecorators: { required: [{
48
77
  type: Input
49
78
  }], isFraction: [{
@@ -55,4 +84,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
55
84
  }], inputFieldChange: [{
56
85
  type: Output
57
86
  }] } });
58
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHNpLXJhdGUtaW5wdXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdHNpLXNoYXJlZC11aS9zcmMvbGliL3RzaS1jb21wb25lbnRzL2lucHV0LWNvbXBvbmVudHMvdHNpLXJhdGUtaW5wdXQvdHNpLXJhdGUtaW5wdXQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdHNpLXNoYXJlZC11aS9zcmMvbGliL3RzaS1jb21wb25lbnRzL2lucHV0LWNvbXBvbmVudHMvdHNpLXJhdGUtaW5wdXQvdHNpLXJhdGUtaW5wdXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkRBQTJELENBQUM7Ozs7OztBQU96RixNQUFNLE9BQU8scUJBQXNCLFNBQVEsWUFBZ0M7SUFMM0U7O1FBVUUsOENBQThDO1FBRTlDLDRDQUE0QztRQUNuQyxlQUFVLEdBQWEsS0FBSyxDQUFDO1FBQzdCLGlCQUFZLEdBQVksQ0FBQyxDQUFDO1FBQ25DLFlBQVk7UUFFWixpQkFBaUI7UUFDUCxpQkFBWSxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFDMUMscUJBQWdCLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUN4RCxZQUFZO1FBRUosbUJBQWMsR0FBWSxLQUFLLENBQUE7S0F1QnhDO0lBckJVLFFBQVE7UUFDZixLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDakIsbUVBQW1FO1FBQ25FLHlCQUF5QjtRQUN6QixpREFBaUQ7UUFDakQsSUFBSTtJQUNOLENBQUM7SUFFRCxZQUFZLENBQUMsS0FBVztRQUN0QixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQTtRQUMxQixJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQTtRQUN2QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQTtJQUNyQixDQUFDO0lBRUQsaUJBQWlCO1FBQ2YsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQ2hELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzVDLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFBO1FBQzdCLENBQUM7SUFDSCxDQUFDOytHQXZDVSxxQkFBcUI7bUdBQXJCLHFCQUFxQix3UENSbEMsZ3NCQVlNOzs0RkRKTyxxQkFBcUI7a0JBTGpDLFNBQVM7K0JBQ0UsZ0JBQWdCOzhCQU9qQixRQUFRO3NCQUFoQixLQUFLO2dCQUtHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFJSSxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLGdCQUFnQjtzQkFBekIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25Jbml0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgVHNpSW5wdXRCYXNlIH0gZnJvbSAnLi4vLi4vLi4vdHNpLWJhc2UvdHNpLWlucHV0LWJhc2UvdHNpLWlucHV0LWJhc2UuY29tcG9uZW50JztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnVHNpLVJhdGUtSW5wdXQnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi90c2ktcmF0ZS1pbnB1dC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vdHNpLXJhdGUtaW5wdXQuY29tcG9uZW50LmNzcyddXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBUc2lSYXRlSW5wdXRDb21wb25lbnQgZXh0ZW5kcyBUc2lJbnB1dEJhc2U8bnVtYmVyIHwgdW5kZWZpbmVkPiBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcbiAgLy8jcmVnaW9uIGlucHV0c1xyXG4gIC8vIEBJbnB1dCgpIGlucHV0RmllbGQ/OiBudW1iZXI7XHJcbiAgQElucHV0KCkgcmVxdWlyZWQ/OiBib29sZWFuO1xyXG5cclxuICAvLyBpc0ZyYWN0aW9uID0gdHJ1ZSAgOiAyJSBlc3QgZW5yZWdpc3Ryw6kgMC4wMlxyXG5cclxuICAvLyBpc0ZyYWN0aW9uID0gZmFsc2UgIDogMiUgZXN0IGVucmVnaXN0csOpIDJcclxuICBASW5wdXQoKSBpc0ZyYWN0aW9uPzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIG51bU9mRGVjaW1hbD86IG51bWJlciA9IDI7XHJcbiAgLy8jZW5kcmVnaW9uXHJcblxyXG4gIC8vI3JlZ2lvbiBvdXRwdXRzXHJcbiAgQE91dHB1dCgpIG5ld0l0ZW1FdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xyXG4gIEBPdXRwdXQoKSBpbnB1dEZpZWxkQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XHJcbiAgLy8jZW5kcmVnaW9uXHJcblxyXG4gIHByaXZhdGUgaXNWYWx1ZUNoYW5nZWQ6IGJvb2xlYW4gPSBmYWxzZVxyXG5cclxuICBvdmVycmlkZSBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIHN1cGVyLm5nT25Jbml0KCk7XHJcbiAgICAvLyBpZiAodGhpcy5pbnB1dEZpZWxkID09PSB1bmRlZmluZWQgfHwgdGhpcy5pbnB1dEZpZWxkID09PSBudWxsKSB7XHJcbiAgICAvLyAgIHRoaXMuaW5wdXRGaWVsZCA9IDA7XHJcbiAgICAvLyAgIHRoaXMuaW5wdXRGaWVsZENoYW5nZS5lbWl0KHRoaXMuaW5wdXRGaWVsZCk7XHJcbiAgICAvLyB9XHJcbiAgfVxyXG5cclxuICB2YWx1ZUNoYW5nZWQoZXZlbnQgOiBhbnkpIHtcclxuICAgIHRoaXMuaXNWYWx1ZUNoYW5nZWQgPSB0cnVlXHJcbiAgICB0aGlzLmlucHV0RmllbGQgPSBldmVudFxyXG4gICAgdGhpcy5pc0RpcnR5ID0gdHJ1ZVxyXG4gIH1cclxuXHJcbiAgb25DaGFuZ2VvZk9wdGlvbnMoKSB7XHJcbiAgICBpZiAodGhpcy5pc1ZhbHVlQ2hhbmdlZCkge1xyXG4gICAgICB0aGlzLm5ld0l0ZW1FdmVudC5lbWl0KE51bWJlcih0aGlzLmlucHV0RmllbGQpKTtcclxuICAgICAgdGhpcy5pbnB1dEZpZWxkQ2hhbmdlLmVtaXQodGhpcy5pbnB1dEZpZWxkKTtcclxuICAgICAgdGhpcy5pc1ZhbHVlQ2hhbmdlZCA9IGZhbHNlXHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJmbGV4IGgtMnJlbVwiPlxyXG4gICAgPHAtaW5wdXROdW1iZXIgYXV0b1NlbGVjdCBjbGFzcz1cInt7bXlTdHlsZUNsYXNzfX1cIiBcclxuICAgICAgICBzdHlsZUNsYXNzPVwie3tteVN0eWxlQ2xhc3N9fSBib3JkZXItcmFkaXVzLTdcIiBcclxuICAgICAgICBpbnB1dFN0eWxlQ2xhc3M9XCJ7e215U3R5bGVDbGFzc319IHt7dmFsaWRhdGlvblN0YXR1c0Nzc0NsYXNzfX1cIlxyXG4gICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiIFtuZ01vZGVsXT1cImlucHV0RmllbGRcIiBcclxuICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJ2YWx1ZUNoYW5nZWQoJGV2ZW50KVwiXHJcbiAgICAgICAgW3JlcXVpcmVkXT1cImlzUmVxdWlyZWRcIlxyXG4gICAgICAgIChvbkJsdXIpPVwib25DaGFuZ2VvZk9wdGlvbnMoKVwiIG5hbWU9XCJ7e2lucHV0TmFtZX19XCJcclxuICAgICAgICBpZD1cInt7aW5wdXRJZH19XCIgc3VmZml4PVwiJVwiIFttaW5GcmFjdGlvbkRpZ2l0c109XCJudW1PZkRlY2ltYWwgPz8gMFwiIFttYXhGcmFjdGlvbkRpZ2l0c109XCJudW1PZkRlY2ltYWwgPz8gMFwiXHJcbiAgICAgICAgW2xvY2FsZV09XCJsb2NhbGVcIj5cclxuICAgIDwvcC1pbnB1dE51bWJlcj5cclxuICAgIDxUc2ktQnViYmxlLUluZm8gW2luZm9UZXh0XT1cImluZm9UZXh0XCI+PC9Uc2ktQnViYmxlLUluZm8+XHJcbjwvZGl2PiJdfQ==
87
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHNpLXJhdGUtaW5wdXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdHNpLXNoYXJlZC11aS9zcmMvbGliL3RzaS1jb21wb25lbnRzL2lucHV0LWNvbXBvbmVudHMvdHNpLXJhdGUtaW5wdXQvdHNpLXJhdGUtaW5wdXQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdHNpLXNoYXJlZC11aS9zcmMvbGliL3RzaS1jb21wb25lbnRzL2lucHV0LWNvbXBvbmVudHMvdHNpLXJhdGUtaW5wdXQvdHNpLXJhdGUtaW5wdXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkRBQTJELENBQUM7Ozs7OztBQU96RixNQUFNLE9BQU8scUJBQXNCLFNBQVEsWUFBZ0M7SUFMM0U7O1FBU0U7Ozs7Ozs7OztXQVNHO1FBQ00sZUFBVSxHQUFhLEtBQUssQ0FBQztRQUM3QixpQkFBWSxHQUFZLENBQUMsQ0FBQztRQUNuQyxZQUFZO1FBRVosaUJBQWlCO1FBQ1AsaUJBQVksR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBQzFDLHFCQUFnQixHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFDeEQsWUFBWTtRQUVKLG1CQUFjLEdBQVksS0FBSyxDQUFBO0tBK0N4QztJQTdDQzs7OztPQUlHO0lBQ0gsSUFBSSxZQUFZO1FBQ2QsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQsWUFBWSxDQUFDLEtBQVU7UUFDckIsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUE7UUFDMUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3JDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFBO0lBQ3JCLENBQUM7SUFFRCxpQkFBaUI7UUFDZixJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDaEQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDNUMsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUE7UUFDN0IsQ0FBQztJQUNILENBQUM7SUFFRCxpREFBaUQ7SUFDekMsU0FBUyxDQUFDLEtBQXlCO1FBQ3pDLElBQUksS0FBSyxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ2xCLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsR0FBRyxFQUFFLElBQUksQ0FBQyxZQUFZLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztJQUNuRixDQUFDO0lBRUQsaURBQWlEO0lBQ3pDLE9BQU8sQ0FBQyxZQUFnQztRQUM5QyxJQUFJLFlBQVksSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUN6QixPQUFPLFlBQVksQ0FBQztRQUN0QixDQUFDO1FBQ0QseUVBQXlFO1FBQ3pFLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDO0lBQ3ZHLENBQUM7SUFFRCxtSEFBbUg7SUFDM0csS0FBSyxDQUFDLEtBQWEsRUFBRSxRQUFnQjtRQUMzQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN0QyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQztJQUNoRSxDQUFDOytHQXJFVSxxQkFBcUI7bUdBQXJCLHFCQUFxQix3UENSbEMsaXNCQVlNOzs0RkRKTyxxQkFBcUI7a0JBTGpDLFNBQVM7K0JBQ0UsZ0JBQWdCOzhCQU1qQixRQUFRO3NCQUFoQixLQUFLO2dCQVlHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFJSSxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLGdCQUFnQjtzQkFBekIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFRzaUlucHV0QmFzZSB9IGZyb20gJy4uLy4uLy4uL3RzaS1iYXNlL3RzaS1pbnB1dC1iYXNlL3RzaS1pbnB1dC1iYXNlLmNvbXBvbmVudCc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ1RzaS1SYXRlLUlucHV0JyxcclxuICB0ZW1wbGF0ZVVybDogJy4vdHNpLXJhdGUtaW5wdXQuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL3RzaS1yYXRlLWlucHV0LmNvbXBvbmVudC5jc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgVHNpUmF0ZUlucHV0Q29tcG9uZW50IGV4dGVuZHMgVHNpSW5wdXRCYXNlPG51bWJlciB8IHVuZGVmaW5lZD4ge1xyXG4gIC8vI3JlZ2lvbiBpbnB1dHNcclxuICBASW5wdXQoKSByZXF1aXJlZD86IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIEdvdmVybnMgaG93IHRoZSBwZXJjZW50YWdlIHRoZSB1c2VyIHNlZXMvZWRpdHMgcmVsYXRlcyB0byB0aGUgdmFsdWUgc3RvcmVkIGluIHRoZSBtb2RlbC5cclxuICAgKiBUaGUgdXNlciBhbHdheXMgcmVhZHMgYW5kIHR5cGVzIGEgcGVyY2VudGFnZTsgdGhpcyBmbGFnIG9ubHkgY2hhbmdlcyB3aGF0IGlzIHBlcnNpc3RlZC5cclxuICAgKlxyXG4gICAqIC0gZmFsc2UgKGRlZmF1bHQpOiBcIjIgJVwiIG9uIHNjcmVlbiBpcyBzdG9yZWQgYXMgdGhlIHdob2xlIHBlcmNlbnQgYDJgLlxyXG4gICAqIC0gdHJ1ZSAgICAgICAgICAgIDogXCIyICVcIiBvbiBzY3JlZW4gaXMgc3RvcmVkIGFzIHRoZSBmcmFjdGlvbiBgMC4wMmAuXHJcbiAgICpcclxuICAgKiBNdXN0IG1hdGNoIHRoZSBgaXNGcmFjdGlvbmAgZ2l2ZW4gdG8gdGhlIG1pcnJvciBgVHNpLVJhdGUtRGlzcGxheWAgc28gdGhlIHBhaXJcclxuICAgKiBpbnRlcnByZXRzIGEgc3RvcmVkIHZhbHVlIGlkZW50aWNhbGx5LlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIGlzRnJhY3Rpb24/OiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgbnVtT2ZEZWNpbWFsPzogbnVtYmVyID0gMjtcclxuICAvLyNlbmRyZWdpb25cclxuXHJcbiAgLy8jcmVnaW9uIG91dHB1dHNcclxuICBAT3V0cHV0KCkgbmV3SXRlbUV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XHJcbiAgQE91dHB1dCgpIGlucHV0RmllbGRDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcclxuICAvLyNlbmRyZWdpb25cclxuXHJcbiAgcHJpdmF0ZSBpc1ZhbHVlQ2hhbmdlZDogYm9vbGVhbiA9IGZhbHNlXHJcblxyXG4gIC8qKlxyXG4gICAqIFRoZSBwZXJjZW50YWdlIHNob3duIGluIC8gdHlwZWQgaW50byB0aGUgcC1pbnB1dE51bWJlci4gSXQgaXMgYSB2aWV3LW9ubHlcclxuICAgKiBwcm9qZWN0aW9uIG9mIHRoZSBzdG9yZWQgbW9kZWwgdmFsdWUgKGBpbnB1dEZpZWxkYCksIGNvbnZlcnRlZCBhY2NvcmRpbmcgdG9cclxuICAgKiBgaXNGcmFjdGlvbmAuIFRoZSBtb2RlbCByZW1haW5zIHRoZSBzaW5nbGUgc291cmNlIG9mIHRydXRoLlxyXG4gICAqL1xyXG4gIGdldCBkaXNwbGF5VmFsdWUoKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcclxuICAgIHJldHVybiB0aGlzLnRvRGlzcGxheSh0aGlzLmlucHV0RmllbGQpO1xyXG4gIH1cclxuXHJcbiAgdmFsdWVDaGFuZ2VkKGV2ZW50OiBhbnkpIHtcclxuICAgIHRoaXMuaXNWYWx1ZUNoYW5nZWQgPSB0cnVlXHJcbiAgICB0aGlzLmlucHV0RmllbGQgPSB0aGlzLnRvTW9kZWwoZXZlbnQpXHJcbiAgICB0aGlzLmlzRGlydHkgPSB0cnVlXHJcbiAgfVxyXG5cclxuICBvbkNoYW5nZW9mT3B0aW9ucygpIHtcclxuICAgIGlmICh0aGlzLmlzVmFsdWVDaGFuZ2VkKSB7XHJcbiAgICAgIHRoaXMubmV3SXRlbUV2ZW50LmVtaXQoTnVtYmVyKHRoaXMuaW5wdXRGaWVsZCkpO1xyXG4gICAgICB0aGlzLmlucHV0RmllbGRDaGFuZ2UuZW1pdCh0aGlzLmlucHV0RmllbGQpO1xyXG4gICAgICB0aGlzLmlzVmFsdWVDaGFuZ2VkID0gZmFsc2VcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBzdG9yZWQgbW9kZWwgdmFsdWUgLT4gb24tc2NyZWVuIHBlcmNlbnRhZ2UgKi9cclxuICBwcml2YXRlIHRvRGlzcGxheShtb2RlbDogbnVtYmVyIHwgdW5kZWZpbmVkKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcclxuICAgIGlmIChtb2RlbCA9PSBudWxsKSB7XHJcbiAgICAgIHJldHVybiBtb2RlbDtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLmlzRnJhY3Rpb24gPyB0aGlzLnJvdW5kKG1vZGVsICogMTAwLCB0aGlzLm51bU9mRGVjaW1hbCA/PyAwKSA6IG1vZGVsO1xyXG4gIH1cclxuXHJcbiAgLyoqIG9uLXNjcmVlbiBwZXJjZW50YWdlIC0+IHN0b3JlZCBtb2RlbCB2YWx1ZSAqL1xyXG4gIHByaXZhdGUgdG9Nb2RlbChkaXNwbGF5VmFsdWU6IG51bWJlciB8IHVuZGVmaW5lZCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XHJcbiAgICBpZiAoZGlzcGxheVZhbHVlID09IG51bGwpIHtcclxuICAgICAgcmV0dXJuIGRpc3BsYXlWYWx1ZTtcclxuICAgIH1cclxuICAgIC8vIEEgZnJhY3Rpb24gbmVlZHMgdHdvIG1vcmUgZGVjaW1hbHMgdGhhbiB0aGUgcGVyY2VudGFnZSB0aGUgdXNlciB0eXBlZC5cclxuICAgIHJldHVybiB0aGlzLmlzRnJhY3Rpb24gPyB0aGlzLnJvdW5kKGRpc3BsYXlWYWx1ZSAvIDEwMCwgKHRoaXMubnVtT2ZEZWNpbWFsID8/IDApICsgMikgOiBkaXNwbGF5VmFsdWU7XHJcbiAgfVxyXG5cclxuICAvKiogUm91bmRzIHRvIGEgZml4ZWQgbnVtYmVyIG9mIGRlY2ltYWxzLCBndWFyZGluZyBhZ2FpbnN0IGJpbmFyeS1mbG9hdCBkcmlmdCBpbnRyb2R1Y2VkIGJ5IHRoZSB4MTAwIGNvbnZlcnNpb24uICovXHJcbiAgcHJpdmF0ZSByb3VuZCh2YWx1ZTogbnVtYmVyLCBkZWNpbWFsczogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgIGNvbnN0IGZhY3RvciA9IE1hdGgucG93KDEwLCBkZWNpbWFscyk7XHJcbiAgICByZXR1cm4gTWF0aC5yb3VuZCgodmFsdWUgKyBOdW1iZXIuRVBTSUxPTikgKiBmYWN0b3IpIC8gZmFjdG9yO1xyXG4gIH1cclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwiZmxleCBoLTJyZW1cIj5cclxuICAgIDxwLWlucHV0TnVtYmVyIGF1dG9TZWxlY3QgY2xhc3M9XCJ7e215U3R5bGVDbGFzc319XCIgXHJcbiAgICAgICAgc3R5bGVDbGFzcz1cInt7bXlTdHlsZUNsYXNzfX0gYm9yZGVyLXJhZGl1cy03XCIgXHJcbiAgICAgICAgaW5wdXRTdHlsZUNsYXNzPVwie3tteVN0eWxlQ2xhc3N9fSB7e3ZhbGlkYXRpb25TdGF0dXNDc3NDbGFzc319XCJcclxuICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIiBbbmdNb2RlbF09XCJkaXNwbGF5VmFsdWVcIlxyXG4gICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInZhbHVlQ2hhbmdlZCgkZXZlbnQpXCJcclxuICAgICAgICBbcmVxdWlyZWRdPVwiaXNSZXF1aXJlZFwiXHJcbiAgICAgICAgKG9uQmx1cik9XCJvbkNoYW5nZW9mT3B0aW9ucygpXCIgbmFtZT1cInt7aW5wdXROYW1lfX1cIlxyXG4gICAgICAgIGlkPVwie3tpbnB1dElkfX1cIiBzdWZmaXg9XCIlXCIgW21pbkZyYWN0aW9uRGlnaXRzXT1cIm51bU9mRGVjaW1hbCA/PyAwXCIgW21heEZyYWN0aW9uRGlnaXRzXT1cIm51bU9mRGVjaW1hbCA/PyAwXCJcclxuICAgICAgICBbbG9jYWxlXT1cImxvY2FsZVwiPlxyXG4gICAgPC9wLWlucHV0TnVtYmVyPlxyXG4gICAgPFRzaS1CdWJibGUtSW5mbyBbaW5mb1RleHRdPVwiaW5mb1RleHRcIj48L1RzaS1CdWJibGUtSW5mbz5cclxuPC9kaXY+Il19
@@ -7,22 +7,32 @@ export class TsiRateDisplayComponent {
7
7
  constructor() {
8
8
  this._localizationService = inject(LocalizationService);
9
9
  //#region inputs
10
- this.isFraction = true;
10
+ /**
11
+ * How to interpret `inputData` as a percentage. Must match the `isFraction`
12
+ * of the mirror `Tsi-Rate-Input`.
13
+ * - false (default): `inputData` is a whole percent (`2` shows as "2 %").
14
+ * - true : `inputData` is a fraction (`0.02` shows as "2 %").
15
+ */
16
+ this.isFraction = false;
11
17
  this.numOfDecimal = 2;
12
18
  this.locale = this._localizationService.locale;
13
19
  }
14
20
  getToFraction() {
15
- return Number(((this.inputData != null && this.inputData != undefined) ? this.inputData : 0) * 0.01);
21
+ // A non-existent value must stay blank; only a real 0 renders as "0.00%".
22
+ if (this.inputData == null || this.inputData == undefined) {
23
+ return null;
24
+ }
25
+ return Number(this.inputData * 0.01);
16
26
  }
17
27
  getFormat() {
18
28
  return `0.${this.numOfDecimal}`;
19
29
  }
20
30
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TsiRateDisplayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
21
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TsiRateDisplayComponent, selector: "Tsi-Rate-Display", inputs: { isFraction: "isFraction", inputData: "inputData", numOfDecimal: "numOfDecimal" }, ngImport: i0, template: "<span class=\"row flex justify-content-end p-2\">\r\n <div *ngIf=\"isFraction == true; else fElseBlock\">\r\n <span>{{ inputData | percent : undefined : locale }}</span>\r\n </div>\r\n <ng-template #fElseBlock>\r\n <ng-container>\r\n <span>{{ getToFraction() | percent : getFormat() : locale }}</span>\r\n </ng-container>\r\n </ng-template>\r\n</span>", styles: [""], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.PercentPipe, name: "percent" }] }); }
31
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TsiRateDisplayComponent, selector: "Tsi-Rate-Display", inputs: { isFraction: "isFraction", inputData: "inputData", numOfDecimal: "numOfDecimal" }, ngImport: i0, template: "<span class=\"row flex justify-content-end p-2\">\r\n <div *ngIf=\"isFraction == true; else fElseBlock\">\r\n <span>{{ inputData | percent : getFormat() : locale }}</span>\r\n </div>\r\n <ng-template #fElseBlock>\r\n <ng-container>\r\n <span>{{ getToFraction() | percent : getFormat() : locale }}</span>\r\n </ng-container>\r\n </ng-template>\r\n</span>", styles: [""], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.PercentPipe, name: "percent" }] }); }
22
32
  }
23
33
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TsiRateDisplayComponent, decorators: [{
24
34
  type: Component,
25
- args: [{ selector: 'Tsi-Rate-Display', template: "<span class=\"row flex justify-content-end p-2\">\r\n <div *ngIf=\"isFraction == true; else fElseBlock\">\r\n <span>{{ inputData | percent : undefined : locale }}</span>\r\n </div>\r\n <ng-template #fElseBlock>\r\n <ng-container>\r\n <span>{{ getToFraction() | percent : getFormat() : locale }}</span>\r\n </ng-container>\r\n </ng-template>\r\n</span>" }]
35
+ args: [{ selector: 'Tsi-Rate-Display', template: "<span class=\"row flex justify-content-end p-2\">\r\n <div *ngIf=\"isFraction == true; else fElseBlock\">\r\n <span>{{ inputData | percent : getFormat() : locale }}</span>\r\n </div>\r\n <ng-template #fElseBlock>\r\n <ng-container>\r\n <span>{{ getToFraction() | percent : getFormat() : locale }}</span>\r\n </ng-container>\r\n </ng-template>\r\n</span>" }]
26
36
  }], ctorParameters: () => [], propDecorators: { isFraction: [{
27
37
  type: Input
28
38
  }], inputData: [{
@@ -30,4 +40,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
30
40
  }], numOfDecimal: [{
31
41
  type: Input
32
42
  }] } });
33
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHNpLXJhdGUtZGlzcGxheS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90c2ktc2hhcmVkLXVpL3NyYy9saWIvdHNpLWNvbXBvbmVudHMvb3V0cHV0LWNvbXBvbmVudHMvdHNpLXJhdGUtZGlzcGxheS90c2ktcmF0ZS1kaXNwbGF5LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RzaS1zaGFyZWQtdWkvc3JjL2xpYi90c2ktY29tcG9uZW50cy9vdXRwdXQtY29tcG9uZW50cy90c2ktcmF0ZS1kaXNwbGF5L3RzaS1yYXRlLWRpc3BsYXkuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHFEQUFxRCxDQUFDOzs7QUFRMUYsTUFBTSxPQUFPLHVCQUF1QjtJQVNsQyxZQUFZO0lBRVo7UUFWUSx5QkFBb0IsR0FBd0IsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFHaEYsZ0JBQWdCO1FBQ1AsZUFBVSxHQUFZLElBQUksQ0FBQztRQUczQixpQkFBWSxHQUFZLENBQUMsQ0FBQztRQUlqQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUM7SUFDakQsQ0FBQztJQUVELGFBQWE7UUFDWCxPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLFNBQVMsSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUE7SUFDdEcsQ0FBQztJQUVELFNBQVM7UUFDUCxPQUFPLEtBQUssSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ2xDLENBQUM7K0dBckJVLHVCQUF1QjttR0FBdkIsdUJBQXVCLG9KQ1RwQyw2WUFTTzs7NEZEQU0sdUJBQXVCO2tCQUxuQyxTQUFTOytCQUNFLGtCQUFrQjt3REFTbkIsVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUVHLFlBQVk7c0JBQXBCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIGluamVjdCwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgTG9jYWxpemF0aW9uU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2xvY2FsaXphdGlvbi9sb2NhbGl6YXRpb24uc2VydmljZSc7XHJcbmltcG9ydCB7IExvY2FsZUNvZGUgfSBmcm9tICcuLi8uLi8uLi9lbnVtcy9MYW5ndWFnZSc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ1RzaS1SYXRlLURpc3BsYXknLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi90c2ktcmF0ZS1kaXNwbGF5LmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi90c2ktcmF0ZS1kaXNwbGF5LmNvbXBvbmVudC5jc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgVHNpUmF0ZURpc3BsYXlDb21wb25lbnQge1xyXG4gIHByaXZhdGUgX2xvY2FsaXphdGlvblNlcnZpY2U6IExvY2FsaXphdGlvblNlcnZpY2UgPSBpbmplY3QoTG9jYWxpemF0aW9uU2VydmljZSk7XHJcbiAgcHJvdGVjdGVkIGxvY2FsZTogTG9jYWxlQ29kZTtcclxuXHJcbiAgLy8jcmVnaW9uIGlucHV0c1xyXG4gIEBJbnB1dCgpIGlzRnJhY3Rpb246IGJvb2xlYW4gPSB0cnVlO1xyXG4gIEBJbnB1dCgpIGlucHV0RGF0YT86IG51bWJlcjtcclxuXHJcbiAgQElucHV0KCkgbnVtT2ZEZWNpbWFsPzogbnVtYmVyID0gMjtcclxuICAvLyNlbmRyZWdpb25cclxuXHJcbiAgY29uc3RydWN0b3IoKSB7XHJcbiAgICB0aGlzLmxvY2FsZSA9IHRoaXMuX2xvY2FsaXphdGlvblNlcnZpY2UubG9jYWxlO1xyXG4gIH1cclxuXHJcbiAgZ2V0VG9GcmFjdGlvbigpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIE51bWJlcigoKHRoaXMuaW5wdXREYXRhICE9IG51bGwgJiYgdGhpcy5pbnB1dERhdGEgIT0gdW5kZWZpbmVkKSA/IHRoaXMuaW5wdXREYXRhIDogMCkgKiAwLjAxKVxyXG4gIH1cclxuXHJcbiAgZ2V0Rm9ybWF0KCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gYDAuJHt0aGlzLm51bU9mRGVjaW1hbH1gO1xyXG4gIH1cclxufVxyXG4iLCI8c3BhbiBjbGFzcz1cInJvdyBmbGV4IGp1c3RpZnktY29udGVudC1lbmQgcC0yXCI+XHJcbiAgICA8ZGl2ICpuZ0lmPVwiaXNGcmFjdGlvbiA9PSB0cnVlOyBlbHNlIGZFbHNlQmxvY2tcIj5cclxuICAgICAgICA8c3Bhbj57eyBpbnB1dERhdGEgfCBwZXJjZW50IDogdW5kZWZpbmVkIDogbG9jYWxlIH19PC9zcGFuPlxyXG4gICAgPC9kaXY+XHJcbiAgICA8bmctdGVtcGxhdGUgI2ZFbHNlQmxvY2s+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPHNwYW4+e3sgZ2V0VG9GcmFjdGlvbigpIHwgcGVyY2VudCA6IGdldEZvcm1hdCgpIDogbG9jYWxlIH19PC9zcGFuPlxyXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgPC9uZy10ZW1wbGF0ZT5cclxuPC9zcGFuPiJdfQ==
43
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHNpLXJhdGUtZGlzcGxheS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90c2ktc2hhcmVkLXVpL3NyYy9saWIvdHNpLWNvbXBvbmVudHMvb3V0cHV0LWNvbXBvbmVudHMvdHNpLXJhdGUtZGlzcGxheS90c2ktcmF0ZS1kaXNwbGF5LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RzaS1zaGFyZWQtdWkvc3JjL2xpYi90c2ktY29tcG9uZW50cy9vdXRwdXQtY29tcG9uZW50cy90c2ktcmF0ZS1kaXNwbGF5L3RzaS1yYXRlLWRpc3BsYXkuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHFEQUFxRCxDQUFDOzs7QUFRMUYsTUFBTSxPQUFPLHVCQUF1QjtJQWVsQyxZQUFZO0lBRVo7UUFoQlEseUJBQW9CLEdBQXdCLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBR2hGLGdCQUFnQjtRQUNoQjs7Ozs7V0FLRztRQUNNLGVBQVUsR0FBWSxLQUFLLENBQUM7UUFHNUIsaUJBQVksR0FBWSxDQUFDLENBQUM7UUFJakMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDO0lBQ2pELENBQUM7SUFFRCxhQUFhO1FBQ1gsMEVBQTBFO1FBQzFFLElBQUksSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLFNBQVMsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUMxRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFDRCxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxTQUFTO1FBQ1AsT0FBTyxLQUFLLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUNsQyxDQUFDOytHQS9CVSx1QkFBdUI7bUdBQXZCLHVCQUF1QixvSkNUcEMsK1lBU087OzRGREFNLHVCQUF1QjtrQkFMbkMsU0FBUzsrQkFDRSxrQkFBa0I7d0RBZW5CLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFFRyxZQUFZO3NCQUFwQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBpbmplY3QsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IExvY2FsaXphdGlvblNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9sb2NhbGl6YXRpb24vbG9jYWxpemF0aW9uLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBMb2NhbGVDb2RlIH0gZnJvbSAnLi4vLi4vLi4vZW51bXMvTGFuZ3VhZ2UnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdUc2ktUmF0ZS1EaXNwbGF5JyxcclxuICB0ZW1wbGF0ZVVybDogJy4vdHNpLXJhdGUtZGlzcGxheS5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vdHNpLXJhdGUtZGlzcGxheS5jb21wb25lbnQuY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIFRzaVJhdGVEaXNwbGF5Q29tcG9uZW50IHtcclxuICBwcml2YXRlIF9sb2NhbGl6YXRpb25TZXJ2aWNlOiBMb2NhbGl6YXRpb25TZXJ2aWNlID0gaW5qZWN0KExvY2FsaXphdGlvblNlcnZpY2UpO1xyXG4gIHByb3RlY3RlZCBsb2NhbGU6IExvY2FsZUNvZGU7XHJcblxyXG4gIC8vI3JlZ2lvbiBpbnB1dHNcclxuICAvKipcclxuICAgKiBIb3cgdG8gaW50ZXJwcmV0IGBpbnB1dERhdGFgIGFzIGEgcGVyY2VudGFnZS4gTXVzdCBtYXRjaCB0aGUgYGlzRnJhY3Rpb25gXHJcbiAgICogb2YgdGhlIG1pcnJvciBgVHNpLVJhdGUtSW5wdXRgLlxyXG4gICAqIC0gZmFsc2UgKGRlZmF1bHQpOiBgaW5wdXREYXRhYCBpcyBhIHdob2xlIHBlcmNlbnQgKGAyYCBzaG93cyBhcyBcIjIgJVwiKS5cclxuICAgKiAtIHRydWUgICAgICAgICAgICA6IGBpbnB1dERhdGFgIGlzIGEgZnJhY3Rpb24gKGAwLjAyYCBzaG93cyBhcyBcIjIgJVwiKS5cclxuICAgKi9cclxuICBASW5wdXQoKSBpc0ZyYWN0aW9uOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgaW5wdXREYXRhPzogbnVtYmVyO1xyXG5cclxuICBASW5wdXQoKSBudW1PZkRlY2ltYWw/OiBudW1iZXIgPSAyO1xyXG4gIC8vI2VuZHJlZ2lvblxyXG5cclxuICBjb25zdHJ1Y3RvcigpIHtcclxuICAgIHRoaXMubG9jYWxlID0gdGhpcy5fbG9jYWxpemF0aW9uU2VydmljZS5sb2NhbGU7XHJcbiAgfVxyXG5cclxuICBnZXRUb0ZyYWN0aW9uKCk6IG51bWJlciB8IG51bGwge1xyXG4gICAgLy8gQSBub24tZXhpc3RlbnQgdmFsdWUgbXVzdCBzdGF5IGJsYW5rOyBvbmx5IGEgcmVhbCAwIHJlbmRlcnMgYXMgXCIwLjAwJVwiLlxyXG4gICAgaWYgKHRoaXMuaW5wdXREYXRhID09IG51bGwgfHwgdGhpcy5pbnB1dERhdGEgPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIE51bWJlcih0aGlzLmlucHV0RGF0YSAqIDAuMDEpO1xyXG4gIH1cclxuXHJcbiAgZ2V0Rm9ybWF0KCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gYDAuJHt0aGlzLm51bU9mRGVjaW1hbH1gO1xyXG4gIH1cclxufVxyXG4iLCI8c3BhbiBjbGFzcz1cInJvdyBmbGV4IGp1c3RpZnktY29udGVudC1lbmQgcC0yXCI+XHJcbiAgICA8ZGl2ICpuZ0lmPVwiaXNGcmFjdGlvbiA9PSB0cnVlOyBlbHNlIGZFbHNlQmxvY2tcIj5cclxuICAgICAgICA8c3Bhbj57eyBpbnB1dERhdGEgfCBwZXJjZW50IDogZ2V0Rm9ybWF0KCkgOiBsb2NhbGUgfX08L3NwYW4+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxuZy10ZW1wbGF0ZSAjZkVsc2VCbG9jaz5cclxuICAgICAgICA8bmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICA8c3Bhbj57eyBnZXRUb0ZyYWN0aW9uKCkgfCBwZXJjZW50IDogZ2V0Rm9ybWF0KCkgOiBsb2NhbGUgfX08L3NwYW4+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICA8L25nLXRlbXBsYXRlPlxyXG48L3NwYW4+Il19
@@ -6721,8 +6721,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
6721
6721
  class TsiRateInputComponent extends TsiInputBase {
6722
6722
  constructor() {
6723
6723
  super(...arguments);
6724
- // isFraction = true : 2% est enregistré 0.02
6725
- // isFraction = false : 2% est enregistré 2
6724
+ /**
6725
+ * Governs how the percentage the user sees/edits relates to the value stored in the model.
6726
+ * The user always reads and types a percentage; this flag only changes what is persisted.
6727
+ *
6728
+ * - false (default): "2 %" on screen is stored as the whole percent `2`.
6729
+ * - true : "2 %" on screen is stored as the fraction `0.02`.
6730
+ *
6731
+ * Must match the `isFraction` given to the mirror `Tsi-Rate-Display` so the pair
6732
+ * interprets a stored value identically.
6733
+ */
6726
6734
  this.isFraction = false;
6727
6735
  this.numOfDecimal = 2;
6728
6736
  //#endregion
@@ -6732,16 +6740,17 @@ class TsiRateInputComponent extends TsiInputBase {
6732
6740
  //#endregion
6733
6741
  this.isValueChanged = false;
6734
6742
  }
6735
- ngOnInit() {
6736
- super.ngOnInit();
6737
- // if (this.inputField === undefined || this.inputField === null) {
6738
- // this.inputField = 0;
6739
- // this.inputFieldChange.emit(this.inputField);
6740
- // }
6743
+ /**
6744
+ * The percentage shown in / typed into the p-inputNumber. It is a view-only
6745
+ * projection of the stored model value (`inputField`), converted according to
6746
+ * `isFraction`. The model remains the single source of truth.
6747
+ */
6748
+ get displayValue() {
6749
+ return this.toDisplay(this.inputField);
6741
6750
  }
6742
6751
  valueChanged(event) {
6743
6752
  this.isValueChanged = true;
6744
- this.inputField = event;
6753
+ this.inputField = this.toModel(event);
6745
6754
  this.isDirty = true;
6746
6755
  }
6747
6756
  onChangeofOptions() {
@@ -6751,12 +6760,32 @@ class TsiRateInputComponent extends TsiInputBase {
6751
6760
  this.isValueChanged = false;
6752
6761
  }
6753
6762
  }
6763
+ /** stored model value -> on-screen percentage */
6764
+ toDisplay(model) {
6765
+ if (model == null) {
6766
+ return model;
6767
+ }
6768
+ return this.isFraction ? this.round(model * 100, this.numOfDecimal ?? 0) : model;
6769
+ }
6770
+ /** on-screen percentage -> stored model value */
6771
+ toModel(displayValue) {
6772
+ if (displayValue == null) {
6773
+ return displayValue;
6774
+ }
6775
+ // A fraction needs two more decimals than the percentage the user typed.
6776
+ return this.isFraction ? this.round(displayValue / 100, (this.numOfDecimal ?? 0) + 2) : displayValue;
6777
+ }
6778
+ /** Rounds to a fixed number of decimals, guarding against binary-float drift introduced by the x100 conversion. */
6779
+ round(value, decimals) {
6780
+ const factor = Math.pow(10, decimals);
6781
+ return Math.round((value + Number.EPSILON) * factor) / factor;
6782
+ }
6754
6783
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TsiRateInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
6755
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TsiRateInputComponent, selector: "Tsi-Rate-Input", inputs: { required: "required", isFraction: "isFraction", numOfDecimal: "numOfDecimal" }, outputs: { newItemEvent: "newItemEvent", inputFieldChange: "inputFieldChange" }, usesInheritance: true, ngImport: i0, template: "<div class=\"flex h-2rem\">\r\n <p-inputNumber autoSelect class=\"{{myStyleClass}}\" \r\n styleClass=\"{{myStyleClass}} border-radius-7\" \r\n inputStyleClass=\"{{myStyleClass}} {{validationStatusCssClass}}\"\r\n [disabled]=\"disabled\" [ngModel]=\"inputField\" \r\n (ngModelChange)=\"valueChanged($event)\"\r\n [required]=\"isRequired\"\r\n (onBlur)=\"onChangeofOptions()\" name=\"{{inputName}}\"\r\n id=\"{{inputId}}\" suffix=\"%\" [minFractionDigits]=\"numOfDecimal ?? 0\" [maxFractionDigits]=\"numOfDecimal ?? 0\"\r\n [locale]=\"locale\">\r\n </p-inputNumber>\r\n <Tsi-Bubble-Info [infoText]=\"infoText\"></Tsi-Bubble-Info>\r\n</div>", styles: [".ColorClass{background-color:#f0f;text-align:right}\n"], dependencies: [{ kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2$4.InputNumber, selector: "p-inputNumber", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabelledBy", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "variant", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus", "disabled"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "component", type: TsiBubbleInfoComponent, selector: "Tsi-Bubble-Info", inputs: ["infoText"] }, { kind: "directive", type: AutoSelectDirective, selector: "[autoSelect]" }] }); }
6784
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TsiRateInputComponent, selector: "Tsi-Rate-Input", inputs: { required: "required", isFraction: "isFraction", numOfDecimal: "numOfDecimal" }, outputs: { newItemEvent: "newItemEvent", inputFieldChange: "inputFieldChange" }, usesInheritance: true, ngImport: i0, template: "<div class=\"flex h-2rem\">\r\n <p-inputNumber autoSelect class=\"{{myStyleClass}}\" \r\n styleClass=\"{{myStyleClass}} border-radius-7\" \r\n inputStyleClass=\"{{myStyleClass}} {{validationStatusCssClass}}\"\r\n [disabled]=\"disabled\" [ngModel]=\"displayValue\"\r\n (ngModelChange)=\"valueChanged($event)\"\r\n [required]=\"isRequired\"\r\n (onBlur)=\"onChangeofOptions()\" name=\"{{inputName}}\"\r\n id=\"{{inputId}}\" suffix=\"%\" [minFractionDigits]=\"numOfDecimal ?? 0\" [maxFractionDigits]=\"numOfDecimal ?? 0\"\r\n [locale]=\"locale\">\r\n </p-inputNumber>\r\n <Tsi-Bubble-Info [infoText]=\"infoText\"></Tsi-Bubble-Info>\r\n</div>", styles: [".ColorClass{background-color:#f0f;text-align:right}\n"], dependencies: [{ kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2$4.InputNumber, selector: "p-inputNumber", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabelledBy", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "variant", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus", "disabled"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "component", type: TsiBubbleInfoComponent, selector: "Tsi-Bubble-Info", inputs: ["infoText"] }, { kind: "directive", type: AutoSelectDirective, selector: "[autoSelect]" }] }); }
6756
6785
  }
6757
6786
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TsiRateInputComponent, decorators: [{
6758
6787
  type: Component,
6759
- args: [{ selector: 'Tsi-Rate-Input', template: "<div class=\"flex h-2rem\">\r\n <p-inputNumber autoSelect class=\"{{myStyleClass}}\" \r\n styleClass=\"{{myStyleClass}} border-radius-7\" \r\n inputStyleClass=\"{{myStyleClass}} {{validationStatusCssClass}}\"\r\n [disabled]=\"disabled\" [ngModel]=\"inputField\" \r\n (ngModelChange)=\"valueChanged($event)\"\r\n [required]=\"isRequired\"\r\n (onBlur)=\"onChangeofOptions()\" name=\"{{inputName}}\"\r\n id=\"{{inputId}}\" suffix=\"%\" [minFractionDigits]=\"numOfDecimal ?? 0\" [maxFractionDigits]=\"numOfDecimal ?? 0\"\r\n [locale]=\"locale\">\r\n </p-inputNumber>\r\n <Tsi-Bubble-Info [infoText]=\"infoText\"></Tsi-Bubble-Info>\r\n</div>", styles: [".ColorClass{background-color:#f0f;text-align:right}\n"] }]
6788
+ args: [{ selector: 'Tsi-Rate-Input', template: "<div class=\"flex h-2rem\">\r\n <p-inputNumber autoSelect class=\"{{myStyleClass}}\" \r\n styleClass=\"{{myStyleClass}} border-radius-7\" \r\n inputStyleClass=\"{{myStyleClass}} {{validationStatusCssClass}}\"\r\n [disabled]=\"disabled\" [ngModel]=\"displayValue\"\r\n (ngModelChange)=\"valueChanged($event)\"\r\n [required]=\"isRequired\"\r\n (onBlur)=\"onChangeofOptions()\" name=\"{{inputName}}\"\r\n id=\"{{inputId}}\" suffix=\"%\" [minFractionDigits]=\"numOfDecimal ?? 0\" [maxFractionDigits]=\"numOfDecimal ?? 0\"\r\n [locale]=\"locale\">\r\n </p-inputNumber>\r\n <Tsi-Bubble-Info [infoText]=\"infoText\"></Tsi-Bubble-Info>\r\n</div>", styles: [".ColorClass{background-color:#f0f;text-align:right}\n"] }]
6760
6789
  }], propDecorators: { required: [{
6761
6790
  type: Input
6762
6791
  }], isFraction: [{
@@ -7072,22 +7101,32 @@ class TsiRateDisplayComponent {
7072
7101
  constructor() {
7073
7102
  this._localizationService = inject(LocalizationService);
7074
7103
  //#region inputs
7075
- this.isFraction = true;
7104
+ /**
7105
+ * How to interpret `inputData` as a percentage. Must match the `isFraction`
7106
+ * of the mirror `Tsi-Rate-Input`.
7107
+ * - false (default): `inputData` is a whole percent (`2` shows as "2 %").
7108
+ * - true : `inputData` is a fraction (`0.02` shows as "2 %").
7109
+ */
7110
+ this.isFraction = false;
7076
7111
  this.numOfDecimal = 2;
7077
7112
  this.locale = this._localizationService.locale;
7078
7113
  }
7079
7114
  getToFraction() {
7080
- return Number(((this.inputData != null && this.inputData != undefined) ? this.inputData : 0) * 0.01);
7115
+ // A non-existent value must stay blank; only a real 0 renders as "0.00%".
7116
+ if (this.inputData == null || this.inputData == undefined) {
7117
+ return null;
7118
+ }
7119
+ return Number(this.inputData * 0.01);
7081
7120
  }
7082
7121
  getFormat() {
7083
7122
  return `0.${this.numOfDecimal}`;
7084
7123
  }
7085
7124
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TsiRateDisplayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7086
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TsiRateDisplayComponent, selector: "Tsi-Rate-Display", inputs: { isFraction: "isFraction", inputData: "inputData", numOfDecimal: "numOfDecimal" }, ngImport: i0, template: "<span class=\"row flex justify-content-end p-2\">\r\n <div *ngIf=\"isFraction == true; else fElseBlock\">\r\n <span>{{ inputData | percent : undefined : locale }}</span>\r\n </div>\r\n <ng-template #fElseBlock>\r\n <ng-container>\r\n <span>{{ getToFraction() | percent : getFormat() : locale }}</span>\r\n </ng-container>\r\n </ng-template>\r\n</span>", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1$1.PercentPipe, name: "percent" }] }); }
7125
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TsiRateDisplayComponent, selector: "Tsi-Rate-Display", inputs: { isFraction: "isFraction", inputData: "inputData", numOfDecimal: "numOfDecimal" }, ngImport: i0, template: "<span class=\"row flex justify-content-end p-2\">\r\n <div *ngIf=\"isFraction == true; else fElseBlock\">\r\n <span>{{ inputData | percent : getFormat() : locale }}</span>\r\n </div>\r\n <ng-template #fElseBlock>\r\n <ng-container>\r\n <span>{{ getToFraction() | percent : getFormat() : locale }}</span>\r\n </ng-container>\r\n </ng-template>\r\n</span>", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1$1.PercentPipe, name: "percent" }] }); }
7087
7126
  }
7088
7127
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TsiRateDisplayComponent, decorators: [{
7089
7128
  type: Component,
7090
- args: [{ selector: 'Tsi-Rate-Display', template: "<span class=\"row flex justify-content-end p-2\">\r\n <div *ngIf=\"isFraction == true; else fElseBlock\">\r\n <span>{{ inputData | percent : undefined : locale }}</span>\r\n </div>\r\n <ng-template #fElseBlock>\r\n <ng-container>\r\n <span>{{ getToFraction() | percent : getFormat() : locale }}</span>\r\n </ng-container>\r\n </ng-template>\r\n</span>" }]
7129
+ args: [{ selector: 'Tsi-Rate-Display', template: "<span class=\"row flex justify-content-end p-2\">\r\n <div *ngIf=\"isFraction == true; else fElseBlock\">\r\n <span>{{ inputData | percent : getFormat() : locale }}</span>\r\n </div>\r\n <ng-template #fElseBlock>\r\n <ng-container>\r\n <span>{{ getToFraction() | percent : getFormat() : locale }}</span>\r\n </ng-container>\r\n </ng-template>\r\n</span>" }]
7091
7130
  }], ctorParameters: () => [], propDecorators: { isFraction: [{
7092
7131
  type: Input
7093
7132
  }], inputData: [{