@weni/unnnic-system 3.11.1-alpha.1 → 3.11.1-alpha.4
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/CHANGELOG.md +32 -0
- package/dist/components/DatePicker/DatePicker.vue.d.ts +69 -249
- package/dist/components/DatePicker/DatePicker.vue.d.ts.map +1 -1
- package/dist/components/Drawer/Drawer.vue.d.ts.map +1 -1
- package/dist/components/InputDatePicker/InputDatePicker.vue.d.ts +47 -911
- package/dist/components/InputDatePicker/InputDatePicker.vue.d.ts.map +1 -1
- package/dist/components/Select/SelectItem.vue.d.ts +1 -1
- package/dist/components/SelectSmart/SelectSmart.vue.d.ts +1 -1
- package/dist/components/SelectSmart/SelectSmartOption.vue.d.ts +1 -1
- package/dist/components/Sidebar/SidebarItem.vue.d.ts +2 -2
- package/dist/components/ui/drawer/Drawer.vue.d.ts.map +1 -1
- package/dist/components/ui/drawer/DrawerClose.vue.d.ts.map +1 -1
- package/dist/components/ui/drawer/DrawerContent.vue.d.ts.map +1 -1
- package/dist/components/ui/drawer/DrawerDescription.vue.d.ts.map +1 -1
- package/dist/components/ui/drawer/DrawerFooter.vue.d.ts.map +1 -1
- package/dist/components/ui/drawer/DrawerHeader.vue.d.ts.map +1 -1
- package/dist/components/ui/drawer/DrawerOverlay.vue.d.ts.map +1 -1
- package/dist/components/ui/drawer/DrawerTitle.vue.d.ts.map +1 -1
- package/dist/components/ui/drawer/DrawerTrigger.vue.d.ts.map +1 -1
- package/dist/{es-1e5cce64.mjs → es-fc643bdb.mjs} +1 -1
- package/dist/{index-8d75623f.mjs → index-4601aaf4.mjs} +9050 -9107
- package/dist/{pt-br-defd03da.mjs → pt-br-0b82e6d2.mjs} +1 -1
- package/dist/style.css +1 -1
- package/dist/unnnic.mjs +1 -1
- package/dist/unnnic.umd.js +42 -42
- package/package.json +1 -1
- package/src/components/DatePicker/DatePicker.vue +628 -516
- package/src/components/DatePicker/__tests__/DatePicker.spec.js +227 -0
- package/src/components/Drawer/Drawer.vue +6 -2
- package/src/components/Drawer/__tests__/Drawer.spec.js +11 -15
- package/src/components/Drawer/__tests__/__snapshots__/Drawer.spec.js.snap +9 -9
- package/src/components/InputDatePicker/InputDatePicker.vue +149 -183
- package/src/components/InputDatePicker/__test__/InputDatePicker.spec.js +159 -0
- package/src/components/Tab/__test__/__snapshots__/Tab.spec.js.snap +1 -1
- package/src/components/ui/drawer/Drawer.vue +4 -0
- package/src/components/ui/drawer/DrawerClose.vue +4 -0
- package/src/components/ui/drawer/DrawerContent.vue +5 -1
- package/src/components/ui/drawer/DrawerDescription.vue +4 -0
- package/src/components/ui/drawer/DrawerFooter.vue +5 -1
- package/src/components/ui/drawer/DrawerHeader.vue +5 -1
- package/src/components/ui/drawer/DrawerOverlay.vue +5 -1
- package/src/components/ui/drawer/DrawerTitle.vue +5 -1
- package/src/components/ui/drawer/DrawerTrigger.vue +4 -0
- package/src/stories/DatePicker.stories.js +71 -0
- package/src/stories/InputDatePicker.stories.js +22 -0
- package/dist/components/index.d.ts +0 -25946
- package/dist/components/index.d.ts.map +0 -1
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
3
|
+
import DatePicker from '../DatePicker.vue';
|
|
4
|
+
|
|
5
|
+
const factory = (props = {}) =>
|
|
6
|
+
mount(DatePicker, {
|
|
7
|
+
props: {
|
|
8
|
+
size: 'large',
|
|
9
|
+
type: 'day',
|
|
10
|
+
...props,
|
|
11
|
+
},
|
|
12
|
+
global: {
|
|
13
|
+
mocks: {
|
|
14
|
+
$i18n: { locale: 'en-us' },
|
|
15
|
+
},
|
|
16
|
+
stubs: {
|
|
17
|
+
UnnnicButton: true,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const findFirstSelectableDay = (wrapper) =>
|
|
23
|
+
wrapper
|
|
24
|
+
.findAll('[data-testid="date-picker-day"]')
|
|
25
|
+
.find((day) => day.classes().includes('selectable'));
|
|
26
|
+
|
|
27
|
+
describe('DatePicker.vue', () => {
|
|
28
|
+
let wrapper;
|
|
29
|
+
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
wrapper = factory({
|
|
32
|
+
options: [
|
|
33
|
+
{ name: 'Last 7 days', id: 'last-7-days' },
|
|
34
|
+
{ name: 'Custom', id: 'custom' },
|
|
35
|
+
],
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('renders day view with two months and options', () => {
|
|
40
|
+
expect(wrapper.find('[data-testid="date-picker-root"]').exists()).toBe(
|
|
41
|
+
true,
|
|
42
|
+
);
|
|
43
|
+
expect(
|
|
44
|
+
wrapper.findAll('[data-testid="date-picker-month-container"]').length,
|
|
45
|
+
).toBe(2);
|
|
46
|
+
expect(wrapper.findAll('[data-testid="date-picker-option"]').length).toBe(
|
|
47
|
+
2,
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('selects a date range and emits change', async () => {
|
|
52
|
+
const first = findFirstSelectableDay(wrapper);
|
|
53
|
+
const second = wrapper
|
|
54
|
+
.findAll('[data-testid="date-picker-day"]')
|
|
55
|
+
.reverse()
|
|
56
|
+
.find((day) => day.classes().includes('selectable'));
|
|
57
|
+
|
|
58
|
+
await first.trigger('click');
|
|
59
|
+
await second.trigger('click');
|
|
60
|
+
|
|
61
|
+
const emittedChange = wrapper.emitted('change');
|
|
62
|
+
expect(emittedChange).toBeTruthy();
|
|
63
|
+
const [{ startDate, endDate }] = emittedChange.pop();
|
|
64
|
+
expect(startDate).not.toBe('');
|
|
65
|
+
expect(endDate).not.toBe('');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('clears selection when clear button is clicked', async () => {
|
|
69
|
+
const day = findFirstSelectableDay(wrapper);
|
|
70
|
+
await day.trigger('click');
|
|
71
|
+
|
|
72
|
+
await wrapper.find('[data-testid="date-picker-clear"]').trigger('click');
|
|
73
|
+
|
|
74
|
+
expect(wrapper.vm.startDate).toBe('');
|
|
75
|
+
expect(wrapper.vm.endDate).toBe('');
|
|
76
|
+
expect(wrapper.vm.optionSelected).toBe('');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('submits with selected period and emits equivalent option name', async () => {
|
|
80
|
+
await wrapper.vm.autoSelect('last-7-days');
|
|
81
|
+
await wrapper.find('[data-testid="date-picker-submit"]').trigger('click');
|
|
82
|
+
|
|
83
|
+
const submit = wrapper.emitted('submit');
|
|
84
|
+
const updateEquivalent = wrapper.emitted('update:equivalentOption');
|
|
85
|
+
|
|
86
|
+
expect(submit).toBeTruthy();
|
|
87
|
+
expect(submit[0][0]).toHaveProperty('startDate');
|
|
88
|
+
expect(submit[0][0]).toHaveProperty('endDate');
|
|
89
|
+
|
|
90
|
+
expect(updateEquivalent[0][0]).toBe('Last 7 days');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('submits with custom selection and clears equivalent option', async () => {
|
|
94
|
+
wrapper.vm.optionSelected = 'custom';
|
|
95
|
+
await wrapper.find('[data-testid="date-picker-submit"]').trigger('click');
|
|
96
|
+
|
|
97
|
+
const updateEquivalent = wrapper.emitted('update:equivalentOption');
|
|
98
|
+
expect(updateEquivalent[0][0]).toBe('');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('uses periodBaseDate to compute relative ranges', async () => {
|
|
102
|
+
const base = '2025-01-15';
|
|
103
|
+
wrapper = factory({
|
|
104
|
+
periodBaseDate: base,
|
|
105
|
+
options: [{ name: 'Last 7 days', id: 'last-7-days' }],
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
await wrapper.vm.autoSelect('last-7-days');
|
|
109
|
+
|
|
110
|
+
const [year, month, day] = base.split('-');
|
|
111
|
+
const baseDate = new Date(Number(year), Number(month) - 1, Number(day));
|
|
112
|
+
const expectedEnd = wrapper.vm.dateToString(baseDate);
|
|
113
|
+
|
|
114
|
+
expect(wrapper.vm.endDate).toBe(expectedEnd);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('renders month view and selects a month', async () => {
|
|
118
|
+
wrapper = factory({
|
|
119
|
+
type: 'month',
|
|
120
|
+
options: [{ name: 'Last 12 months', id: 'last-12-months' }],
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
const monthCell = wrapper.find('[data-testid="date-picker-month-cell"]');
|
|
124
|
+
await monthCell.trigger('click');
|
|
125
|
+
|
|
126
|
+
expect(wrapper.vm.startDate).not.toBe('');
|
|
127
|
+
expect(wrapper.vm.endDate).not.toBe('');
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('renders year view and selects a year', async () => {
|
|
131
|
+
wrapper = factory({
|
|
132
|
+
type: 'year',
|
|
133
|
+
options: [{ name: 'Previous year', id: 'previous-year' }],
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const yearCell = wrapper.find('[data-testid="date-picker-year-cell"]');
|
|
137
|
+
await yearCell.trigger('click');
|
|
138
|
+
|
|
139
|
+
expect(wrapper.vm.startDate).not.toBe('');
|
|
140
|
+
expect(wrapper.vm.endDate).not.toBe('');
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('hides options when size is small and respects disableClear', async () => {
|
|
144
|
+
wrapper = factory({
|
|
145
|
+
size: 'small',
|
|
146
|
+
options: [{ name: 'Last 7 days', id: 'last-7-days' }],
|
|
147
|
+
});
|
|
148
|
+
expect(wrapper.find('[data-testid="date-picker-options"]').exists()).toBe(
|
|
149
|
+
false,
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
wrapper = factory({
|
|
153
|
+
disableClear: true,
|
|
154
|
+
options: [{ name: 'Last 7 days', id: 'last-7-days' }],
|
|
155
|
+
});
|
|
156
|
+
expect(wrapper.find('[data-testid="date-picker-clear"]').exists()).toBe(
|
|
157
|
+
false,
|
|
158
|
+
);
|
|
159
|
+
expect(wrapper.find('[data-testid="date-picker-submit"]').exists()).toBe(
|
|
160
|
+
true,
|
|
161
|
+
);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('navigates between months using navigation buttons', async () => {
|
|
165
|
+
const initialReference = wrapper.vm.referenceDate;
|
|
166
|
+
|
|
167
|
+
const nextButton = wrapper.find('[data-testid="date-picker-nav-right"]');
|
|
168
|
+
await nextButton.trigger('click');
|
|
169
|
+
|
|
170
|
+
expect(wrapper.vm.referenceDate).not.toBe(initialReference);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it('exposes i18n helper compatible with previous mixin', () => {
|
|
174
|
+
const text = wrapper.vm.i18n('clean', 'Clean');
|
|
175
|
+
expect(text).toBeTruthy();
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('computes previous-month period correctly based on periodBaseDate', () => {
|
|
179
|
+
const base = '2025-03-15';
|
|
180
|
+
wrapper = factory({
|
|
181
|
+
periodBaseDate: base,
|
|
182
|
+
options: [{ name: 'Previous month', id: 'previous-month' }],
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
const { startDate, endDate } =
|
|
186
|
+
wrapper.vm.getStartAndEndDateByPeriod('previous-month');
|
|
187
|
+
|
|
188
|
+
const baseDate = new Date(base);
|
|
189
|
+
const firstPrevMonth = new Date(
|
|
190
|
+
baseDate.getFullYear(),
|
|
191
|
+
baseDate.getMonth() - 1,
|
|
192
|
+
1,
|
|
193
|
+
);
|
|
194
|
+
const lastPrevMonth = new Date(
|
|
195
|
+
firstPrevMonth.getFullYear(),
|
|
196
|
+
firstPrevMonth.getMonth() + 1,
|
|
197
|
+
0,
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
const expectedStart = wrapper.vm.dateToString(firstPrevMonth);
|
|
201
|
+
const expectedEnd = wrapper.vm.dateToString(lastPrevMonth);
|
|
202
|
+
|
|
203
|
+
expect(startDate).toBe(expectedStart);
|
|
204
|
+
expect(endDate).toBe(expectedEnd);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it('marks dates outside minDate and maxDate as out of range', () => {
|
|
208
|
+
const min = '2025-02-10';
|
|
209
|
+
const max = '2025-02-20';
|
|
210
|
+
|
|
211
|
+
wrapper = factory({
|
|
212
|
+
minDate: min,
|
|
213
|
+
maxDate: max,
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
const [year, month] = min.split('-');
|
|
217
|
+
const reference = `${Number(month)} 1 ${year}`;
|
|
218
|
+
|
|
219
|
+
const dates = wrapper.vm.getDatesOfTheMonth(reference);
|
|
220
|
+
|
|
221
|
+
const hasOutOfRange = dates.some((d) =>
|
|
222
|
+
d.properties.includes('out of range'),
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
expect(hasOutOfRange).toBe(true);
|
|
226
|
+
});
|
|
227
|
+
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<Drawer
|
|
3
|
-
:open="modelValue"
|
|
4
|
-
@update:open="$emit('update:modelValue', $event)"
|
|
5
3
|
class="unnnic-drawer"
|
|
6
4
|
data-testid="drawer"
|
|
5
|
+
:open="modelValue"
|
|
6
|
+
@update:open="$emit('update:modelValue', $event)"
|
|
7
7
|
>
|
|
8
8
|
<DrawerContent
|
|
9
9
|
:showOverlay="!withoutOverlay"
|
|
@@ -96,6 +96,10 @@ import {
|
|
|
96
96
|
DrawerDescription,
|
|
97
97
|
} from '../ui/drawer';
|
|
98
98
|
|
|
99
|
+
defineOptions({
|
|
100
|
+
name: 'UnnnicDrawer',
|
|
101
|
+
});
|
|
102
|
+
|
|
99
103
|
const props = defineProps({
|
|
100
104
|
title: {
|
|
101
105
|
type: String,
|
|
@@ -10,12 +10,6 @@ describe('Drawer.vue', () => {
|
|
|
10
10
|
UnnnicIcon: true,
|
|
11
11
|
UnnnicButton: true,
|
|
12
12
|
Teleport: templateSlot,
|
|
13
|
-
Drawer: templateSlot,
|
|
14
|
-
DrawerContent: templateSlot,
|
|
15
|
-
DrawerFooter: templateSlot,
|
|
16
|
-
DrawerClose: templateSlot,
|
|
17
|
-
DrawerTitle: templateSlot,
|
|
18
|
-
DrawerDescription: templateSlot,
|
|
19
13
|
};
|
|
20
14
|
|
|
21
15
|
beforeEach(() => {
|
|
@@ -35,7 +29,7 @@ describe('Drawer.vue', () => {
|
|
|
35
29
|
|
|
36
30
|
const element = (id) => wrapper.find(`[data-testid="${id}"]`);
|
|
37
31
|
const component = (id) => wrapper.findComponent(`[data-testid="${id}"]`);
|
|
38
|
-
const
|
|
32
|
+
const drawerRoot = () => wrapper.findComponent({ name: 'UnnnicDrawerNext' });
|
|
39
33
|
const title = () => element('drawer-title');
|
|
40
34
|
const description = () => element('drawer-description');
|
|
41
35
|
const primaryButton = () => component('primary-button');
|
|
@@ -43,6 +37,8 @@ describe('Drawer.vue', () => {
|
|
|
43
37
|
const footer = () => element('footer');
|
|
44
38
|
const closeIcon = () => component('close-icon');
|
|
45
39
|
const drawerContainer = () => element('drawer-container');
|
|
40
|
+
const drawerContentComponent = () =>
|
|
41
|
+
wrapper.findComponent({ name: 'UnnnicDrawerContent' });
|
|
46
42
|
|
|
47
43
|
describe('Component Rendering', () => {
|
|
48
44
|
describe('Component Rendering', () => {
|
|
@@ -51,23 +47,21 @@ describe('Drawer.vue', () => {
|
|
|
51
47
|
});
|
|
52
48
|
|
|
53
49
|
it('should render the drawer when modelValue is true', () => {
|
|
54
|
-
expect(
|
|
50
|
+
expect(drawerRoot().props('open')).toBe(true);
|
|
55
51
|
});
|
|
56
52
|
|
|
57
53
|
it('should not render the drawer when modelValue is false', async () => {
|
|
58
54
|
await wrapper.setProps({ modelValue: false });
|
|
59
|
-
expect(
|
|
55
|
+
expect(drawerRoot().props('open')).toBe(false);
|
|
60
56
|
});
|
|
61
57
|
|
|
62
58
|
it('should render the overlay when withoutOverlay is false', () => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
expect(drawerContainer().attributes('showoverlay')).toBe('true');
|
|
59
|
+
expect(drawerContentComponent().props('showOverlay')).toBe(true);
|
|
66
60
|
});
|
|
67
61
|
|
|
68
62
|
it('should not render the overlay when withoutOverlay is true', async () => {
|
|
69
63
|
await wrapper.setProps({ withoutOverlay: true });
|
|
70
|
-
expect(
|
|
64
|
+
expect(drawerContentComponent().props('showOverlay')).toBe(false);
|
|
71
65
|
});
|
|
72
66
|
|
|
73
67
|
it('should display the title and description correctly', () => {
|
|
@@ -217,14 +211,16 @@ describe('Drawer.vue', () => {
|
|
|
217
211
|
describe('Props and Computed Properties', () => {
|
|
218
212
|
it('should render the correct size class based on size prop', async () => {
|
|
219
213
|
await wrapper.setProps({ size: 'lg' });
|
|
220
|
-
expect(
|
|
214
|
+
expect(drawerContentComponent().props('class')).toContain(
|
|
221
215
|
'unnnic-drawer__container--lg',
|
|
222
216
|
);
|
|
217
|
+
expect(drawerContentComponent().props('size')).toBe('large');
|
|
223
218
|
|
|
224
219
|
await wrapper.setProps({ size: 'xl' });
|
|
225
|
-
expect(
|
|
220
|
+
expect(drawerContentComponent().props('class')).toContain(
|
|
226
221
|
'unnnic-drawer__container--xl',
|
|
227
222
|
);
|
|
223
|
+
expect(drawerContentComponent().props('size')).toBe('extra-large');
|
|
228
224
|
});
|
|
229
225
|
|
|
230
226
|
it('should display footer if either primaryButtonText or secondaryButtonText is provided', async () => {
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
3
|
exports[`Drawer.vue > Component Rendering > Component Rendering > matches the snapshot 1`] = `
|
|
4
|
-
"<div data-v-196de012=""
|
|
5
|
-
<div data-v-
|
|
4
|
+
"<div data-v-e761d31f="" data-v-196de012="" disabled="false" defer="false" forcemount="false" data-testid="drawer-container">
|
|
5
|
+
<div data-v-7f241b30="" data-v-e761d31f="" data-state="open" style="pointer-events: auto;" data-vaul-overlay="" data-vaul-snap-points="false" data-vaul-snap-points-overlay="true" class="unnnic-drawer__overlay"></div>
|
|
6
|
+
<div data-v-e761d31f="" data-dismissable-layer="" style="--snap-point-height: 0; --initial-transform: calc(100% + 8px); pointer-events: auto;" tabindex="-1" data-vaul-drawer="" data-vaul-drawer-direction="right" data-vaul-delayed-snap-points="false" data-vaul-snap-points="false" size="medium" showoverlay="true" class="unnnic-drawer__content unnnic-drawer__content--medium unnnic-drawer__container unnnic-drawer__container--md" id="" role="dialog" aria-describedby="reka-dialog-description-v-1" aria-labelledby="reka-dialog-title-v-0" data-state="open">
|
|
6
7
|
<header data-v-39d0dfb8="" data-v-196de012="" class="unnnic-drawer__header unnnic-drawer__header">
|
|
7
8
|
<section data-v-196de012="" class="unnnic-drawer__title-container">
|
|
8
|
-
<
|
|
9
|
-
<
|
|
10
|
-
</section>
|
|
11
|
-
<div data-v-196de012="">
|
|
9
|
+
<h2 data-v-97709962="" data-v-196de012="" id="reka-dialog-title-v-0" class="unnnic-drawer__title unnnic-drawer__title" data-testid="drawer-title">Test Title</h2>
|
|
10
|
+
<p data-v-750ea255="" data-v-196de012="" id="reka-dialog-description-v-1" class="unnnic-drawer__description unnnic-drawer__description" data-testid="drawer-description">Test Description</p>
|
|
11
|
+
</section><button data-v-4a771f40="" data-v-196de012="" type="button" class="unnnic-drawer__close">
|
|
12
12
|
<unnnic-button-stub data-v-196de012="" size="small" text="" type="tertiary" float="false" iconleft="" iconright="" iconcenter="arrow_forward" iconsfilled="false" disabled="false" loading="false" class="unnnic-drawer__close-icon" data-testid="close-icon"></unnnic-button-stub>
|
|
13
|
-
</
|
|
13
|
+
</button>
|
|
14
14
|
</header>
|
|
15
15
|
<section data-v-196de012="" class="unnnic-drawer__content"></section>
|
|
16
|
-
<
|
|
16
|
+
<footer data-v-02ebc5b4="" data-v-196de012="" class="unnnic-drawer__footer unnnic-drawer__footer" data-testid="footer">
|
|
17
17
|
<unnnic-button-stub data-v-196de012="" size="large" text="Secondary Action" type="tertiary" float="false" iconleft="" iconright="" iconcenter="" iconsfilled="false" disabled="false" loading="false" data-testid="secondary-button"></unnnic-button-stub>
|
|
18
18
|
<unnnic-button-stub data-v-196de012="" size="large" text="Primary Action" type="primary" float="false" iconleft="" iconright="" iconcenter="" iconsfilled="false" disabled="false" loading="false" data-testid="primary-button"></unnnic-button-stub>
|
|
19
|
-
</
|
|
19
|
+
</footer>
|
|
20
20
|
</div>
|
|
21
21
|
</div>"
|
|
22
22
|
`;
|