@farm-investimentos/front-mfe-components 15.5.5 → 15.6.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farm-investimentos/front-mfe-components",
3
- "version": "15.5.5",
3
+ "version": "15.6.0",
4
4
  "author": "farm investimentos",
5
5
  "private": false,
6
6
  "main": "./dist/front-mfe-components.common.js",
@@ -8,62 +8,75 @@
8
8
  display: flex;
9
9
  align-items: center;
10
10
 
11
+ .farm-icon,
12
+ .farm-typography {
13
+ color: var(--farm-neutral-darken);
14
+ }
15
+
11
16
  &--clickable {
12
17
  cursor: pointer;
13
18
  }
14
19
 
15
- > a {
16
- text-decoration: none;
20
+ &--disabled {
21
+ cursor: default;
22
+
23
+ .farm-icon,
24
+ .farm-typography {
25
+ color: var(--farm-stroke-disabled);
26
+ }
17
27
  }
18
28
 
19
- .farm-icon,
20
- .farm-typography {
21
- color: var(--farm-neutral-darken);
29
+ > a {
30
+ text-decoration: none;
22
31
  }
23
32
 
24
33
  &:hover,
25
34
  &:focus {
26
35
  border-radius: 5px;
27
36
 
28
- @each $color in $theme-colors-list {
29
- &#{'.farm-listitem--' + $color + '-base'} {
30
- background-color: rgba(themeColor($color), 0.27);
31
- .farm-icon,
32
- .farm-typography {
33
- color: rgba(themeColor($color), 1);
37
+ &:not(.farm-listitem--disabled) {
38
+ @each $color in $theme-colors-list {
39
+ &#{'.farm-listitem--' + $color + '-base'} {
40
+ background-color: rgba(themeColor($color), 0.27);
41
+ .farm-icon,
42
+ .farm-typography {
43
+ color: rgba(themeColor($color), 1);
44
+ }
34
45
  }
35
- }
36
46
 
37
- &#{'.farm-listitem--' + $color + '-lighten'} {
38
- background-color: rgba(themeColor($color, 'lighten'), 0.27);
39
- .farm-icon,
40
- .farm-typography {
41
- color: rgba(themeColor($color), 1);
47
+ &#{'.farm-listitem--' + $color + '-lighten'} {
48
+ background-color: rgba(themeColor($color, 'lighten'), 0.27);
49
+ .farm-icon,
50
+ .farm-typography {
51
+ color: rgba(themeColor($color), 1);
52
+ }
42
53
  }
43
- }
44
54
 
45
- &#{'.farm-listitem--' + $color + '-darken'} {
46
- background-color: rgba(themeColor($color, 'darken'), 0.27);
47
- .farm-icon,
48
- .farm-typography {
49
- color: rgba(themeColor($color), 1);
55
+ &#{'.farm-listitem--' + $color + '-darken'} {
56
+ background-color: rgba(themeColor($color, 'darken'), 0.27);
57
+ .farm-icon,
58
+ .farm-typography {
59
+ color: rgba(themeColor($color), 1);
60
+ }
50
61
  }
51
62
  }
52
63
  }
53
64
  }
54
65
 
55
66
  &:active {
56
- @each $color in $theme-colors-list {
57
- &#{'.farm-listitem--' + $color + '-base'} {
58
- background-color: rgba(themeColor($color), 0.8);
59
- }
67
+ &:not(.farm-listitem--disabled) {
68
+ @each $color in $theme-colors-list {
69
+ &#{'.farm-listitem--' + $color + '-base'} {
70
+ background-color: rgba(themeColor($color), 0.8);
71
+ }
60
72
 
61
- &#{'.farm-listitem--' + $color + '-lighten'} {
62
- background-color: rgba(themeColor($color, 'lighten'), 0.8);
63
- }
73
+ &#{'.farm-listitem--' + $color + '-lighten'} {
74
+ background-color: rgba(themeColor($color, 'lighten'), 0.8);
75
+ }
64
76
 
65
- &#{'.farm-listitem--' + $color + '-darken'} {
66
- background-color: rgba(themeColor($color, 'darken'), 0.8);
77
+ &#{'.farm-listitem--' + $color + '-darken'} {
78
+ background-color: rgba(themeColor($color, 'darken'), 0.8);
79
+ }
67
80
  }
68
81
  }
69
82
  }
@@ -28,19 +28,19 @@
28
28
  margin-right: 8px;
29
29
  }
30
30
 
31
- :deep(.farm-listitem:hover .farm-typography) {
31
+ :deep(.farm-listitem:not(.farm-listitem--disabled):hover .farm-typography) {
32
32
  color: var(--farm-primary-base);
33
33
  }
34
34
 
35
- :deep(.farm-listitem:focus .farm-typography) {
35
+ :deep(.farm-listitem:not(.farm-listitem--disabled):focus .farm-typography) {
36
36
  color: var(--farm-primary-base);
37
37
  }
38
38
 
39
- :deep(.farm-listitem:hover .farm-checkbox .farm-icon) {
39
+ :deep(.farm-listitem:not(.farm-listitem--disabled):hover .farm-checkbox .farm-icon) {
40
40
  color: var(--farm-primary-lighten);
41
41
  }
42
42
 
43
- :deep(.farm-listitem:focus .farm-checkbox .farm-icon) {
43
+ :deep(.farm-listitem:not(.farm-listitem--disabled):focus .farm-checkbox .farm-icon) {
44
44
  color: var(--farm-primary-lighten);
45
45
  }
46
46
 
@@ -10,7 +10,8 @@ export default {
10
10
  description: {
11
11
  component: `Select<br />
12
12
  selector: <em>farm-select</em><br />
13
- <span style="color: var(--farm-primary-base);">ready for use</span>
13
+ <span style="color: var(--farm-primary-base);">ready for use</span><br />
14
+ <a href="https://github.com/Farm-Investimentos/front-mfe-components/blob/develop/src/components/Select/Select.vue" target="_blank">Github</a>
14
15
  `,
15
16
  },
16
17
  },
@@ -129,6 +130,42 @@ export const Disabled = () => ({
129
130
  </div>`,
130
131
  });
131
132
 
133
+ export const DisabledKeys = () => ({
134
+ data() {
135
+ return {
136
+ v: null,
137
+ items: [
138
+ { value: 1, text: ' value 1', disabled: true },
139
+ { value: 2, text: ' value 2', disabled: true },
140
+ { value: 3, text: ' value 3' },
141
+ ],
142
+ };
143
+ },
144
+ methods: {
145
+ allowAllOptions() {
146
+ this.items = [
147
+ { value: 1, text: ' value 1' },
148
+ { value: 2, text: ' value 2' },
149
+ { value: 3, text: ' value 3' },
150
+ ];
151
+ },
152
+ reset() {
153
+ this.items = [
154
+ { value: 1, text: ' value 1', disabled: true },
155
+ { value: 2, text: ' value 2', disabled: true },
156
+ { value: 3, text: ' value 3' },
157
+ ];
158
+ },
159
+ },
160
+ template: `<div style="width: 480px">
161
+ <farm-select v-model="v" :items="items" />
162
+ v-model: {{ v }}
163
+ <br><br>
164
+ <farm-btn @click="allowAllOptions">Habilitar todos itens</farm-btn>
165
+ <farm-btn @click="reset">Resetar</farm-btn>
166
+ </div>`,
167
+ });
168
+
132
169
  export const Validate = () => ({
133
170
  data() {
134
171
  return {
@@ -13,16 +13,24 @@
13
13
  v-if="!readonly && !disabled"
14
14
  :id="customId"
15
15
  >
16
- <farm-contextmenu bottom v-model="isVisible" :stay-open="multiple" ref="contextmenu">
16
+ <farm-contextmenu
17
+ bottom
18
+ v-model="isVisible"
19
+ :stay-open="multiple || clickedDisabledItem"
20
+ ref="contextmenu"
21
+ >
17
22
  <farm-list v-if="!readonly" ref="listRef" @keydown="onKeyDown">
18
23
  <farm-listitem
19
- tabindex="0"
20
24
  v-for="(item, index) in items"
25
+ tabindex="0"
21
26
  clickable
22
- hoverColorVariation="lighten"
23
- hover-color="primary"
27
+ hover-color-variation="lighten"
28
+ :hover-color="item.disabled ? 'neutral' : 'primary'"
24
29
  :key="'contextmenu_item_' + index"
25
- :class="{ 'farm-listitem--selected': item[itemValue] === innerValue }"
30
+ :class="{
31
+ 'farm-listitem--selected': item[itemValue] === innerValue,
32
+ 'farm-listitem--disabled': item.disabled,
33
+ }"
26
34
  @click="selectItem(item)"
27
35
  >
28
36
  <farm-checkbox
@@ -30,6 +38,7 @@
30
38
  v-model="checked"
31
39
  value="1"
32
40
  size="sm"
41
+ :disabled="item.disabled"
33
42
  v-if="isChecked(item)"
34
43
  />
35
44
  <farm-checkbox
@@ -37,6 +46,7 @@
37
46
  v-model="checked"
38
47
  value="2"
39
48
  size="sm"
49
+ :disabled="item.disabled"
40
50
  v-else-if="multiple"
41
51
  />
42
52
  <farm-caption bold tag="span">{{ item[itemText] }}</farm-caption>
@@ -242,6 +252,7 @@ export default defineComponent({
242
252
  keys,
243
253
  } = buildData(props);
244
254
 
255
+ const clickedDisabledItem = ref(false);
245
256
  const listRef = ref();
246
257
 
247
258
  const contextmenu = ref(null);
@@ -339,7 +350,20 @@ export default defineComponent({
339
350
  };
340
351
 
341
352
  const selectItem = item => {
342
- inputField.value.focus();
353
+ if (inputField.value) {
354
+ inputField.value.focus();
355
+ }
356
+
357
+ if (item.disabled) {
358
+ clickedDisabledItem.value = true;
359
+
360
+ // "Schedule" execution to next loop, so the contextMenu won't close immediately if a disabled item is clicked
361
+ setTimeout(() => {
362
+ clickedDisabledItem.value = false;
363
+ });
364
+ return;
365
+ }
366
+
343
367
  if (multiple.value) {
344
368
  const alreadyAdded = multipleValues.value.findIndex(
345
369
  val => val === item[itemValue.value]
@@ -457,6 +481,7 @@ export default defineComponent({
457
481
  customId,
458
482
  showErrorText,
459
483
  contextmenu,
484
+ clickedDisabledItem,
460
485
  validate,
461
486
  reset,
462
487
  selectItem,
@@ -1,6 +1,11 @@
1
1
  import { shallowMount } from '@vue/test-utils';
2
2
  import Select from '../Select';
3
3
 
4
+ /* jest.spyOn(global, 'setTimeout').mockImplementation(fn => {
5
+ fn();
6
+ return setTimeout(() => 1, 0);
7
+ }); */
8
+
4
9
  describe('Select component', () => {
5
10
  let wrapper;
6
11
  let component;
@@ -124,6 +129,66 @@ describe('Select component', () => {
124
129
  expect(component.selectedText).toBe('value 0 (+2 outros)');
125
130
  });
126
131
  });
132
+ describe('disabled items', () => {
133
+ it('should not select a disabled item', async () => {
134
+ const items = [
135
+ { value: 0, text: 'value 0', disabled: true },
136
+ { value: 1, text: 'value 1' },
137
+ { value: 2, text: 'value 2' },
138
+ { value: 3, text: 'value 3' },
139
+ ];
140
+
141
+ await wrapper.setProps({
142
+ items,
143
+ value: 1,
144
+ });
145
+
146
+ expect(component.innerValue).toBe(1);
147
+ expect(component.selectedText).toBe('value 1');
148
+ component.selectItem(items[2]);
149
+ setTimeout(() => {
150
+ expect(component.innerValue).toBe(2);
151
+ expect(component.selectedText).toBe('value 2');
152
+ }, 150);
153
+ component.selectItem(items[0]);
154
+ setTimeout(() => {
155
+ expect(component.innerValue).toBe(2);
156
+ expect(component.selectedText).toBe('value 2');
157
+ }, 150);
158
+ component.selectItem(items[3]);
159
+ setTimeout(() => {
160
+ expect(component.innerValue).toBe(3);
161
+ expect(component.selectedText).toBe('value 3');
162
+ }, 150);
163
+ });
164
+ it('should not select a disabled item if is multiple', async () => {
165
+ const items = [
166
+ { value: 0, text: 'value 0' },
167
+ { value: 1, text: 'value 1', disabled: true },
168
+ { value: 2, text: 'value 2' },
169
+ { value: 3, text: 'value 3', disabled: true },
170
+ ];
171
+
172
+ await wrapper.setProps({
173
+ multiple: true,
174
+ items,
175
+ value: [0],
176
+ });
177
+
178
+ expect(component.innerValue).toEqual([0]);
179
+ expect(component.selectedText).toBe('value 0');
180
+ component.selectItem(items[2]);
181
+ setTimeout(() => {
182
+ expect(component.innerValue).toEqual([0, 2]);
183
+ expect(component.selectedText).toBe('value 0 (+1 outro)');
184
+ }, 150);
185
+ component.selectItem(items[1]);
186
+ setTimeout(() => {
187
+ expect(component.innerValue).toEqual([0, 2]);
188
+ expect(component.selectedText).toBe('value 0 (+1 outro)');
189
+ }, 150);
190
+ });
191
+ });
127
192
 
128
193
  describe('onKeyDown', () => {
129
194
  it('should open the ContextMenu and click on current element', () => {