@farm-investimentos/front-mfe-components 3.4.2 → 3.4.5
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/README.md +2 -0
- package/dist/front-mfe-components.common.js +321 -240
- 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 +321 -240
- 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 +11 -14
- package/src/components/Buttons/ConfirmButton/ConfirmButton.stories.js +10 -0
- package/src/components/Buttons/DangerButton/DangerButton.stories.js +10 -0
- package/src/components/Buttons/DefaultButton/DefaultButton.stories.js +10 -0
- package/src/components/DataTablePaginator/DataTablePaginator.stories.js +17 -2
- package/src/components/DataTablePaginator/DataTablePaginator.vue +5 -3
- package/src/components/DatePicker/DatePicker.stories.js +13 -3
- package/src/components/DatePicker/DatePicker.vue +4 -2
- package/src/components/DatePicker/__tests__/DatePicker.spec.js +13 -0
- package/src/components/DefaultTextField/DefaultTextField.stories.js +36 -7
- package/src/components/DefaultTextField/DefaultTextField.vue +23 -2
- package/src/components/DefaultTextField/__tests__/DefaultTextField.spec.js +21 -0
- package/src/components/FilePicker/FilePicker.scss +5 -4
- package/src/components/FilePicker/FilePicker.stories.js +10 -4
- package/src/components/FilePicker/FilePicker.vue +95 -67
- package/src/components/FilePicker/__tests__/FilePicker.spec.js +17 -0
- package/src/components/ModalPromptUser/ModalPromptUser.stories.js +46 -3
- package/src/components/ModalPromptUser/__tests__/ModalPromptUser.spec.js +27 -0
- package/src/components/PromptUserToConfirm/PromptUserToConfirm.stories.js +22 -2
- package/src/components/PromptUserToConfirm/__tests__/PromptUserToConfirm.spec.js +24 -0
- package/src/components/TableContextMenu/TableContextMenu.scss +3 -0
- package/src/components/TableContextMenu/TableContextMenu.stories.js +39 -2
- package/src/components/TableContextMenu/TableContextMenu.vue +3 -0
- package/src/examples/Table.stories.js +27 -16
- package/src/examples/inputs/Password.stories.js +42 -0
- package/src/scss/ButtonOverrides.scss +7 -1
- package/src/scss/DefaultModal.scss +66 -64
- package/src/scss/DialogOverrides.scss +86 -0
- package/src/scss/FormOverrides.scss +46 -6
- package/src/scss/Sticky-table.scss +69 -0
- package/src/scss/Table.scss +2 -0
- package/src/scss/VMenuOverrides.scss +5 -0
- package/src/scss/main.scss +4 -0
- package/src/scss/utils.scss +138 -99
- package/src/stories/Introduction.stories.mdx +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farm-investimentos/front-mfe-components",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.5",
|
|
4
4
|
"author": "farm investimentos",
|
|
5
5
|
"private": false,
|
|
6
6
|
"main": "./dist/front-mfe-components.common.js",
|
|
@@ -21,31 +21,28 @@
|
|
|
21
21
|
"src/*"
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"core-js": "^3.6.5",
|
|
28
|
-
"sass": "~1.32.0",
|
|
29
|
-
"sass-loader": "^10.2.0",
|
|
24
|
+
"core-js": "3.21.1",
|
|
25
|
+
"sass": "1.32.13",
|
|
26
|
+
"sass-loader": "^10.1.1",
|
|
30
27
|
"vue": "^2.6.11",
|
|
31
28
|
"vuetify": "^2.5.7"
|
|
32
29
|
},
|
|
33
30
|
"devDependencies": {
|
|
34
|
-
"@
|
|
31
|
+
"@socheatsok78/storybook-addon-vuetify": "^0.1.8",
|
|
35
32
|
"@storybook/addon-actions": "^6.3.6",
|
|
36
33
|
"@storybook/addon-essentials": "^6.3.6",
|
|
37
34
|
"@storybook/addon-links": "^6.3.6",
|
|
38
35
|
"@storybook/vue": "^6.3.6",
|
|
39
|
-
"@vue/cli-plugin-babel": "
|
|
40
|
-
"@vue/cli-plugin-eslint": "~4.5.
|
|
41
|
-
"@vue/cli-plugin-unit-jest": "
|
|
42
|
-
"@vue/cli-service": "~4.5.
|
|
36
|
+
"@vue/cli-plugin-babel": "4.5.15",
|
|
37
|
+
"@vue/cli-plugin-eslint": "~4.5.14",
|
|
38
|
+
"@vue/cli-plugin-unit-jest": "~4.5.14",
|
|
39
|
+
"@vue/cli-service": "~4.5.14",
|
|
40
|
+
"@vue/test-utils": "^1.3.0",
|
|
43
41
|
"babel-eslint": "^10.1.0",
|
|
44
|
-
"babel-loader": "^8.2.2",
|
|
45
42
|
"eslint": "^6.7.2",
|
|
46
43
|
"eslint-plugin-vue": "^6.2.2",
|
|
47
|
-
"jest": "^25.5.4",
|
|
48
44
|
"storybook-addon-designs": "^6.2.1",
|
|
45
|
+
"v-mask": "^2.3.0",
|
|
49
46
|
"vue-template-compiler": "^2.6.11",
|
|
50
47
|
"webpack-cli": "^4.9.0"
|
|
51
48
|
},
|
|
@@ -3,6 +3,16 @@ import ConfirmButton from './ConfirmButton.vue';
|
|
|
3
3
|
export default {
|
|
4
4
|
title: 'API/Buttons/Confirm',
|
|
5
5
|
component: ConfirmButton,
|
|
6
|
+
parameters: {
|
|
7
|
+
docs: {
|
|
8
|
+
description: {
|
|
9
|
+
component: `Confirm button<br />
|
|
10
|
+
selector: <em>farm-btn-confirm</em>
|
|
11
|
+
`,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
viewMode: 'docs',
|
|
15
|
+
},
|
|
6
16
|
};
|
|
7
17
|
|
|
8
18
|
export const Primary = () => ({
|
|
@@ -3,6 +3,16 @@ import DangerButton from './DangerButton.vue';
|
|
|
3
3
|
export default {
|
|
4
4
|
title: 'API/Buttons/DangerButton',
|
|
5
5
|
component: DangerButton,
|
|
6
|
+
parameters: {
|
|
7
|
+
docs: {
|
|
8
|
+
description: {
|
|
9
|
+
component: `Danger button<br />
|
|
10
|
+
selector: <em>farm-btn-fanger</em>
|
|
11
|
+
`,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
viewMode: 'docs',
|
|
15
|
+
},
|
|
6
16
|
};
|
|
7
17
|
|
|
8
18
|
export const Primary = () => ({
|
|
@@ -3,6 +3,16 @@ import DefaultButton from './DefaultButton.vue';
|
|
|
3
3
|
export default {
|
|
4
4
|
title: 'API/Buttons/Default',
|
|
5
5
|
component: DefaultButton,
|
|
6
|
+
parameters: {
|
|
7
|
+
docs: {
|
|
8
|
+
description: {
|
|
9
|
+
component: `Default button (inherit from Vuetify)<br />
|
|
10
|
+
selector: <em>farm-btn</em>
|
|
11
|
+
`,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
viewMode: 'docs',
|
|
15
|
+
},
|
|
6
16
|
};
|
|
7
17
|
|
|
8
18
|
export const Primary = () => ({
|
|
@@ -1,8 +1,24 @@
|
|
|
1
|
+
import { withDesign } from 'storybook-addon-designs';
|
|
1
2
|
import DataTablePaginator from './DataTablePaginator.vue';
|
|
2
3
|
|
|
3
4
|
export default {
|
|
4
5
|
title: 'API/Table/DataTablePaginator',
|
|
5
6
|
component: DataTablePaginator,
|
|
7
|
+
decorators: [withDesign],
|
|
8
|
+
parameters: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: {
|
|
11
|
+
component: `Paginator with items per page select<br />
|
|
12
|
+
selector: <em>farm-datatable-paginator</em>
|
|
13
|
+
`,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
design: {
|
|
17
|
+
type: 'figma',
|
|
18
|
+
url: 'https://www.figma.com/file/1f84J4m1IBghWhozQvdyyt/%E2%9C%8D---Design-System?node-id=1503%3A921',
|
|
19
|
+
},
|
|
20
|
+
viewMode: 'docs',
|
|
21
|
+
},
|
|
6
22
|
};
|
|
7
23
|
|
|
8
24
|
export const Primary = () => ({
|
|
@@ -29,8 +45,7 @@ export const CustomPerPage = () => ({
|
|
|
29
45
|
const parameters = {
|
|
30
46
|
design: {
|
|
31
47
|
type: 'figma',
|
|
32
|
-
url:
|
|
33
|
-
'https://www.figma.com/file/1f84J4m1IBghWhozQvdyyt/%E2%9C%8D---Design-System?node-id=1503%3A921',
|
|
48
|
+
url: 'https://www.figma.com/file/1f84J4m1IBghWhozQvdyyt/%E2%9C%8D---Design-System?node-id=1503%3A921',
|
|
34
49
|
},
|
|
35
50
|
};
|
|
36
51
|
|
|
@@ -22,14 +22,16 @@
|
|
|
22
22
|
</section>
|
|
23
23
|
</template>
|
|
24
24
|
<script>
|
|
25
|
+
import Vue from 'vue';
|
|
25
26
|
import { VSelect } from 'vuetify/lib/components/VSelect';
|
|
26
27
|
import { VPagination } from 'vuetify/lib/components/VPagination';
|
|
28
|
+
|
|
27
29
|
/**
|
|
28
30
|
* Componente de paginação usado em tabelas e listas
|
|
29
31
|
* com opção de itens por página
|
|
30
32
|
*/
|
|
31
|
-
export default {
|
|
32
|
-
name: '
|
|
33
|
+
export default Vue.extend({
|
|
34
|
+
name: 'farm-datatable-paginator',
|
|
33
35
|
props: {
|
|
34
36
|
/**
|
|
35
37
|
* Lista de opções para o controle de registros por página
|
|
@@ -100,7 +102,7 @@ export default {
|
|
|
100
102
|
VSelect,
|
|
101
103
|
VPagination,
|
|
102
104
|
},
|
|
103
|
-
};
|
|
105
|
+
});
|
|
104
106
|
</script>
|
|
105
107
|
|
|
106
108
|
<style lang="scss">
|
|
@@ -3,24 +3,34 @@ import DatePicker from './DatePicker';
|
|
|
3
3
|
export default {
|
|
4
4
|
title: 'API/Form/DatePicker',
|
|
5
5
|
component: DatePicker,
|
|
6
|
+
parameters: {
|
|
7
|
+
docs: {
|
|
8
|
+
description: {
|
|
9
|
+
component: `Input Date Picker<br />
|
|
10
|
+
selector: <em>farm-input-datepicker</em>
|
|
11
|
+
`,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
viewMode: 'docs',
|
|
15
|
+
},
|
|
6
16
|
};
|
|
7
17
|
|
|
8
18
|
export const Primary = () => ({
|
|
9
19
|
components: { DatePicker },
|
|
10
20
|
template: `<div style='max-width: 320px'>
|
|
11
|
-
<DatePicker inputId="input-custom-id" />
|
|
21
|
+
<DatePicker inputId="input-custom-id-0" />
|
|
12
22
|
</div>`,
|
|
13
23
|
});
|
|
14
24
|
|
|
15
25
|
export const InitValue = () => ({
|
|
16
26
|
components: { DatePicker },
|
|
17
|
-
template: `<div style='max-width: 320px'><DatePicker inputId="input-custom-id" value="2021-08-01" /></div>`,
|
|
27
|
+
template: `<div style='max-width: 320px'><DatePicker inputId="input-custom-id-1" value="2021-08-01" /></div>`,
|
|
18
28
|
});
|
|
19
29
|
|
|
20
30
|
export const MinMaxDates = () => ({
|
|
21
31
|
components: { DatePicker },
|
|
22
32
|
template: `<div style='max-width: 320px'>
|
|
23
|
-
<DatePicker inputId="input-custom-id" max="2021-12-02" min="2021-07-01" />
|
|
33
|
+
<DatePicker inputId="input-custom-id-2" max="2021-12-02" min="2021-07-01" />
|
|
24
34
|
max="2021-12-02" min="2021-07-01"
|
|
25
35
|
</div>`,
|
|
26
36
|
});
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
</v-menu>
|
|
50
50
|
</template>
|
|
51
51
|
<script>
|
|
52
|
+
import Vue from 'vue';
|
|
52
53
|
import { VTextField } from 'vuetify/lib/components/VTextField';
|
|
53
54
|
import { VMenu } from 'vuetify/lib/components/VMenu';
|
|
54
55
|
import { VBtn } from 'vuetify/lib/components/VBtn';
|
|
@@ -57,7 +58,8 @@ import { defaultFormat as dateDefaultFormatter } from '../../helpers/date';
|
|
|
57
58
|
/**
|
|
58
59
|
* Componente de input com datepicker para data
|
|
59
60
|
*/
|
|
60
|
-
export default {
|
|
61
|
+
export default Vue.extend({
|
|
62
|
+
name: 'farm-input-datepicker',
|
|
61
63
|
components: {
|
|
62
64
|
VTextField,
|
|
63
65
|
VMenu,
|
|
@@ -136,5 +138,5 @@ export default {
|
|
|
136
138
|
},
|
|
137
139
|
},
|
|
138
140
|
},
|
|
139
|
-
};
|
|
141
|
+
});
|
|
140
142
|
</script>
|
|
@@ -3,6 +3,7 @@ import DatePicker from '../DatePicker';
|
|
|
3
3
|
|
|
4
4
|
describe('DatePicker component', () => {
|
|
5
5
|
let wrapper;
|
|
6
|
+
let component;
|
|
6
7
|
|
|
7
8
|
beforeEach(() => {
|
|
8
9
|
wrapper = shallowMount(DatePicker, {
|
|
@@ -10,6 +11,7 @@ describe('DatePicker component', () => {
|
|
|
10
11
|
inputId: 'someid',
|
|
11
12
|
},
|
|
12
13
|
});
|
|
14
|
+
component = wrapper.vm;
|
|
13
15
|
});
|
|
14
16
|
|
|
15
17
|
test('Created hook', () => {
|
|
@@ -21,4 +23,15 @@ describe('DatePicker component', () => {
|
|
|
21
23
|
expect(wrapper.element).toMatchSnapshot();
|
|
22
24
|
});
|
|
23
25
|
});
|
|
26
|
+
|
|
27
|
+
describe('computed properties', () => {
|
|
28
|
+
it('get inputVal', () => {
|
|
29
|
+
expect(component.inputVal).toBeFalsy();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('get inputVal', () => {
|
|
33
|
+
component.inputVal = 'teste';
|
|
34
|
+
expect(wrapper.emitted().input).toBeDefined();
|
|
35
|
+
});
|
|
36
|
+
});
|
|
24
37
|
});
|
|
@@ -1,8 +1,19 @@
|
|
|
1
|
+
import { withDesign } from 'storybook-addon-designs';
|
|
1
2
|
import DefaultTextField from './DefaultTextField.vue';
|
|
2
3
|
|
|
3
4
|
export default {
|
|
4
5
|
title: 'API/Form/DefaultTextField',
|
|
5
6
|
component: DefaultTextField,
|
|
7
|
+
decorators: [withDesign],
|
|
8
|
+
parameters: {
|
|
9
|
+
viewMode: 'docs',
|
|
10
|
+
docs: {
|
|
11
|
+
description: {
|
|
12
|
+
component: `Default Text Field with label (inherit from Vuetify)<br />
|
|
13
|
+
selector: <em>farm-textfield-labelled</em>`,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
6
17
|
};
|
|
7
18
|
|
|
8
19
|
export const Primary = () => ({
|
|
@@ -10,7 +21,7 @@ export const Primary = () => ({
|
|
|
10
21
|
data() {
|
|
11
22
|
return {
|
|
12
23
|
model: 'primary',
|
|
13
|
-
item: { label: 'Nome do campo', key: 'key' },
|
|
24
|
+
item: { label: 'Nome do campo', key: 'key', md: 4 },
|
|
14
25
|
};
|
|
15
26
|
},
|
|
16
27
|
template: '<DefaultTextField v-model="model" :item="item" />',
|
|
@@ -21,10 +32,12 @@ export const Secondary = () => ({
|
|
|
21
32
|
data() {
|
|
22
33
|
return {
|
|
23
34
|
model: 'secondary',
|
|
24
|
-
item: { label: 'Nome do campo', key: 'key' },
|
|
35
|
+
item: { label: 'Nome do campo', key: 'key', md: 4 },
|
|
25
36
|
};
|
|
26
37
|
},
|
|
27
|
-
template:
|
|
38
|
+
template: `<v-form>
|
|
39
|
+
<DefaultTextField :item="item" v-model="model" :required="true" />
|
|
40
|
+
</v-form>`,
|
|
28
41
|
});
|
|
29
42
|
|
|
30
43
|
export const ReadOnly = () => ({
|
|
@@ -32,12 +45,28 @@ export const ReadOnly = () => ({
|
|
|
32
45
|
data() {
|
|
33
46
|
return {
|
|
34
47
|
model: 'readonly',
|
|
35
|
-
item: { label: 'Nome do campo', key: 'key' },
|
|
48
|
+
item: { label: 'Nome do campo', key: 'key', md: 4 },
|
|
36
49
|
};
|
|
37
50
|
},
|
|
38
51
|
template: '<DefaultTextField :item="item" v-model="model" :readonly="true" />',
|
|
39
52
|
});
|
|
40
53
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
54
|
+
export const Masked = () => ({
|
|
55
|
+
components: { DefaultTextField },
|
|
56
|
+
data() {
|
|
57
|
+
return {
|
|
58
|
+
model: '12345',
|
|
59
|
+
item: { label: 'Máscara (##.###)', key: 'key', md: 4 },
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
template: `
|
|
63
|
+
<v-form>
|
|
64
|
+
<DefaultTextField :item="item" v-model="model" mask="##.###" />
|
|
65
|
+
</v-form>
|
|
66
|
+
`,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
Primary.storyName = 'Basic';
|
|
70
|
+
Secondary.storyName = 'Required field';
|
|
71
|
+
ReadOnly.storyName = 'Readonly input';
|
|
72
|
+
Masked.storyName = 'Masked';
|
|
@@ -18,20 +18,32 @@
|
|
|
18
18
|
</v-col>
|
|
19
19
|
</template>
|
|
20
20
|
<script>
|
|
21
|
+
import Vue from 'vue';
|
|
21
22
|
import { VTextField } from 'vuetify/lib/components/VTextField';
|
|
22
23
|
import { VCol } from 'vuetify/lib/components/VGrid';
|
|
23
|
-
|
|
24
|
+
|
|
25
|
+
export default Vue.extend({
|
|
26
|
+
name: 'farm-textfield-labelled',
|
|
24
27
|
props: {
|
|
25
28
|
item: {
|
|
26
29
|
type: Object,
|
|
27
30
|
required: true,
|
|
28
31
|
},
|
|
32
|
+
/**
|
|
33
|
+
* v-model
|
|
34
|
+
*/
|
|
29
35
|
value: {
|
|
30
36
|
required: true,
|
|
31
37
|
},
|
|
38
|
+
/**
|
|
39
|
+
* Array of rules
|
|
40
|
+
*/
|
|
32
41
|
rules: {
|
|
33
42
|
type: Array,
|
|
34
43
|
},
|
|
44
|
+
/**
|
|
45
|
+
* Input is disabled or not
|
|
46
|
+
*/
|
|
35
47
|
disabled: {
|
|
36
48
|
type: Boolean,
|
|
37
49
|
default: false,
|
|
@@ -41,14 +53,23 @@ export default {
|
|
|
41
53
|
required: false,
|
|
42
54
|
default: 'form',
|
|
43
55
|
},
|
|
56
|
+
/**
|
|
57
|
+
* Input is required or not
|
|
58
|
+
*/
|
|
44
59
|
required: {
|
|
45
60
|
type: Boolean,
|
|
46
61
|
default: false,
|
|
47
62
|
},
|
|
63
|
+
/**
|
|
64
|
+
* Mask (v-mask)
|
|
65
|
+
*/
|
|
48
66
|
mask: {
|
|
49
67
|
type: String,
|
|
50
68
|
default: null,
|
|
51
69
|
},
|
|
70
|
+
/**
|
|
71
|
+
* Input is readonly or not
|
|
72
|
+
*/
|
|
52
73
|
readonly: {
|
|
53
74
|
type: Boolean,
|
|
54
75
|
default: false,
|
|
@@ -80,5 +101,5 @@ export default {
|
|
|
80
101
|
return `${this.forKey}-${this.item.key}`;
|
|
81
102
|
},
|
|
82
103
|
},
|
|
83
|
-
};
|
|
104
|
+
});
|
|
84
105
|
</script>
|
|
@@ -29,5 +29,26 @@ describe('DefaultTextField component', () => {
|
|
|
29
29
|
it('Should have inputId', () => {
|
|
30
30
|
expect(component.inputId).toEqual('form-key');
|
|
31
31
|
});
|
|
32
|
+
|
|
33
|
+
it('Should have default inputRules', () => {
|
|
34
|
+
expect(component.inputRules).toEqual([]);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('Should have inputRules from prop', async () => {
|
|
38
|
+
expect(component.inputRules).toEqual([]);
|
|
39
|
+
await wrapper.setProps({
|
|
40
|
+
rules: [jest.fn()],
|
|
41
|
+
});
|
|
42
|
+
expect(component.inputRules.length).toEqual(1);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('Should not have inputRules if disabled', async () => {
|
|
46
|
+
expect(component.inputRules).toEqual([]);
|
|
47
|
+
await wrapper.setProps({
|
|
48
|
+
rules: [jest.fn()],
|
|
49
|
+
disabled: true,
|
|
50
|
+
});
|
|
51
|
+
expect(component.inputRules.length).toEqual(0);
|
|
52
|
+
});
|
|
32
53
|
});
|
|
33
54
|
});
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
section {
|
|
2
|
-
//outline: 1px dashed grey;
|
|
3
|
-
//outline-offset: -0.5rem;
|
|
4
2
|
border: 2px dashed var(--v-gray-lighten1);
|
|
5
3
|
border-radius: 2rem;
|
|
6
4
|
background-color: var(--v-gray-lighten4);
|
|
7
|
-
//color: var(--v-primary-base);
|
|
8
5
|
padding: 1rem;
|
|
9
6
|
position: relative;
|
|
10
7
|
cursor: pointer;
|
|
11
|
-
height:
|
|
8
|
+
height: 12rem;
|
|
12
9
|
display: flex;
|
|
13
10
|
flex-direction: column;
|
|
14
11
|
align-items: center;
|
|
@@ -45,6 +42,10 @@ section {
|
|
|
45
42
|
flex-direction: column;
|
|
46
43
|
align-items: center;
|
|
47
44
|
justify-content: center;
|
|
45
|
+
> p {
|
|
46
|
+
margin-bottom: 0;
|
|
47
|
+
font-size: 0.75rem;
|
|
48
|
+
}
|
|
48
49
|
.v-btn {
|
|
49
50
|
margin-top: 1rem;
|
|
50
51
|
}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import FilePicker from './FilePicker.vue';
|
|
2
2
|
|
|
3
3
|
export default {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
title: 'API/FilePicker',
|
|
5
|
+
component: FilePicker,
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
export const Primary = () => ({
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
components: { FilePicker },
|
|
10
|
+
template: '<FilePicker />',
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export const MaxFileSize = () => ({
|
|
14
|
+
components: { FilePicker },
|
|
15
|
+
template: '<FilePicker maxFileSize="5" />',
|
|
11
16
|
});
|
|
12
17
|
|
|
13
18
|
Primary.storyName = 'Básico';
|
|
19
|
+
MaxFileSize.storyName = 'Max File Size';
|
|
@@ -1,78 +1,106 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
2
|
+
<section ref="container" id="droparea-container">
|
|
3
|
+
<input
|
|
4
|
+
type="file"
|
|
5
|
+
name="file"
|
|
6
|
+
@change="fileChange($event.target.files)"
|
|
7
|
+
:accept="acceptedFileTypes"
|
|
8
|
+
/>
|
|
9
|
+
<div v-if="!selectedFile" class="selectfile-container">
|
|
10
|
+
<v-icon color="secondary">mdi-cloud-upload</v-icon>
|
|
11
|
+
<p>Clique para selecionar ou arraste o arquivo aqui</p>
|
|
12
|
+
</div>
|
|
13
|
+
<div v-if="selectedFile || maxSizeReach" class="reset-container">
|
|
14
|
+
<div v-if="selectedFile">
|
|
15
|
+
<v-icon>mdi-file</v-icon> Arquivo selecionado: {{ selectedFile.name }} ({{
|
|
16
|
+
Math.floor(selectedFile.size / 1024)
|
|
17
|
+
}}kB)
|
|
18
|
+
</div>
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
<p v-if="maxSizeReach" v-html="maxSizeReachMsg"></p>
|
|
21
|
+
|
|
22
|
+
<v-btn depressed outlined color="secondary" class="v-btn-responsive" @click="reset"
|
|
23
|
+
>Escolher outro</v-btn
|
|
24
|
+
>
|
|
25
|
+
</div>
|
|
26
|
+
</section>
|
|
25
27
|
</template>
|
|
26
28
|
<script>
|
|
27
29
|
import { VBtn } from 'vuetify/lib/components/VBtn';
|
|
28
30
|
import { VIcon } from 'vuetify/lib/components/VIcon';
|
|
29
31
|
export default {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
this.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
32
|
+
props: {
|
|
33
|
+
/*
|
|
34
|
+
* Accepted file types
|
|
35
|
+
*/
|
|
36
|
+
acceptedFileTypes: {
|
|
37
|
+
type: String,
|
|
38
|
+
default: '*',
|
|
39
|
+
},
|
|
40
|
+
/**
|
|
41
|
+
* Max file size (in MB)
|
|
42
|
+
*/
|
|
43
|
+
maxFileSize: {
|
|
44
|
+
default: null,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
data() {
|
|
48
|
+
return {
|
|
49
|
+
selectedFile: null,
|
|
50
|
+
dropArea: null,
|
|
51
|
+
maxSizeReach: false,
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
computed: {
|
|
55
|
+
maxSizeReachMsg() {
|
|
56
|
+
return `Arquivo ultrapassou o tamanho máximo de ${this.maxFileSize}MB`;
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
mounted() {
|
|
60
|
+
this.dropArea = this.$refs.container;
|
|
61
|
+
this.addListeners();
|
|
62
|
+
},
|
|
63
|
+
methods: {
|
|
64
|
+
reset() {
|
|
65
|
+
this.$refs.container.querySelector('input').value = '';
|
|
66
|
+
this.$emit('onReset');
|
|
67
|
+
this.maxSizeReach = false;
|
|
68
|
+
this.selectedFile = null;
|
|
69
|
+
},
|
|
70
|
+
fileChange(fileList) {
|
|
71
|
+
this.maxSizeReach = false;
|
|
72
|
+
if (!fileList.length || fileList.length > 1) return;
|
|
73
|
+
|
|
74
|
+
if (this.maxFileSize) {
|
|
75
|
+
const sizeInMB = fileList[0].size / (1024 * 1024);
|
|
76
|
+
|
|
77
|
+
if (sizeInMB > this.maxFileSize) {
|
|
78
|
+
this.maxSizeReach = true;
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
this.selectedFile = fileList[0];
|
|
83
|
+
this.$emit('onFileChange', this.selectedFile);
|
|
84
|
+
},
|
|
85
|
+
handlerFunctionHighlight() {
|
|
86
|
+
this.dropArea.classList.add('highlight');
|
|
87
|
+
},
|
|
88
|
+
handlerFunctionUnhighlight() {
|
|
89
|
+
this.dropArea.classList.remove('highlight');
|
|
90
|
+
},
|
|
91
|
+
addListeners() {
|
|
92
|
+
this.dropArea.addEventListener('dragenter', this.handlerFunctionHighlight, false);
|
|
93
|
+
this.dropArea.addEventListener('dragleave', this.handlerFunctionUnhighlight, false);
|
|
94
|
+
this.dropArea.addEventListener('dragover', this.handlerFunctionHighlight, false);
|
|
95
|
+
this.dropArea.addEventListener('drop', this.handlerFunctionUnhighlight, false);
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
components: {
|
|
99
|
+
VBtn,
|
|
100
|
+
VIcon,
|
|
101
|
+
},
|
|
74
102
|
};
|
|
75
103
|
</script>
|
|
76
104
|
<style scoped lang="scss">
|
|
77
105
|
@import './FilePicker.scss';
|
|
78
|
-
</style>
|
|
106
|
+
</style>
|