@weni/unnnic-system 3.13.0 → 3.14.0-alpha-teleports.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.
- package/CHANGELOG.md +7 -0
- package/README.md +9 -1
- package/dist/{es-41fceca9.mjs → es-0d53b5b2.mjs} +1 -1
- package/dist/{index-cca96b43.mjs → index-d7070de8.mjs} +29952 -27094
- package/dist/index.d.ts +5111 -1770
- package/dist/{pt-br-a3088529.mjs → pt-br-bf4e1f97.mjs} +1 -1
- package/dist/style.css +1 -1
- package/dist/unnnic.mjs +232 -204
- package/dist/unnnic.umd.js +48 -44
- package/package.json +3 -2
- package/src/assets/scss/tailwind.scss +8 -0
- package/src/components/Alert/__tests__/__snapshots__/Alert.spec.js.snap +1 -1
- package/src/components/ChartFunnel/DefaultFunnel/ChartDefaultFunnelBase.vue +2 -1
- package/src/components/ChartFunnel/SvgFunnel/ChartFunnelTwoRows.vue +61 -60
- package/src/components/Checkbox/Checkbox.vue +1 -1
- package/src/components/CheckboxGroup/CheckboxGroup.vue +5 -7
- package/src/components/Chip/Chip.vue +1 -1
- package/src/components/DatePicker/DatePicker.vue +10 -1
- package/src/components/Drawer/Drawer.vue +180 -270
- package/src/components/Drawer/__tests__/Drawer.spec.js +32 -43
- package/src/components/Drawer/__tests__/__snapshots__/Drawer.spec.js.snap +18 -19
- package/src/components/FormElement/FormElement.vue +87 -96
- package/src/components/InputDatePicker/InputDatePicker.vue +68 -73
- package/src/components/InputDatePicker/__test__/InputDatePicker.spec.js +31 -24
- package/src/components/ModalDialog/ModalDialog.vue +63 -154
- package/src/components/ModalDialog/__tests__/ModalDialog.spec.js +30 -210
- package/src/components/ModalDialog/__tests__/__snapshots__/ModalDialog.spec.js.snap +1 -22
- package/src/components/MultiSelect/MultSelectOption.vue +49 -0
- package/src/components/MultiSelect/__tests__/MultiSelect.spec.js +557 -0
- package/src/components/MultiSelect/__tests__/MultiSelectOption.spec.js +229 -0
- package/src/components/MultiSelect/__tests__/__snapshots__/MultiSelect.spec.js.snap +87 -0
- package/src/components/MultiSelect/__tests__/__snapshots__/MultiSelectOption.spec.js.snap +51 -0
- package/src/components/MultiSelect/index.vue +265 -0
- package/src/components/Radio/Radio.vue +6 -12
- package/src/components/Radio/__test__/Radio.spec.js +1 -3
- package/src/components/RadioGroup/RadioGroup.vue +10 -18
- package/src/components/Select/__tests__/SelectItem.spec.js +15 -35
- package/src/components/Select/index.vue +3 -3
- package/src/components/Switch/Switch.vue +3 -10
- package/src/components/Tab/__test__/__snapshots__/Tab.spec.js.snap +3 -1
- package/src/components/TemplatePreview/TemplatePreview.vue +25 -28
- package/src/components/TemplatePreview/TemplatePreviewModal.vue +10 -10
- package/src/components/TemplatePreview/types.d.ts +3 -3
- package/src/components/Toast/Toast.vue +4 -1
- package/src/components/Toast/ToastManager.ts +4 -1
- package/src/components/Toast/__tests__/ToastManager.spec.js +10 -6
- package/src/components/ToolTip/ToolTip.vue +25 -177
- package/src/components/ToolTip/__tests__/ToolTip.spec.js +339 -61
- package/src/components/index.ts +58 -2
- package/src/components/ui/dialog/Dialog.vue +19 -0
- package/src/components/ui/dialog/DialogClose.vue +29 -0
- package/src/components/ui/dialog/DialogContent.vue +140 -0
- package/src/components/ui/dialog/DialogFooter.vue +50 -0
- package/src/components/ui/dialog/DialogHeader.vue +83 -0
- package/src/components/ui/dialog/DialogTitle.vue +38 -0
- package/src/components/ui/dialog/DialogTrigger.vue +16 -0
- package/src/components/ui/dialog/index.ts +7 -0
- package/src/components/ui/drawer/Drawer.vue +27 -0
- package/src/components/ui/drawer/DrawerClose.vue +31 -0
- package/src/components/ui/drawer/DrawerContent.vue +113 -0
- package/src/components/ui/drawer/DrawerDescription.vue +40 -0
- package/src/components/ui/drawer/DrawerFooter.vue +38 -0
- package/src/components/ui/drawer/DrawerHeader.vue +57 -0
- package/src/components/ui/drawer/DrawerOverlay.vue +33 -0
- package/src/components/ui/drawer/DrawerTitle.vue +37 -0
- package/src/components/ui/drawer/DrawerTrigger.vue +31 -0
- package/src/components/ui/drawer/index.ts +10 -0
- package/src/components/ui/popover/PopoverContent.vue +7 -4
- package/src/components/ui/popover/PopoverTrigger.vue +5 -1
- package/src/components/ui/tooltip/Tooltip.vue +21 -0
- package/src/components/ui/tooltip/TooltipContent.vue +77 -0
- package/src/components/ui/tooltip/TooltipTrigger.vue +24 -0
- package/src/components/ui/tooltip/index.ts +3 -0
- package/src/index.ts +9 -2
- package/src/lib/__tests__/teleport-target.spec.ts +73 -0
- package/src/lib/layer-manager.ts +64 -0
- package/src/lib/teleport-target.ts +46 -0
- package/src/stories/Dialog.stories.js +832 -0
- package/src/stories/Drawer.stories.js +1 -1
- package/src/stories/DrawerNext.stories.js +611 -0
- package/src/stories/LayerManager.docs.mdx +40 -0
- package/src/stories/LayerManager.stories.js +407 -0
- package/src/stories/ModalDialog.mdx +3 -0
- package/src/stories/ModalDialog.stories.js +96 -1
- package/src/stories/MultiSelect.stories.js +143 -45
- package/src/stories/TemplatePreview.stories.js +27 -27
- package/src/stories/TemplatePreviewModal.stories.js +31 -31
- package/src/components/MultiSelect/MultiSelect.vue +0 -297
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
:
|
|
5
|
-
|
|
6
|
-
'force-open': forceOpen,
|
|
7
|
-
}"
|
|
8
|
-
@mouseover="handleResize"
|
|
2
|
+
<Tooltip
|
|
3
|
+
:disabled="!(enabled || forceOpen)"
|
|
4
|
+
:open="forceOpen || undefined"
|
|
5
|
+
data-testid="tooltip-wrapper"
|
|
9
6
|
>
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
<TooltipTrigger data-testid="tooltip-trigger">
|
|
8
|
+
<slot />
|
|
9
|
+
</TooltipTrigger>
|
|
10
|
+
|
|
11
|
+
<TooltipContent
|
|
14
12
|
:class="['unnnic-tooltip-label', `unnnic-tooltip-label-${side}`]"
|
|
15
|
-
:style="{ maxWidth: maxWidth
|
|
16
|
-
|
|
13
|
+
:style="{ maxWidth: maxWidth }"
|
|
14
|
+
:side="side"
|
|
15
|
+
data-testid="tooltip-content"
|
|
17
16
|
>
|
|
18
17
|
<template v-if="enableHtml">
|
|
19
18
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
|
20
|
-
<section
|
|
19
|
+
<section
|
|
20
|
+
v-html="text"
|
|
21
|
+
data-testid="tooltip-html-content"
|
|
22
|
+
></section>
|
|
21
23
|
</template>
|
|
22
24
|
<template
|
|
23
25
|
v-for="(line, index) in text.split('\n')"
|
|
@@ -27,22 +29,20 @@
|
|
|
27
29
|
{{ line }}
|
|
28
30
|
<br />
|
|
29
31
|
</template>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
<span
|
|
33
|
-
class="unnnic-tooltip-label-shortcut"
|
|
34
|
-
data-testid="tooltip-label-shortcut"
|
|
35
|
-
>
|
|
36
|
-
{{ shortcutText }}
|
|
37
|
-
</span>
|
|
38
|
-
</template>
|
|
39
|
-
</span>
|
|
40
|
-
</div>
|
|
32
|
+
</TooltipContent>
|
|
33
|
+
</Tooltip>
|
|
41
34
|
</template>
|
|
42
35
|
|
|
43
36
|
<script>
|
|
37
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip';
|
|
38
|
+
|
|
44
39
|
export default {
|
|
45
40
|
name: 'UnnnicTooltip',
|
|
41
|
+
components: {
|
|
42
|
+
Tooltip,
|
|
43
|
+
TooltipTrigger,
|
|
44
|
+
TooltipContent,
|
|
45
|
+
},
|
|
46
46
|
props: {
|
|
47
47
|
text: {
|
|
48
48
|
type: String,
|
|
@@ -67,162 +67,10 @@ export default {
|
|
|
67
67
|
type: String,
|
|
68
68
|
default: '',
|
|
69
69
|
},
|
|
70
|
-
shortcutText: {
|
|
71
|
-
type: String,
|
|
72
|
-
default: null,
|
|
73
|
-
},
|
|
74
70
|
enableHtml: {
|
|
75
71
|
type: Boolean,
|
|
76
72
|
default: false,
|
|
77
73
|
},
|
|
78
74
|
},
|
|
79
|
-
data() {
|
|
80
|
-
return {
|
|
81
|
-
topPos: null,
|
|
82
|
-
leftPos: null,
|
|
83
|
-
};
|
|
84
|
-
},
|
|
85
|
-
watch: {
|
|
86
|
-
side() {
|
|
87
|
-
this.getRightPost(this.$refs.tooltip);
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
mounted() {
|
|
91
|
-
this.handleResize();
|
|
92
|
-
|
|
93
|
-
window.addEventListener('scroll', this.handleResize);
|
|
94
|
-
window.addEventListener('resize', this.handleResize);
|
|
95
|
-
},
|
|
96
|
-
unmounted() {
|
|
97
|
-
window.removeEventListener('scroll', this.handleResize);
|
|
98
|
-
window.removeEventListener('resize', this.handleResize);
|
|
99
|
-
},
|
|
100
|
-
methods: {
|
|
101
|
-
handleResize() {
|
|
102
|
-
this.getRightPost(this.$refs.tooltip);
|
|
103
|
-
},
|
|
104
|
-
getRightPost(element) {
|
|
105
|
-
const elementPos = element.getBoundingClientRect();
|
|
106
|
-
|
|
107
|
-
if (element && this.$refs.label) {
|
|
108
|
-
if (this.side === 'right') {
|
|
109
|
-
this.leftPos = `${elementPos.x + elementPos.width + 8}px`;
|
|
110
|
-
this.topPos = `${elementPos.y + elementPos.height / 2 - this.$refs.label.offsetHeight / 2}px`;
|
|
111
|
-
} else if (this.side === 'left') {
|
|
112
|
-
this.leftPos = `${elementPos.x - this.$refs.label.offsetWidth - 8}px`;
|
|
113
|
-
this.topPos = `${elementPos.y + elementPos.height / 2 - this.$refs.label.offsetHeight / 2}px`;
|
|
114
|
-
} else if (this.side === 'top') {
|
|
115
|
-
this.leftPos = `${elementPos.x + elementPos.width / 2 - this.$refs.label.clientWidth / 2}px`;
|
|
116
|
-
this.topPos = `${elementPos.y - this.$refs.label.offsetHeight - 8}px`;
|
|
117
|
-
} else if (this.side === 'bottom') {
|
|
118
|
-
this.leftPos = `${elementPos.x + elementPos.width / 2 - this.$refs.label.clientWidth / 2}px`;
|
|
119
|
-
this.topPos = `${elementPos.y + elementPos.height + 8}px`;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
75
|
};
|
|
125
76
|
</script>
|
|
126
|
-
|
|
127
|
-
<style lang="scss" scoped>
|
|
128
|
-
@use '@/assets/scss/unnnic' as *;
|
|
129
|
-
|
|
130
|
-
.unnnic-tooltip {
|
|
131
|
-
position: relative;
|
|
132
|
-
display: inline-block;
|
|
133
|
-
overflow-wrap: break-word;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
.unnnic-tooltip-label {
|
|
137
|
-
z-index: 1;
|
|
138
|
-
visibility: hidden;
|
|
139
|
-
text-align: center;
|
|
140
|
-
position: fixed;
|
|
141
|
-
width: max-content;
|
|
142
|
-
min-width: 2 * $unnnic-font-size;
|
|
143
|
-
box-sizing: border-box;
|
|
144
|
-
width: auto;
|
|
145
|
-
display: flex;
|
|
146
|
-
justify-content: center;
|
|
147
|
-
gap: $unnnic-spacing-xs;
|
|
148
|
-
align-items: center;
|
|
149
|
-
|
|
150
|
-
background-color: $unnnic-color-neutral-black;
|
|
151
|
-
color: $unnnic-color-neutral-snow;
|
|
152
|
-
border-radius: $unnnic-border-radius-sm;
|
|
153
|
-
padding: $unnnic-inset-nano;
|
|
154
|
-
box-shadow: $unnnic-shadow-level-near;
|
|
155
|
-
font-size: $unnnic-font-size-body-md;
|
|
156
|
-
font-family: $unnnic-font-family-secondary;
|
|
157
|
-
font-weight: $unnnic-font-weight-regular;
|
|
158
|
-
line-height: ($unnnic-font-size-body-md + $unnnic-line-height-medium);
|
|
159
|
-
|
|
160
|
-
&::after {
|
|
161
|
-
content: '';
|
|
162
|
-
position: absolute;
|
|
163
|
-
border-width: 5px;
|
|
164
|
-
border-style: solid;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
&-top {
|
|
168
|
-
position: fixed;
|
|
169
|
-
&::after {
|
|
170
|
-
top: 100%;
|
|
171
|
-
left: 50%;
|
|
172
|
-
margin-left: -5px;
|
|
173
|
-
border-color: $unnnic-color-neutral-black transparent transparent
|
|
174
|
-
transparent;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
&-bottom {
|
|
179
|
-
position: fixed;
|
|
180
|
-
&::after {
|
|
181
|
-
bottom: 100%;
|
|
182
|
-
left: 50%;
|
|
183
|
-
margin-left: -5px;
|
|
184
|
-
border-color: transparent transparent $unnnic-color-neutral-black
|
|
185
|
-
transparent;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
&-right {
|
|
189
|
-
position: fixed;
|
|
190
|
-
&::after {
|
|
191
|
-
top: 50%;
|
|
192
|
-
right: 100%;
|
|
193
|
-
margin-top: -5px;
|
|
194
|
-
border-color: transparent $unnnic-color-neutral-black transparent
|
|
195
|
-
transparent;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
&-left {
|
|
199
|
-
position: fixed;
|
|
200
|
-
&::after {
|
|
201
|
-
top: 50%;
|
|
202
|
-
left: 100%;
|
|
203
|
-
margin-top: -5px;
|
|
204
|
-
border-color: transparent transparent transparent
|
|
205
|
-
$unnnic-color-neutral-black;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
&-shortcut {
|
|
210
|
-
background-color: $unnnic-color-neutral-darkest;
|
|
211
|
-
border-radius: $unnnic-border-radius-sm;
|
|
212
|
-
padding: calc($unnnic-inset-nano / 2) $unnnic-inset-nano;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
.unnnic-tooltip.force-open {
|
|
217
|
-
.unnnic-tooltip-label {
|
|
218
|
-
visibility: visible;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
.unnnic-tooltip:hover {
|
|
223
|
-
.unnnic-tooltip-label {
|
|
224
|
-
visibility: visible;
|
|
225
|
-
width: auto;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
</style>
|
|
@@ -3,102 +3,380 @@ import { mount } from '@vue/test-utils';
|
|
|
3
3
|
|
|
4
4
|
import ToolTip from '../ToolTip.vue';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
globalThis.ResizeObserver = vi.fn().mockImplementation(() => ({
|
|
7
|
+
observe: vi.fn(),
|
|
8
|
+
unobserve: vi.fn(),
|
|
9
|
+
disconnect: vi.fn(),
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
const createWrapper = (props = {}, slots = {}) => {
|
|
13
|
+
return mount(ToolTip, {
|
|
14
|
+
props,
|
|
15
|
+
slots: {
|
|
16
|
+
default: '<button data-testid="trigger-button">Hover me</button>',
|
|
17
|
+
...slots,
|
|
18
|
+
},
|
|
19
|
+
attachTo: document.body,
|
|
20
|
+
global: {
|
|
21
|
+
stubs: {
|
|
22
|
+
teleport: true,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
});
|
|
8
26
|
};
|
|
9
27
|
|
|
10
28
|
describe('ToolTip', () => {
|
|
11
29
|
let wrapper;
|
|
30
|
+
|
|
12
31
|
beforeEach(() => {
|
|
13
|
-
wrapper = createWrapper({ text: '
|
|
32
|
+
wrapper = createWrapper({ text: 'Tooltip text', enabled: true });
|
|
14
33
|
});
|
|
15
34
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
35
|
+
afterEach(() => {
|
|
36
|
+
if (wrapper) {
|
|
37
|
+
wrapper.unmount();
|
|
38
|
+
}
|
|
20
39
|
});
|
|
21
40
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
41
|
+
describe('Component Rendering', () => {
|
|
42
|
+
it('should render the component', () => {
|
|
43
|
+
expect(wrapper.exists()).toBe(true);
|
|
44
|
+
expect(wrapper.vm).toBeTruthy();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should render slot content', () => {
|
|
48
|
+
const triggerButton = wrapper.find('[data-testid="trigger-button"]');
|
|
49
|
+
expect(triggerButton.exists()).toBe(true);
|
|
50
|
+
expect(triggerButton.text()).toBe('Hover me');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('should render custom slot content', () => {
|
|
54
|
+
const customWrapper = createWrapper(
|
|
55
|
+
{ text: 'Tooltip text', enabled: true },
|
|
56
|
+
{
|
|
57
|
+
default: '<span data-testid="custom-trigger">Custom Content</span>',
|
|
58
|
+
},
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const customTrigger = customWrapper.find(
|
|
62
|
+
'[data-testid="custom-trigger"]',
|
|
63
|
+
);
|
|
64
|
+
expect(customTrigger.exists()).toBe(true);
|
|
65
|
+
expect(customTrigger.text()).toBe('Custom Content');
|
|
66
|
+
|
|
67
|
+
customWrapper.unmount();
|
|
68
|
+
});
|
|
25
69
|
});
|
|
26
70
|
|
|
27
|
-
|
|
28
|
-
|
|
71
|
+
describe('Props', () => {
|
|
72
|
+
it('should accept text prop', () => {
|
|
73
|
+
expect(wrapper.vm.$props.text).toBe('Tooltip text');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should accept enabled prop', () => {
|
|
77
|
+
expect(wrapper.vm.$props.enabled).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should accept forceOpen prop', () => {
|
|
81
|
+
const testWrapper = createWrapper({ text: 'Text', forceOpen: true });
|
|
82
|
+
expect(testWrapper.vm.$props.forceOpen).toBe(true);
|
|
83
|
+
testWrapper.unmount();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should accept side prop with valid values', () => {
|
|
87
|
+
const sides = ['top', 'right', 'bottom', 'left'];
|
|
88
|
+
|
|
89
|
+
sides.forEach((side) => {
|
|
90
|
+
const sideWrapper = createWrapper({
|
|
91
|
+
text: 'Text',
|
|
92
|
+
enabled: true,
|
|
93
|
+
side,
|
|
94
|
+
});
|
|
95
|
+
expect(sideWrapper.vm.$props.side).toBe(side);
|
|
96
|
+
sideWrapper.unmount();
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should default to "right" side when not specified', () => {
|
|
101
|
+
expect(wrapper.vm.$props.side).toBe('right');
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('should accept maxWidth prop', () => {
|
|
105
|
+
const maxWidthWrapper = createWrapper({
|
|
106
|
+
text: 'Text',
|
|
107
|
+
enabled: true,
|
|
108
|
+
maxWidth: '200px',
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
expect(maxWidthWrapper.vm.$props.maxWidth).toBe('200px');
|
|
29
112
|
|
|
30
|
-
|
|
31
|
-
|
|
113
|
+
maxWidthWrapper.unmount();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should accept enableHtml prop', () => {
|
|
117
|
+
const htmlWrapper = createWrapper({
|
|
118
|
+
text: 'Text',
|
|
119
|
+
enableHtml: true,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
expect(htmlWrapper.vm.$props.enableHtml).toBe(true);
|
|
123
|
+
|
|
124
|
+
htmlWrapper.unmount();
|
|
125
|
+
});
|
|
32
126
|
});
|
|
33
127
|
|
|
34
|
-
|
|
35
|
-
|
|
128
|
+
describe('Boolean Props', () => {
|
|
129
|
+
it('should handle enabled false', () => {
|
|
130
|
+
const disabledWrapper = createWrapper({
|
|
131
|
+
text: 'Text',
|
|
132
|
+
enabled: false,
|
|
133
|
+
});
|
|
36
134
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
135
|
+
expect(disabledWrapper.vm.$props.enabled).toBe(false);
|
|
136
|
+
|
|
137
|
+
disabledWrapper.unmount();
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should handle forceOpen true', () => {
|
|
141
|
+
const forceOpenWrapper = createWrapper({
|
|
142
|
+
text: 'Text',
|
|
143
|
+
enabled: false,
|
|
144
|
+
forceOpen: true,
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
expect(forceOpenWrapper.vm.$props.forceOpen).toBe(true);
|
|
148
|
+
|
|
149
|
+
forceOpenWrapper.unmount();
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('should handle enableHtml false', () => {
|
|
153
|
+
expect(wrapper.vm.$props.enableHtml).toBe(false);
|
|
154
|
+
});
|
|
42
155
|
});
|
|
43
156
|
|
|
44
|
-
|
|
45
|
-
|
|
157
|
+
describe('Text Content Rendering', () => {
|
|
158
|
+
it('should accept plain text content via prop', () => {
|
|
159
|
+
const plainWrapper = createWrapper({
|
|
160
|
+
text: 'Simple tooltip text',
|
|
161
|
+
enabled: true,
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
expect(plainWrapper.vm.$props.text).toBe('Simple tooltip text');
|
|
165
|
+
|
|
166
|
+
plainWrapper.unmount();
|
|
167
|
+
});
|
|
46
168
|
|
|
47
|
-
|
|
169
|
+
it('should accept multiline text via prop', () => {
|
|
170
|
+
const multilineWrapper = createWrapper({
|
|
171
|
+
text: 'First line\nSecond line\nThird line',
|
|
172
|
+
enabled: true,
|
|
173
|
+
});
|
|
48
174
|
|
|
49
|
-
|
|
50
|
-
|
|
175
|
+
expect(multilineWrapper.vm.$props.text).toBe(
|
|
176
|
+
'First line\nSecond line\nThird line',
|
|
177
|
+
);
|
|
51
178
|
|
|
52
|
-
|
|
53
|
-
|
|
179
|
+
multilineWrapper.unmount();
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('should handle empty text', () => {
|
|
183
|
+
const emptyWrapper = createWrapper({ text: '', enabled: true });
|
|
184
|
+
|
|
185
|
+
expect(emptyWrapper.vm.$props.text).toBe('');
|
|
186
|
+
expect(emptyWrapper.exists()).toBe(true);
|
|
187
|
+
|
|
188
|
+
emptyWrapper.unmount();
|
|
189
|
+
});
|
|
54
190
|
});
|
|
55
191
|
|
|
56
|
-
|
|
57
|
-
|
|
192
|
+
describe('HTML Content', () => {
|
|
193
|
+
it('should accept HTML text with enableHtml prop set to true', () => {
|
|
194
|
+
const htmlWrapper = createWrapper({
|
|
195
|
+
enableHtml: true,
|
|
196
|
+
enabled: true,
|
|
197
|
+
text: 'Tooltip with <strong>bold</strong> text',
|
|
198
|
+
});
|
|
58
199
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
200
|
+
expect(htmlWrapper.vm.$props.enableHtml).toBe(true);
|
|
201
|
+
expect(htmlWrapper.vm.$props.text).toBe(
|
|
202
|
+
'Tooltip with <strong>bold</strong> text',
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
htmlWrapper.unmount();
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('should accept HTML link with enableHtml prop', () => {
|
|
209
|
+
const linkWrapper = createWrapper({
|
|
210
|
+
enableHtml: true,
|
|
211
|
+
enabled: true,
|
|
212
|
+
text: 'Visit <a href="https://weni.ai/" target="_blank">Weni</a>',
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
expect(linkWrapper.vm.$props.enableHtml).toBe(true);
|
|
216
|
+
expect(linkWrapper.vm.$props.text).toContain('href="https://weni.ai/"');
|
|
217
|
+
expect(linkWrapper.vm.$props.text).toContain('target="_blank"');
|
|
218
|
+
|
|
219
|
+
linkWrapper.unmount();
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it('should handle plain text when enableHtml is false', () => {
|
|
223
|
+
const plainWrapper = createWrapper({
|
|
224
|
+
enableHtml: false,
|
|
225
|
+
enabled: true,
|
|
226
|
+
text: 'Tooltip with <strong>bold</strong> text',
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
expect(plainWrapper.vm.$props.enableHtml).toBe(false);
|
|
230
|
+
expect(plainWrapper.vm.$props.text).toBe(
|
|
231
|
+
'Tooltip with <strong>bold</strong> text',
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
plainWrapper.unmount();
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
describe('Component Structure', () => {
|
|
239
|
+
it('should have Tooltip component', () => {
|
|
240
|
+
expect(wrapper.findComponent({ name: 'Tooltip' }).exists()).toBe(true);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('should have TooltipTrigger component', () => {
|
|
244
|
+
expect(wrapper.findComponent({ name: 'TooltipTrigger' }).exists()).toBe(
|
|
245
|
+
true,
|
|
246
|
+
);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('should have TooltipContent component', () => {
|
|
250
|
+
expect(wrapper.findComponent({ name: 'TooltipContent' }).exists()).toBe(
|
|
251
|
+
true,
|
|
252
|
+
);
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
describe('CSS Classes', () => {
|
|
257
|
+
it('should pass side prop to TooltipContent', () => {
|
|
258
|
+
const sides = ['top', 'right', 'bottom', 'left'];
|
|
259
|
+
|
|
260
|
+
sides.forEach((side) => {
|
|
261
|
+
const sideWrapper = createWrapper({
|
|
262
|
+
text: 'Text',
|
|
263
|
+
enabled: true,
|
|
264
|
+
side,
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
const tooltipContent = sideWrapper.findComponent({
|
|
268
|
+
name: 'TooltipContent',
|
|
269
|
+
});
|
|
270
|
+
expect(tooltipContent.exists()).toBe(true);
|
|
271
|
+
expect(tooltipContent.props('side')).toBe(side);
|
|
272
|
+
|
|
273
|
+
sideWrapper.unmount();
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('should pass class prop to TooltipContent component', () => {
|
|
278
|
+
const tooltipContent = wrapper.findComponent({ name: 'TooltipContent' });
|
|
279
|
+
expect(tooltipContent.exists()).toBe(true);
|
|
280
|
+
expect(tooltipContent.props('class')).toContain('unnnic-tooltip-label');
|
|
281
|
+
});
|
|
64
282
|
});
|
|
65
283
|
|
|
66
|
-
|
|
67
|
-
|
|
284
|
+
describe('Side Validator', () => {
|
|
285
|
+
it('should validate side prop correctly', () => {
|
|
286
|
+
const validator = wrapper.vm.$options.props.side.validator;
|
|
287
|
+
|
|
288
|
+
expect(validator('top')).toBe(true);
|
|
289
|
+
expect(validator('right')).toBe(true);
|
|
290
|
+
expect(validator('bottom')).toBe(true);
|
|
291
|
+
expect(validator('left')).toBe(true);
|
|
292
|
+
expect(validator('invalid')).toBe(false);
|
|
293
|
+
});
|
|
294
|
+
});
|
|
68
295
|
|
|
69
|
-
|
|
296
|
+
describe('Props Defaults', () => {
|
|
297
|
+
it('should have correct default values', () => {
|
|
298
|
+
const defaultWrapper = createWrapper();
|
|
70
299
|
|
|
71
|
-
|
|
72
|
-
|
|
300
|
+
expect(defaultWrapper.vm.$props.text).toBe('');
|
|
301
|
+
expect(defaultWrapper.vm.$props.enabled).toBe(false);
|
|
302
|
+
expect(defaultWrapper.vm.$props.forceOpen).toBe(false);
|
|
303
|
+
expect(defaultWrapper.vm.$props.side).toBe('right');
|
|
304
|
+
expect(defaultWrapper.vm.$props.maxWidth).toBe('');
|
|
305
|
+
expect(defaultWrapper.vm.$props.enableHtml).toBe(false);
|
|
306
|
+
|
|
307
|
+
defaultWrapper.unmount();
|
|
308
|
+
});
|
|
73
309
|
});
|
|
74
310
|
|
|
75
|
-
|
|
76
|
-
|
|
311
|
+
describe('Max Width Style', () => {
|
|
312
|
+
it('should pass maxWidth prop to TooltipContent', () => {
|
|
313
|
+
const maxWidthWrapper = createWrapper({
|
|
314
|
+
text: 'Text',
|
|
315
|
+
enabled: true,
|
|
316
|
+
maxWidth: '250px',
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
expect(maxWidthWrapper.vm.$props.maxWidth).toBe('250px');
|
|
320
|
+
|
|
321
|
+
maxWidthWrapper.unmount();
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it('should handle different maxWidth values', () => {
|
|
325
|
+
const values = ['100px', '50%', '20rem', '300px'];
|
|
326
|
+
|
|
327
|
+
values.forEach((maxWidth) => {
|
|
328
|
+
const testWrapper = createWrapper({
|
|
329
|
+
text: 'Text',
|
|
330
|
+
enabled: true,
|
|
331
|
+
maxWidth,
|
|
332
|
+
});
|
|
77
333
|
|
|
78
|
-
|
|
334
|
+
expect(testWrapper.vm.$props.maxWidth).toBe(maxWidth);
|
|
79
335
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
);
|
|
84
|
-
expect(removeEventListenerSpy).toHaveBeenCalledWith(
|
|
85
|
-
'resize',
|
|
86
|
-
expect.any(Function),
|
|
87
|
-
);
|
|
336
|
+
testWrapper.unmount();
|
|
337
|
+
});
|
|
338
|
+
});
|
|
88
339
|
});
|
|
89
340
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
341
|
+
describe('Component Props Types', () => {
|
|
342
|
+
it('should have correct prop types', () => {
|
|
343
|
+
const { props } = wrapper.vm.$options;
|
|
344
|
+
|
|
345
|
+
expect(props.text.type).toBe(String);
|
|
346
|
+
expect(props.enabled.type).toBe(Boolean);
|
|
347
|
+
expect(props.forceOpen.type).toBe(Boolean);
|
|
348
|
+
expect(props.side.type).toBe(String);
|
|
349
|
+
expect(props.maxWidth.type).toBe(String);
|
|
350
|
+
expect(props.enableHtml.type).toBe(Boolean);
|
|
351
|
+
});
|
|
94
352
|
});
|
|
95
353
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
354
|
+
describe('Enabled and ForceOpen Logic', () => {
|
|
355
|
+
it('should be disabled when enabled is false and forceOpen is false', () => {
|
|
356
|
+
const disabledWrapper = createWrapper({
|
|
357
|
+
text: 'Text',
|
|
358
|
+
enabled: false,
|
|
359
|
+
forceOpen: false,
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
expect(disabledWrapper.vm.$props.enabled).toBe(false);
|
|
363
|
+
expect(disabledWrapper.vm.$props.forceOpen).toBe(false);
|
|
364
|
+
|
|
365
|
+
disabledWrapper.unmount();
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
it('should override disabled state when forceOpen is true', () => {
|
|
369
|
+
const forceOpenWrapper = createWrapper({
|
|
370
|
+
text: 'Text',
|
|
371
|
+
enabled: false,
|
|
372
|
+
forceOpen: true,
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
expect(forceOpenWrapper.vm.$props.enabled).toBe(false);
|
|
376
|
+
expect(forceOpenWrapper.vm.$props.forceOpen).toBe(true);
|
|
377
|
+
expect(forceOpenWrapper.html()).toContain('unnnic-tooltip');
|
|
378
|
+
|
|
379
|
+
forceOpenWrapper.unmount();
|
|
100
380
|
});
|
|
101
|
-
const link = wrapper.find('a[data-testid="weni-link"]');
|
|
102
|
-
expect(link.exists()).toBeTruthy();
|
|
103
381
|
});
|
|
104
382
|
});
|