@farm-investimentos/front-mfe-components 15.7.3 → 15.8.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/dist/front-mfe-components.common.js +314 -134
- package/dist/front-mfe-components.common.js.map +1 -1
- package/dist/front-mfe-components.css +1 -1
- package/dist/front-mfe-components.umd.js +314 -134
- package/dist/front-mfe-components.umd.js.map +1 -1
- package/dist/front-mfe-components.umd.min.js +1 -1
- package/dist/front-mfe-components.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Select/Select.stories.js +36 -0
- package/src/components/Select/Select.vue +78 -8
- package/src/components/Select/__tests__/Select.spec.js +70 -26
- package/src/components/SelectAutoComplete/SelectAutoComplete.scss +13 -5
- package/src/components/SelectAutoComplete/SelectAutoComplete.stories.js +36 -0
- package/src/components/SelectAutoComplete/SelectAutoComplete.vue +100 -4
package/package.json
CHANGED
|
@@ -288,6 +288,42 @@ export const Multiple = () => ({
|
|
|
288
288
|
</div>`,
|
|
289
289
|
});
|
|
290
290
|
|
|
291
|
+
export const MultipleWithAllOption = () => ({
|
|
292
|
+
data() {
|
|
293
|
+
return {
|
|
294
|
+
v: null,
|
|
295
|
+
items: [
|
|
296
|
+
{ value: 0, text: 'value 0' },
|
|
297
|
+
{ value: 1, text: 'value 1' },
|
|
298
|
+
{ value: 2, text: 'value 2' },
|
|
299
|
+
{ value: 3, text: 'value 3' },
|
|
300
|
+
],
|
|
301
|
+
};
|
|
302
|
+
},
|
|
303
|
+
template: `<div style="width: 400px">
|
|
304
|
+
<farm-select v-model="v" :items="items" multiple has-all-option />
|
|
305
|
+
v-model: {{ v }}
|
|
306
|
+
</div>`,
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
export const MultipleWithAllOptionAndDisabledItems = () => ({
|
|
310
|
+
data() {
|
|
311
|
+
return {
|
|
312
|
+
v: null,
|
|
313
|
+
items: [
|
|
314
|
+
{ value: 0, text: 'value 0' },
|
|
315
|
+
{ value: 1, text: 'value 1', disabled: true },
|
|
316
|
+
{ value: 2, text: 'value 2' },
|
|
317
|
+
{ value: 3, text: 'value 3', disabled: true },
|
|
318
|
+
],
|
|
319
|
+
};
|
|
320
|
+
},
|
|
321
|
+
template: `<div style="width: 400px">
|
|
322
|
+
<farm-select v-model="v" :items="items" multiple has-all-option />
|
|
323
|
+
v-model: {{ v }}
|
|
324
|
+
</div>`,
|
|
325
|
+
});
|
|
326
|
+
|
|
291
327
|
export const MultipleInitValue = () => ({
|
|
292
328
|
data() {
|
|
293
329
|
return {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
+
v-if="!readonly && !disabled"
|
|
4
|
+
:id="customId"
|
|
3
5
|
:class="{
|
|
4
6
|
'farm-textfield': true,
|
|
5
7
|
'farm-textfield--validatable': rules.length > 0,
|
|
@@ -10,8 +12,6 @@
|
|
|
10
12
|
'farm-textfield--focused': isFocus || isVisible,
|
|
11
13
|
'farm-textfield--hiddendetails': hideDetails,
|
|
12
14
|
}"
|
|
13
|
-
v-if="!readonly && !disabled"
|
|
14
|
-
:id="customId"
|
|
15
15
|
>
|
|
16
16
|
<farm-contextmenu
|
|
17
17
|
bottom
|
|
@@ -20,13 +20,34 @@
|
|
|
20
20
|
ref="contextmenu"
|
|
21
21
|
>
|
|
22
22
|
<farm-list v-if="!readonly" ref="listRef" @keydown="onKeyDown">
|
|
23
|
+
<farm-listitem
|
|
24
|
+
v-if="hasAllOption"
|
|
25
|
+
tabindex="0"
|
|
26
|
+
clickable
|
|
27
|
+
hover-color-variation="lighten"
|
|
28
|
+
:hover-color="hasAllDisabled ? 'neutral' : 'primary'"
|
|
29
|
+
:class="{
|
|
30
|
+
'farm-listitem--selected': innerValue === 'all',
|
|
31
|
+
'farm-listitem--disabled': hasAllDisabled,
|
|
32
|
+
}"
|
|
33
|
+
@click="selectAll"
|
|
34
|
+
>
|
|
35
|
+
<farm-checkbox
|
|
36
|
+
v-model="hasAllSelected"
|
|
37
|
+
class="farm-select__checkbox"
|
|
38
|
+
value="all"
|
|
39
|
+
size="sm"
|
|
40
|
+
:disabled="hasAllDisabled"
|
|
41
|
+
/>
|
|
42
|
+
<farm-caption bold tag="span">Todos</farm-caption>
|
|
43
|
+
</farm-listitem>
|
|
23
44
|
<farm-listitem
|
|
24
45
|
v-for="(item, index) in items"
|
|
25
46
|
tabindex="0"
|
|
26
47
|
clickable
|
|
27
48
|
hover-color-variation="lighten"
|
|
28
|
-
:hover-color="item.disabled ? 'neutral' : 'primary'"
|
|
29
49
|
:key="'contextmenu_item_' + index"
|
|
50
|
+
:hover-color="item.disabled ? 'neutral' : 'primary'"
|
|
30
51
|
:class="{
|
|
31
52
|
'farm-listitem--selected': item[itemValue] === innerValue,
|
|
32
53
|
'farm-listitem--disabled': item.disabled,
|
|
@@ -34,20 +55,20 @@
|
|
|
34
55
|
@click="selectItem(item)"
|
|
35
56
|
>
|
|
36
57
|
<farm-checkbox
|
|
37
|
-
|
|
58
|
+
v-if="isChecked(item)"
|
|
38
59
|
v-model="checked"
|
|
60
|
+
class="farm-select__checkbox"
|
|
39
61
|
value="1"
|
|
40
62
|
size="sm"
|
|
41
63
|
:disabled="item.disabled"
|
|
42
|
-
v-if="isChecked(item)"
|
|
43
64
|
/>
|
|
44
65
|
<farm-checkbox
|
|
45
|
-
|
|
66
|
+
v-else-if="multiple"
|
|
46
67
|
v-model="checked"
|
|
68
|
+
class="farm-select__checkbox"
|
|
47
69
|
value="2"
|
|
48
70
|
size="sm"
|
|
49
71
|
:disabled="item.disabled"
|
|
50
|
-
v-else-if="multiple"
|
|
51
72
|
/>
|
|
52
73
|
<farm-caption bold tag="span">{{ item[itemText] }}</farm-caption>
|
|
53
74
|
</farm-listitem>
|
|
@@ -55,7 +76,7 @@
|
|
|
55
76
|
{{ noDataText }}
|
|
56
77
|
</farm-listitem>
|
|
57
78
|
</farm-list>
|
|
58
|
-
<template
|
|
79
|
+
<template #activator="{}">
|
|
59
80
|
<div
|
|
60
81
|
class="farm-textfield--input farm-textfield--input--iconed"
|
|
61
82
|
@keydown="onKeyDown"
|
|
@@ -198,6 +219,13 @@ export default defineComponent({
|
|
|
198
219
|
type: String,
|
|
199
220
|
default: '',
|
|
200
221
|
},
|
|
222
|
+
/**
|
|
223
|
+
* Set "All" as first option to select all other values<br />
|
|
224
|
+
*/
|
|
225
|
+
hasAllOption: {
|
|
226
|
+
type: Boolean,
|
|
227
|
+
default: false,
|
|
228
|
+
},
|
|
201
229
|
/**
|
|
202
230
|
* The updated bound model<br />
|
|
203
231
|
* _event_
|
|
@@ -262,9 +290,32 @@ export default defineComponent({
|
|
|
262
290
|
let fieldValidator = validateFormFieldBuilder(rules.value);
|
|
263
291
|
let validate = validateFormMethodBuilder(errorBucket, valid, fieldValidator);
|
|
264
292
|
|
|
293
|
+
const enabledItems = computed(() => items.value.filter(item => !item.disabled));
|
|
294
|
+
const disabledItems = computed(() => items.value.filter(item => item.disabled));
|
|
265
295
|
const hasError = computed(() => {
|
|
266
296
|
return errorBucket.value.length > 0;
|
|
267
297
|
});
|
|
298
|
+
const hasAllSelected = computed({
|
|
299
|
+
get() {
|
|
300
|
+
if (
|
|
301
|
+
!multiple.value ||
|
|
302
|
+
!Array.isArray(items.value) ||
|
|
303
|
+
!Array.isArray(innerValue.value)
|
|
304
|
+
) {
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (innerValue.value.length === enabledItems.value.length) {
|
|
309
|
+
return 'all';
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return false;
|
|
313
|
+
},
|
|
314
|
+
set() {
|
|
315
|
+
emit('input', innerValue.value);
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
const hasAllDisabled = computed(() => items.value.length == disabledItems.value.length);
|
|
268
319
|
|
|
269
320
|
const customId = 'farm-select-' + (props.id || randomId(2));
|
|
270
321
|
|
|
@@ -282,6 +333,7 @@ export default defineComponent({
|
|
|
282
333
|
) {
|
|
283
334
|
multipleValues.value = [];
|
|
284
335
|
}
|
|
336
|
+
|
|
285
337
|
if (Array.isArray(newValue) && newValue.length > 0) {
|
|
286
338
|
multipleValues.value = [...newValue];
|
|
287
339
|
}
|
|
@@ -386,6 +438,21 @@ export default defineComponent({
|
|
|
386
438
|
emit('change', innerValue.value);
|
|
387
439
|
}, 100);
|
|
388
440
|
};
|
|
441
|
+
const selectAll = () => {
|
|
442
|
+
if (hasAllDisabled.value) {
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
if (multipleValues.value.length === enabledItems.value.length) {
|
|
447
|
+
multipleValues.value = [];
|
|
448
|
+
} else {
|
|
449
|
+
multipleValues.value = enabledItems.value.map(item => item[itemValue.value]);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
checked.value = '1';
|
|
453
|
+
innerValue.value = [...multipleValues.value];
|
|
454
|
+
validate(innerValue.value);
|
|
455
|
+
};
|
|
389
456
|
|
|
390
457
|
const clickInput = () => {
|
|
391
458
|
isTouched.value = true;
|
|
@@ -474,6 +541,8 @@ export default defineComponent({
|
|
|
474
541
|
valid,
|
|
475
542
|
validatable,
|
|
476
543
|
hasError,
|
|
544
|
+
hasAllSelected,
|
|
545
|
+
hasAllDisabled,
|
|
477
546
|
isTouched,
|
|
478
547
|
isBlured,
|
|
479
548
|
isFocus,
|
|
@@ -485,6 +554,7 @@ export default defineComponent({
|
|
|
485
554
|
validate,
|
|
486
555
|
reset,
|
|
487
556
|
selectItem,
|
|
557
|
+
selectAll,
|
|
488
558
|
onBlur,
|
|
489
559
|
onFocus,
|
|
490
560
|
clickInput,
|
|
@@ -1,17 +1,16 @@
|
|
|
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
|
-
|
|
9
4
|
describe('Select component', () => {
|
|
10
5
|
let wrapper;
|
|
11
6
|
let component;
|
|
12
7
|
|
|
13
8
|
beforeEach(() => {
|
|
14
|
-
wrapper = shallowMount(Select
|
|
9
|
+
wrapper = shallowMount(Select, {
|
|
10
|
+
propsData: {
|
|
11
|
+
id: 'my-custom-id',
|
|
12
|
+
},
|
|
13
|
+
});
|
|
15
14
|
component = wrapper.vm;
|
|
16
15
|
});
|
|
17
16
|
|
|
@@ -145,21 +144,15 @@ describe('Select component', () => {
|
|
|
145
144
|
|
|
146
145
|
expect(component.innerValue).toBe(1);
|
|
147
146
|
expect(component.selectedText).toBe('value 1');
|
|
147
|
+
|
|
148
148
|
component.selectItem(items[2]);
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
expect(component.selectedText).toBe('value 2');
|
|
152
|
-
}, 150);
|
|
149
|
+
expect(component.innerValue).toBe(2);
|
|
150
|
+
|
|
153
151
|
component.selectItem(items[0]);
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
expect(component.selectedText).toBe('value 2');
|
|
157
|
-
}, 150);
|
|
152
|
+
expect(component.innerValue).toBe(2);
|
|
153
|
+
|
|
158
154
|
component.selectItem(items[3]);
|
|
159
|
-
|
|
160
|
-
expect(component.innerValue).toBe(3);
|
|
161
|
-
expect(component.selectedText).toBe('value 3');
|
|
162
|
-
}, 150);
|
|
155
|
+
expect(component.innerValue).toBe(3);
|
|
163
156
|
});
|
|
164
157
|
it('should not select a disabled item if is multiple', async () => {
|
|
165
158
|
const items = [
|
|
@@ -177,16 +170,67 @@ describe('Select component', () => {
|
|
|
177
170
|
|
|
178
171
|
expect(component.innerValue).toEqual([0]);
|
|
179
172
|
expect(component.selectedText).toBe('value 0');
|
|
173
|
+
|
|
180
174
|
component.selectItem(items[2]);
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
expect(component.selectedText).toBe('value 0 (+1 outro)');
|
|
184
|
-
}, 150);
|
|
175
|
+
expect(component.innerValue).toEqual([0, 2]);
|
|
176
|
+
|
|
185
177
|
component.selectItem(items[1]);
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
178
|
+
expect(component.innerValue).toEqual([0, 2]);
|
|
179
|
+
|
|
180
|
+
component.selectItem(items[0]);
|
|
181
|
+
expect(component.innerValue).toEqual([2]);
|
|
182
|
+
|
|
183
|
+
component.selectItem(items[0]);
|
|
184
|
+
expect(component.innerValue).toEqual([2, 0]);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
describe('multiple with all option', () => {
|
|
189
|
+
it('should check all options', async () => {
|
|
190
|
+
const items = [
|
|
191
|
+
{ value: 0, text: 'value 0' },
|
|
192
|
+
{ value: 1, text: 'value 1' },
|
|
193
|
+
{ value: 2, text: 'value 2' },
|
|
194
|
+
{ value: 3, text: 'value 3' },
|
|
195
|
+
];
|
|
196
|
+
|
|
197
|
+
await wrapper.setProps({
|
|
198
|
+
items,
|
|
199
|
+
value: null,
|
|
200
|
+
multiple: true,
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
expect(component.hasAllSelected).toBe(false);
|
|
204
|
+
expect(component.multipleValues).toEqual([]);
|
|
205
|
+
|
|
206
|
+
component.selectAll();
|
|
207
|
+
|
|
208
|
+
expect(component.hasAllSelected).toBe('all');
|
|
209
|
+
expect(component.multipleValues).toEqual(items.map(item => item.value));
|
|
210
|
+
});
|
|
211
|
+
it('should check all options but disabled', async () => {
|
|
212
|
+
const items = [
|
|
213
|
+
{ value: 0, text: 'value 0' },
|
|
214
|
+
{ value: 1, text: 'value 1', disabled: true },
|
|
215
|
+
{ value: 2, text: 'value 2' },
|
|
216
|
+
{ value: 3, text: 'value 3', disabled: true },
|
|
217
|
+
];
|
|
218
|
+
|
|
219
|
+
await wrapper.setProps({
|
|
220
|
+
items,
|
|
221
|
+
value: null,
|
|
222
|
+
multiple: true,
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
expect(component.hasAllSelected).toBe(false);
|
|
226
|
+
expect(component.multipleValues).toEqual([]);
|
|
227
|
+
|
|
228
|
+
component.selectAll();
|
|
229
|
+
|
|
230
|
+
expect(component.hasAllSelected).toBe('all');
|
|
231
|
+
expect(component.multipleValues).toEqual(
|
|
232
|
+
items.filter(item => !item.disabled).map(item => item.value)
|
|
233
|
+
);
|
|
190
234
|
});
|
|
191
235
|
});
|
|
192
236
|
|
|
@@ -28,22 +28,30 @@
|
|
|
28
28
|
margin-right: 8px;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
:deep(.farm-listitem:
|
|
31
|
+
:deep(.farm-listitem:focus .farm-typography) {
|
|
32
32
|
color: var(--farm-primary-base);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
:deep(.farm-listitem:focus .farm-
|
|
35
|
+
:deep(.farm-listitem:focus .farm-checkbox .farm-icon) {
|
|
36
|
+
color: var(--farm-primary-lighten);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
:deep(.farm-listitem:not(.farm-listitem--disabled):hover .farm-typography) {
|
|
36
40
|
color: var(--farm-primary-base);
|
|
37
41
|
}
|
|
38
42
|
|
|
39
|
-
:deep(.farm-listitem:
|
|
43
|
+
:deep(.farm-listitem:not(.farm-listitem--disabled):focus .farm-typography) {
|
|
44
|
+
color: var(--farm-primary-base);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
:deep(.farm-listitem:not(.farm-listitem--disabled):hover .farm-checkbox .farm-icon) {
|
|
40
48
|
color: var(--farm-primary-lighten);
|
|
41
49
|
}
|
|
42
50
|
|
|
43
|
-
:deep(.farm-listitem:focus .farm-checkbox .farm-icon) {
|
|
51
|
+
:deep(.farm-listitem:not(.farm-listitem--disabled):focus .farm-checkbox .farm-icon) {
|
|
44
52
|
color: var(--farm-primary-lighten);
|
|
45
53
|
}
|
|
46
54
|
|
|
47
55
|
:deep(.farm-listitem:hover .farm-checkbox.farm-checkbox--checked .farm-icon) {
|
|
48
56
|
color: white;
|
|
49
|
-
}
|
|
57
|
+
}
|
|
@@ -326,3 +326,39 @@ export const ChangeEvent = () => ({
|
|
|
326
326
|
|
|
327
327
|
</div>`,
|
|
328
328
|
});
|
|
329
|
+
|
|
330
|
+
export const MultipleWithAllOption = () => ({
|
|
331
|
+
data() {
|
|
332
|
+
return {
|
|
333
|
+
v: null,
|
|
334
|
+
items: [
|
|
335
|
+
{ value: 0, text: 'value 0' },
|
|
336
|
+
{ value: 1, text: 'value 1' },
|
|
337
|
+
{ value: 2, text: 'value 2' },
|
|
338
|
+
{ value: 3, text: 'value 3' },
|
|
339
|
+
],
|
|
340
|
+
};
|
|
341
|
+
},
|
|
342
|
+
template: `<div style="width: 400px">
|
|
343
|
+
<farm-select-auto-complete v-model="v" :items="items" multiple has-all-option />
|
|
344
|
+
v-model: {{ v }}
|
|
345
|
+
</div>`,
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
export const MultipleWithAllOptionAndDisabledItems = () => ({
|
|
349
|
+
data() {
|
|
350
|
+
return {
|
|
351
|
+
v: null,
|
|
352
|
+
items: [
|
|
353
|
+
{ value: 0, text: 'value 0' },
|
|
354
|
+
{ value: 1, text: 'value 1', disabled: true },
|
|
355
|
+
{ value: 2, text: 'value 2' },
|
|
356
|
+
{ value: 3, text: 'value 3', disabled: true },
|
|
357
|
+
],
|
|
358
|
+
};
|
|
359
|
+
},
|
|
360
|
+
template: `<div style="width: 400px">
|
|
361
|
+
<farm-select-auto-complete v-model="v" :items="items" multiple has-all-option />
|
|
362
|
+
v-model: {{ v }}
|
|
363
|
+
</div>`,
|
|
364
|
+
});
|
|
@@ -14,16 +14,45 @@
|
|
|
14
14
|
v-if="!readonly && !disabled"
|
|
15
15
|
:id="customId"
|
|
16
16
|
>
|
|
17
|
-
<farm-contextmenu
|
|
17
|
+
<farm-contextmenu
|
|
18
|
+
bottom
|
|
19
|
+
v-model="isVisible"
|
|
20
|
+
:stay-open="multiple || clickedDisabledItem"
|
|
21
|
+
ref="contextmenu"
|
|
22
|
+
>
|
|
18
23
|
<farm-list v-if="!readonly" ref="listRef" @keyup="onKeyUp">
|
|
24
|
+
<farm-listitem
|
|
25
|
+
v-if="hasAllOption"
|
|
26
|
+
tabindex="0"
|
|
27
|
+
clickable
|
|
28
|
+
hover-color-variation="lighten"
|
|
29
|
+
:hover-color="hasAllDisabled ? 'neutral' : 'primary'"
|
|
30
|
+
:class="{
|
|
31
|
+
'farm-listitem--selected': innerValue === 'all',
|
|
32
|
+
'farm-listitem--disabled': hasAllDisabled,
|
|
33
|
+
}"
|
|
34
|
+
@click="selectAll"
|
|
35
|
+
>
|
|
36
|
+
<farm-checkbox
|
|
37
|
+
v-model="hasAllSelected"
|
|
38
|
+
class="farm-select__checkbox"
|
|
39
|
+
value="all"
|
|
40
|
+
size="sm"
|
|
41
|
+
:disabled="hasAllDisabled"
|
|
42
|
+
/>
|
|
43
|
+
<farm-caption bold tag="span">Todos</farm-caption>
|
|
44
|
+
</farm-listitem>
|
|
19
45
|
<farm-listitem
|
|
20
46
|
tabindex="0"
|
|
21
47
|
v-for="(item, index) in showFilteredItems ? filteredItems : items"
|
|
22
48
|
clickable
|
|
23
49
|
hoverColorVariation="lighten"
|
|
24
|
-
hover-color="primary"
|
|
50
|
+
:hover-color="item.disabled ? 'neutral' : 'primary'"
|
|
25
51
|
:key="'contextmenu_item_' + index"
|
|
26
|
-
:class="{
|
|
52
|
+
:class="{
|
|
53
|
+
'farm-listitem--selected': item[itemValue] === innerValue,
|
|
54
|
+
'farm-listitem--disabled': item.disabled,
|
|
55
|
+
}"
|
|
27
56
|
@click="selectItem(item)"
|
|
28
57
|
>
|
|
29
58
|
<farm-checkbox
|
|
@@ -32,6 +61,7 @@
|
|
|
32
61
|
value="1"
|
|
33
62
|
size="sm"
|
|
34
63
|
v-if="isChecked(item)"
|
|
64
|
+
:disabled="item.disabled"
|
|
35
65
|
/>
|
|
36
66
|
<farm-checkbox
|
|
37
67
|
class="farm-select__checkbox"
|
|
@@ -39,6 +69,7 @@
|
|
|
39
69
|
value="2"
|
|
40
70
|
size="sm"
|
|
41
71
|
v-else-if="multiple"
|
|
72
|
+
:disabled="item.disabled"
|
|
42
73
|
/>
|
|
43
74
|
<farm-caption bold tag="span">{{ item[itemText] }}</farm-caption>
|
|
44
75
|
</farm-listitem>
|
|
@@ -161,7 +192,7 @@ export default defineComponent({
|
|
|
161
192
|
* This can be changed using the item-text ad item-value
|
|
162
193
|
*/
|
|
163
194
|
items: {
|
|
164
|
-
type: Array
|
|
195
|
+
type: Array as PropType<Array<Function>>,
|
|
165
196
|
default: () => [],
|
|
166
197
|
},
|
|
167
198
|
/**
|
|
@@ -242,6 +273,13 @@ export default defineComponent({
|
|
|
242
273
|
// eslint-disable-next-line
|
|
243
274
|
default: (event: Event) => {},
|
|
244
275
|
},
|
|
276
|
+
/**
|
|
277
|
+
* Set "All" as first option to select all other values<br />
|
|
278
|
+
*/
|
|
279
|
+
hasAllOption: {
|
|
280
|
+
type: Boolean,
|
|
281
|
+
default: false,
|
|
282
|
+
},
|
|
245
283
|
},
|
|
246
284
|
setup(props, { emit }) {
|
|
247
285
|
const { rules, items, itemText, itemValue, disabled, multiple } = toRefs(props);
|
|
@@ -269,6 +307,9 @@ export default defineComponent({
|
|
|
269
307
|
let fieldValidator = validateFormFieldBuilder(rules.value);
|
|
270
308
|
let validate = validateFormMethodBuilder(errorBucket, valid, fieldValidator);
|
|
271
309
|
|
|
310
|
+
const enabledItems = computed(() => items.value.filter(item => !item.disabled));
|
|
311
|
+
const disabledItems = computed(() => items.value.filter(item => item.disabled));
|
|
312
|
+
|
|
272
313
|
const hasError = computed(() => {
|
|
273
314
|
return errorBucket.value.length > 0;
|
|
274
315
|
});
|
|
@@ -279,6 +320,43 @@ export default defineComponent({
|
|
|
279
320
|
|
|
280
321
|
const searchText = ref('');
|
|
281
322
|
|
|
323
|
+
const hasAllDisabled = computed(() => items.value.length == disabledItems.value.length);
|
|
324
|
+
|
|
325
|
+
const clickedDisabledItem = ref(false);
|
|
326
|
+
|
|
327
|
+
const hasAllSelected = computed({
|
|
328
|
+
get() {
|
|
329
|
+
if (
|
|
330
|
+
!multiple.value ||
|
|
331
|
+
!Array.isArray(items.value) ||
|
|
332
|
+
!Array.isArray(innerValue.value)
|
|
333
|
+
) {
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
if (innerValue.value.length === enabledItems.value.length) {
|
|
337
|
+
return 'all';
|
|
338
|
+
}
|
|
339
|
+
return false;
|
|
340
|
+
},
|
|
341
|
+
set() {
|
|
342
|
+
emit('input', innerValue.value);
|
|
343
|
+
},
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
const selectAll = () => {
|
|
347
|
+
if (hasAllDisabled.value) {
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
if (multipleValues.value.length === enabledItems.value.length) {
|
|
351
|
+
multipleValues.value = [];
|
|
352
|
+
} else {
|
|
353
|
+
multipleValues.value = enabledItems.value.map(item => item[itemValue.value]);
|
|
354
|
+
}
|
|
355
|
+
checked.value = '1';
|
|
356
|
+
innerValue.value = [...multipleValues.value];
|
|
357
|
+
validate(innerValue.value);
|
|
358
|
+
};
|
|
359
|
+
|
|
282
360
|
const filterOptions = () => {
|
|
283
361
|
searchText.value = selectedText.value.toLowerCase();
|
|
284
362
|
if (!searchText || searchText.value.includes('+')) {
|
|
@@ -408,6 +486,20 @@ export default defineComponent({
|
|
|
408
486
|
};
|
|
409
487
|
|
|
410
488
|
const selectItem = item => {
|
|
489
|
+
if (inputField.value) {
|
|
490
|
+
inputField.value.focus();
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
if (item.disabled) {
|
|
494
|
+
clickedDisabledItem.value = true;
|
|
495
|
+
|
|
496
|
+
// "Schedule" execution to next loop, so the contextMenu won't close immediately if a disabled item is clicked
|
|
497
|
+
setTimeout(() => {
|
|
498
|
+
clickedDisabledItem.value = false;
|
|
499
|
+
});
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
|
|
411
503
|
if (multiple.value) {
|
|
412
504
|
const alreadyAdded = multipleValues.value.findIndex(
|
|
413
505
|
val => val === item[itemValue.value]
|
|
@@ -531,6 +623,7 @@ export default defineComponent({
|
|
|
531
623
|
isChecked,
|
|
532
624
|
multipleValues,
|
|
533
625
|
addLabelToMultiple,
|
|
626
|
+
clickedDisabledItem,
|
|
534
627
|
inputField,
|
|
535
628
|
onKeyUp,
|
|
536
629
|
addFocusToInput,
|
|
@@ -541,6 +634,9 @@ export default defineComponent({
|
|
|
541
634
|
showFilteredItems,
|
|
542
635
|
searchText,
|
|
543
636
|
handleOutsideClick,
|
|
637
|
+
hasAllDisabled,
|
|
638
|
+
hasAllSelected,
|
|
639
|
+
selectAll,
|
|
544
640
|
};
|
|
545
641
|
},
|
|
546
642
|
});
|