@farm-investimentos/front-mfe-components-vue3 0.4.1 → 0.5.1

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": "@farm-investimentos/front-mfe-components-vue3",
3
- "version": "0.4.1",
3
+ "version": "0.5.1",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,7 +34,8 @@
34
34
  "core-js": "3.33.1",
35
35
  "text-mask-addons": "^3.8.0",
36
36
  "v-mask": "2.3.0",
37
- "vuetify": "3.3.23",
37
+ "v-money3": "^3.24.0",
38
+ "vuetify": "3.4.0",
38
39
  "webpack": "5.89.0"
39
40
  },
40
41
  "devDependencies": {
@@ -8,7 +8,7 @@
8
8
  position: absolute;
9
9
  right: -20px;
10
10
  top: -1px;
11
- transition: transform 0.8s ease-in-out;
11
+ transition: transform 0.5s ease-in-out;
12
12
 
13
13
  &.farm-icon--asc {
14
14
  transform: rotateX(180deg);
@@ -18,15 +18,14 @@
18
18
 
19
19
  th.sortable {
20
20
  cursor: pointer;
21
+
21
22
  .farm-icon::before {
22
23
  transition: all 0.3s linear;
23
24
  }
24
-
25
+
25
26
  &:not(.active) {
26
- &:hover {
27
- .farm-icon::before {
28
- color: var(--farm-bw-black-10) !important;
29
- }
27
+ .farm-icon::before {
28
+ color: var(--farm-bw-black-10) !important;
30
29
  }
31
30
  }
32
31
  }
@@ -29,7 +29,7 @@
29
29
  {{ item.text }}
30
30
 
31
31
  <farm-icon
32
- v-if="item.sortable && sortClick[$index].show"
32
+ v-show="item.sortable"
33
33
  v-bind:class="[
34
34
  sortClick[$index][item.value] ? 'farm-icon--desc' : 'farm-icon--asc',
35
35
  ]"
@@ -42,7 +42,10 @@
42
42
  </farm-icon>
43
43
  </span>
44
44
 
45
- <span v-if="isTHDataTableSelect(item) && showCheckbox" class="span-checkbox">
45
+ <span
46
+ v-if="isTHDataTableSelect(item) && showCheckbox"
47
+ class="span-checkbox"
48
+ >
46
49
  <farm-checkbox
47
50
  size="sm"
48
51
  v-model="inputVal"
@@ -59,7 +62,6 @@
59
62
  <script lang="ts">
60
63
  /* eslint-disable */
61
64
 
62
-
63
65
  export default {
64
66
  name: 'farm-datatable-header',
65
67
  props: {
@@ -0,0 +1,96 @@
1
+ @import '../../configurations/mixins';
2
+
3
+ .farm-input-decimal-formatter {
4
+ height: 64px;
5
+
6
+ &--hiddendetails {
7
+ height: 40px;
8
+ }
9
+
10
+ &--input {
11
+ display: flex;
12
+ align-items: center;
13
+ gap: 8px;
14
+ border: 1px solid;
15
+ border-color: var(--farm-bw-black-10);
16
+ height: 36px;
17
+ border-radius: 5px;
18
+ padding: 8px;
19
+ margin-bottom: 4px;
20
+ background-color: white;
21
+
22
+ >button {
23
+ display: flex;
24
+ }
25
+
26
+ &>input {
27
+ flex: 1;
28
+ outline: none;
29
+ color: var(--farm-bw-black-50);
30
+ font-size: 12px;
31
+ font-weight: 400;
32
+ max-width: 100%;
33
+ }
34
+
35
+ &--iconed>input {
36
+ max-width: calc(100% - 32px);
37
+ }
38
+
39
+ width: 100%;
40
+ }
41
+
42
+ &--focused .farm-input-decimal-formatter--input {
43
+ border-color: var(--farm-bw-black-30);
44
+ }
45
+
46
+ &--disabled {
47
+ input {
48
+ color: var(--farm-bw-black-30);
49
+ }
50
+
51
+ .farm-icon {
52
+ color: var(--farm-bw-black-30);
53
+ cursor: default;
54
+ }
55
+ }
56
+
57
+ .farm-caption {
58
+ line-height: 12px;
59
+ }
60
+
61
+ &__hint-text {
62
+ @include hintText;
63
+ }
64
+ }
65
+
66
+ .farm-input-decimal-formatter--touched.farm-input-decimal-formatter--blured.farm-input-decimal-formatter--validatable {
67
+ &.farm-input-decimal-formatter--error {
68
+ .farm-input-decimal-formatter {
69
+ &--input {
70
+ border-color: var(--farm-error-base);
71
+
72
+ &>input {
73
+ color: var(--farm-neutral-darken);
74
+ }
75
+
76
+ .farm-icon {
77
+ color: var(--farm-error-base);
78
+ }
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+ .farm-input-decimal-formatter--blured.farm-input-decimal-formatter--validatable:not(.farm-input-decimal-formatter--error) {
85
+ .farm-input-decimal-formatter--input {
86
+ border-color: var(--farm-primary-base);
87
+
88
+ &>input {
89
+ color: var(--farm-neutral-darken);
90
+ }
91
+
92
+ .farm-icon {
93
+ color: var(--farm-primary-base);
94
+ }
95
+ }
96
+ }
@@ -0,0 +1,123 @@
1
+
2
+ import InputDecimalFormatter from './InputDecimalFormatter.vue';
3
+
4
+
5
+ export default {
6
+ title: 'Form/InputDecimalFormatter',
7
+ component: InputDecimalFormatter,
8
+ // decorators: [withDesign],
9
+ parameters: {
10
+ docs: {
11
+ description: {
12
+ component: `Input Money<br />
13
+ selector: <em>farm-input-decimal-formatter</em><br />
14
+ <span style="color: var(--farm-primary-base);">ready for use</span>
15
+ `,
16
+ },
17
+ },
18
+ design: {
19
+ type: 'figma',
20
+ url: '',
21
+ },
22
+ viewMode: 'docs',
23
+ },
24
+ };
25
+
26
+ export const Default = () => ({
27
+ data() {
28
+ return {
29
+ v: '1.200,00',
30
+ };
31
+ },
32
+ template: `<div style="width: 480px;">
33
+ <farm-label for="input-money">
34
+ label
35
+ </farm-label>
36
+ <farm-input-decimal-formatter id="input-money-default" v-model="v" />
37
+ <span>{{v}}</span>
38
+ </div>`,
39
+ });
40
+
41
+
42
+ export const Prefix = () => ({
43
+ data() {
44
+ return {
45
+ v: '1.200,00',
46
+ };
47
+ },
48
+ template: `<div style="width: 480px;">
49
+ <farm-label for="input-money">
50
+ label
51
+ </farm-label>
52
+ <farm-input-decimal-formatter prefix="R$ " id="input-money-prefix" v-model="v" />
53
+ <span>{{v}}</span>
54
+ </div>`,
55
+ });
56
+
57
+
58
+ export const Sufix = () => ({
59
+ data() {
60
+ return {
61
+ v: '1.200,00',
62
+ };
63
+ },
64
+ template: `<div style="width: 480px;">
65
+ <farm-label for="input-money">
66
+ label
67
+ </farm-label>
68
+ <farm-input-decimal-formatter suffix="%" id="input-money-prefix" v-model="v" />
69
+ <span>{{v}}</span>
70
+ </div>`,
71
+ });
72
+
73
+
74
+ export const Precision = () => ({
75
+ data() {
76
+ return {
77
+ v: '3,14159265358979323846',
78
+ };
79
+ },
80
+ template: `<div style="width: 480px;">
81
+ <farm-label for="input-money">
82
+ label
83
+ </farm-label>
84
+ <farm-input-decimal-formatter :precision="20" id="input-money-prefix" v-model="v" />
85
+ <span>{{v}}</span>
86
+ </div>`,
87
+ });
88
+
89
+
90
+ export const Icon = () => ({
91
+ data() {
92
+ return {
93
+ v: '1.200,00',
94
+ };
95
+ },
96
+ template: `<div style="width: 480px;">
97
+ <farm-label for="input-money">
98
+ label
99
+ </farm-label>
100
+ <farm-input-decimal-formatter id="input-money" v-model="v" icon="currency-usd" />
101
+ <span>{{v}}</span>
102
+ </div>`,
103
+ });
104
+
105
+ export const Required = () => ({
106
+ data() {
107
+
108
+ return {
109
+ v: '0,00',
110
+ rules: {
111
+ required: value => value !== "0,00" || 'Required field',
112
+ }
113
+ };
114
+ },
115
+ template: `<div style="width: 480px;">
116
+ <farm-label for="input-money">
117
+ label
118
+ </farm-label>
119
+ <farm-input-decimal-formatter id="input-money" v-model="v" :rules="[rules.required]" />
120
+ <span>{{v}}</span>
121
+ </div>`,
122
+ });
123
+
@@ -0,0 +1,316 @@
1
+ <template>
2
+ <div
3
+ class="farm-input-decimal-formatter"
4
+ :class="{
5
+ 'farm-input-decimal-formatter': true,
6
+ 'farm-input-decimal-formatter--validatable': rules.length > 0,
7
+ 'farm-input-decimal-formatter--touched': isTouched,
8
+ 'farm-input-decimal-formatter--blured': isBlured,
9
+ 'farm-input-decimal-formatter--error': hasError,
10
+ 'farm-input-decimal-formatter--focused': isFocus && !readonly,
11
+ 'farm-input-decimal-formatter--disabled': disabled,
12
+ 'farm-input-decimal-formatter--hiddendetails': hideDetails,
13
+ }"
14
+ :id="customId"
15
+ >
16
+ <div
17
+ :class="{
18
+ 'farm-input-decimal-formatter--input': true,
19
+ 'farm-input-decimal-formatter--input--iconed': icon,
20
+ }"
21
+ >
22
+ <button
23
+ type="button"
24
+ v-if="icon && iconPosition === 'left'"
25
+ @click="$emit('onClickIcon')"
26
+ >
27
+ <farm-icon
28
+ color="gray"
29
+ size="20px"
30
+ >{{ icon }}</farm-icon
31
+ >
32
+ </button>
33
+ <input
34
+ v-bind="$attrs"
35
+ v-model.lazy="innerValue"
36
+ v-money3="{
37
+ decimal,
38
+ thousands,
39
+ prefix,
40
+ suffix,
41
+ precision,
42
+ masked: false,
43
+ }"
44
+ :id="$props.id"
45
+ :disabled="disabled"
46
+ :readonly="readonly"
47
+ :model-modifiers="{ number: true }"
48
+ @click="$emit('click')"
49
+ @keyup="onKeyUp"
50
+ @blur="onBlur"
51
+ @focusin="onFocus(true)"
52
+ @focusout="onFocus(false)"
53
+ />
54
+ <button
55
+ type="button"
56
+ v-if="icon && iconPosition === 'right'"
57
+ @click="$emit('onClickIcon')"
58
+ >
59
+ <farm-icon
60
+ color="gray"
61
+ size="20px"
62
+ >{{ icon }}</farm-icon
63
+ >
64
+ </button>
65
+ </div>
66
+ <farm-caption
67
+ v-if="!hideDetails && showErrorText"
68
+ color="error"
69
+ variation="regular"
70
+ >
71
+ {{ errorBucket[0] }}
72
+ </farm-caption>
73
+ <farm-caption
74
+ v-if="!hideDetails && hint && !showErrorText"
75
+ class="farm-input-decimal-formatter__hint-text"
76
+ :class="{
77
+ 'farm-input-decimal-formatter__hint-text--show': persistentHint || isFocus,
78
+ }"
79
+ color="gray"
80
+ variation="regular"
81
+ >
82
+ {{ hint }}
83
+ </farm-caption>
84
+ </div>
85
+ </template>
86
+
87
+ <script lang="ts">
88
+ import { computed, onBeforeMount, PropType, ref, toRefs, watch } from 'vue';
89
+
90
+ import deepEqual from '../../composition/deepEqual';
91
+ import validateFormFieldBuilder from '../../composition/validateFormFieldBuilder';
92
+ import validateFormMethodBuilder from '../../composition/validateFormMethodBuilder';
93
+ import validateFormStateBuilder from '../../composition/validateFormStateBuilder';
94
+ import randomId from '../../helpers/randomId';
95
+
96
+ export default {
97
+ name: 'farm-input-decimal-formatter',
98
+ inheritAttrs: false,
99
+ props: {
100
+ /**
101
+ * v-model binding
102
+ */
103
+ modelValue: { type: [String, Number], default: '' },
104
+ /**
105
+ * Show icon?
106
+ */
107
+ icon: {
108
+ type: String,
109
+ default: null,
110
+ },
111
+ /**
112
+ * Icon position
113
+ */
114
+ iconPosition: { type: String as PropType<'left' | 'right'>, default: 'right' },
115
+ /**
116
+ * Show hint text
117
+ */
118
+ hint: {
119
+ type: String,
120
+ default: null,
121
+ },
122
+ /**
123
+ * Always show hint text
124
+ */
125
+ persistentHint: {
126
+ type: Boolean,
127
+ default: false,
128
+ },
129
+ /**
130
+ * Disabled the input
131
+ */
132
+ disabled: {
133
+ type: Boolean,
134
+ default: false,
135
+ },
136
+ /**
137
+ * Puts input in readonly state
138
+ */
139
+ readonly: {
140
+ type: Boolean,
141
+ default: false,
142
+ },
143
+
144
+ errorMessage: String,
145
+ /**
146
+ * Array of rules used for validation
147
+ */
148
+ rules: {
149
+ type: Array as PropType<Array<Function>>,
150
+ default: () => [],
151
+ },
152
+ /**
153
+ * Hides hint and validation errors
154
+ */
155
+ hideDetails: {
156
+ type: Boolean,
157
+ default: false,
158
+ },
159
+ /**
160
+ * Input id
161
+ */
162
+ id: {
163
+ type: String,
164
+ default: '',
165
+ },
166
+
167
+ /**
168
+ * Emitted when any key is pressed<br />
169
+ * _event_
170
+ */
171
+ keyup: {
172
+ type: Function,
173
+ // eslint-disable-next-line
174
+ default: (event: Event) => {},
175
+ },
176
+
177
+ /**
178
+ * Currency symbol followed by a Space, like "R$ "
179
+ */
180
+ prefix: {
181
+ type: String,
182
+ default: '',
183
+ },
184
+
185
+ /**
186
+ * Percentage for example: " %"
187
+ */
188
+ suffix: {
189
+ type: String,
190
+ default: '',
191
+ },
192
+ /**
193
+ * Thousands separator
194
+ */
195
+ thousands: {
196
+ type: String,
197
+ default: '.',
198
+ },
199
+ /**
200
+ * Decimal separator
201
+ */
202
+ decimal: {
203
+ type: String,
204
+ default: ',',
205
+ },
206
+ /**
207
+ * How many decimal places
208
+ */
209
+ precision: {
210
+ type: Number,
211
+ default: 2,
212
+ },
213
+ },
214
+ setup(props, { emit }) {
215
+ const { rules } = toRefs(props);
216
+ const innerValue = ref(props.modelValue);
217
+ const isTouched = ref(false);
218
+ const isBlured = ref(false);
219
+ const isFocus = ref(false);
220
+
221
+ const { errorBucket, valid, validatable } = validateFormStateBuilder();
222
+
223
+ let fieldValidator = validateFormFieldBuilder(rules.value);
224
+
225
+ const hasError = computed(() => {
226
+ return errorBucket.value.length > 0;
227
+ });
228
+ const customId = 'farm-input-decimal-formatter-' + (props.id || randomId(2));
229
+
230
+ const showErrorText = computed(() => hasError.value && isTouched.value && isBlured.value);
231
+
232
+ watch(
233
+ () => props.modelValue,
234
+ () => {
235
+ innerValue.value = props.modelValue;
236
+ validate(innerValue.value);
237
+ }
238
+ );
239
+
240
+ watch(
241
+ () => innerValue.value,
242
+ () => {
243
+ emit('update:modelValue', innerValue.value);
244
+ validate(innerValue.value);
245
+ }
246
+ );
247
+
248
+ watch(
249
+ () => props.rules,
250
+ (newVal, oldVal) => {
251
+ if (deepEqual(newVal, oldVal)) return;
252
+ fieldValidator = validateFormFieldBuilder(rules.value);
253
+ validate = validateFormMethodBuilder(errorBucket, valid, fieldValidator);
254
+ validate(innerValue.value);
255
+ }
256
+ );
257
+
258
+ onBeforeMount(() => {
259
+ validate(innerValue.value);
260
+ });
261
+
262
+ let validate = validateFormMethodBuilder(errorBucket, valid, fieldValidator);
263
+
264
+ const onKeyUp = (event: Event) => {
265
+ isTouched.value = true;
266
+ emit('keyup', event);
267
+
268
+ setTimeout(() => {
269
+ emit('change', innerValue.value);
270
+ }, 100);
271
+ };
272
+
273
+ const onBlur = (event: Event) => {
274
+ isBlured.value = true;
275
+ emit('blur', event);
276
+ };
277
+
278
+ const onFocus = (focus: boolean) => {
279
+ isFocus.value = focus;
280
+ };
281
+
282
+ const reset = () => {
283
+ innerValue.value = '';
284
+ isTouched.value = true;
285
+ emit('update:modelValue', innerValue.value);
286
+ };
287
+
288
+ const makePristine = () => {
289
+ isTouched.value = false;
290
+ isBlured.value = false;
291
+ };
292
+
293
+ return {
294
+ innerValue,
295
+ errorBucket,
296
+ valid,
297
+ validatable,
298
+ hasError,
299
+ customId,
300
+ isTouched,
301
+ isBlured,
302
+ isFocus,
303
+ showErrorText,
304
+ validate,
305
+ onKeyUp,
306
+ onBlur,
307
+ onFocus,
308
+ reset,
309
+ makePristine,
310
+ };
311
+ },
312
+ };
313
+ </script>
314
+ <style lang="scss" scoped>
315
+ @import 'InputDecimalFormatter';
316
+ </style>
@@ -0,0 +1,53 @@
1
+ import { shallowMount } from '@vue/test-utils';
2
+
3
+ import InputDecimalFormatter from '../InputDecimalFormatter';
4
+
5
+ describe('InputDecimalFormatter component', () => {
6
+ let wrapper;
7
+ let component;
8
+
9
+ beforeEach(() => {
10
+ wrapper = shallowMount(InputDecimalFormatter, {
11
+ directives: {
12
+ mask: () => { },
13
+ },
14
+ });
15
+ component = wrapper.vm;
16
+ });
17
+
18
+ test('Created hook', () => {
19
+ expect(wrapper).toBeDefined();
20
+ });
21
+
22
+ describe('mount component', () => {
23
+ it('renders correctly', () => {
24
+ expect(wrapper.element).toBeDefined();
25
+ });
26
+ });
27
+
28
+ describe('methods', () => {
29
+ it('reset', () => {
30
+ component.reset();
31
+ expect(component.isTouched).toBeTruthy();
32
+ expect(component.innerValue).toEqual('');
33
+ });
34
+
35
+ it('onKeyUp', () => {
36
+ component.onKeyUp();
37
+ expect(component.isTouched).toBeTruthy();
38
+ });
39
+
40
+ it('onBlur', () => {
41
+ component.onBlur();
42
+ expect(component.isBlured).toBeTruthy();
43
+ });
44
+
45
+ it('makePristine', () => {
46
+ component.isTouched = true;
47
+ component.isBlured = true;
48
+ component.makePristine();
49
+ expect(component.isTouched).toBeFalsy();
50
+ expect(component.isBlured).toBeFalsy();
51
+ });
52
+ });
53
+ });
@@ -0,0 +1,4 @@
1
+ import InputDecimalFormatter from './InputDecimalFormatter.vue';
2
+
3
+ export { InputDecimalFormatter };
4
+ export default InputDecimalFormatter;