@weni/unnnic-system 3.1.2 → 3.1.3-alpha.2
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 +13 -1
- package/dist/components/DatePicker/DatePicker.vue.d.ts +2 -2
- package/dist/components/DropArea/DropArea.vue.d.ts +2 -0
- package/dist/components/DropArea/DropArea.vue.d.ts.map +1 -1
- package/dist/components/EmojiPicker/EmojiPicker.vue.d.ts +16 -22292
- package/dist/components/EmojiPicker/EmojiPicker.vue.d.ts.map +1 -1
- package/dist/components/InputDatePicker/InputDatePicker.vue.d.ts +3 -3
- package/dist/components/ModalDialog/ModalDialog.vue.d.ts +1 -1
- package/dist/components/ModalDialog/ModalDialog.vue.d.ts.map +1 -1
- package/dist/components/ModalUpload/ModalUpload.vue.d.ts +6 -0
- package/dist/components/TemplatePreview/TemplatePreview.vue.d.ts +9 -0
- package/dist/components/TemplatePreview/TemplatePreview.vue.d.ts.map +1 -0
- package/dist/components/TemplatePreview/TemplatePreviewModal.vue.d.ts +15 -0
- package/dist/components/TemplatePreview/TemplatePreviewModal.vue.d.ts.map +1 -0
- package/dist/components/UploadArea/UploadArea.vue.d.ts +6 -0
- package/dist/{es-b95265ef.mjs → es-67d2c06d.mjs} +1 -1
- package/dist/index-da3d1ae4.mjs +93513 -0
- package/dist/locales/en.json.d.ts +18 -0
- package/dist/locales/es.json.d.ts +18 -0
- package/dist/locales/pt_br.json.d.ts +18 -0
- package/dist/{pt-br-80b6b07a.mjs → pt-br-5ca1066d.mjs} +1 -1
- package/dist/style.css +1 -1
- package/dist/unnnic.mjs +26 -24
- package/dist/unnnic.umd.js +46 -760
- package/package.json +3 -4
- package/src/assets/img/previews/doc-preview.png +0 -0
- package/src/assets/img/previews/image-preview.png +0 -0
- package/src/assets/img/previews/video-preview.png +0 -0
- package/src/components/DropArea/DropArea.vue +26 -2
- package/src/components/EmojiPicker/EmojiPicker.vue +130 -63
- package/src/components/EmojiPicker/__tests__/EmojiPicker.spec.js +112 -36
- package/src/components/ModalDialog/ModalDialog.vue +27 -29
- package/src/components/ModalDialog/__tests__/__snapshots__/ModalDialog.spec.js.snap +1 -1
- package/src/components/TemplatePreview/TemplatePreview.vue +249 -0
- package/src/components/TemplatePreview/TemplatePreviewModal.vue +51 -0
- package/src/components/TemplatePreview/types.d.ts +16 -0
- package/src/components/index.ts +8 -2
- package/src/locales/en.json +18 -0
- package/src/locales/es.json +18 -0
- package/src/locales/pt_br.json +18 -0
- package/src/stories/TemplatePreview.stories.js +94 -0
- package/src/stories/TemplatePreviewModal.stories.js +110 -0
- package/dist/components/index.d.ts +0 -40344
- package/dist/components/index.d.ts.map +0 -1
- package/dist/index-d6c4fffb.mjs +0 -77440
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weni/unnnic-system",
|
|
3
|
-
"version": "3.1.2",
|
|
3
|
+
"version": "3.1.3-alpha.2",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -50,9 +50,8 @@
|
|
|
50
50
|
"vue": "^3.4.8"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@emoji-mart/data": "^1.1.2",
|
|
54
53
|
"@vueuse/components": "^10.4.1",
|
|
55
|
-
"emoji-mart": "^
|
|
54
|
+
"emoji-mart-vue-fast": "^15.0.5",
|
|
56
55
|
"lodash": "^4.17.21",
|
|
57
56
|
"mime": "^4.0.1",
|
|
58
57
|
"mitt": "^3.0.1",
|
|
@@ -99,4 +98,4 @@
|
|
|
99
98
|
"vue-eslint-parser": "^9.4.2",
|
|
100
99
|
"vue-tsc": "^3.0.5"
|
|
101
100
|
}
|
|
102
|
-
}
|
|
101
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
@dragleave.stop.prevent="dragleave"
|
|
12
12
|
@dragend.stop.prevent="dragend"
|
|
13
13
|
@drop.stop.prevent="drop"
|
|
14
|
-
@click="
|
|
14
|
+
@click="handleDropzoneClick"
|
|
15
15
|
>
|
|
16
16
|
<UnnnicIcon
|
|
17
17
|
class="unnnic-upload-area__dropzone__icon"
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
</template>
|
|
65
65
|
|
|
66
66
|
<script setup>
|
|
67
|
-
import { ref, computed, getCurrentInstance } from 'vue';
|
|
67
|
+
import { ref, computed, getCurrentInstance, useTemplateRef } from 'vue';
|
|
68
68
|
import mime from 'mime';
|
|
69
69
|
|
|
70
70
|
import UnnnicIcon from '../Icon.vue';
|
|
@@ -73,6 +73,7 @@ const isDragging = ref(false);
|
|
|
73
73
|
const hasError = ref(false);
|
|
74
74
|
const dragEnterCounter = ref(0);
|
|
75
75
|
const file = ref();
|
|
76
|
+
const fileRef = useTemplateRef('file');
|
|
76
77
|
|
|
77
78
|
const props = defineProps({
|
|
78
79
|
acceptMultiple: {
|
|
@@ -111,6 +112,11 @@ const props = defineProps({
|
|
|
111
112
|
type: String,
|
|
112
113
|
default: '',
|
|
113
114
|
},
|
|
115
|
+
|
|
116
|
+
disabled: {
|
|
117
|
+
type: Boolean,
|
|
118
|
+
default: false,
|
|
119
|
+
}
|
|
114
120
|
});
|
|
115
121
|
|
|
116
122
|
const emit = defineEmits([
|
|
@@ -135,15 +141,21 @@ const formattedSupportedFormats = computed(() => {
|
|
|
135
141
|
});
|
|
136
142
|
|
|
137
143
|
function dragenter() {
|
|
144
|
+
if (props.disabled) return;
|
|
145
|
+
|
|
138
146
|
dragEnterCounter.value += 1;
|
|
139
147
|
isDragging.value = true;
|
|
140
148
|
}
|
|
141
149
|
|
|
142
150
|
function dragover() {
|
|
151
|
+
if (props.disabled) return;
|
|
152
|
+
|
|
143
153
|
isDragging.value = true;
|
|
144
154
|
}
|
|
145
155
|
|
|
146
156
|
function dragleave() {
|
|
157
|
+
if (props.disabled) return;
|
|
158
|
+
|
|
147
159
|
dragEnterCounter.value -= 1;
|
|
148
160
|
if (dragEnterCounter.value === 0) {
|
|
149
161
|
isDragging.value = false;
|
|
@@ -151,10 +163,14 @@ function dragleave() {
|
|
|
151
163
|
}
|
|
152
164
|
|
|
153
165
|
function dragend() {
|
|
166
|
+
if (props.disabled) return;
|
|
167
|
+
|
|
154
168
|
isDragging.value = false;
|
|
155
169
|
}
|
|
156
170
|
|
|
157
171
|
function drop(event) {
|
|
172
|
+
if (props.disabled) return;
|
|
173
|
+
|
|
158
174
|
isDragging.value = false;
|
|
159
175
|
|
|
160
176
|
const { files } = event.dataTransfer;
|
|
@@ -164,7 +180,15 @@ function drop(event) {
|
|
|
164
180
|
}
|
|
165
181
|
}
|
|
166
182
|
|
|
183
|
+
function handleDropzoneClick() {
|
|
184
|
+
if (props.disabled) return;
|
|
185
|
+
|
|
186
|
+
fileRef.value.click();
|
|
187
|
+
}
|
|
188
|
+
|
|
167
189
|
function handleFileChange(event) {
|
|
190
|
+
if (props.disabled) return;
|
|
191
|
+
|
|
168
192
|
const { files } = event.target;
|
|
169
193
|
|
|
170
194
|
if (validateFiles(files)) {
|
|
@@ -1,64 +1,112 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
ref="
|
|
3
|
+
ref="emojiPickerRef"
|
|
4
4
|
:class="['emoji-picker', `emoji-picker--${position}`]"
|
|
5
5
|
@click.stop
|
|
6
6
|
@keypress.enter.stop
|
|
7
|
-
|
|
7
|
+
>
|
|
8
|
+
<Picker
|
|
9
|
+
:data="emojiIndex"
|
|
10
|
+
set="apple"
|
|
11
|
+
theme="light"
|
|
12
|
+
:preview="false"
|
|
13
|
+
:search="true"
|
|
14
|
+
nav-position="bottom"
|
|
15
|
+
no-results-emoji="cry"
|
|
16
|
+
:max-frequent-rows="3"
|
|
17
|
+
:i18n="translations"
|
|
18
|
+
:color="accentColor"
|
|
19
|
+
@select="onEmojiSelect"
|
|
20
|
+
/>
|
|
21
|
+
</div>
|
|
8
22
|
</template>
|
|
9
23
|
|
|
10
|
-
<script>
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
24
|
+
<script setup lang="ts">
|
|
25
|
+
import { computed, ref, onMounted, onUnmounted } from 'vue'
|
|
26
|
+
import { get } from 'lodash'
|
|
27
|
+
import i18n from '../../utils/plugins/i18n'
|
|
28
|
+
import { Picker, EmojiIndex } from 'emoji-mart-vue-fast/src'
|
|
29
|
+
import data from 'emoji-mart-vue-fast/data/all.json'
|
|
30
|
+
import 'emoji-mart-vue-fast/css/emoji-mart.css'
|
|
31
|
+
import UnnnicI18n from '../../mixins/i18n'
|
|
32
|
+
|
|
33
|
+
defineOptions({
|
|
34
|
+
mixins: [UnnnicI18n],
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
interface Emoji {
|
|
38
|
+
id: string
|
|
39
|
+
native: string
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface Props {
|
|
43
|
+
returnName?: boolean
|
|
44
|
+
position?: 'top' | 'bottom'
|
|
45
|
+
locale?: string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
49
|
+
returnName: false,
|
|
50
|
+
position: 'top',
|
|
51
|
+
locale: 'pt-br'
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
const emit = defineEmits<{
|
|
55
|
+
close: []
|
|
56
|
+
emojiSelected: [emoji: string]
|
|
57
|
+
}>()
|
|
58
|
+
|
|
59
|
+
const emojiPickerRef = ref<HTMLElement>()
|
|
60
|
+
const emojiIndex = computed(() => new EmojiIndex(data))
|
|
61
|
+
|
|
62
|
+
const accentColor = '#00A49F' // $unnnic-color-weni-600
|
|
63
|
+
|
|
64
|
+
const currentLocale = computed(() => props.locale || 'pt-br')
|
|
65
|
+
|
|
66
|
+
const translation = (key: string) => {
|
|
67
|
+
const messages: Record<string, unknown> = i18n.global.messages as Record<string, unknown>
|
|
68
|
+
const loc = currentLocale.value
|
|
69
|
+
const localeMsgs = messages?.[loc] || messages?.[loc?.toLowerCase?.()] || messages?.[loc?.toUpperCase?.()]
|
|
70
|
+
const enMsgs = messages?.['en']
|
|
71
|
+
return get(localeMsgs, key) || get(enMsgs, key) || key
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const translations = computed(() => ({
|
|
75
|
+
search: translation('emoji_picker.search'),
|
|
76
|
+
notfound: translation('emoji_picker.notfound'),
|
|
77
|
+
categories: {
|
|
78
|
+
search: translation('emoji_picker.categories.search'),
|
|
79
|
+
recent: translation('emoji_picker.categories.recent'),
|
|
80
|
+
smileys: translation('emoji_picker.categories.smileys'),
|
|
81
|
+
people: translation('emoji_picker.categories.people'),
|
|
82
|
+
nature: translation('emoji_picker.categories.nature'),
|
|
83
|
+
foods: translation('emoji_picker.categories.foods'),
|
|
84
|
+
activity: translation('emoji_picker.categories.activity'),
|
|
85
|
+
places: translation('emoji_picker.categories.places'),
|
|
86
|
+
objects: translation('emoji_picker.categories.objects'),
|
|
87
|
+
symbols: translation('emoji_picker.categories.symbols'),
|
|
88
|
+
flags: translation('emoji_picker.categories.flags'),
|
|
89
|
+
custom: translation('emoji_picker.categories.custom')
|
|
90
|
+
}
|
|
91
|
+
}))
|
|
92
|
+
|
|
93
|
+
const handleClickOutside = (event: Event) => {
|
|
94
|
+
if (emojiPickerRef.value && !emojiPickerRef.value.contains(event.target as Node)) {
|
|
95
|
+
emit('close')
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
onMounted(() => {
|
|
100
|
+
document.addEventListener('click', handleClickOutside)
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
onUnmounted(() => {
|
|
104
|
+
document.removeEventListener('click', handleClickOutside)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
const onEmojiSelect = (emoji: Emoji) => {
|
|
108
|
+
emit('emojiSelected', props.returnName ? emoji.id : emoji.native)
|
|
109
|
+
}
|
|
62
110
|
</script>
|
|
63
111
|
|
|
64
112
|
<style lang="scss" scoped>
|
|
@@ -78,16 +126,35 @@ export default {
|
|
|
78
126
|
animation-name: slideInDown;
|
|
79
127
|
}
|
|
80
128
|
|
|
81
|
-
:deep(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
--rgb-color: 59, 65, 77; // $unnnic-color-neutral-darkest
|
|
87
|
-
--color-border: rgb(244, 246, 248);
|
|
88
|
-
--shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.1);
|
|
89
|
-
|
|
129
|
+
:deep(.emoji-mart) {
|
|
130
|
+
border-radius: 16px;
|
|
131
|
+
font-family: Lato, sans-serif; // $unnnic-font-family
|
|
132
|
+
border: 1px solid rgb(244, 246, 248);
|
|
133
|
+
box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.1);
|
|
90
134
|
cursor: default;
|
|
135
|
+
color: #3B4151; // $unnnic-color-neutral-darkest
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
:deep(.emoji-mart-emoji) {
|
|
139
|
+
cursor: pointer;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
:deep(.emoji-mart-category .emoji-mart-emoji span) {
|
|
143
|
+
cursor: pointer;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
:deep(.emoji-mart-anchor) {
|
|
147
|
+
cursor: pointer;
|
|
148
|
+
color: #858585;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
:deep(.emoji-mart-anchor:hover),
|
|
152
|
+
:deep(.emoji-mart-anchor-selected) {
|
|
153
|
+
color: #00A49F; // $unnnic-color-weni-600
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
:deep(.emoji-mart-anchor-bar) {
|
|
157
|
+
background-color: #00A49F; // $unnnic-color-weni-600
|
|
91
158
|
}
|
|
92
159
|
}
|
|
93
160
|
|
|
@@ -1,16 +1,37 @@
|
|
|
1
1
|
import { mount } from '@vue/test-utils';
|
|
2
2
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
3
|
-
|
|
4
3
|
import UnnnicEmojiPicker from '../EmojiPicker.vue';
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
vi.mock('emoji-mart-vue-fast/src', () => ({
|
|
6
|
+
Picker: {
|
|
7
|
+
name: 'Picker',
|
|
8
|
+
props: ['data', 'set', 'theme', 'preview', 'search', 'navPosition', 'noResultsEmoji', 'maxFrequentRows', 'i18n', 'color'],
|
|
9
|
+
emits: ['select', 'click-outside'],
|
|
10
|
+
template: '<div class="emoji-mart-picker"></div>'
|
|
11
|
+
},
|
|
12
|
+
EmojiIndex: vi.fn().mockImplementation(() => ({}))
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
vi.mock('emoji-mart-vue-fast/data/all.json', () => ({
|
|
16
|
+
default: {}
|
|
17
|
+
}));
|
|
7
18
|
|
|
8
|
-
vi.mock('emoji-mart/', () => {
|
|
19
|
+
vi.mock('emoji-mart-vue-fast/css/emoji-mart.css', () => ({}));
|
|
20
|
+
|
|
21
|
+
vi.mock('../../utils/plugins/i18n', () => {
|
|
22
|
+
const current = 'pt-br'
|
|
9
23
|
return {
|
|
10
|
-
|
|
11
|
-
|
|
24
|
+
default: {
|
|
25
|
+
global: {
|
|
26
|
+
get locale() { return current },
|
|
27
|
+
set locale(_v) {},
|
|
28
|
+
t: (key) => `${key}`,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
}
|
|
12
32
|
});
|
|
13
33
|
|
|
34
|
+
|
|
14
35
|
describe('UnnnicEmojiPicker', () => {
|
|
15
36
|
let wrapper;
|
|
16
37
|
|
|
@@ -21,59 +42,99 @@ describe('UnnnicEmojiPicker', () => {
|
|
|
21
42
|
position: 'top',
|
|
22
43
|
returnName: false,
|
|
23
44
|
},
|
|
45
|
+
global: {
|
|
46
|
+
config: {
|
|
47
|
+
errorHandler: () => {},
|
|
48
|
+
warnHandler: () => {},
|
|
49
|
+
},
|
|
50
|
+
stubs: {
|
|
51
|
+
Picker: {
|
|
52
|
+
name: 'Picker',
|
|
53
|
+
props: ['data', 'set', 'theme', 'preview', 'search', 'navPosition', 'noResultsEmoji', 'maxFrequentRows', 'i18n', 'color'],
|
|
54
|
+
emits: ['select', 'click-outside'],
|
|
55
|
+
template: '<div class="emoji-mart-picker" @select="$emit(\'select\', $event)" @click-outside="$emit(\'click-outside\')"></div>'
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
24
59
|
});
|
|
25
60
|
});
|
|
26
61
|
|
|
27
62
|
it('renders correctly with the correct position class', () => {
|
|
28
|
-
const position = wrapper.vm.position;
|
|
29
63
|
expect(wrapper.classes()).toContain('emoji-picker');
|
|
30
|
-
expect(wrapper.classes()).toContain(
|
|
64
|
+
expect(wrapper.classes()).toContain('emoji-picker--top');
|
|
31
65
|
});
|
|
32
66
|
|
|
33
|
-
it('
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
expect(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
searchPosition: 'none',
|
|
46
|
-
navPosition: 'bottom',
|
|
47
|
-
noResultsEmoji: 'cry',
|
|
48
|
-
maxFrequentRows: 3,
|
|
49
|
-
});
|
|
67
|
+
it('renders the Picker component with correct props', () => {
|
|
68
|
+
const picker = wrapper.findComponent({ name: 'Picker' });
|
|
69
|
+
expect(picker.exists()).toBe(true);
|
|
70
|
+
expect(picker.props('set')).toBe('apple');
|
|
71
|
+
expect(picker.props('theme')).toBe('light');
|
|
72
|
+
expect(picker.props('preview')).toBe(false);
|
|
73
|
+
expect(picker.props('search')).toBe(true);
|
|
74
|
+
expect(picker.props('navPosition')).toBe('bottom');
|
|
75
|
+
expect(picker.props('noResultsEmoji')).toBe('cry');
|
|
76
|
+
expect(picker.props('maxFrequentRows')).toBe(3);
|
|
77
|
+
expect(picker.props('color')).toBe('#00A49F');
|
|
78
|
+
expect(picker.props('i18n')).toBeDefined();
|
|
50
79
|
});
|
|
51
80
|
|
|
52
|
-
it('emits "emojiSelected" with the correct data when an emoji is selected', () => {
|
|
81
|
+
it('emits "emojiSelected" with the correct data when an emoji is selected', async () => {
|
|
53
82
|
const emojiMock = { id: 'smile', native: '😊' };
|
|
54
|
-
const
|
|
83
|
+
const picker = wrapper.findComponent({ name: 'Picker' });
|
|
55
84
|
|
|
56
|
-
|
|
85
|
+
await picker.vm.$emit('select', emojiMock);
|
|
57
86
|
expect(wrapper.emitted('emojiSelected')).toBeTruthy();
|
|
58
87
|
expect(wrapper.emitted('emojiSelected')[0]).toEqual(['😊']);
|
|
59
88
|
});
|
|
60
89
|
|
|
61
90
|
it('emits "emojiSelected" with the name when `returnName` is true', async () => {
|
|
62
|
-
|
|
91
|
+
const custom = mount(UnnnicEmojiPicker, {
|
|
92
|
+
props: { position: 'top', returnName: true },
|
|
93
|
+
global: {
|
|
94
|
+
stubs: {
|
|
95
|
+
Picker: {
|
|
96
|
+
name: 'Picker',
|
|
97
|
+
props: ['data', 'set', 'theme', 'preview', 'search', 'navPosition', 'noResultsEmoji', 'maxFrequentRows', 'i18n', 'color'],
|
|
98
|
+
emits: ['select', 'click-outside'],
|
|
99
|
+
template: '<div class="emoji-mart-picker" @select="$emit(\'select\', $event)"></div>'
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
});
|
|
63
104
|
|
|
64
105
|
const emojiMock = { id: 'smile', native: '😊' };
|
|
65
|
-
const
|
|
106
|
+
const picker = custom.findComponent({ name: 'Picker' });
|
|
66
107
|
|
|
67
|
-
|
|
68
|
-
expect(
|
|
69
|
-
expect(
|
|
108
|
+
await picker.vm.$emit('select', emojiMock);
|
|
109
|
+
expect(custom.emitted('emojiSelected')).toBeTruthy();
|
|
110
|
+
expect(custom.emitted('emojiSelected')[0]).toEqual(['smile']);
|
|
111
|
+
custom.unmount();
|
|
70
112
|
});
|
|
71
113
|
|
|
72
|
-
it('emits "close" when
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
114
|
+
it('emits "close" when clicking outside the component', async () => {
|
|
115
|
+
// Simula um click fora do componente
|
|
116
|
+
const outsideElement = document.createElement('div');
|
|
117
|
+
document.body.appendChild(outsideElement);
|
|
118
|
+
|
|
119
|
+
const clickEvent = new Event('click', { bubbles: true });
|
|
120
|
+
Object.defineProperty(clickEvent, 'target', { value: outsideElement });
|
|
121
|
+
|
|
122
|
+
document.dispatchEvent(clickEvent);
|
|
123
|
+
|
|
124
|
+
await wrapper.vm.$nextTick();
|
|
76
125
|
expect(wrapper.emitted('close')).toBeTruthy();
|
|
126
|
+
|
|
127
|
+
// Cleanup
|
|
128
|
+
document.body.removeChild(outsideElement);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('renders bottom position class when position is bottom', async () => {
|
|
132
|
+
const custom = mount(UnnnicEmojiPicker, {
|
|
133
|
+
props: { position: 'bottom' },
|
|
134
|
+
global: { stubs: { Picker: { name: 'Picker', props: ['data','set','theme','preview','search','navPosition','noResultsEmoji','maxFrequentRows','i18n','color'], template: '<div />' } } }
|
|
135
|
+
});
|
|
136
|
+
expect(custom.classes()).toContain('emoji-picker--bottom');
|
|
137
|
+
custom.unmount();
|
|
77
138
|
});
|
|
78
139
|
|
|
79
140
|
it('stops event propagation on click', async () => {
|
|
@@ -94,4 +155,19 @@ describe('UnnnicEmojiPicker', () => {
|
|
|
94
155
|
});
|
|
95
156
|
expect(stopPropagationSpy).toHaveBeenCalled();
|
|
96
157
|
});
|
|
158
|
+
|
|
159
|
+
it('uses pt-br as default locale', () => {
|
|
160
|
+
const picker = wrapper.findComponent({ name: 'Picker' });
|
|
161
|
+
const i18nProp = picker.props('i18n');
|
|
162
|
+
expect(i18nProp).toBeDefined();
|
|
163
|
+
expect(i18nProp.search).toBeDefined();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it('uses custom locale when provided', async () => {
|
|
167
|
+
await wrapper.setProps({ locale: 'en' });
|
|
168
|
+
const picker = wrapper.findComponent({ name: 'Picker' });
|
|
169
|
+
const i18nProp = picker.props('i18n');
|
|
170
|
+
expect(i18nProp).toBeDefined();
|
|
171
|
+
expect(i18nProp.search).toBeDefined();
|
|
172
|
+
});
|
|
97
173
|
});
|
|
@@ -24,10 +24,7 @@
|
|
|
24
24
|
</section>
|
|
25
25
|
|
|
26
26
|
<section class="unnnic-modal-dialog__container__body">
|
|
27
|
-
<header
|
|
28
|
-
v-if="title"
|
|
29
|
-
class="unnnic-modal-dialog__container__header"
|
|
30
|
-
>
|
|
27
|
+
<header v-if="title" class="unnnic-modal-dialog__container__header">
|
|
31
28
|
<section class="unnnic-modal-dialog__container__title-container">
|
|
32
29
|
<UnnnicIcon
|
|
33
30
|
v-if="icon || type"
|
|
@@ -49,6 +46,7 @@
|
|
|
49
46
|
data-testid="close-icon"
|
|
50
47
|
icon="close"
|
|
51
48
|
clickable
|
|
49
|
+
scheme="neutral-cloudy"
|
|
52
50
|
@click="close()"
|
|
53
51
|
/>
|
|
54
52
|
</header>
|
|
@@ -98,12 +96,12 @@
|
|
|
98
96
|
</template>
|
|
99
97
|
|
|
100
98
|
<script>
|
|
101
|
-
import UnnnicIcon from
|
|
102
|
-
import UnnnicButton from
|
|
103
|
-
import UnnnicI18n from
|
|
99
|
+
import UnnnicIcon from "../Icon.vue";
|
|
100
|
+
import UnnnicButton from "../Button/Button.vue";
|
|
101
|
+
import UnnnicI18n from "../../mixins/i18n";
|
|
104
102
|
|
|
105
103
|
export default {
|
|
106
|
-
name:
|
|
104
|
+
name: "UnnnicModalDialog",
|
|
107
105
|
components: {
|
|
108
106
|
UnnnicIcon,
|
|
109
107
|
UnnnicButton,
|
|
@@ -120,29 +118,29 @@ export default {
|
|
|
120
118
|
},
|
|
121
119
|
type: {
|
|
122
120
|
type: String,
|
|
123
|
-
default:
|
|
121
|
+
default: "",
|
|
124
122
|
validate(type) {
|
|
125
|
-
return [
|
|
123
|
+
return ["success", "warning", "attention"].includes(type);
|
|
126
124
|
},
|
|
127
125
|
},
|
|
128
126
|
size: {
|
|
129
127
|
type: String,
|
|
130
|
-
default:
|
|
128
|
+
default: "md",
|
|
131
129
|
validate(size) {
|
|
132
|
-
return [
|
|
130
|
+
return ["sm", "md", "lg"].includes(size);
|
|
133
131
|
},
|
|
134
132
|
},
|
|
135
133
|
title: {
|
|
136
134
|
type: String,
|
|
137
|
-
default:
|
|
135
|
+
default: "",
|
|
138
136
|
},
|
|
139
137
|
icon: {
|
|
140
138
|
type: String,
|
|
141
|
-
default:
|
|
139
|
+
default: "",
|
|
142
140
|
},
|
|
143
141
|
iconScheme: {
|
|
144
142
|
type: String,
|
|
145
|
-
default:
|
|
143
|
+
default: "",
|
|
146
144
|
},
|
|
147
145
|
showCloseIcon: {
|
|
148
146
|
type: Boolean,
|
|
@@ -165,26 +163,26 @@ export default {
|
|
|
165
163
|
default: () => ({}),
|
|
166
164
|
},
|
|
167
165
|
},
|
|
168
|
-
emits: [
|
|
166
|
+
emits: ["primaryButtonClick", "secondaryButtonClick", "update:modelValue"],
|
|
169
167
|
|
|
170
168
|
data() {
|
|
171
169
|
return {
|
|
172
170
|
defaultTranslations: {
|
|
173
171
|
cancel: {
|
|
174
|
-
|
|
175
|
-
en:
|
|
176
|
-
es:
|
|
172
|
+
"pt-br": "Cancelar",
|
|
173
|
+
en: "Cancel",
|
|
174
|
+
es: "Cancelar",
|
|
177
175
|
},
|
|
178
176
|
},
|
|
179
177
|
iconsMapper: {
|
|
180
|
-
success: { icon:
|
|
181
|
-
warning: { icon:
|
|
182
|
-
attention: { icon:
|
|
178
|
+
success: { icon: "check_circle", scheme: "aux-green-500" },
|
|
179
|
+
warning: { icon: "warning", scheme: "aux-red-500" },
|
|
180
|
+
attention: { icon: "error", scheme: "aux-yellow-500" },
|
|
183
181
|
},
|
|
184
182
|
primaryButtonTypeMapper: {
|
|
185
|
-
success:
|
|
186
|
-
warning:
|
|
187
|
-
attention:
|
|
183
|
+
success: "primary",
|
|
184
|
+
warning: "warning",
|
|
185
|
+
attention: "attention",
|
|
188
186
|
},
|
|
189
187
|
};
|
|
190
188
|
},
|
|
@@ -195,17 +193,17 @@ export default {
|
|
|
195
193
|
},
|
|
196
194
|
methods: {
|
|
197
195
|
close() {
|
|
198
|
-
this.$emit(
|
|
196
|
+
this.$emit("update:modelValue", false);
|
|
199
197
|
},
|
|
200
198
|
updateBodyOverflow(isHidden) {
|
|
201
|
-
document.body.style.overflow = isHidden ?
|
|
199
|
+
document.body.style.overflow = isHidden ? "hidden" : "";
|
|
202
200
|
},
|
|
203
201
|
},
|
|
204
202
|
};
|
|
205
203
|
</script>
|
|
206
204
|
|
|
207
205
|
<style lang="scss" scoped>
|
|
208
|
-
@use
|
|
206
|
+
@use "@/assets/scss/unnnic" as *;
|
|
209
207
|
* {
|
|
210
208
|
margin: 0;
|
|
211
209
|
padding: 0;
|
|
@@ -312,7 +310,7 @@ export default {
|
|
|
312
310
|
&__actions {
|
|
313
311
|
display: grid;
|
|
314
312
|
grid-template-columns: 1fr 1fr;
|
|
315
|
-
grid-template-areas:
|
|
313
|
+
grid-template-areas: "secondary-button primary-button";
|
|
316
314
|
gap: $unnnic-spacing-sm;
|
|
317
315
|
padding: $unnnic-spacing-md;
|
|
318
316
|
flex-shrink: 0;
|