@weni/unnnic-system 2.15.0 → 2.16.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.
Files changed (26) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/style.css +1 -1
  3. package/dist/unnnic.mjs +5802 -5721
  4. package/dist/unnnic.umd.js +31 -31
  5. package/package.json +6 -3
  6. package/src/components/ChartFunnel/ChartFunnel.vue +34 -8
  7. package/src/components/ChartFunnel/DefaultFunnel/ChartDefaultFunnelBase.vue +195 -0
  8. package/src/components/ChartFunnel/{ChartFunnelBaseRow.vue → SvgFunnel/ChartFunnelBaseRow.vue} +1 -1
  9. package/src/components/ChartFunnel/{ChartFunnelFiveRows.vue → SvgFunnel/ChartFunnelFiveRows.vue} +1 -1
  10. package/src/components/ChartFunnel/{ChartFunnelFourRows.vue → SvgFunnel/ChartFunnelFourRows.vue} +1 -1
  11. package/src/components/ChartFunnel/{ChartFunnelThreeRows.vue → SvgFunnel/ChartFunnelThreeRows.vue} +1 -1
  12. package/src/components/Dropdown/Dropdown.vue +1 -0
  13. package/src/components/Dropdown/DropdownItem.vue +4 -1
  14. package/src/components/Dropdown/DropdownSkeleton.vue +2 -0
  15. package/src/components/Dropdown/__tests__/Dropdown.spec.js +98 -0
  16. package/src/components/Dropdown/__tests__/DropdownItem.spec.js +25 -0
  17. package/src/components/Dropdown/__tests__/DropdownSkeleton.spec.js +147 -0
  18. package/src/components/SelectSmart/SelectSmart.vue +5 -0
  19. package/src/components/SelectSmart/SelectSmartMultipleHeader.vue +2 -0
  20. package/src/components/SelectSmart/SelectSmartOption.vue +4 -0
  21. package/src/components/SelectSmart/__tests__/SelectSmart.spec.js +240 -0
  22. package/src/components/SelectSmart/__tests__/SelectSmartMultipleHeader.spec.js +86 -0
  23. package/src/components/SelectSmart/__tests__/SelectSmartOption.spec.js +114 -0
  24. package/src/components/SelectSmart/__tests__/__snapshots__/SelectSmartMultipleHeader.spec.js.snap +8 -0
  25. package/src/components/SelectSmart/__tests__/__snapshots__/SelectSmartOption.spec.js.snap +10 -0
  26. package/src/stories/ChartFunnel.stories.js +54 -25
@@ -16,6 +16,7 @@
16
16
  <p
17
17
  v-if="selectedOptions.length > multipleSelectedsTags"
18
18
  class="unnnic-select-smart__options__multiple__selecteds__remaining"
19
+ data-testid="remaining-count"
19
20
  >
20
21
  +{{ selectedOptions.length - multipleSelectedsTags }}
21
22
  </p>
@@ -24,6 +25,7 @@
24
25
  <p
25
26
  v-if="!selectedOptions[0]"
26
27
  class="unnnic-select-smart__options__multiple--without-multiples"
28
+ data-testid="without-selects-message"
27
29
  >
28
30
  {{ withoutSelectsMessage || i18n('without_multiple_selected') }}
29
31
  </p>
@@ -9,10 +9,12 @@
9
9
  'unnnic-select-smart-option--with-checkbox': allowCheckbox,
10
10
  }"
11
11
  :title="label"
12
+ data-testid="select-smart-option"
12
13
  >
13
14
  <UnnnicCheckbox
14
15
  v-if="allowCheckbox"
15
16
  ref="checkbox"
17
+ data-testid="checkbox"
16
18
  :modelValue="active"
17
19
  :size="size"
18
20
  />
@@ -22,10 +24,12 @@
22
24
  'unnnic-select-smart-option__label',
23
25
  `unnnic-select-smart-option__label--${size}`,
24
26
  ]"
27
+ data-testid="label"
25
28
  >{{ label }}</span
26
29
  >
27
30
  <p
28
31
  v-if="description"
32
+ data-testid="description"
29
33
  :class="[
30
34
  'unnnic-select-smart-option__description',
31
35
  `unnnic-select-smart-option__description--${size}`,
@@ -0,0 +1,240 @@
1
+ import { vi } from 'vitest';
2
+ import { nextTick } from 'vue';
3
+ import { shallowMount } from '@vue/test-utils';
4
+
5
+ import SelectSmart from '../SelectSmart.vue';
6
+ import DropdownSkeleton from '../../Dropdown/DropdownSkeleton.vue';
7
+
8
+ describe('SelectSmart.vue', () => {
9
+ let wrapper;
10
+
11
+ const options = [
12
+ { label: 'Option 1', value: 'option1' },
13
+ { label: 'Option 2', value: 'option2' },
14
+ { label: 'Option 3', value: 'option3' },
15
+ { label: 'Option 4', value: 'option4' },
16
+ { label: 'Option 5', value: 'option5' },
17
+ ];
18
+
19
+ const mountWrapper = (props = {}) => {
20
+ wrapper = shallowMount(SelectSmart, {
21
+ propsData: {
22
+ options: [],
23
+ ...props,
24
+ },
25
+ global: {
26
+ stubs: {
27
+ DropdownSkeleton,
28
+ },
29
+ },
30
+ });
31
+ };
32
+
33
+ beforeEach(() => {
34
+ mountWrapper();
35
+ });
36
+
37
+ const selectSmart = () => wrapper.find('[data-testid="select-smart"]');
38
+ const input = () =>
39
+ wrapper.findComponent('[data-testid="select-smart-input"]');
40
+ const optionsContainer = () =>
41
+ wrapper.find('[data-testid="options-container"]');
42
+
43
+ describe('Rendering', () => {
44
+ it('should render the component correctly', () => {
45
+ expect(selectSmart().exists()).toBe(true);
46
+ });
47
+
48
+ it('should display placeholder text when no selection is made', () => {
49
+ const placeholderText = 'Select an option';
50
+ mountWrapper({ placeholder: placeholderText });
51
+
52
+ expect(input().props('placeholder')).toBe(placeholderText);
53
+ });
54
+ });
55
+
56
+ describe('Dropdown Visibility', () => {
57
+ it('should open the dropdown when input is clicked', async () => {
58
+ await input().trigger('click');
59
+
60
+ expect(optionsContainer().exists()).toBe(true);
61
+ });
62
+
63
+ it('should close the dropdown on active is false', async () => {
64
+ wrapper.vm.active = true;
65
+ await nextTick();
66
+ expect(optionsContainer().exists()).toBe(true);
67
+
68
+ wrapper.vm.active = false;
69
+ await nextTick();
70
+ expect(optionsContainer().exists()).toBe(false);
71
+ });
72
+
73
+ it('should toggle the dropdown visibility on input click', async () => {
74
+ await input().trigger('click');
75
+ expect(optionsContainer().exists()).toBe(true);
76
+
77
+ await input().trigger('click');
78
+
79
+ expect(optionsContainer().exists()).toBe(false);
80
+ });
81
+
82
+ it('should close the dropdown when pressing escape key', async () => {
83
+ await input().trigger('click');
84
+ expect(optionsContainer().exists()).toBe(true);
85
+
86
+ await selectSmart().trigger('keydown', { key: 'Escape' });
87
+
88
+ expect(optionsContainer().exists()).toBe(false);
89
+ });
90
+ });
91
+
92
+ describe('Autocomplete Functionality', () => {
93
+ beforeEach(async () => {
94
+ mountWrapper({
95
+ options: [
96
+ { label: 'Apple', value: 'apple' },
97
+ { label: 'Banana', value: 'banana' },
98
+ { label: 'Orange', value: 'orange' },
99
+ ],
100
+ });
101
+ });
102
+
103
+ it('should filter options based on search input', async () => {
104
+ wrapper.vm.active = true;
105
+ const filteredOptions = () =>
106
+ wrapper.findAllComponents('[data-testid="option"]');
107
+
108
+ await wrapper.setData({ searchValue: 'ap' });
109
+
110
+ expect(filteredOptions().length).toBe(1);
111
+ expect(filteredOptions()[0].props('label')).toBe('Apple');
112
+
113
+ await wrapper.setData({ searchValue: 'or' });
114
+ expect(filteredOptions().length).toBe(1);
115
+ expect(filteredOptions()[0].props('label')).toBe('Orange');
116
+ });
117
+
118
+ it('should clear search input on focus if autocompleteClearOnFocus is true', async () => {
119
+ await wrapper.setProps({
120
+ autocomplete: true,
121
+ autocompleteClearOnFocus: true,
122
+ });
123
+ await wrapper.setData({ searchValue: 'ap' });
124
+
125
+ await input().trigger('click');
126
+
127
+ expect(wrapper.vm.searchValue).toBe('');
128
+ });
129
+ });
130
+
131
+ describe('Option Selection', () => {
132
+ beforeEach(async () => {
133
+ mountWrapper({
134
+ options,
135
+ });
136
+
137
+ wrapper.vm.active = true;
138
+ });
139
+
140
+ afterEach(() => {
141
+ vi.clearAllMocks();
142
+ });
143
+
144
+ it('should select a single option', async () => {
145
+ await wrapper.setProps({ modelValue: [] });
146
+
147
+ const option = wrapper.findComponent('[data-testid="option"]');
148
+ await option.trigger('click');
149
+
150
+ expect(wrapper.emitted('update:modelValue')[0][0]).toEqual([options[0]]);
151
+ });
152
+
153
+ it('should add an option to the selection if multiple is true', async () => {
154
+ await wrapper.setProps({
155
+ multiple: true,
156
+ modelValue: [options[0]],
157
+ });
158
+
159
+ const optionsElements = wrapper.findAllComponents(
160
+ '[data-testid="option"]',
161
+ );
162
+ await optionsElements[1].trigger('click');
163
+
164
+ expect(wrapper.emitted('update:modelValue')[2][0]).toEqual([
165
+ options[0],
166
+ options[1],
167
+ ]);
168
+ });
169
+
170
+ it('should unselect an option if clicked again in multiple mode', async () => {
171
+ await wrapper.setProps({
172
+ multiple: true,
173
+ modelValue: [options[0]],
174
+ });
175
+
176
+ const optionsElements = wrapper.findAllComponents(
177
+ '[data-testid="option"]',
178
+ );
179
+ await optionsElements[0].trigger('click');
180
+
181
+ expect(wrapper.emitted('update:modelValue')[1][0]).toEqual([]);
182
+ });
183
+ });
184
+
185
+ describe('Scrolling Behavior', () => {
186
+ beforeEach(async () => {
187
+ mountWrapper({
188
+ options,
189
+ });
190
+ });
191
+
192
+ it('should scroll to selected option on opening', async () => {
193
+ wrapper.vm.scrollToOption = vi.fn();
194
+ await wrapper.setProps({
195
+ modelValue: [options[2]],
196
+ });
197
+
198
+ await nextTick();
199
+ wrapper.vm.active = true;
200
+ await nextTick();
201
+ await nextTick();
202
+
203
+ expect(wrapper.vm.scrollToOption).toHaveBeenCalledWith(2, 'center');
204
+ });
205
+
206
+ it('should scroll to focused option when navigating with keyboard', async () => {
207
+ wrapper.vm.active = true;
208
+ await nextTick();
209
+
210
+ await selectSmart().trigger('keydown', { key: 'ArrowDown' });
211
+
212
+ const optionsElements = wrapper.findAllComponents(
213
+ '[data-testid="option"]',
214
+ );
215
+ const focusedOption = optionsElements.find(
216
+ (option) => option.props('focused') === true,
217
+ );
218
+
219
+ expect(focusedOption.exists()).toBe(true);
220
+
221
+ const dropdownRect = optionsContainer().element.getBoundingClientRect();
222
+ const focusedRect = focusedOption.element.getBoundingClientRect();
223
+
224
+ expect(focusedRect.top).toBeGreaterThanOrEqual(dropdownRect.top);
225
+ expect(focusedRect.bottom).toBeLessThanOrEqual(dropdownRect.bottom);
226
+ });
227
+ });
228
+
229
+ describe('Keyboard Navigation', () => {
230
+ it('should select focused option with enter key', async () => {
231
+ wrapper.vm.active = true;
232
+ await wrapper.setData({ focusedOption: options[1] });
233
+
234
+ await selectSmart().trigger('keydown', { key: 'Enter' });
235
+
236
+ expect(wrapper.emitted('update:modelValue')).toBeTruthy();
237
+ expect(wrapper.emitted('update:modelValue')[0][0]).toEqual([options[1]]);
238
+ });
239
+ });
240
+ });
@@ -0,0 +1,86 @@
1
+ import { shallowMount } from '@vue/test-utils';
2
+ import SelectSmartMultipleHeader from '../SelectSmartMultipleHeader.vue';
3
+ import Tag from '@/components/Tag/Tag.vue';
4
+
5
+ describe('SelectSmartMultipleHeader.vue', () => {
6
+ let wrapper;
7
+
8
+ const mountWrapper = (props = {}) => {
9
+ wrapper = shallowMount(SelectSmartMultipleHeader, {
10
+ propsData: {
11
+ selectedOptions: [],
12
+ ...props,
13
+ },
14
+ stubs: {
15
+ Tag,
16
+ },
17
+ });
18
+ };
19
+
20
+ beforeEach(() => {
21
+ mountWrapper();
22
+ });
23
+
24
+ describe('initial rendering', () => {
25
+ it('matches the snapshot', () => {
26
+ expect(wrapper.html()).toMatchSnapshot();
27
+ });
28
+
29
+ it('renders without any selected options by default', () => {
30
+ const withoutSelectsMessage = wrapper.find(
31
+ '[data-testid="without-selects-message"]',
32
+ );
33
+ expect(withoutSelectsMessage.exists()).toBe(true);
34
+ expect(withoutSelectsMessage.text()).toBe('No option selected');
35
+ });
36
+
37
+ it('displays the correct "without selects" message when no options are selected', async () => {
38
+ await wrapper.setProps({ withoutSelectsMessage: 'No items selected' });
39
+ const withoutSelectsMessage = wrapper.find(
40
+ '[data-testid="without-selects-message"]',
41
+ );
42
+ expect(withoutSelectsMessage.text()).toBe('No items selected');
43
+ });
44
+ });
45
+
46
+ describe('selected options display', () => {
47
+ beforeEach(() => {
48
+ mountWrapper({
49
+ selectedOptions: [
50
+ { value: 1, label: 'Option 1' },
51
+ { value: 2, label: 'Option 2' },
52
+ { value: 3, label: 'Option 3' },
53
+ ],
54
+ });
55
+ });
56
+
57
+ it('renders tags for the first multiple selected options', () => {
58
+ const tags = wrapper.findAllComponents(Tag);
59
+ expect(tags.length).toBe(2);
60
+ });
61
+
62
+ it('displays remaining selected options count correctly', () => {
63
+ const remainingCount = wrapper.find('[data-testid="remaining-count"]');
64
+ expect(remainingCount.exists()).toBe(true);
65
+ expect(remainingCount.text()).toBe('+1');
66
+ });
67
+ });
68
+
69
+ describe('unselectOption method', () => {
70
+ it('emits "unselect-option" event when a Tag close icon is clicked', async () => {
71
+ mountWrapper({
72
+ selectedOptions: [
73
+ { value: 1, label: 'Option 1' },
74
+ { value: 2, label: 'Option 2' },
75
+ ],
76
+ });
77
+
78
+ const firstTag = wrapper.findComponent(Tag);
79
+ await firstTag.vm.$emit('close');
80
+ expect(wrapper.emitted('unselect-option')).toBeTruthy();
81
+ expect(wrapper.emitted('unselect-option')[0]).toEqual([
82
+ { value: 1, label: 'Option 1' },
83
+ ]);
84
+ });
85
+ });
86
+ });
@@ -0,0 +1,114 @@
1
+ import { shallowMount } from '@vue/test-utils';
2
+ import SelectSmartOption from '../SelectSmartOption.vue';
3
+
4
+ describe('SelectSmartOption.vue', () => {
5
+ let wrapper;
6
+
7
+ const mountWrapper = (props = {}) => {
8
+ wrapper = shallowMount(SelectSmartOption, {
9
+ propsData: {
10
+ label: 'Test Option',
11
+ ...props,
12
+ },
13
+ });
14
+ };
15
+
16
+ beforeEach(() => {
17
+ mountWrapper();
18
+ });
19
+
20
+ describe('Initial rendering', () => {
21
+ it('matches the snapshot', () => {
22
+ expect(wrapper.html()).toMatchSnapshot();
23
+ });
24
+
25
+ it('renders the component with the correct label', () => {
26
+ expect(wrapper.find('[data-testid="label"]').text()).toBe('Test Option');
27
+ });
28
+
29
+ it('applies the title attribute with the label text', () => {
30
+ expect(wrapper.attributes('title')).toBe('Test Option');
31
+ });
32
+ });
33
+
34
+ describe('Dynamic classes', () => {
35
+ it('adds focused class when focused prop is true', async () => {
36
+ await wrapper.setProps({ focused: true });
37
+ expect(wrapper.classes()).toContain(
38
+ 'unnnic-select-smart-option--focused',
39
+ );
40
+ });
41
+
42
+ it('adds active class when active prop is true', async () => {
43
+ await wrapper.setProps({ active: true });
44
+ expect(wrapper.classes()).toContain('unnnic-select-smart-option--active');
45
+ });
46
+
47
+ it('adds selectable class when selectable prop is true', async () => {
48
+ await wrapper.setProps({ selectable: true });
49
+ expect(wrapper.classes()).toContain(
50
+ 'unnnic-select-smart-option--selectable',
51
+ );
52
+ });
53
+
54
+ it('adds with-checkbox class when allowCheckbox prop is true', async () => {
55
+ await wrapper.setProps({ allowCheckbox: true });
56
+ expect(wrapper.classes()).toContain(
57
+ 'unnnic-select-smart-option--with-checkbox',
58
+ );
59
+ });
60
+ });
61
+
62
+ describe('Checkbox rendering', () => {
63
+ beforeEach(() => {
64
+ mountWrapper({ allowCheckbox: true });
65
+ });
66
+
67
+ it('renders checkbox when allowCheckbox is true', () => {
68
+ const checkbox = wrapper.findComponent('[data-testid="checkbox"]');
69
+ expect(checkbox.exists()).toBe(true);
70
+ });
71
+
72
+ it('does not render checkbox when allowCheckbox is false', () => {
73
+ mountWrapper({ allowCheckbox: false });
74
+ const checkbox = wrapper.findComponent('[data-testid="checkbox"]');
75
+ expect(checkbox.exists()).toBe(false);
76
+ });
77
+
78
+ it('binds active prop to checkbox modelValue', async () => {
79
+ await wrapper.setProps({ active: true });
80
+ const checkbox = wrapper.findComponent('[data-testid="checkbox"]');
81
+ expect(checkbox.props('modelValue')).toBe(true);
82
+ });
83
+ });
84
+
85
+ describe('Label and description rendering', () => {
86
+ it('displays the label with the correct size class', async () => {
87
+ await wrapper.setProps({ size: 'large' });
88
+ const label = wrapper.find('[data-testid="label"]');
89
+ expect(label.classes()).toContain(
90
+ 'unnnic-select-smart-option__label--large',
91
+ );
92
+ });
93
+
94
+ it('displays the description if provided', async () => {
95
+ await wrapper.setProps({ description: 'This is a test description' });
96
+ const description = wrapper.find('[data-testid="description"]');
97
+ expect(description.exists()).toBe(true);
98
+ expect(description.text()).toBe('This is a test description');
99
+ });
100
+
101
+ it('does not render description if it is not provided', () => {
102
+ const description = wrapper.find('[data-testid="description"]');
103
+ expect(description.exists()).toBe(false);
104
+ });
105
+
106
+ it('applies size class to description if provided', async () => {
107
+ await wrapper.setProps({ description: 'Description', size: 'small' });
108
+ const description = wrapper.find('[data-testid="description"]');
109
+ expect(description.classes()).toContain(
110
+ 'unnnic-select-smart-option__description--small',
111
+ );
112
+ });
113
+ });
114
+ });
@@ -0,0 +1,8 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`SelectSmartMultipleHeader.vue > initial rendering > matches the snapshot 1`] = `
4
+ "<div data-v-4950cf71="" class="unnnic-select-smart__options__multiple">
5
+ <!--v-if-->
6
+ <p data-v-4950cf71="" class="unnnic-select-smart__options__multiple--without-multiples" data-testid="without-selects-message">No option selected</p>
7
+ </div>"
8
+ `;
@@ -0,0 +1,10 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`SelectSmartOption.vue > Initial rendering > matches the snapshot 1`] = `
4
+ "<div class="unnnic-select-smart-option unnnic--clickable unnnic-select-smart-option--selectable" title="Test Option" data-testid="select-smart-option">
5
+ <!--v-if-->
6
+ <div><span class="unnnic-select-smart-option__label unnnic-select-smart-option__label--" data-testid="label">Test Option</span>
7
+ <!--v-if-->
8
+ </div>
9
+ </div>"
10
+ `;
@@ -4,8 +4,13 @@ export default {
4
4
  title: 'Charts/ChartFunnel',
5
5
  tags: ['autodocs'],
6
6
  component: UnnnicChartFunnel,
7
+ argTypes: {
8
+ type: { control: { type: 'select' }, options: ['default', 'basic'] },
9
+ },
7
10
  decorators: [
8
- () => ({ template: '<div style="width: 500px;"><story /></div>' }),
11
+ () => ({
12
+ template: '<div style="width: 500px; height: 500px;"><story /></div>',
13
+ }),
9
14
  ],
10
15
  };
11
16
 
@@ -13,16 +18,22 @@ export const ThreeRows = {
13
18
  args: {
14
19
  data: [
15
20
  {
16
- title: '100% (18.621)',
17
- description: 'Execução de fluxo',
21
+ title: '100%',
22
+ description: 'Clicou em comprar',
23
+ value: '18.621',
24
+ color: '#F6E05E',
18
25
  },
19
26
  {
20
- title: '67% (12.476)',
21
- description: 'Execução de fluxo',
27
+ title: '67%',
28
+ description: 'Informou entrega',
29
+ value: '12.476',
30
+ color: '#F6AD55',
22
31
  },
23
32
  {
24
- title: '12% (2.234)',
25
- description: 'Execução de fluxo',
33
+ title: '24%',
34
+ description: 'Selecionou Itens',
35
+ value: '4.469',
36
+ color: '#B794F4',
26
37
  },
27
38
  ],
28
39
  },
@@ -32,20 +43,28 @@ export const FourRows = {
32
43
  args: {
33
44
  data: [
34
45
  {
35
- title: '100% (18.621)',
36
- description: 'Execução de fluxo',
46
+ title: '100%',
47
+ description: 'Clicou em comprar',
48
+ value: '18.621',
49
+ color: '#F6E05E',
37
50
  },
38
51
  {
39
- title: '67% (12.476)',
40
- description: 'Execução de fluxo',
52
+ title: '67%',
53
+ description: 'Informou entrega',
54
+ value: '12.476',
55
+ color: '#F6AD55',
41
56
  },
42
57
  {
43
- title: '12% (2.234)',
44
- description: 'Execução de fluxo',
58
+ title: '24%',
59
+ description: 'Selecionou Itens',
60
+ value: '4.469',
61
+ color: '#B794F4',
45
62
  },
46
63
  {
47
- title: '5% (931)',
48
- description: 'Execução de fluxo',
64
+ title: '12%',
65
+ description: 'Foi para checkout',
66
+ value: '2.234',
67
+ color: '#63B3ED',
49
68
  },
50
69
  ],
51
70
  },
@@ -55,24 +74,34 @@ export const FiveRows = {
55
74
  args: {
56
75
  data: [
57
76
  {
58
- title: '100% (18.621)',
59
- description: 'Execução de fluxo',
77
+ title: '100%',
78
+ description: 'Clicou em comprar',
79
+ value: '18.621',
80
+ color: '#F6E05E',
60
81
  },
61
82
  {
62
- title: '67% (12.476)',
63
- description: 'Execução de fluxo',
83
+ title: '67%',
84
+ description: 'Informou entrega',
85
+ value: '12.476',
86
+ color: '#F6AD55',
64
87
  },
65
88
  {
66
- title: '12% (2.234)',
67
- description: 'Execução de fluxo',
89
+ title: '24%',
90
+ description: 'Selecionou Itens',
91
+ value: '4.469',
92
+ color: '#B794F4',
68
93
  },
69
94
  {
70
- title: '5% (931)',
71
- description: 'Execução de fluxo',
95
+ title: '12%',
96
+ description: 'Foi para checkout',
97
+ value: '2.234',
98
+ color: '#63B3ED',
72
99
  },
73
100
  {
74
- title: '2% (372)',
75
- description: 'Execução de fluxo',
101
+ title: '5%',
102
+ description: 'Finalizou a compra',
103
+ value: '931',
104
+ color: '#68D391',
76
105
  },
77
106
  ],
78
107
  },