@itfin/components 1.2.129 → 1.2.131

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itfin/components",
3
- "version": "1.2.129",
3
+ "version": "1.2.131",
4
4
  "author": "Vitalii Savchuk <esvit666@gmail.com>",
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -2,12 +2,15 @@
2
2
  <div class="itf-money-field" :class="{'currency-arrow': !currencyDisabled, 'currency-select': currencySelect}">
3
3
  <div :style="`--itf-money-field-padding-left: ${selectedCurrencySymbol.length * 0.6 + 1}rem`">
4
4
  <span class="itf-money-field__prepend">{{ selectedCurrencySymbol }}</span>
5
- <itf-text-field
6
- :disabled="disabled"
7
- :value="value"
8
- type="number"
9
- step="1"
10
- @input="setValue"
5
+ <i-mask-component
6
+ ref="input"
7
+ v-bind="mask"
8
+ class="form-control"
9
+ :class="{ 'is-invalid': isInvalid(), 'is-valid': isSuccess() }"
10
+ @input="setValue"
11
+ :value="maskedValue"
12
+ :unmask="false"
13
+ :disabled="disabled"
11
14
  />
12
15
  </div>
13
16
 
@@ -25,7 +28,7 @@
25
28
  .itf-money-field {
26
29
  position: relative;
27
30
 
28
- .itf-text-field input {
31
+ input {
29
32
  padding-left: var(--itf-money-field-padding-left, 1.5rem);
30
33
 
31
34
  &.is-invalid, &.is-valid {
@@ -33,11 +36,11 @@
33
36
  }
34
37
  }
35
38
  &.currency-select {
36
- .itf-text-field input {
39
+ input {
37
40
  padding-right: 3rem;
38
41
  }
39
42
  &.currency-arrow {
40
- .itf-text-field input {
43
+ input {
41
44
  padding-right: 4.5rem;
42
45
  }
43
46
  }
@@ -69,11 +72,13 @@
69
72
  }
70
73
  </style>
71
74
  <script>
72
- import { Component, Emit, Model, Prop, Vue } from 'vue-property-decorator';
75
+ import {Component, Emit, Inject, Model, Prop, Vue} from 'vue-property-decorator';
76
+ import { IMask, IMaskComponent } from 'vue-imask';
73
77
  import itfTextField from './TextField';
74
78
  import itfSelect from '../select/Select';
75
79
  import itfLabel from '../form/Label';
76
80
  import itfIcon from '../icon/Icon';
81
+ import {stringToNumber} from '../../helpers/formatters';
77
82
 
78
83
  export default @Component({
79
84
  name: 'itfMoneyField',
@@ -81,22 +86,57 @@ export default @Component({
81
86
  itfIcon,
82
87
  itfLabel,
83
88
  itfSelect,
84
- itfTextField
89
+ itfTextField,
90
+ IMaskComponent,
85
91
  }
86
92
  })
87
93
  class itfMoneyField extends Vue {
94
+ @Inject({ default: null }) itemLabel;
95
+
88
96
  @Model('input', { default: '' }) value;
89
97
  @Prop({ type: Object, default: null }) currency;
90
98
  @Prop({ type: Boolean, default: false }) disabled;
91
99
  @Prop({ type: Boolean, default: true }) currencySelect;
92
100
  @Prop({ type: Array, default: () => ([]) }) currencies;
93
101
  @Prop({ type: Boolean, default: false }) currencyDisabled;
102
+ @Prop({ type: Number, default: -1000000000}) minValue;
103
+ @Prop({ type: Number, default: 1000000000}) maxValue;
104
+
105
+ get mask() {
106
+ return {
107
+ mask: Number,
108
+ scale: this.precition, // digits after point, 0 for integers
109
+ thousandsSeparator: '', // any single char
110
+ padFractionalZeros: false, // if true, then pads zeros at end to the length of scale
111
+ normalizeZeros: true, // appends or removes zeros at ends
112
+ radix: '.', // fractional delimiter
113
+ mapToRadix: [','], // symbols to process as radix
114
+ min: this.minValue,
115
+ max: this.maxValue
116
+ };
117
+ }
118
+
119
+ get maskedValue() {
120
+ return this.value ? this.value.toString() : '';
121
+ }
122
+
123
+ isInvalid() {
124
+ return this.itemLabel && this.itemLabel.isHasError();
125
+ }
126
+
127
+ isSuccess() {
128
+ return this.itemLabel && this.itemLabel.isHasSuccess();
129
+ }
94
130
 
95
131
  onCurrencyChanged(e) {
96
132
  const currency = this.currencies.find((c) => c.Id === parseInt(e.target.value));
97
133
  this.$emit('update:currency', currency)
98
134
  }
99
135
 
136
+ get precition() {
137
+ return this.selectedCurrency ? this.selectedCurrency.Precision : 2;
138
+ }
139
+
100
140
  get selectedCurrencySymbol() {
101
141
  return this.selectedCurrency ? this.selectedCurrency.Symbol : '#';
102
142
  }
@@ -120,7 +160,7 @@ class itfMoneyField extends Vue {
120
160
  if (!isNumeric(val)) {
121
161
  return;
122
162
  }
123
- this.$emit('input', val);
163
+ this.$emit('input', stringToNumber((val || '').toString().replace(/,/g, '')));
124
164
 
125
165
  function isNumeric(value) {
126
166
  return /^-?\d+([\,\.]\d+)?$/.test(value);
@@ -107,3 +107,31 @@ export function formatHours (val, removeEmptyMinutes = false) {
107
107
  }
108
108
  return `${sign}${hours}h${minutes}`;
109
109
  }
110
+
111
+
112
+ /**
113
+ * Округлює число до заданої точності
114
+ *
115
+ * @param number Вхідне число
116
+ * @param digits Кількість знаків після коми
117
+ * @param ceil99 якщо число закінчується на .99, то додає .01 щоб воно було кругле
118
+ * @returns {number}
119
+ */
120
+ export function round (number, digits = 2, ceil99 = false) {
121
+ const pow = 10 ** digits;
122
+ let res = Math.round((number + Number.EPSILON) * pow) / pow;
123
+ if (ceil99) {
124
+ const str = res.toFixed(2);
125
+ if (str.substring(str.length - 3) === '.99') {
126
+ res += 0.01;
127
+ }
128
+ }
129
+ return res;
130
+ }
131
+
132
+
133
+ export function stringToNumber(str) {
134
+ const formated = (str || '').toString().replace(/[,.](\d+)$/g, '^$1').replace(/[,.\s]/g, '').replace('^', '.');
135
+ return parseFloat(formated);
136
+ }
137
+