@farm-investimentos/front-mfe-components 15.0.5 → 15.0.7
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 +384 -241
- 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 +384 -241
- 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/ContextMenu/ContextMenu.vue +1 -1
- package/src/components/Form/Form.stories.js +5 -4
- package/src/components/Label/Label.scss +7 -0
- package/src/components/Label/Label.stories.js +14 -0
- package/src/components/List/List.vue +62 -3
- package/src/components/List/__tests__/List.spec.js +13 -0
- package/src/components/List/composition/index.ts +3 -0
- package/src/components/List/composition/useFocus.ts +49 -0
- package/src/components/ListItem/ListItem.scss +34 -36
- package/src/components/RangeDatePicker/RangeDatePicker.stories.js +20 -0
- package/src/components/RangeDatePicker/RangeDatePicker.vue +1 -2
- package/src/components/Select/Select.scss +8 -1
- package/src/components/Select/Select.stories.js +0 -1
- package/src/components/Select/Select.vue +43 -5
- package/src/components/Select/__tests__/Select.spec.js +46 -0
- package/src/components/Select/composition/buildData.ts +7 -0
- package/src/components/Switcher/Switcher.stories.js +20 -1
- package/src/components/Switcher/Switcher.vue +36 -28
package/package.json
CHANGED
|
@@ -31,11 +31,12 @@ export const Primary = () => ({
|
|
|
31
31
|
return {
|
|
32
32
|
form: {
|
|
33
33
|
document: 'Document',
|
|
34
|
-
name: '
|
|
34
|
+
name: '',
|
|
35
35
|
checkbox: '2',
|
|
36
36
|
birthDate: new Date('1980/09/20').toISOString(),
|
|
37
37
|
selectId: 1,
|
|
38
38
|
rangeDate: [],
|
|
39
|
+
cityName: null,
|
|
39
40
|
},
|
|
40
41
|
validForm: false,
|
|
41
42
|
rules: {
|
|
@@ -51,14 +52,14 @@ export const Primary = () => ({
|
|
|
51
52
|
};
|
|
52
53
|
},
|
|
53
54
|
template: `
|
|
54
|
-
<farm-form v-model="validForm" :style="[styles.vForm]" ref="form">
|
|
55
|
+
<farm-form v-model="validForm" :style="[styles.vForm]" ref="form" autocomplete="off">
|
|
55
56
|
<div>
|
|
56
57
|
<farm-label :required="true">Documento</farm-label>
|
|
57
58
|
<farm-textfield-v2 v-model="form.document" :rules="[rules.required]" />
|
|
58
59
|
</div>
|
|
59
60
|
<farm-label :required="true">Nome</farm-label>
|
|
60
|
-
<farm-textfield-v2 v-model="form.name" :rules="[rules.required]" />
|
|
61
|
-
|
|
61
|
+
<farm-textfield-v2 v-model="form.name" :rules="[rules.required]" hint="Seu nome igual ao do RG" />
|
|
62
|
+
|
|
62
63
|
<farm-label :required="true">True/false</farm-label>
|
|
63
64
|
<farm-checkbox v-model="form.checkbox" value="1" :rules="[rules.checked]" />
|
|
64
65
|
|
|
@@ -32,6 +32,20 @@ export const Required = () => ({
|
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
export const Tooltip = () => ({
|
|
35
|
+
template: `<div>
|
|
36
|
+
<farm-label>
|
|
37
|
+
Label with tooltip
|
|
38
|
+
<farm-tooltip>
|
|
39
|
+
this is the tooltip!
|
|
40
|
+
<template v-slot:activator="{ on, attrs }">
|
|
41
|
+
<farm-icon size="sm" color="gray">help-circle</farm-icon>
|
|
42
|
+
</template>
|
|
43
|
+
</farm-tooltip>
|
|
44
|
+
</farm-label>
|
|
45
|
+
</div>`,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
export const TooltipWithRequired = () => ({
|
|
35
49
|
template: `<div>
|
|
36
50
|
<farm-label required>
|
|
37
51
|
Label with tooltip
|
|
@@ -1,14 +1,73 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<ul>
|
|
2
|
+
<ul ref="contentRef" @focusin="onFocusin" @focusout="onFocusout" @focus="onFocus">
|
|
3
3
|
<slot></slot>
|
|
4
4
|
</ul>
|
|
5
5
|
</template>
|
|
6
6
|
<script lang="ts">
|
|
7
|
-
import Vue from 'vue';
|
|
7
|
+
import Vue, { onMounted, onUnmounted, ref } from 'vue';
|
|
8
|
+
import { useFocus } from './composition';
|
|
8
9
|
|
|
9
10
|
export default Vue.extend({
|
|
10
11
|
name: 'farm-list',
|
|
11
|
-
setup() {
|
|
12
|
+
setup(_, { emit }) {
|
|
13
|
+
const contentRef = ref<HTMLElement>();
|
|
14
|
+
const isFocused = ref(false);
|
|
15
|
+
const { focus } = useFocus(contentRef);
|
|
16
|
+
|
|
17
|
+
onMounted(() => {
|
|
18
|
+
contentRef.value.querySelectorAll('[tabindex]:not([tabindex="-1"]), li').forEach(tag =>
|
|
19
|
+
tag.addEventListener('keydown', (e: KeyboardEvent) => {
|
|
20
|
+
e.preventDefault();
|
|
21
|
+
if (isFocused.value) {
|
|
22
|
+
emit('keydown', e);
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
onUnmounted(() => {
|
|
29
|
+
if (contentRef.value) {
|
|
30
|
+
contentRef.value
|
|
31
|
+
.querySelectorAll('[tabindex]:not([tabindex="-1"]), li')
|
|
32
|
+
.forEach(tag =>
|
|
33
|
+
tag.removeEventListener('keydown', (e: KeyboardEvent) => {
|
|
34
|
+
e.preventDefault();
|
|
35
|
+
if (isFocused.value) {
|
|
36
|
+
emit('keydown', e);
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
function onFocusin() {
|
|
44
|
+
isFocused.value = true;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function onFocusout() {
|
|
48
|
+
isFocused.value = false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function onFocus(e: FocusEvent) {
|
|
52
|
+
if (
|
|
53
|
+
!(
|
|
54
|
+
isFocused.value ||
|
|
55
|
+
(e.relatedTarget && contentRef.value.contains(e.relatedTarget as Node))
|
|
56
|
+
)
|
|
57
|
+
) {
|
|
58
|
+
focus();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
contentRef,
|
|
64
|
+
focus,
|
|
65
|
+
onFocus,
|
|
66
|
+
onFocusin,
|
|
67
|
+
onFocusout,
|
|
68
|
+
isFocused,
|
|
69
|
+
};
|
|
70
|
+
},
|
|
12
71
|
});
|
|
13
72
|
</script>
|
|
14
73
|
<style lang="scss" scoped>
|
|
@@ -3,9 +3,11 @@ import List from '../List';
|
|
|
3
3
|
|
|
4
4
|
describe('List component', () => {
|
|
5
5
|
let wrapper;
|
|
6
|
+
let component;
|
|
6
7
|
|
|
7
8
|
beforeEach(() => {
|
|
8
9
|
wrapper = shallowMount(List);
|
|
10
|
+
component = wrapper.vm;
|
|
9
11
|
});
|
|
10
12
|
|
|
11
13
|
test('Created hook', () => {
|
|
@@ -17,4 +19,15 @@ describe('List component', () => {
|
|
|
17
19
|
expect(wrapper.element).toMatchSnapshot();
|
|
18
20
|
});
|
|
19
21
|
});
|
|
22
|
+
describe('Methods', () => {
|
|
23
|
+
it('should isFocused be true when call onFocusin', () => {
|
|
24
|
+
component.onFocusin();
|
|
25
|
+
expect(component.isFocused).toBeTruthy();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should isFocused be false when call onFocusout', () => {
|
|
29
|
+
component.onFocusout();
|
|
30
|
+
expect(component.isFocused).toBeFalsy();
|
|
31
|
+
});
|
|
32
|
+
});
|
|
20
33
|
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
|
|
3
|
+
type UseFocusReturn = {
|
|
4
|
+
focus: (location?: 'next' | 'prev' | 'first' | 'last') => void;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export default function useFocus(contentRef: Ref<HTMLElement>): UseFocusReturn {
|
|
8
|
+
function focus(location?: 'next' | 'prev' | 'first' | 'last') {
|
|
9
|
+
if (!contentRef.value) return;
|
|
10
|
+
|
|
11
|
+
const focusable = [
|
|
12
|
+
...contentRef.value.querySelectorAll('[tabindex]:not([tabindex="-1"]), li'),
|
|
13
|
+
].filter(el => !el.hasAttribute('disabled')) as HTMLElement[];
|
|
14
|
+
|
|
15
|
+
const idx = focusable.indexOf(document.activeElement as HTMLElement);
|
|
16
|
+
|
|
17
|
+
if (!location) {
|
|
18
|
+
if (!contentRef.value.contains(document.activeElement)) {
|
|
19
|
+
focusable[0].focus();
|
|
20
|
+
}
|
|
21
|
+
} else if (location === 'first') {
|
|
22
|
+
const savedTabIndex = focusable[0].getAttribute('tabindex');
|
|
23
|
+
|
|
24
|
+
focusable[0].setAttribute('tabindex', '-1');
|
|
25
|
+
focusable[0].focus();
|
|
26
|
+
focusable[0].setAttribute('tabindex', savedTabIndex);
|
|
27
|
+
} else if (location === 'last') {
|
|
28
|
+
focusable[focusable.length - 1].focus();
|
|
29
|
+
} else {
|
|
30
|
+
let el;
|
|
31
|
+
let idxx = idx;
|
|
32
|
+
const inc = location === 'next' ? 1 : -1;
|
|
33
|
+
|
|
34
|
+
do {
|
|
35
|
+
idxx += inc;
|
|
36
|
+
el = focusable[idxx];
|
|
37
|
+
} while ((!el || el.offsetParent == null) && idxx < focusable.length && idxx >= 0);
|
|
38
|
+
if (el) {
|
|
39
|
+
el.focus();
|
|
40
|
+
} else {
|
|
41
|
+
focus(location === 'next' ? 'first' : 'last');
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
focus,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -1,39 +1,37 @@
|
|
|
1
1
|
@import '../../configurations/theme-colors';
|
|
2
2
|
|
|
3
3
|
.farm-listitem {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
4
|
+
list-style-type: none;
|
|
5
|
+
transition: background-color 300ms linear;
|
|
6
|
+
padding: 8px;
|
|
7
|
+
height: 36px;
|
|
8
|
+
display: flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
|
|
11
|
+
&--clickable {
|
|
12
|
+
cursor: pointer;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
> a {
|
|
16
|
+
text-decoration: none;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
&:hover,
|
|
20
|
+
&:focus {
|
|
21
|
+
border-radius: 5px;
|
|
22
|
+
|
|
23
|
+
@each $color in $theme-colors-list {
|
|
24
|
+
&#{'.farm-listitem--' + $color + '-base'} {
|
|
25
|
+
background-color: rgba(themeColor($color), 0.27);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&#{'.farm-listitem--' + $color + '-lighten'} {
|
|
29
|
+
background-color: rgba(themeColor($color, 'lighten'), 0.27);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&#{'.farm-listitem--' + $color + '-darken'} {
|
|
33
|
+
background-color: rgba(themeColor($color, 'darken'), 0.27);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -49,3 +49,23 @@ export const InitialValue = () => ({
|
|
|
49
49
|
export const MinMax = () => ({
|
|
50
50
|
template: `<RangeDatePicker inputId="input-custom-id" min="2022-01-17" max="2022-02-15" />`,
|
|
51
51
|
});
|
|
52
|
+
|
|
53
|
+
export const Reset = () => ({
|
|
54
|
+
data() {
|
|
55
|
+
return {
|
|
56
|
+
date: null,
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
methods: {
|
|
60
|
+
click() {
|
|
61
|
+
this.$refs.datepickerExemple.clear();
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
template: `<div style="width: 480px">
|
|
65
|
+
<RangeDatePicker ref="datepickerExemple" inputId="input-custom-id" v-model="date" />
|
|
66
|
+
date: {{ date }}
|
|
67
|
+
<farm-btn @click="click">
|
|
68
|
+
reset
|
|
69
|
+
</farm-btn>
|
|
70
|
+
</div>`,
|
|
71
|
+
});
|
|
@@ -178,10 +178,9 @@ export default Vue.extend({
|
|
|
178
178
|
return true;
|
|
179
179
|
},
|
|
180
180
|
isInvertedDate() {
|
|
181
|
-
if (this.dateField.length === 2) {
|
|
181
|
+
if ((Array.isArray(this.dateField)) && this.dateField.length === 2) {
|
|
182
182
|
const firstDate = new Date(this.dateField[0]);
|
|
183
183
|
const secondDate = new Date(this.dateField[1]);
|
|
184
|
-
|
|
185
184
|
return firstDate.getTime() > secondDate.getTime();
|
|
186
185
|
}
|
|
187
186
|
return false;
|
|
@@ -32,11 +32,18 @@
|
|
|
32
32
|
color: var(--farm-primary-base);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
:deep(.farm-listitem:focus .farm-typography) {
|
|
36
|
+
color: var(--farm-primary-base);
|
|
37
|
+
}
|
|
38
|
+
|
|
35
39
|
:deep(.farm-listitem:hover .farm-checkbox .farm-icon) {
|
|
36
40
|
color: var(--farm-primary-lighten);
|
|
37
41
|
}
|
|
38
42
|
|
|
43
|
+
:deep(.farm-listitem:focus .farm-checkbox .farm-icon) {
|
|
44
|
+
color: var(--farm-primary-lighten);
|
|
45
|
+
}
|
|
39
46
|
|
|
40
47
|
:deep(.farm-listitem:hover .farm-checkbox.farm-checkbox--checked .farm-icon) {
|
|
41
48
|
color: white;
|
|
42
|
-
}
|
|
49
|
+
}
|
|
@@ -14,8 +14,9 @@
|
|
|
14
14
|
:id="customId"
|
|
15
15
|
>
|
|
16
16
|
<farm-contextmenu bottom v-model="isVisible" :stay-open="multiple" ref="contextmenu">
|
|
17
|
-
<farm-list v-if="!readonly">
|
|
17
|
+
<farm-list v-if="!readonly" ref="listRef" @keydown="onKeyDown">
|
|
18
18
|
<farm-listitem
|
|
19
|
+
tabindex="0"
|
|
19
20
|
v-for="(item, index) in items"
|
|
20
21
|
clickable
|
|
21
22
|
hoverColorVariation="lighten"
|
|
@@ -45,7 +46,10 @@
|
|
|
45
46
|
</farm-listitem>
|
|
46
47
|
</farm-list>
|
|
47
48
|
<template v-slot:activator="{}">
|
|
48
|
-
<div
|
|
49
|
+
<div
|
|
50
|
+
class="farm-textfield--input farm-textfield--input--iconed"
|
|
51
|
+
@keydown="onKeyDown"
|
|
52
|
+
>
|
|
49
53
|
<input
|
|
50
54
|
v-bind="$attrs"
|
|
51
55
|
v-model="selectedText"
|
|
@@ -57,7 +61,11 @@
|
|
|
57
61
|
@focusin="onFocus(true)"
|
|
58
62
|
@focusout="onFocus(false)"
|
|
59
63
|
/>
|
|
60
|
-
<farm-icon
|
|
64
|
+
<farm-icon
|
|
65
|
+
color="gray"
|
|
66
|
+
:class="{ 'farm-icon--rotate': isVisible }"
|
|
67
|
+
@click="addFocusToInput"
|
|
68
|
+
>
|
|
61
69
|
menu-down
|
|
62
70
|
</farm-icon>
|
|
63
71
|
</div>
|
|
@@ -231,8 +239,13 @@ export default Vue.extend({
|
|
|
231
239
|
checked,
|
|
232
240
|
notChecked,
|
|
233
241
|
inputField,
|
|
242
|
+
keys,
|
|
234
243
|
} = buildData(props);
|
|
235
244
|
|
|
245
|
+
const listRef = ref();
|
|
246
|
+
|
|
247
|
+
const contextmenu = ref(null);
|
|
248
|
+
|
|
236
249
|
const { errorBucket, valid, validatable } = validateFormStateBuilder();
|
|
237
250
|
|
|
238
251
|
let fieldValidator = validateFormFieldBuilder(rules.value);
|
|
@@ -251,7 +264,10 @@ export default Vue.extend({
|
|
|
251
264
|
newValue => {
|
|
252
265
|
innerValue.value = newValue;
|
|
253
266
|
errorBucket.value = [];
|
|
254
|
-
if
|
|
267
|
+
if (
|
|
268
|
+
(multiple.value && newValue === null) ||
|
|
269
|
+
(Array.isArray(newValue) && newValue.length === 0)
|
|
270
|
+
) {
|
|
255
271
|
multipleValues.value = [];
|
|
256
272
|
}
|
|
257
273
|
validate(newValue);
|
|
@@ -400,8 +416,27 @@ export default Vue.extend({
|
|
|
400
416
|
);
|
|
401
417
|
};
|
|
402
418
|
|
|
403
|
-
|
|
419
|
+
function onKeyDown(e) {
|
|
420
|
+
if (props.readonly) return;
|
|
421
|
+
|
|
422
|
+
if (['Space'].includes(e.code)) {
|
|
423
|
+
isVisible.value = true;
|
|
424
|
+
e.currentTarget.click();
|
|
425
|
+
}
|
|
426
|
+
if (['Escape'].includes(e.code)) {
|
|
427
|
+
isVisible.value = false;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if (keys[e.code]) {
|
|
431
|
+
listRef.value.focus(keys[e.code]);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
e.preventDefault();
|
|
435
|
+
}
|
|
404
436
|
|
|
437
|
+
function addFocusToInput() {
|
|
438
|
+
inputField.value.focus();
|
|
439
|
+
}
|
|
405
440
|
|
|
406
441
|
return {
|
|
407
442
|
items,
|
|
@@ -432,6 +467,9 @@ export default Vue.extend({
|
|
|
432
467
|
multipleValues,
|
|
433
468
|
addLabelToMultiple,
|
|
434
469
|
inputField,
|
|
470
|
+
onKeyDown,
|
|
471
|
+
addFocusToInput,
|
|
472
|
+
listRef,
|
|
435
473
|
};
|
|
436
474
|
},
|
|
437
475
|
});
|
|
@@ -124,5 +124,51 @@ describe('Select component', () => {
|
|
|
124
124
|
expect(component.selectedText).toBe('value 0 (+2 outros)');
|
|
125
125
|
});
|
|
126
126
|
});
|
|
127
|
+
|
|
128
|
+
describe('onKeyDown', () => {
|
|
129
|
+
it('should open the ContextMenu and click on current element', () => {
|
|
130
|
+
const event = {
|
|
131
|
+
code: 'Space',
|
|
132
|
+
preventDefault: jest.fn(),
|
|
133
|
+
currentTarget: {
|
|
134
|
+
click: jest.fn(),
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
component.onKeyDown(event);
|
|
138
|
+
|
|
139
|
+
expect(component.isVisible).toBeTruthy();
|
|
140
|
+
expect(event.currentTarget.click).toHaveBeenCalled();
|
|
141
|
+
expect(event.preventDefault).toHaveBeenCalled();
|
|
142
|
+
});
|
|
143
|
+
it('should open the ContextMenu and click on current element when prop readonly is true', async () => {
|
|
144
|
+
await wrapper.setProps({
|
|
145
|
+
readonly: true,
|
|
146
|
+
});
|
|
147
|
+
const event = {
|
|
148
|
+
code: 'Space',
|
|
149
|
+
preventDefault: jest.fn(),
|
|
150
|
+
currentTarget: {
|
|
151
|
+
click: jest.fn(),
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
component.onKeyDown(event);
|
|
155
|
+
|
|
156
|
+
expect(component.isVisible).toBeFalsy();
|
|
157
|
+
expect(event.currentTarget.click).not.toHaveBeenCalled();
|
|
158
|
+
expect(event.preventDefault).not.toHaveBeenCalled();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('should close the ContextMenu', () => {
|
|
162
|
+
const event = {
|
|
163
|
+
code: 'Escape',
|
|
164
|
+
preventDefault: jest.fn(),
|
|
165
|
+
};
|
|
166
|
+
component.onKeyDown(event);
|
|
167
|
+
|
|
168
|
+
expect(component.isVisible).toBeFalsy();
|
|
169
|
+
|
|
170
|
+
expect(event.preventDefault).toHaveBeenCalled();
|
|
171
|
+
});
|
|
172
|
+
});
|
|
127
173
|
});
|
|
128
174
|
});
|
|
@@ -11,6 +11,12 @@ export default function (props) {
|
|
|
11
11
|
const checked = ref('1');
|
|
12
12
|
const notChecked = ref(false);
|
|
13
13
|
const inputField = ref();
|
|
14
|
+
const keys = {
|
|
15
|
+
ArrowDown: 'next',
|
|
16
|
+
ArrowUp: 'prev',
|
|
17
|
+
Home: 'first',
|
|
18
|
+
End: 'last',
|
|
19
|
+
};
|
|
14
20
|
|
|
15
21
|
return {
|
|
16
22
|
multipleValues,
|
|
@@ -23,5 +29,6 @@ export default function (props) {
|
|
|
23
29
|
checked,
|
|
24
30
|
notChecked,
|
|
25
31
|
inputField,
|
|
32
|
+
keys,
|
|
26
33
|
};
|
|
27
34
|
}
|
|
@@ -90,4 +90,23 @@ export const Colors = () => ({
|
|
|
90
90
|
</farm-col>
|
|
91
91
|
|
|
92
92
|
</farm-row>`,
|
|
93
|
-
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
export const OutsideChangeVmodel = () => ({
|
|
96
|
+
data() {
|
|
97
|
+
return {
|
|
98
|
+
selectedValue: true,
|
|
99
|
+
};
|
|
100
|
+
},
|
|
101
|
+
methods: {
|
|
102
|
+
onClick() {
|
|
103
|
+
this.selectedValue = !this.selectedValue;
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
template: `<div>
|
|
107
|
+
<farm-switcher v-model="selectedValue" block />
|
|
108
|
+
<farm-btn @click="onClick">
|
|
109
|
+
toggle selection: {{ selectedValue }}
|
|
110
|
+
</farm-btn>
|
|
111
|
+
</div>`,
|
|
112
|
+
});
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
</div>
|
|
12
12
|
</template>
|
|
13
13
|
<script lang="ts">
|
|
14
|
-
import Vue, { PropType } from 'vue';
|
|
14
|
+
import Vue, { PropType, computed, ref, watch } from 'vue';
|
|
15
15
|
|
|
16
16
|
export default Vue.extend({
|
|
17
17
|
name: 'farm-switcher',
|
|
@@ -47,37 +47,45 @@ export default Vue.extend({
|
|
|
47
47
|
* Is disabled?
|
|
48
48
|
*/
|
|
49
49
|
disabled: { type: Boolean, default: false },
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
'farm-switch--selected': this.value && !this.isDisabled,
|
|
60
|
-
'farm-switch--idle': !this.value && !this.isDisabled,
|
|
61
|
-
'farm-switch--disabled-on': this.value && this.isDisabled,
|
|
62
|
-
'farm-switch--disabled-off': !this.value && this.isDisabled,
|
|
63
|
-
};
|
|
64
|
-
},
|
|
65
|
-
indicatorStyles() {
|
|
66
|
-
return { transform: this.value ? 'translateX(16px)' : 'translateX(0)' };
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
watch: {
|
|
70
|
-
disabled(newValue: boolean) {
|
|
71
|
-
this.isDisabled = newValue;
|
|
50
|
+
/**
|
|
51
|
+
* The updated bound model<br />
|
|
52
|
+
* _event_
|
|
53
|
+
*/
|
|
54
|
+
input: {
|
|
55
|
+
type: Function,
|
|
56
|
+
// eslint-disable-next-line
|
|
57
|
+
default: (value: [String, Number]) => {},
|
|
72
58
|
},
|
|
73
59
|
},
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
60
|
+
setup(props, { emit }) {
|
|
61
|
+
const isDisabled = ref(props.disabled);
|
|
62
|
+
|
|
63
|
+
const backgroundStyles = computed(() => ({
|
|
64
|
+
'farm-switch--selected': props.value && !isDisabled.value,
|
|
65
|
+
'farm-switch--idle': !props.value && !isDisabled.value,
|
|
66
|
+
'farm-switch--disabled-on': props.value && isDisabled.value,
|
|
67
|
+
'farm-switch--disabled-off': !props.value && isDisabled.value,
|
|
68
|
+
}));
|
|
69
|
+
|
|
70
|
+
const indicatorStyles = computed(() => ({
|
|
71
|
+
transform: props.value ? 'translateX(16px)' : 'translateX(0)',
|
|
72
|
+
}));
|
|
73
|
+
|
|
74
|
+
watch(
|
|
75
|
+
() => props.disabled,
|
|
76
|
+
newValue => {
|
|
77
|
+
isDisabled.value = newValue;
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const toggle = () => {
|
|
82
|
+
if (isDisabled.value) {
|
|
77
83
|
return false;
|
|
78
84
|
}
|
|
79
|
-
|
|
80
|
-
}
|
|
85
|
+
emit('input', !props.value);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
return { isDisabled, backgroundStyles, indicatorStyles, toggle };
|
|
81
89
|
},
|
|
82
90
|
});
|
|
83
91
|
</script>
|