@weni/unnnic-system 3.2.9-alpha.1 → 3.2.9-alpha.11
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 +18 -0
- package/dist/components/ChartFunnel/DefaultFunnel/ChartDefaultFunnelBase.vue.d.ts.map +1 -1
- package/dist/components/ChartFunnel/SvgFunnel/ChartFunnelTwoRows.vue.d.ts +43 -0
- package/dist/components/ChartFunnel/SvgFunnel/ChartFunnelTwoRows.vue.d.ts.map +1 -0
- package/dist/components/Chip/Chip.vue.d.ts.map +1 -1
- package/dist/components/DataTable/index.vue.d.ts +7 -0
- package/dist/components/DataTable/index.vue.d.ts.map +1 -1
- package/dist/components/DateFilter/DateFilter.vue.d.ts +87 -95
- package/dist/components/Input/BaseInput.vue.d.ts +22 -0
- package/dist/components/Input/BaseInput.vue.d.ts.map +1 -1
- package/dist/components/Input/Input.vue.d.ts +87 -95
- package/dist/components/Input/Input.vue.d.ts.map +1 -1
- package/dist/components/Input/TextInput.vue.d.ts +52 -1
- package/dist/components/Input/TextInput.vue.d.ts.map +1 -1
- package/dist/components/InputDatePicker/InputDatePicker.vue.d.ts +87 -95
- package/dist/components/InputNext/InputNext.vue.d.ts +1 -1
- package/dist/components/Label/Label.vue.d.ts +2 -2
- package/dist/components/Label/Label.vue.d.ts.map +1 -1
- package/dist/components/ModalNext/ModalNext.vue.d.ts +87 -95
- package/dist/components/SelectSmart/SelectSmart.vue.d.ts +52 -1
- package/dist/components/SelectTime/index.vue.d.ts +52 -1
- package/dist/components/Tab/Tab.vue.d.ts +11 -0
- package/dist/components/index.d.ts +895 -937
- package/dist/components/index.d.ts.map +1 -1
- package/dist/{es-2735a8fb.js → es-dcef703d.js} +1 -1
- package/dist/{index-e012fa52.js → index-6ddf8580.js} +4673 -4567
- package/dist/locales/en.json.d.ts +2 -1
- package/dist/locales/es.json.d.ts +2 -1
- package/dist/locales/pt_br.json.d.ts +2 -1
- package/dist/{pt-br-f38a8b9c.js → pt-br-485ef253.js} +1 -1
- package/dist/style.css +1 -1
- package/dist/unnnic.js +1 -1
- package/dist/unnnic.umd.cjs +39 -39
- package/package.json +1 -1
- package/src/assets/scss/scheme-colors.scss +115 -238
- package/src/components/Alert/__tests__/__snapshots__/Alert.spec.js.snap +11 -7
- package/src/components/Alert/__tests__/__snapshots__/Version1dot1.spec.js.snap +2 -2
- package/src/components/ChartFunnel/ChartFunnel.vue +4 -0
- package/src/components/ChartFunnel/DefaultFunnel/ChartDefaultFunnelBase.vue +8 -2
- package/src/components/ChartFunnel/SvgFunnel/ChartFunnelBaseRow.vue +1 -1
- package/src/components/ChartFunnel/SvgFunnel/ChartFunnelTwoRows.vue +64 -0
- package/src/components/Chip/Chip.vue +3 -2
- package/src/components/DataTable/index.vue +25 -10
- package/src/components/Input/BaseInput.vue +21 -2
- package/src/components/Input/Input.scss +2 -1
- package/src/components/Input/Input.vue +26 -30
- package/src/components/Input/TextInput.vue +59 -22
- package/src/components/Input/__test__/__snapshots__/Input.spec.js.snap +7 -3
- package/src/components/Input/__test__/__snapshots__/TextInput.spec.js.snap +7 -1
- package/src/components/Label/Label.vue +2 -2
- package/src/components/Popover/__tests__/Popover.spec.js +147 -0
- package/src/components/Popover/__tests__/__snapshots__/Popover.spec.js.snap +8 -0
- package/src/components/Popover/index.vue +146 -0
- package/src/components/Select/SelectOption.vue +65 -0
- package/src/components/Select/__tests__/Select.spec.js +412 -0
- package/src/components/Select/__tests__/SelectItem.spec.js +330 -0
- package/src/components/Select/__tests__/SelectOption.spec.js +174 -0
- package/src/components/Select/__tests__/__snapshots__/Select.spec.js.snap +97 -0
- package/src/components/Select/__tests__/__snapshots__/SelectItem.spec.js.snap +15 -0
- package/src/components/Select/__tests__/__snapshots__/SelectOption.spec.js.snap +25 -0
- package/src/components/Select/index.vue +245 -0
- package/src/components/Tab/Tab.vue +37 -23
- package/src/components/Tab/__test__/__snapshots__/Tab.spec.js.snap +1 -1
- package/src/locales/en.json +2 -1
- package/src/locales/es.json +2 -1
- package/src/locales/pt_br.json +2 -1
- package/src/stories/ChartFunnel.stories.js +19 -0
- package/src/stories/DataTable.stories.js +60 -0
- package/src/stories/Input.stories.js +6 -0
- package/src/stories/Popover.stories.js +39 -0
- package/src/stories/Select.stories.js +91 -0
- package/src/stories/Tab.stories.js +11 -4
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
{
|
|
17
17
|
'unnnic-data-table__header-cell--clickable': header.isSortable,
|
|
18
18
|
'unnnic-data-table__header-cell--sorting':
|
|
19
|
-
|
|
19
|
+
sortState.header === header.title && sortState.order !== '',
|
|
20
20
|
},
|
|
21
21
|
]"
|
|
22
22
|
@click.stop="handleClickHeader(header)"
|
|
@@ -31,12 +31,12 @@
|
|
|
31
31
|
</template>
|
|
32
32
|
<template v-if="header.isSortable">
|
|
33
33
|
<IconArrowsDefault
|
|
34
|
-
v-if="
|
|
34
|
+
v-if="sortState.header !== header.title"
|
|
35
35
|
class="order-default-icon"
|
|
36
36
|
data-testid="arrow-default-icon"
|
|
37
37
|
/>
|
|
38
38
|
<Icon
|
|
39
|
-
v-else-if="
|
|
39
|
+
v-else-if="sortState.order === 'asc'"
|
|
40
40
|
clickable
|
|
41
41
|
size="ant"
|
|
42
42
|
:icon="'switch_left'"
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
data-testid="arrow-asc-icon"
|
|
45
45
|
/>
|
|
46
46
|
<Icon
|
|
47
|
-
v-else-if="
|
|
47
|
+
v-else-if="sortState.order === 'desc'"
|
|
48
48
|
clickable
|
|
49
49
|
size="ant"
|
|
50
50
|
:icon="'switch_left'"
|
|
@@ -183,6 +183,12 @@ type DataTableItem = {
|
|
|
183
183
|
[key: string]: any;
|
|
184
184
|
};
|
|
185
185
|
|
|
186
|
+
type SortState = {
|
|
187
|
+
header: string;
|
|
188
|
+
itemKey: string;
|
|
189
|
+
order: string;
|
|
190
|
+
};
|
|
191
|
+
|
|
186
192
|
interface Props {
|
|
187
193
|
headers: DataTableHeader[];
|
|
188
194
|
items: DataTableItem[];
|
|
@@ -198,6 +204,7 @@ interface Props {
|
|
|
198
204
|
pageTotal?: number;
|
|
199
205
|
pageInterval?: number;
|
|
200
206
|
locale?: string;
|
|
207
|
+
sort?: SortState;
|
|
201
208
|
}
|
|
202
209
|
|
|
203
210
|
defineOptions({
|
|
@@ -225,6 +232,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
225
232
|
pageTotal: 0,
|
|
226
233
|
pageInterval: 5,
|
|
227
234
|
locale: 'en',
|
|
235
|
+
sort: undefined,
|
|
228
236
|
});
|
|
229
237
|
|
|
230
238
|
const defaultTranslations = {
|
|
@@ -251,12 +259,16 @@ const headersItemsKeys: ComputedRef<string[]> = computed(() => {
|
|
|
251
259
|
return props.headers.map((header) => header.itemKey);
|
|
252
260
|
});
|
|
253
261
|
|
|
254
|
-
const
|
|
262
|
+
const internalSort = ref({
|
|
255
263
|
header: '',
|
|
256
264
|
itemKey: '',
|
|
257
265
|
order: '',
|
|
258
266
|
});
|
|
259
267
|
|
|
268
|
+
const sortState = computed(() => {
|
|
269
|
+
return props.sort !== undefined ? props.sort : internalSort.value;
|
|
270
|
+
});
|
|
271
|
+
|
|
260
272
|
const getHeaderColumnSize = (header: DataTableHeader): string => {
|
|
261
273
|
return typeof header.size === 'number'
|
|
262
274
|
? `${header.size || 1}fr`
|
|
@@ -271,9 +283,12 @@ const gridTemplateColumns: ComputedRef<string> = computed(() => {
|
|
|
271
283
|
return columnSizes.join(' ');
|
|
272
284
|
});
|
|
273
285
|
|
|
274
|
-
const handleSort = (header:
|
|
275
|
-
sort
|
|
276
|
-
|
|
286
|
+
const handleSort = (header: SortState, order: string) => {
|
|
287
|
+
if (props.sort === undefined) {
|
|
288
|
+
internalSort.value = { ...header, order };
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
emit('update:sort', { ...header, order });
|
|
277
292
|
};
|
|
278
293
|
|
|
279
294
|
const handleClickHeader = (header: DataTableHeader) => {
|
|
@@ -286,9 +301,9 @@ const handleClickHeader = (header: DataTableHeader) => {
|
|
|
286
301
|
};
|
|
287
302
|
|
|
288
303
|
const nextSort =
|
|
289
|
-
header.title !==
|
|
304
|
+
header.title !== sortState.value.header
|
|
290
305
|
? 'asc'
|
|
291
|
-
: nextSortOrderMapper[
|
|
306
|
+
: nextSortOrderMapper[sortState.value.order];
|
|
292
307
|
|
|
293
308
|
handleSort(
|
|
294
309
|
nextSort === ''
|
|
@@ -4,16 +4,18 @@
|
|
|
4
4
|
v-mask="mask"
|
|
5
5
|
v-bind="attributes"
|
|
6
6
|
:value="fullySanitize(modelValue)"
|
|
7
|
-
:class="classes"
|
|
7
|
+
:class="[classes, { focus: forceActiveStatus }]"
|
|
8
8
|
:type="nativeType"
|
|
9
|
+
:readonly="readonly"
|
|
9
10
|
/>
|
|
10
11
|
<input
|
|
11
12
|
v-else
|
|
12
13
|
v-bind="attributes"
|
|
13
14
|
:value="fullySanitize(modelValue)"
|
|
14
|
-
:class="classes"
|
|
15
|
+
:class="[classes, { focus: forceActiveStatus }]"
|
|
15
16
|
:type="nativeType"
|
|
16
17
|
:maxlength="maxlength"
|
|
18
|
+
:readonly="readonly"
|
|
17
19
|
/>
|
|
18
20
|
</template>
|
|
19
21
|
|
|
@@ -49,10 +51,19 @@ export default {
|
|
|
49
51
|
},
|
|
50
52
|
hasIconLeft: Boolean,
|
|
51
53
|
hasIconRight: Boolean,
|
|
54
|
+
hasClearIcon: Boolean,
|
|
52
55
|
maxlength: {
|
|
53
56
|
type: Number,
|
|
54
57
|
default: null,
|
|
55
58
|
},
|
|
59
|
+
readonly: {
|
|
60
|
+
type: Boolean,
|
|
61
|
+
default: false,
|
|
62
|
+
},
|
|
63
|
+
forceActiveStatus: {
|
|
64
|
+
type: Boolean,
|
|
65
|
+
default: false,
|
|
66
|
+
},
|
|
56
67
|
},
|
|
57
68
|
emits: ['update:modelValue'],
|
|
58
69
|
data() {
|
|
@@ -77,6 +88,7 @@ export default {
|
|
|
77
88
|
{
|
|
78
89
|
'input--has-icon-left': this.hasIconLeft,
|
|
79
90
|
'input--has-icon-right': this.hasIconRight,
|
|
91
|
+
'input--has-clear-icon': this.hasClearIcon,
|
|
80
92
|
},
|
|
81
93
|
];
|
|
82
94
|
},
|
|
@@ -115,6 +127,13 @@ export default {
|
|
|
115
127
|
|
|
116
128
|
&.input--has-icon-right {
|
|
117
129
|
padding-right: $unnnic-space-10;
|
|
130
|
+
&.input--has-clear-icon {
|
|
131
|
+
padding-right: $unnnic-space-10 + $unnnic-space-6;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
&.input--has-clear-icon {
|
|
136
|
+
padding-right: $unnnic-space-10;
|
|
118
137
|
}
|
|
119
138
|
|
|
120
139
|
&.error {
|
|
@@ -6,30 +6,19 @@
|
|
|
6
6
|
>
|
|
7
7
|
<slot name="label" />
|
|
8
8
|
</p>
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
<UnnnicLabel
|
|
10
11
|
v-else-if="label"
|
|
11
12
|
class="unnnic-form__label"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
</p>
|
|
16
|
-
<UnnnicToolTip
|
|
17
|
-
v-if="tooltip"
|
|
18
|
-
enabled
|
|
19
|
-
:text="tooltip"
|
|
20
|
-
>
|
|
21
|
-
<UnnnicIcon
|
|
22
|
-
icon="help"
|
|
23
|
-
size="sm"
|
|
24
|
-
scheme="fg-base"
|
|
25
|
-
/>
|
|
26
|
-
</UnnnicToolTip>
|
|
27
|
-
</section>
|
|
13
|
+
:label="label"
|
|
14
|
+
:tooltip="tooltip"
|
|
15
|
+
/>
|
|
28
16
|
|
|
29
17
|
<TextInput
|
|
30
18
|
v-bind="$attrs"
|
|
31
19
|
v-model="val"
|
|
32
20
|
class="unnnic-form-input"
|
|
21
|
+
:forceActiveStatus="forceActiveStatus"
|
|
33
22
|
:placeholder="placeholder"
|
|
34
23
|
:iconLeft="iconLeft"
|
|
35
24
|
:iconRight="iconRight"
|
|
@@ -42,6 +31,9 @@
|
|
|
42
31
|
:nativeType="nativeType"
|
|
43
32
|
:maxlength="maxlength"
|
|
44
33
|
:disabled="disabled"
|
|
34
|
+
:readonly="readonly"
|
|
35
|
+
:showClear="showClear"
|
|
36
|
+
@clear="$emit('clear')"
|
|
45
37
|
/>
|
|
46
38
|
|
|
47
39
|
<section class="unnnic-form__hints-container">
|
|
@@ -69,12 +61,11 @@
|
|
|
69
61
|
<script>
|
|
70
62
|
import { fullySanitize } from '../../utils/sanitize';
|
|
71
63
|
import TextInput from './TextInput.vue';
|
|
72
|
-
import
|
|
73
|
-
import UnnnicIcon from '../Icon.vue';
|
|
64
|
+
import UnnnicLabel from '../Label/Label.vue';
|
|
74
65
|
|
|
75
66
|
export default {
|
|
76
67
|
name: 'UnnnicInput',
|
|
77
|
-
components: { TextInput,
|
|
68
|
+
components: { TextInput, UnnnicLabel },
|
|
78
69
|
props: {
|
|
79
70
|
placeholder: {
|
|
80
71
|
type: String,
|
|
@@ -155,8 +146,22 @@ export default {
|
|
|
155
146
|
type: Boolean,
|
|
156
147
|
default: false,
|
|
157
148
|
},
|
|
149
|
+
readonly: {
|
|
150
|
+
type: Boolean,
|
|
151
|
+
default: false,
|
|
152
|
+
},
|
|
153
|
+
forceActiveStatus: {
|
|
154
|
+
type: Boolean,
|
|
155
|
+
default: false,
|
|
156
|
+
},
|
|
157
|
+
showClear: {
|
|
158
|
+
type: Boolean,
|
|
159
|
+
default: false,
|
|
160
|
+
},
|
|
158
161
|
},
|
|
159
|
-
|
|
162
|
+
|
|
163
|
+
emits: ['update:modelValue', 'clear'],
|
|
164
|
+
|
|
160
165
|
data() {
|
|
161
166
|
return {
|
|
162
167
|
val: this.modelValue,
|
|
@@ -203,16 +208,7 @@ export default {
|
|
|
203
208
|
}
|
|
204
209
|
|
|
205
210
|
&__label {
|
|
206
|
-
font: $unnnic-font-body;
|
|
207
|
-
color: $unnnic-color-neutral-cloudy;
|
|
208
211
|
margin-bottom: $unnnic-space-1;
|
|
209
|
-
display: flex;
|
|
210
|
-
align-items: center;
|
|
211
|
-
gap: $unnnic-space-2;
|
|
212
|
-
|
|
213
|
-
:deep(.unnnic-tooltip) {
|
|
214
|
-
display: flex;
|
|
215
|
-
}
|
|
216
212
|
}
|
|
217
213
|
|
|
218
214
|
&__hints-container {
|
|
@@ -12,7 +12,10 @@
|
|
|
12
12
|
class="input-itself"
|
|
13
13
|
:hasIconLeft="!!iconLeft"
|
|
14
14
|
:hasIconRight="!!iconRight || allowTogglePassword"
|
|
15
|
+
:hasClearIcon="showClear"
|
|
15
16
|
:maxlength="maxlength"
|
|
17
|
+
:readonly="readonly"
|
|
18
|
+
:forceActiveStatus="forceActiveStatus"
|
|
16
19
|
@focus="onFocus"
|
|
17
20
|
@blur="onBlur"
|
|
18
21
|
/>
|
|
@@ -27,18 +30,28 @@
|
|
|
27
30
|
@click="onIconLeftClick"
|
|
28
31
|
/>
|
|
29
32
|
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
<section class="icon-right-container">
|
|
34
|
+
<UnnnicIcon
|
|
35
|
+
v-if="showClear"
|
|
36
|
+
class="icon-clear"
|
|
37
|
+
:scheme="iconScheme"
|
|
38
|
+
icon="close"
|
|
39
|
+
size="ant"
|
|
40
|
+
clickable
|
|
41
|
+
@click.stop="onClearClick"
|
|
42
|
+
/>
|
|
43
|
+
|
|
44
|
+
<UnnnicIcon
|
|
45
|
+
v-if="iconRightSvg"
|
|
46
|
+
:scheme="iconScheme"
|
|
47
|
+
:icon="iconRightSvg"
|
|
48
|
+
size="ant"
|
|
49
|
+
:clickable="iconRightClickable || allowTogglePassword"
|
|
50
|
+
class="icon-right"
|
|
51
|
+
:class="{ clickable: iconRightClickable || allowTogglePassword }"
|
|
52
|
+
@click="onIconRightClick"
|
|
53
|
+
/>
|
|
54
|
+
</section>
|
|
42
55
|
</div>
|
|
43
56
|
</template>
|
|
44
57
|
|
|
@@ -107,8 +120,20 @@ export default {
|
|
|
107
120
|
type: Boolean,
|
|
108
121
|
default: false,
|
|
109
122
|
},
|
|
123
|
+
readonly: {
|
|
124
|
+
type: Boolean,
|
|
125
|
+
default: false,
|
|
126
|
+
},
|
|
127
|
+
forceActiveStatus: {
|
|
128
|
+
type: Boolean,
|
|
129
|
+
default: false,
|
|
130
|
+
},
|
|
131
|
+
showClear: {
|
|
132
|
+
type: Boolean,
|
|
133
|
+
default: false,
|
|
134
|
+
},
|
|
110
135
|
},
|
|
111
|
-
emits: ['icon-left-click', 'icon-right-click'],
|
|
136
|
+
emits: ['icon-left-click', 'icon-right-click', 'clear'],
|
|
112
137
|
data() {
|
|
113
138
|
return {
|
|
114
139
|
isFocused: false,
|
|
@@ -137,7 +162,7 @@ export default {
|
|
|
137
162
|
return 'fg-muted';
|
|
138
163
|
}
|
|
139
164
|
|
|
140
|
-
if (this.modelValue || this.isFocused) {
|
|
165
|
+
if (this.modelValue || this.isFocused || this.forceActiveStatus) {
|
|
141
166
|
return 'color-gray-700';
|
|
142
167
|
}
|
|
143
168
|
|
|
@@ -170,6 +195,10 @@ export default {
|
|
|
170
195
|
if (this.iconLeftClickable) this.$emit('icon-left-click');
|
|
171
196
|
},
|
|
172
197
|
|
|
198
|
+
onClearClick() {
|
|
199
|
+
this.$emit('clear');
|
|
200
|
+
},
|
|
201
|
+
|
|
173
202
|
onIconRightClick() {
|
|
174
203
|
if (this.attributes.disabled) return;
|
|
175
204
|
if (this.allowTogglePassword) this.showPassword = !this.showPassword;
|
|
@@ -187,25 +216,33 @@ export default {
|
|
|
187
216
|
}
|
|
188
217
|
|
|
189
218
|
.icon {
|
|
190
|
-
&-left,
|
|
191
|
-
&-right {
|
|
192
|
-
&:not(.clickable) {
|
|
193
|
-
pointer-events: none;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
219
|
&-left {
|
|
198
220
|
position: absolute;
|
|
199
221
|
top: 50%;
|
|
200
222
|
transform: translateY(-50%);
|
|
201
223
|
left: $unnnic-space-4;
|
|
224
|
+
|
|
225
|
+
&:not(.clickable) {
|
|
226
|
+
pointer-events: none;
|
|
227
|
+
}
|
|
202
228
|
}
|
|
203
229
|
|
|
204
|
-
&-right {
|
|
230
|
+
&-right-container {
|
|
205
231
|
position: absolute;
|
|
206
232
|
top: 50%;
|
|
207
233
|
transform: translateY(-50%);
|
|
208
234
|
right: $unnnic-space-4;
|
|
235
|
+
|
|
236
|
+
display: flex;
|
|
237
|
+
align-items: center;
|
|
238
|
+
gap: $unnnic-space-2;
|
|
239
|
+
|
|
240
|
+
.icon-clear {
|
|
241
|
+
cursor: pointer;
|
|
242
|
+
}
|
|
243
|
+
.icon-right:not(.clickable) {
|
|
244
|
+
pointer-events: none;
|
|
245
|
+
}
|
|
209
246
|
}
|
|
210
247
|
}
|
|
211
248
|
</style>
|
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`Input.vue > matches the snapshot 1`] = `
|
|
4
4
|
"<div data-v-d890ad85="" class="unnnic-form md">
|
|
5
|
-
<section data-v-d890ad85="" class="unnnic-form__label">
|
|
6
|
-
<p data-v-
|
|
5
|
+
<section data-v-7f222291="" data-v-d890ad85="" class="unnnic-label unnnic-form__label">
|
|
6
|
+
<p data-v-7f222291="" class="unnnic-label__label">Sample Label</p>
|
|
7
7
|
<!--v-if-->
|
|
8
8
|
</section>
|
|
9
|
-
<div data-v-a0d36167="" data-v-d890ad85="" class="text-input size--md unnnic-form-input" mask="####-####"><input data-v-86533b41="" data-v-a0d36167="" class="unnnic-form-input input-itself input size-md normal input--has-icon-left input--has-icon-right unnnic-form-input input-itself" placeholder="Enter text" iconleft="search" iconright="clear" iconleftclickable="true" iconrightclickable="true" hascloudycolor="false" type="text" value=""><span data-v-26446d8e="" data-v-a0d36167="" class="material-symbols-rounded unnnic-icon-scheme--fg-base unnnic-icon-size--ant unnnic--clickable icon-left clickable" data-testid="material-icon" translate="no">search</span
|
|
9
|
+
<div data-v-a0d36167="" data-v-d890ad85="" class="text-input size--md unnnic-form-input" mask="####-####"><input data-v-86533b41="" data-v-a0d36167="" class="unnnic-form-input input-itself input size-md normal input--has-icon-left input--has-icon-right unnnic-form-input input-itself" placeholder="Enter text" iconleft="search" iconright="clear" iconleftclickable="true" iconrightclickable="true" hascloudycolor="false" showclear="false" type="text" value=""><span data-v-26446d8e="" data-v-a0d36167="" class="material-symbols-rounded unnnic-icon-scheme--fg-base unnnic-icon-size--ant unnnic--clickable icon-left clickable" data-testid="material-icon" translate="no">search</span>
|
|
10
|
+
<section data-v-a0d36167="" class="icon-right-container">
|
|
11
|
+
<!--v-if--><span data-v-26446d8e="" data-v-a0d36167="" class="material-symbols-rounded unnnic-icon-scheme--fg-base unnnic-icon-size--ant unnnic--clickable icon-right clickable" data-testid="material-icon" translate="no">clear</span>
|
|
12
|
+
</section>
|
|
13
|
+
</div>
|
|
10
14
|
<section data-v-d890ad85="" class="unnnic-form__hints-container">
|
|
11
15
|
<section data-v-d890ad85="" class="unnnic-form__message-container">
|
|
12
16
|
<p data-v-d890ad85="" class="unnnic-form__message">Error message</p>
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
|
-
exports[`TextInput.vue > matches the snapshot 1`] = `
|
|
3
|
+
exports[`TextInput.vue > matches the snapshot 1`] = `
|
|
4
|
+
"<div data-v-a0d36167="" class="text-input size--md"><input data-v-86533b41="" data-v-a0d36167="" placeholder="Enter text" iconleft="search" iconright="clear" iconleftclickable="true" iconrightclickable="true" allowtogglepassword="false" hascloudycolor="false" showclear="false" class="input-itself input size-md normal input--has-icon-left input--has-icon-right input-itself" type="text" value=""><span data-v-26446d8e="" data-v-a0d36167="" class="material-symbols-rounded unnnic-icon-scheme--fg-base unnnic-icon-size--ant unnnic--clickable icon-left clickable" data-testid="material-icon" translate="no">search</span>
|
|
5
|
+
<section data-v-a0d36167="" class="icon-right-container">
|
|
6
|
+
<!--v-if--><span data-v-26446d8e="" data-v-a0d36167="" class="material-symbols-rounded unnnic-icon-scheme--fg-base unnnic-icon-size--ant unnnic--clickable icon-right clickable" data-testid="material-icon" translate="no">clear</span>
|
|
7
|
+
</section>
|
|
8
|
+
</div>"
|
|
9
|
+
`;
|
|
@@ -26,13 +26,13 @@ defineOptions({
|
|
|
26
26
|
name: 'UnnnicLabel',
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
-
interface
|
|
29
|
+
export interface LabelProps {
|
|
30
30
|
label?: string;
|
|
31
31
|
tooltip?: string;
|
|
32
32
|
useHtmlTooltip?: boolean;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
const props = withDefaults(defineProps<
|
|
35
|
+
const props = withDefaults(defineProps<LabelProps>(), {
|
|
36
36
|
label: '',
|
|
37
37
|
tooltip: '',
|
|
38
38
|
useHtmlTooltip: false,
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import { beforeEach, describe, expect, afterEach, test, vi } from 'vitest';
|
|
3
|
+
import UnnnicPopover from '@/components/Popover/index.vue';
|
|
4
|
+
|
|
5
|
+
vi.mock('@vueuse/core', () => ({
|
|
6
|
+
onClickOutside: vi.fn(),
|
|
7
|
+
useResizeObserver: vi.fn(),
|
|
8
|
+
}));
|
|
9
|
+
|
|
10
|
+
describe('UnnnicPopover.vue', () => {
|
|
11
|
+
let wrapper;
|
|
12
|
+
|
|
13
|
+
const defaultSlots = {
|
|
14
|
+
trigger: '<button data-testid="trigger-button">Click me</button>',
|
|
15
|
+
content: '<div data-testid="popover-content">Popover content</div>',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const mountWrapper = (props) => {
|
|
19
|
+
return mount(UnnnicPopover, {
|
|
20
|
+
slots: defaultSlots,
|
|
21
|
+
props: {
|
|
22
|
+
...props,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
wrapper = mountWrapper();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
wrapper?.unmount();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test('renders correctly', () => {
|
|
36
|
+
expect(wrapper.exists()).toBe(true);
|
|
37
|
+
expect(wrapper.find('.unnnic-popover').exists()).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('renders trigger slot', () => {
|
|
41
|
+
const trigger = wrapper.find('[data-testid="popover-trigger"]');
|
|
42
|
+
const triggerButton = wrapper.find('[data-testid="trigger-button"]');
|
|
43
|
+
|
|
44
|
+
expect(trigger.exists()).toBe(true);
|
|
45
|
+
expect(triggerButton.exists()).toBe(true);
|
|
46
|
+
expect(triggerButton.text()).toBe('Click me');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('renders content slot inside balloon', async () => {
|
|
50
|
+
wrapper.vm.open = true;
|
|
51
|
+
await wrapper.vm.$nextTick();
|
|
52
|
+
const balloon = wrapper.find('[data-testid="popover-balloon"]');
|
|
53
|
+
const content = wrapper.find('[data-testid="popover-content"]');
|
|
54
|
+
|
|
55
|
+
expect(balloon.exists()).toBe(true);
|
|
56
|
+
expect(content.exists()).toBe(true);
|
|
57
|
+
expect(content.text()).toBe('Popover content');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('balloon is hidden by default', () => {
|
|
61
|
+
const balloon = wrapper.find('[data-testid="popover-balloon"]');
|
|
62
|
+
expect(balloon.exists()).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test('toggles balloon visibility when trigger is clicked', async () => {
|
|
66
|
+
const trigger = wrapper.find('[data-testid="popover-trigger"]');
|
|
67
|
+
|
|
68
|
+
let balloon = wrapper.find('[data-testid="popover-balloon"]');
|
|
69
|
+
|
|
70
|
+
expect(balloon.exists()).toBe(false);
|
|
71
|
+
|
|
72
|
+
await trigger.trigger('click');
|
|
73
|
+
await wrapper.vm.$nextTick();
|
|
74
|
+
|
|
75
|
+
balloon = wrapper.find('[data-testid="popover-balloon"]');
|
|
76
|
+
|
|
77
|
+
expect(balloon.exists()).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('uses modelValue when provided', async () => {
|
|
81
|
+
const wrapper = mountWrapper({ modelValue: true });
|
|
82
|
+
const balloon = wrapper.find('[data-testid="popover-balloon"]');
|
|
83
|
+
expect(balloon.isVisible()).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('emits update:modelValue when open state changes', async () => {
|
|
87
|
+
await wrapper.setProps({ modelValue: false });
|
|
88
|
+
|
|
89
|
+
const trigger = wrapper.find('[data-testid="popover-trigger"]');
|
|
90
|
+
await trigger.trigger('click');
|
|
91
|
+
|
|
92
|
+
expect(wrapper.emitted('update:modelValue')).toBeTruthy();
|
|
93
|
+
expect(wrapper.emitted('update:modelValue')[0]).toEqual([true]);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('does not emit update:modelValue when modelValue is undefined', async () => {
|
|
97
|
+
const trigger = wrapper.find('[data-testid="popover-trigger"]');
|
|
98
|
+
await trigger.trigger('click');
|
|
99
|
+
|
|
100
|
+
expect(wrapper.emitted('update:modelValue')).toBeFalsy();
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test('exposes open ref', () => {
|
|
104
|
+
expect(wrapper.vm.open).toBeDefined();
|
|
105
|
+
expect(typeof wrapper.vm.open).toBe('boolean');
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test('open ref can be controlled programmatically', async () => {
|
|
109
|
+
wrapper.vm.open = true;
|
|
110
|
+
await wrapper.vm.$nextTick();
|
|
111
|
+
|
|
112
|
+
const balloon = wrapper.find('[data-testid="popover-balloon"]');
|
|
113
|
+
expect(balloon.isVisible()).toBe(true);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test('persistent prop prevents closing on outside click', async () => {
|
|
117
|
+
await wrapper.setProps({ persistent: true });
|
|
118
|
+
|
|
119
|
+
const { onClickOutside } = await import('@vueuse/core');
|
|
120
|
+
const mockOnClickOutside = vi.mocked(onClickOutside);
|
|
121
|
+
|
|
122
|
+
const callback = mockOnClickOutside.mock.calls[0][1];
|
|
123
|
+
|
|
124
|
+
wrapper.vm.open = true;
|
|
125
|
+
await wrapper.vm.$nextTick();
|
|
126
|
+
|
|
127
|
+
callback();
|
|
128
|
+
|
|
129
|
+
const balloon = wrapper.find('[data-testid="popover-balloon"]');
|
|
130
|
+
expect(balloon.isVisible()).toBe(true);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test('applies correct CSS classes', async () => {
|
|
134
|
+
wrapper.vm.open = true;
|
|
135
|
+
await wrapper.vm.$nextTick();
|
|
136
|
+
|
|
137
|
+
const popover = wrapper.find('.unnnic-popover');
|
|
138
|
+
const balloon = wrapper.find('.unnnic-popover__balloon');
|
|
139
|
+
|
|
140
|
+
expect(popover.exists()).toBe(true);
|
|
141
|
+
expect(balloon.exists()).toBe(true);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test('matches the snapshot', () => {
|
|
145
|
+
expect(wrapper.html()).toMatchSnapshot();
|
|
146
|
+
});
|
|
147
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`UnnnicPopover.vue > matches the snapshot 1`] = `
|
|
4
|
+
"<section data-v-5a3125ac="" class="unnnic-popover">
|
|
5
|
+
<div data-v-5a3125ac="" class="unnnic-popover__trigger" data-testid="popover-trigger"><button data-testid="trigger-button">Click me</button></div>
|
|
6
|
+
<!--v-if-->
|
|
7
|
+
</section>"
|
|
8
|
+
`;
|