@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
|
@@ -43,9 +43,7 @@ describe('Radio.vue', () => {
|
|
|
43
43
|
|
|
44
44
|
test('applies disabled class when disabled prop is true', async () => {
|
|
45
45
|
await wrapper.setProps({ disabled: true });
|
|
46
|
-
expect(wrapper.find('.unnnic-radio__label').classes()).toContain(
|
|
47
|
-
'unnnic-radio__label--disabled',
|
|
48
|
-
);
|
|
46
|
+
expect(wrapper.find('.unnnic-radio__label').classes()).toContain('unnnic-radio__label--disabled');
|
|
49
47
|
});
|
|
50
48
|
|
|
51
49
|
test('icon changes based on valueName', async () => {
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<section
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
]"
|
|
7
|
-
>
|
|
2
|
+
<section :class="[
|
|
3
|
+
'unnnic-radio-group__container',
|
|
4
|
+
`unnnic-radio-group--state-${state}`
|
|
5
|
+
]">
|
|
8
6
|
<UnnnicLabel
|
|
9
7
|
v-if="label"
|
|
10
8
|
:label="label"
|
|
@@ -70,14 +68,11 @@ const emit = defineEmits(['update:modelValue']);
|
|
|
70
68
|
|
|
71
69
|
const contextModelValue = ref(props.modelValue);
|
|
72
70
|
|
|
73
|
-
watch(
|
|
74
|
-
(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
);
|
|
71
|
+
watch(() => props.modelValue, (newVal) => {
|
|
72
|
+
if (newVal !== contextModelValue.value) {
|
|
73
|
+
contextModelValue.value = newVal;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
81
76
|
|
|
82
77
|
watch(contextModelValue, (newVal) => {
|
|
83
78
|
if (newVal !== props.modelValue) {
|
|
@@ -86,10 +81,7 @@ watch(contextModelValue, (newVal) => {
|
|
|
86
81
|
});
|
|
87
82
|
|
|
88
83
|
const computedName = computed(() => {
|
|
89
|
-
return (
|
|
90
|
-
props.name ||
|
|
91
|
-
`unnnic-radio-group-${Math.random().toString(36).substring(2, 15)}`
|
|
92
|
-
);
|
|
84
|
+
return props.name || `unnnic-radio-group-${Math.random().toString(36).substring(2, 15)}`;
|
|
93
85
|
});
|
|
94
86
|
|
|
95
87
|
provide('contextModelValue', contextModelValue);
|
|
@@ -3,9 +3,9 @@ import { beforeEach, describe, expect, test } from 'vitest';
|
|
|
3
3
|
import SelectItem from '../SelectItem.vue';
|
|
4
4
|
|
|
5
5
|
const createWrapper = (props = {}, slots = {}) => {
|
|
6
|
-
return mount(SelectItem, {
|
|
6
|
+
return mount(SelectItem, {
|
|
7
7
|
props,
|
|
8
|
-
slots: slots.default ? { default: slots.default } : {}
|
|
8
|
+
slots: slots.default ? { default: slots.default } : {}
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
|
|
@@ -76,12 +76,8 @@ describe('SelectItem.vue', () => {
|
|
|
76
76
|
test('does not apply size class when size is empty', async () => {
|
|
77
77
|
await wrapper.setProps({ size: '' });
|
|
78
78
|
const labelElement = wrapper.find('.unnnic-select-item__label');
|
|
79
|
-
expect(labelElement.classes()).not.toContain(
|
|
80
|
-
|
|
81
|
-
);
|
|
82
|
-
expect(labelElement.classes()).not.toContain(
|
|
83
|
-
'unnnic-select-item__label--sm',
|
|
84
|
-
);
|
|
79
|
+
expect(labelElement.classes()).not.toContain('unnnic-select-item__label--md');
|
|
80
|
+
expect(labelElement.classes()).not.toContain('unnnic-select-item__label--sm');
|
|
85
81
|
});
|
|
86
82
|
});
|
|
87
83
|
|
|
@@ -132,10 +128,7 @@ describe('SelectItem.vue', () => {
|
|
|
132
128
|
});
|
|
133
129
|
|
|
134
130
|
test('emits click event even when selectable is false', async () => {
|
|
135
|
-
const clickWrapper = createWrapper(
|
|
136
|
-
{ selectable: false },
|
|
137
|
-
{ default: 'Test Item' },
|
|
138
|
-
);
|
|
131
|
+
const clickWrapper = createWrapper({ selectable: false }, { default: 'Test Item' });
|
|
139
132
|
await clickWrapper.trigger('click');
|
|
140
133
|
expect(clickWrapper.emitted('click')).toBeTruthy();
|
|
141
134
|
expect(clickWrapper.emitted('click').length).toBeGreaterThanOrEqual(1);
|
|
@@ -201,7 +194,7 @@ describe('SelectItem.vue', () => {
|
|
|
201
194
|
test('has proper semantic structure', () => {
|
|
202
195
|
const div = wrapper.find('.unnnic-select-item');
|
|
203
196
|
const span = wrapper.find('.unnnic-select-item__label');
|
|
204
|
-
|
|
197
|
+
|
|
205
198
|
expect(div.exists()).toBe(true);
|
|
206
199
|
expect(span.exists()).toBe(true);
|
|
207
200
|
expect(span.element.tagName).toBe('SPAN');
|
|
@@ -221,8 +214,7 @@ describe('SelectItem.vue', () => {
|
|
|
221
214
|
});
|
|
222
215
|
|
|
223
216
|
test('handles long slot content', async () => {
|
|
224
|
-
const longText =
|
|
225
|
-
'This is a very long text content that should be handled properly by the component';
|
|
217
|
+
const longText = 'This is a very long text content that should be handled properly by the component';
|
|
226
218
|
const longWrapper = createWrapper({}, { default: longText });
|
|
227
219
|
const labelElement = longWrapper.find('.unnnic-select-item__label');
|
|
228
220
|
expect(labelElement.text()).toBe(longText);
|
|
@@ -245,12 +237,8 @@ describe('SelectItem.vue', () => {
|
|
|
245
237
|
|
|
246
238
|
describe('CSS class combinations', () => {
|
|
247
239
|
test('applies correct classes for non-selectable inactive item', async () => {
|
|
248
|
-
await wrapper.setProps({
|
|
249
|
-
|
|
250
|
-
active: false,
|
|
251
|
-
textFocused: false,
|
|
252
|
-
});
|
|
253
|
-
|
|
240
|
+
await wrapper.setProps({ selectable: false, active: false, textFocused: false });
|
|
241
|
+
|
|
254
242
|
expect(wrapper.classes()).toContain('unnnic-select-item');
|
|
255
243
|
expect(wrapper.classes()).not.toContain('unnnic-select-item--selectable');
|
|
256
244
|
expect(wrapper.classes()).not.toContain('unnnic--clickable');
|
|
@@ -259,12 +247,8 @@ describe('SelectItem.vue', () => {
|
|
|
259
247
|
});
|
|
260
248
|
|
|
261
249
|
test('applies correct classes for selectable active item', async () => {
|
|
262
|
-
await wrapper.setProps({
|
|
263
|
-
|
|
264
|
-
active: true,
|
|
265
|
-
textFocused: false,
|
|
266
|
-
});
|
|
267
|
-
|
|
250
|
+
await wrapper.setProps({ selectable: true, active: true, textFocused: false });
|
|
251
|
+
|
|
268
252
|
expect(wrapper.classes()).toContain('unnnic-select-item');
|
|
269
253
|
expect(wrapper.classes()).toContain('unnnic-select-item--selectable');
|
|
270
254
|
expect(wrapper.classes()).toContain('unnnic--clickable');
|
|
@@ -273,12 +257,8 @@ describe('SelectItem.vue', () => {
|
|
|
273
257
|
});
|
|
274
258
|
|
|
275
259
|
test('applies correct classes for text-focused item', async () => {
|
|
276
|
-
await wrapper.setProps({
|
|
277
|
-
|
|
278
|
-
active: false,
|
|
279
|
-
textFocused: true,
|
|
280
|
-
});
|
|
281
|
-
|
|
260
|
+
await wrapper.setProps({ selectable: true, active: false, textFocused: true });
|
|
261
|
+
|
|
282
262
|
expect(wrapper.classes()).toContain('unnnic-select-item');
|
|
283
263
|
expect(wrapper.classes()).toContain('unnnic-select-item--selectable');
|
|
284
264
|
expect(wrapper.classes()).toContain('unnnic--clickable');
|
|
@@ -318,11 +298,11 @@ describe('SelectItem.vue', () => {
|
|
|
318
298
|
});
|
|
319
299
|
|
|
320
300
|
test('matches snapshot with all states combined', async () => {
|
|
321
|
-
await wrapper.setProps({
|
|
301
|
+
await wrapper.setProps({
|
|
322
302
|
size: 'md',
|
|
323
303
|
selectable: true,
|
|
324
304
|
active: true,
|
|
325
|
-
textFocused: true
|
|
305
|
+
textFocused: true
|
|
326
306
|
});
|
|
327
307
|
expect(wrapper.html()).toMatchSnapshot();
|
|
328
308
|
});
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
>
|
|
10
10
|
<PopoverTrigger class="w-full">
|
|
11
11
|
<UnnnicInput
|
|
12
|
-
ref="
|
|
12
|
+
ref="selectInputRef"
|
|
13
13
|
:modelValue="inputValue"
|
|
14
14
|
class="unnnic-select__input"
|
|
15
15
|
readonly
|
|
@@ -132,8 +132,8 @@ const emit = defineEmits<{
|
|
|
132
132
|
}>();
|
|
133
133
|
|
|
134
134
|
const openPopover = ref(false);
|
|
135
|
-
const
|
|
136
|
-
const { width: inputWidth } = useElementSize(
|
|
135
|
+
const selectInputRef = ref<HTMLInputElement | null>(null);
|
|
136
|
+
const { width: inputWidth } = useElementSize(selectInputRef);
|
|
137
137
|
|
|
138
138
|
const inputWidthString = computed(() => {
|
|
139
139
|
return `${inputWidth.value}px`;
|
|
@@ -8,12 +8,7 @@
|
|
|
8
8
|
class="unnnic-switch__label"
|
|
9
9
|
/>
|
|
10
10
|
|
|
11
|
-
<label
|
|
12
|
-
:class="[
|
|
13
|
-
'unnnic-switch__input-wrapper',
|
|
14
|
-
{ 'unnnic-switch__input-wrapper--disabled': disabled },
|
|
15
|
-
]"
|
|
16
|
-
>
|
|
11
|
+
<label :class="['unnnic-switch__input-wrapper', {'unnnic-switch__input-wrapper--disabled': disabled}]">
|
|
17
12
|
<input
|
|
18
13
|
class="unnnic-switch__input"
|
|
19
14
|
type="checkbox"
|
|
@@ -83,7 +78,7 @@ export default {
|
|
|
83
78
|
type: String,
|
|
84
79
|
default: '',
|
|
85
80
|
},
|
|
86
|
-
|
|
81
|
+
|
|
87
82
|
helper: {
|
|
88
83
|
type: String,
|
|
89
84
|
default: '',
|
|
@@ -181,9 +176,7 @@ $switch-height: 20px;
|
|
|
181
176
|
background-repeat: no-repeat;
|
|
182
177
|
background-position: 4px center;
|
|
183
178
|
|
|
184
|
-
transition:
|
|
185
|
-
120ms linear background-position,
|
|
186
|
-
120ms linear background-color;
|
|
179
|
+
transition: 120ms linear background-position, 120ms linear background-color;
|
|
187
180
|
|
|
188
181
|
cursor: pointer;
|
|
189
182
|
|
|
@@ -4,7 +4,9 @@ exports[`Tab.vue > matches the snapshot 1`] = `
|
|
|
4
4
|
"<div data-v-b4e39fac="" class="tab size-md">
|
|
5
5
|
<header data-v-b4e39fac="" class="tab-header">
|
|
6
6
|
<ul data-v-b4e39fac="" class="tab-content">
|
|
7
|
-
<li data-v-b4e39fac="" class="tab-head">tab1<div data-v-
|
|
7
|
+
<li data-v-b4e39fac="" class="tab-head">tab1<div data-v-b3d24f2b="" class="unnnic-tooltip-trigger" data-testid="tooltip-trigger" data-state="closed" data-grace-area-trigger=""><span data-v-26446d8e="" data-v-b4e39fac="" class="unnnic-icon material-symbols-rounded unnnic-icon-scheme--fg-base unnnic-icon-size--sm unnnic-icon__size--sm" data-testid="material-icon" translate="no">help</span></div>
|
|
8
|
+
<!--teleport start-->
|
|
9
|
+
<!--teleport end-->
|
|
8
10
|
</li>
|
|
9
11
|
<li data-v-b4e39fac="" class="tab-head tab-head--active">tab2
|
|
10
12
|
<!--v-if-->
|
|
@@ -75,10 +75,7 @@
|
|
|
75
75
|
{{ template?.footer }}
|
|
76
76
|
</footer>
|
|
77
77
|
</section>
|
|
78
|
-
<footer
|
|
79
|
-
v-if="hasButtons"
|
|
80
|
-
class="unnnic-template-preview__buttons"
|
|
81
|
-
>
|
|
78
|
+
<footer v-if="hasButtons" class="unnnic-template-preview__buttons">
|
|
82
79
|
<section
|
|
83
80
|
v-for="(button, index) in template?.buttons"
|
|
84
81
|
:key="`button-${index}`"
|
|
@@ -99,15 +96,15 @@
|
|
|
99
96
|
</template>
|
|
100
97
|
|
|
101
98
|
<script lang="ts" setup>
|
|
102
|
-
import { computed } from
|
|
99
|
+
import { computed } from "vue";
|
|
103
100
|
|
|
104
|
-
import type { Template } from
|
|
101
|
+
import type { Template } from "./types";
|
|
105
102
|
|
|
106
|
-
import imagePreview from
|
|
107
|
-
import documentPreview from
|
|
108
|
-
import videoPreview from
|
|
103
|
+
import imagePreview from "../../assets/img/previews/image-preview.png";
|
|
104
|
+
import documentPreview from "../../assets/img/previews/doc-preview.png";
|
|
105
|
+
import videoPreview from "../../assets/img/previews/video-preview.png";
|
|
109
106
|
|
|
110
|
-
import UnnnicIcon from
|
|
107
|
+
import UnnnicIcon from "../Icon.vue";
|
|
111
108
|
|
|
112
109
|
interface Props {
|
|
113
110
|
template?: Template | null;
|
|
@@ -118,30 +115,30 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
118
115
|
});
|
|
119
116
|
|
|
120
117
|
const hasHeader = computed(
|
|
121
|
-
() => props.template?.header && props.template.header.type
|
|
118
|
+
() => props.template?.header && props.template.header.type
|
|
122
119
|
);
|
|
123
120
|
const hasHeaderMedia = computed(
|
|
124
|
-
() => !!props.template?.header && props.template.header.type ===
|
|
121
|
+
() => !!props.template?.header && props.template.header.type === "MEDIA"
|
|
125
122
|
);
|
|
126
123
|
const hasBody = computed(
|
|
127
|
-
() => !!props.template?.body && props.template.body.length > 0
|
|
124
|
+
() => !!props.template?.body && props.template.body.length > 0
|
|
128
125
|
);
|
|
129
126
|
const hasFooter = computed(
|
|
130
|
-
() => !!props.template?.footer && props.template.footer.length > 0
|
|
127
|
+
() => !!props.template?.footer && props.template.footer.length > 0
|
|
131
128
|
);
|
|
132
129
|
const hasButtons = computed(
|
|
133
|
-
() => !!props.template?.buttons && props.template.buttons.length > 0
|
|
130
|
+
() => !!props.template?.buttons && props.template.buttons.length > 0
|
|
134
131
|
);
|
|
135
132
|
const parsedBody = computed(() => {
|
|
136
|
-
if (!hasBody.value) return
|
|
133
|
+
if (!hasBody.value) return "";
|
|
137
134
|
|
|
138
135
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
139
136
|
const result = props
|
|
140
|
-
.template!.body!.replaceAll(
|
|
141
|
-
.replaceAll(/(?:\*)([^*<\n]+)(?:\*)/g,
|
|
142
|
-
.replaceAll(/(?:_)([^_<\n]+)(?:_)/g,
|
|
143
|
-
.replaceAll(/(?:~)([^~<\n]+)(?:~)/g,
|
|
144
|
-
.replaceAll(/(?:```)([^```<\n]+)(?:```)/g,
|
|
137
|
+
.template!.body!.replaceAll("\n", "<br/>")
|
|
138
|
+
.replaceAll(/(?:\*)([^*<\n]+)(?:\*)/g, "<strong>$1</strong>")
|
|
139
|
+
.replaceAll(/(?:_)([^_<\n]+)(?:_)/g, "<i>$1</i>")
|
|
140
|
+
.replaceAll(/(?:~)([^~<\n]+)(?:~)/g, "<s>$1</s>")
|
|
141
|
+
.replaceAll(/(?:```)([^```<\n]+)(?:```)/g, "<tt>$1</tt>")
|
|
145
142
|
.replaceAll(/{{.*?}}/g, (match) => `<strong>${match}</strong>`);
|
|
146
143
|
|
|
147
144
|
return result;
|
|
@@ -149,19 +146,19 @@ const parsedBody = computed(() => {
|
|
|
149
146
|
|
|
150
147
|
const getButtonIcon = (buttonType) => {
|
|
151
148
|
const buttonMapper = {
|
|
152
|
-
PHONE_NUMBER:
|
|
153
|
-
URL:
|
|
154
|
-
COPY_CODE:
|
|
155
|
-
FLOW:
|
|
156
|
-
QUICK_REPLY:
|
|
149
|
+
PHONE_NUMBER: "phone",
|
|
150
|
+
URL: "open_in_new",
|
|
151
|
+
COPY_CODE: "content_copy",
|
|
152
|
+
FLOW: "",
|
|
153
|
+
QUICK_REPLY: "reply",
|
|
157
154
|
};
|
|
158
155
|
|
|
159
|
-
return buttonMapper[buttonType] ||
|
|
156
|
+
return buttonMapper[buttonType] || "";
|
|
160
157
|
};
|
|
161
158
|
</script>
|
|
162
159
|
|
|
163
160
|
<style lang="scss" scoped>
|
|
164
|
-
@use
|
|
161
|
+
@use "@/assets/scss/unnnic" as *;
|
|
165
162
|
|
|
166
163
|
.unnnic-template-preview {
|
|
167
164
|
display: flex;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<UnnnicModalDialog
|
|
3
|
-
:
|
|
3
|
+
:model-value="modelValue"
|
|
4
4
|
@update:modelValue="$event === false && $emit('close')"
|
|
5
5
|
:title="defaultTranslations.title[props.locale]"
|
|
6
|
-
:
|
|
6
|
+
:show-close-icon="true"
|
|
7
7
|
class="unnnic-template-preview-modal"
|
|
8
8
|
>
|
|
9
9
|
<UnnnicTemplatePreview :template="template" />
|
|
@@ -11,16 +11,16 @@
|
|
|
11
11
|
</template>
|
|
12
12
|
|
|
13
13
|
<script lang="ts" setup>
|
|
14
|
-
import UnnnicTemplatePreview from
|
|
15
|
-
import UnnnicModalDialog from
|
|
14
|
+
import UnnnicTemplatePreview from "./TemplatePreview.vue";
|
|
15
|
+
import UnnnicModalDialog from "../ModalDialog/ModalDialog.vue";
|
|
16
16
|
|
|
17
|
-
import type { Template } from
|
|
17
|
+
import type { Template } from "./types";
|
|
18
18
|
|
|
19
19
|
const defaultTranslations = {
|
|
20
20
|
title: {
|
|
21
|
-
|
|
22
|
-
en:
|
|
23
|
-
es:
|
|
21
|
+
"pt-br": "Visualizar modelo",
|
|
22
|
+
en: "Template preview",
|
|
23
|
+
es: "Vista previa de plantilla",
|
|
24
24
|
},
|
|
25
25
|
};
|
|
26
26
|
|
|
@@ -31,7 +31,7 @@ interface Props {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
const props = withDefaults(defineProps<Props>(), {
|
|
34
|
-
locale:
|
|
34
|
+
locale: "en",
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
defineEmits<{
|
|
@@ -40,7 +40,7 @@ defineEmits<{
|
|
|
40
40
|
</script>
|
|
41
41
|
|
|
42
42
|
<style lang="scss" scoped>
|
|
43
|
-
@use
|
|
43
|
+
@use "@/assets/scss/unnnic" as *;
|
|
44
44
|
|
|
45
45
|
:deep(.unnnic-modal-dialog__container__content) {
|
|
46
46
|
display: flex;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
export interface Template {
|
|
2
2
|
header: {
|
|
3
|
-
type:
|
|
4
|
-
mediaType?:
|
|
3
|
+
type: "TEXT" | "MEDIA";
|
|
4
|
+
mediaType?: "IMAGE" | "VIDEO" | "DOCUMENT";
|
|
5
5
|
text?: string | null;
|
|
6
6
|
src?: string | null;
|
|
7
7
|
};
|
|
8
8
|
body?: string;
|
|
9
9
|
footer?: string;
|
|
10
10
|
buttons?: Array<{
|
|
11
|
-
type:
|
|
11
|
+
type: "QUICK_REPLY" | "PHONE_NUMBER";
|
|
12
12
|
text: string;
|
|
13
13
|
countryCode?: string;
|
|
14
14
|
phoneNumber?: string;
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
:role="type === 'error' ? 'alert' : 'status'"
|
|
12
12
|
:aria-live="type === 'error' ? 'assertive' : 'polite'"
|
|
13
13
|
data-testid="toast"
|
|
14
|
+
:style="{ zIndex: toastZIndex }"
|
|
14
15
|
>
|
|
15
16
|
<section
|
|
16
17
|
class="unnnic-toast__content"
|
|
@@ -74,6 +75,7 @@ import { ref, computed, onMounted, onUnmounted } from 'vue';
|
|
|
74
75
|
|
|
75
76
|
import UnnnicIcon from '@/components/Icon.vue';
|
|
76
77
|
import UnnnicButton from '@/components/Button/Button.vue';
|
|
78
|
+
import { useLayerZIndex } from '@/lib/layer-manager';
|
|
77
79
|
|
|
78
80
|
import type { ToastProps, ToastEmits } from './types';
|
|
79
81
|
import type { SchemeColor } from '@/types/scheme-colors';
|
|
@@ -109,6 +111,8 @@ const typeConfig = computed(() => {
|
|
|
109
111
|
};
|
|
110
112
|
});
|
|
111
113
|
|
|
114
|
+
const toastZIndex = useLayerZIndex();
|
|
115
|
+
|
|
112
116
|
const handleClose = () => {
|
|
113
117
|
isVisible.value = false;
|
|
114
118
|
emit('close');
|
|
@@ -152,7 +156,6 @@ onUnmounted(() => {
|
|
|
152
156
|
position: fixed;
|
|
153
157
|
bottom: $unnnic-space-4;
|
|
154
158
|
right: $unnnic-space-4;
|
|
155
|
-
z-index: 9999;
|
|
156
159
|
|
|
157
160
|
display: flex;
|
|
158
161
|
align-items: flex-end;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createApp } from 'vue';
|
|
2
|
+
import { getTeleportContainer } from '@/lib/teleport-target';
|
|
2
3
|
import Toast from './Toast.vue';
|
|
3
4
|
import type {
|
|
4
5
|
ToastProps,
|
|
@@ -20,7 +21,9 @@ class ToastManager implements ToastManager {
|
|
|
20
21
|
this.container = document.createElement('div');
|
|
21
22
|
this.container.setAttribute('unnnic-toast-container', 'true');
|
|
22
23
|
|
|
23
|
-
document.body
|
|
24
|
+
const host = getTeleportContainer() ?? document.body;
|
|
25
|
+
host?.appendChild(this.container);
|
|
26
|
+
|
|
24
27
|
return this.container;
|
|
25
28
|
}
|
|
26
29
|
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, afterEach, test, vi } from 'vitest';
|
|
2
2
|
|
|
3
|
-
vi.mock('vue', () =>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
vi.mock('vue', async () => {
|
|
4
|
+
const actual = await vi.importActual('vue');
|
|
5
|
+
return {
|
|
6
|
+
...actual,
|
|
7
|
+
createApp: vi.fn(() => ({
|
|
8
|
+
mount: vi.fn(),
|
|
9
|
+
unmount: vi.fn(),
|
|
10
|
+
})),
|
|
11
|
+
};
|
|
12
|
+
});
|
|
9
13
|
|
|
10
14
|
vi.mock('../Toast.vue', () => ({
|
|
11
15
|
default: {
|