@farm-investimentos/front-mfe-components-vue3 1.6.8 → 1.6.10
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 +28 -23
- package/dist/front-mfe-components.common.js +219 -4
- 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 +219 -4
- 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/FilterEmptyState/EmptyDataSvg.vue +92 -0
- package/src/components/FilterEmptyState/EmptyNotFoundSvg.vue +65 -0
- package/src/components/FilterEmptyState/FilterEmptyState.scss +17 -0
- package/src/components/FilterEmptyState/FilterEmptyState.stories.js +272 -0
- package/src/components/FilterEmptyState/FilterEmptyState.vue +111 -0
- package/src/components/FilterEmptyState/__tests__/FilterEmptyState.spec.ts +149 -0
- package/src/components/FilterEmptyState/index.ts +4 -0
- package/src/main.ts +1 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<farm-box>
|
|
3
|
+
<farm-row justify="center" class="mb-4">
|
|
4
|
+
<!-- Custom image via prop -->
|
|
5
|
+
<img
|
|
6
|
+
v-if="hasCustomImage"
|
|
7
|
+
:src="currentImageSrc"
|
|
8
|
+
:alt="currentImageAlt"
|
|
9
|
+
class="filter-empty-state__image"
|
|
10
|
+
/>
|
|
11
|
+
<!-- SVG component for not found state -->
|
|
12
|
+
<EmptyNotFoundSvg
|
|
13
|
+
v-else-if="isNotFound"
|
|
14
|
+
:alt="isNotFoundImageAlt"
|
|
15
|
+
class="filter-empty-state__image"
|
|
16
|
+
/>
|
|
17
|
+
<!-- SVG component for empty state -->
|
|
18
|
+
<EmptyDataSvg v-else :alt="isEmptyImageAlt" class="filter-empty-state__image" />
|
|
19
|
+
</farm-row>
|
|
20
|
+
<farm-row justify="center">
|
|
21
|
+
<farm-bodytext variation="bold" color="gray" :type="2">
|
|
22
|
+
<slot name="title">
|
|
23
|
+
{{ title || 'Nenhuma informação para exibir aqui' }}
|
|
24
|
+
</slot>
|
|
25
|
+
</farm-bodytext>
|
|
26
|
+
</farm-row>
|
|
27
|
+
<farm-row justify="center" class="mt-2">
|
|
28
|
+
<farm-caption variation="regular" color="gray">
|
|
29
|
+
<slot name="subtitle">
|
|
30
|
+
{{ subtitle || 'Tente filtrar novamente sua pesquisa.' }}
|
|
31
|
+
</slot>
|
|
32
|
+
</farm-caption>
|
|
33
|
+
</farm-row>
|
|
34
|
+
</farm-box>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<script setup lang="ts">
|
|
38
|
+
import { computed } from 'vue';
|
|
39
|
+
|
|
40
|
+
import EmptyDataSvg from './EmptyDataSvg.vue';
|
|
41
|
+
import EmptyNotFoundSvg from './EmptyNotFoundSvg.vue';
|
|
42
|
+
|
|
43
|
+
defineOptions({
|
|
44
|
+
name: 'farm-filter-empty-state',
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
interface FilterEmptyStateProps {
|
|
48
|
+
/**
|
|
49
|
+
* Indicates if the state is empty (no data)
|
|
50
|
+
*/
|
|
51
|
+
isEmpty?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Indicates if the state is not found (no results from filter)
|
|
54
|
+
*/
|
|
55
|
+
isNotFound?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Custom image URL for empty state
|
|
58
|
+
*/
|
|
59
|
+
isEmptyImage?: string;
|
|
60
|
+
/**
|
|
61
|
+
* Alt text for empty state image
|
|
62
|
+
*/
|
|
63
|
+
isEmptyImageAlt?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Custom image URL for not found state
|
|
66
|
+
*/
|
|
67
|
+
isNotFoundImage?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Alt text for not found state image
|
|
70
|
+
*/
|
|
71
|
+
isNotFoundImageAlt?: string;
|
|
72
|
+
/**
|
|
73
|
+
* Title to be displayed
|
|
74
|
+
*/
|
|
75
|
+
title?: string;
|
|
76
|
+
/**
|
|
77
|
+
* Subtitle to be displayed
|
|
78
|
+
*/
|
|
79
|
+
subtitle?: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const props = withDefaults(defineProps<FilterEmptyStateProps>(), {
|
|
83
|
+
isEmpty: true,
|
|
84
|
+
isNotFound: false,
|
|
85
|
+
isEmptyImage: '',
|
|
86
|
+
isEmptyImageAlt: 'Imagem referente a dados vazios',
|
|
87
|
+
isNotFoundImage: '',
|
|
88
|
+
isNotFoundImageAlt: 'Imagem referente a filtro vazio',
|
|
89
|
+
title: '',
|
|
90
|
+
subtitle: '',
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Check if user provided custom images
|
|
94
|
+
const hasCustomImage = computed(() => {
|
|
95
|
+
return props.isNotFound ? !!props.isNotFoundImage : !!props.isEmptyImage;
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Get the current image source (for custom images)
|
|
99
|
+
const currentImageSrc = computed(() => {
|
|
100
|
+
return props.isNotFound ? props.isNotFoundImage : props.isEmptyImage;
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Get the current image alt text
|
|
104
|
+
const currentImageAlt = computed(() => {
|
|
105
|
+
return props.isNotFound ? props.isNotFoundImageAlt : props.isEmptyImageAlt;
|
|
106
|
+
});
|
|
107
|
+
</script>
|
|
108
|
+
|
|
109
|
+
<style scoped lang="scss">
|
|
110
|
+
@import './FilterEmptyState.scss';
|
|
111
|
+
</style>
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
|
|
3
|
+
import FilterEmptyState from '../FilterEmptyState.vue';
|
|
4
|
+
|
|
5
|
+
const globalStubs = {
|
|
6
|
+
'farm-box': { template: '<div><slot /></div>' },
|
|
7
|
+
'farm-row': { template: '<div><slot /></div>' },
|
|
8
|
+
'farm-bodytext': { template: '<div><slot /></div>' },
|
|
9
|
+
'farm-caption': { template: '<div><slot /></div>' },
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
describe('FilterEmptyState', () => {
|
|
13
|
+
it('renders empty state correctly', () => {
|
|
14
|
+
const wrapper = mount(FilterEmptyState, {
|
|
15
|
+
props: {
|
|
16
|
+
isEmpty: true,
|
|
17
|
+
isNotFound: false,
|
|
18
|
+
},
|
|
19
|
+
global: {
|
|
20
|
+
stubs: globalStubs,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
expect(wrapper.find('.filter-empty-state__image').exists()).toBe(true);
|
|
25
|
+
expect(wrapper.text()).toContain('Nenhuma informação para exibir aqui');
|
|
26
|
+
expect(wrapper.text()).toContain('Tente filtrar novamente sua pesquisa.');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('renders not found state correctly', () => {
|
|
30
|
+
const wrapper = mount(FilterEmptyState, {
|
|
31
|
+
props: {
|
|
32
|
+
isEmpty: false,
|
|
33
|
+
isNotFound: true,
|
|
34
|
+
},
|
|
35
|
+
global: {
|
|
36
|
+
stubs: globalStubs,
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
expect(wrapper.find('.filter-empty-state__image').exists()).toBe(true);
|
|
41
|
+
expect(wrapper.text()).toContain('Nenhuma informação para exibir aqui');
|
|
42
|
+
expect(wrapper.text()).toContain('Tente filtrar novamente sua pesquisa.');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('renders custom title and subtitle', () => {
|
|
46
|
+
const wrapper = mount(FilterEmptyState, {
|
|
47
|
+
props: {
|
|
48
|
+
isEmpty: true,
|
|
49
|
+
title: 'Custom Title',
|
|
50
|
+
subtitle: 'Custom Subtitle',
|
|
51
|
+
},
|
|
52
|
+
global: {
|
|
53
|
+
stubs: globalStubs,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
expect(wrapper.text()).toContain('Custom Title');
|
|
58
|
+
expect(wrapper.text()).toContain('Custom Subtitle');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('uses custom images when provided', () => {
|
|
62
|
+
const wrapper = mount(FilterEmptyState, {
|
|
63
|
+
props: {
|
|
64
|
+
isEmpty: true,
|
|
65
|
+
isEmptyImage: 'custom-empty-image.svg',
|
|
66
|
+
isEmptyImageAlt: 'Custom empty image',
|
|
67
|
+
},
|
|
68
|
+
global: {
|
|
69
|
+
stubs: globalStubs,
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const img = wrapper.find('.filter-empty-state__image');
|
|
74
|
+
expect(img.exists()).toBe(true);
|
|
75
|
+
expect(img.attributes('src')).toBe('custom-empty-image.svg');
|
|
76
|
+
expect(img.attributes('alt')).toBe('Custom empty image');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('uses custom not found images when provided', () => {
|
|
80
|
+
const wrapper = mount(FilterEmptyState, {
|
|
81
|
+
props: {
|
|
82
|
+
isNotFound: true,
|
|
83
|
+
isNotFoundImage: 'custom-not-found-image.svg',
|
|
84
|
+
isNotFoundImageAlt: 'Custom not found image',
|
|
85
|
+
},
|
|
86
|
+
global: {
|
|
87
|
+
stubs: globalStubs,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const img = wrapper.find('.filter-empty-state__image');
|
|
92
|
+
expect(img.exists()).toBe(true);
|
|
93
|
+
expect(img.attributes('src')).toBe('custom-not-found-image.svg');
|
|
94
|
+
expect(img.attributes('alt')).toBe('Custom not found image');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('has correct default props', () => {
|
|
98
|
+
const wrapper: any = mount(FilterEmptyState, {
|
|
99
|
+
global: {
|
|
100
|
+
stubs: globalStubs,
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
expect(wrapper.vm.isEmpty).toBe(true);
|
|
105
|
+
expect(wrapper.vm.isNotFound).toBe(false);
|
|
106
|
+
expect(wrapper.vm.title).toBe('');
|
|
107
|
+
expect(wrapper.vm.subtitle).toBe('');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('shows empty image by default when no props are provided', () => {
|
|
111
|
+
const wrapper = mount(FilterEmptyState, {
|
|
112
|
+
global: {
|
|
113
|
+
stubs: globalStubs,
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
expect(wrapper.find('.filter-empty-state__image').exists()).toBe(true);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('shows empty image when isEmpty is false and isNotFound is false', () => {
|
|
121
|
+
const wrapper = mount(FilterEmptyState, {
|
|
122
|
+
props: {
|
|
123
|
+
isEmpty: false,
|
|
124
|
+
isNotFound: false,
|
|
125
|
+
},
|
|
126
|
+
global: {
|
|
127
|
+
stubs: globalStubs,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
expect(wrapper.find('.filter-empty-state__image').exists()).toBe(true);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('prioritizes isNotFound over isEmpty', () => {
|
|
135
|
+
const wrapper = mount(FilterEmptyState, {
|
|
136
|
+
props: {
|
|
137
|
+
isEmpty: true,
|
|
138
|
+
isNotFound: true,
|
|
139
|
+
},
|
|
140
|
+
global: {
|
|
141
|
+
stubs: globalStubs,
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const img = wrapper.find('.filter-empty-state__image');
|
|
146
|
+
expect(img.exists()).toBe(true);
|
|
147
|
+
expect(img.attributes('aria-label')).toBe('Imagem referente a filtro vazio');
|
|
148
|
+
});
|
|
149
|
+
});
|