@weni/unnnic-system 3.2.5 → 3.2.7-alpha.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.
Files changed (145) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/components/Accordion/Accordion.vue.d.ts +1 -1
  3. package/dist/components/Alert/Alert.vue.d.ts +5 -5
  4. package/dist/components/Alert/Version1dot1.vue.d.ts +2 -2
  5. package/dist/components/AudioRecorder/AudioHandler.vue.d.ts +1 -1
  6. package/dist/components/AudioRecorder/AudioPlayer.vue.d.ts +1 -1
  7. package/dist/components/AudioRecorder/AudioRecorder.vue.d.ts +3 -3
  8. package/dist/components/AvatarIcon/AvatarIcon.vue.d.ts +2 -2
  9. package/dist/components/Banner/Banner.vue.d.ts +1 -1
  10. package/dist/components/Banner/InfoBanner.vue.d.ts +1 -1
  11. package/dist/components/Breadcrumb/Breadcrumb.vue.d.ts +1 -1
  12. package/dist/components/Button/Button.vue.d.ts +2 -2
  13. package/dist/components/Button/Button.vue.d.ts.map +1 -1
  14. package/dist/components/Button/ButtonIcon.vue.d.ts +1 -1
  15. package/dist/components/Button/types.d.ts +1 -1
  16. package/dist/components/Button/types.d.ts.map +1 -1
  17. package/dist/components/Card/AccountCard.vue.d.ts +3 -3
  18. package/dist/components/Card/BlankCard.vue.d.ts +1 -1
  19. package/dist/components/Card/Card.vue.d.ts +20 -20
  20. package/dist/components/Card/CardCompany.vue.d.ts +7 -7
  21. package/dist/components/Card/CardData.vue.d.ts +1 -1
  22. package/dist/components/Card/CardStatusesContainer.vue.d.ts +3 -3
  23. package/dist/components/Card/ContentCard.vue.d.ts +2 -2
  24. package/dist/components/Card/DashCard.vue.d.ts +4 -4
  25. package/dist/components/Card/DefaultCard.vue.d.ts +1 -1
  26. package/dist/components/Card/MarketplaceCard.vue.d.ts +2 -2
  27. package/dist/components/Card/SimpleCard.vue.d.ts +2 -2
  28. package/dist/components/Card/StatusCard.vue.d.ts +2 -2
  29. package/dist/components/Card/TitleCard.vue.d.ts +1 -1
  30. package/dist/components/CardImage/CardImage.vue.d.ts +16 -7
  31. package/dist/components/CardInformation/CardInformation.vue.d.ts +3 -3
  32. package/dist/components/CardProject/CardProject.vue.d.ts +11 -2
  33. package/dist/components/Carousel/Carousel.vue.d.ts +10 -10
  34. package/dist/components/Carousel/TagCarousel.vue.d.ts +8 -8
  35. package/dist/components/ChartBar/ChartBar.vue.d.ts +7 -7
  36. package/dist/components/ChatText/ChatText.vue.d.ts +1 -1
  37. package/dist/components/ChatsContact/ChatsContact.vue.d.ts +14 -14
  38. package/dist/components/ChatsDashboardTagLive/ChatsDashboardTagLive.vue.d.ts +1 -1
  39. package/dist/components/ChatsHeader/ChatsHeader.vue.d.ts +1 -1
  40. package/dist/components/ChatsHeader/ChatsHeader.vue.d.ts.map +1 -1
  41. package/dist/components/ChatsMessage/ChatsMessage.vue.d.ts +4 -4
  42. package/dist/components/ChatsMessage/ChatsMessageStatusBackdrop.vue.d.ts +2 -2
  43. package/dist/components/ChatsNavbar/ChatsNavbar.vue.d.ts +1 -1
  44. package/dist/components/ChatsUserAvatar/ChatsUserAvatar.vue.d.ts +2 -2
  45. package/dist/components/Checkbox/Checkbox.vue.d.ts +3 -3
  46. package/dist/components/Comment/Comment.vue.d.ts +1 -1
  47. package/dist/components/DataArea/DataArea.vue.d.ts +1 -1
  48. package/dist/components/DataTable/index.vue.d.ts +3 -1
  49. package/dist/components/DataTable/index.vue.d.ts.map +1 -1
  50. package/dist/components/DateFilter/DateFilter.vue.d.ts +182 -27
  51. package/dist/components/DatePicker/DatePicker.vue.d.ts +8 -8
  52. package/dist/components/Drawer/Drawer.vue.d.ts +7 -7
  53. package/dist/components/DropArea/DropArea.vue.d.ts +2 -0
  54. package/dist/components/DropArea/DropArea.vue.d.ts.map +1 -1
  55. package/dist/components/Dropdown/Dropdown.vue.d.ts +9 -0
  56. package/dist/components/Dropdown/LanguageSelect.vue.d.ts +3 -3
  57. package/dist/components/Flag.vue.d.ts +2 -2
  58. package/dist/components/FormElement/FormElement.vue.d.ts +38 -32
  59. package/dist/components/FormElement/FormElement.vue.d.ts.map +1 -1
  60. package/dist/components/Icon.vue.d.ts +1 -1
  61. package/dist/components/IconLoading/IconLoading.vue.d.ts +1 -1
  62. package/dist/components/ImportCard/ImportCard.vue.d.ts +7 -7
  63. package/dist/components/Input/BaseInput.vue.d.ts +10 -1
  64. package/dist/components/Input/BaseInput.vue.d.ts.map +1 -1
  65. package/dist/components/Input/Input.vue.d.ts +182 -27
  66. package/dist/components/Input/Input.vue.d.ts.map +1 -1
  67. package/dist/components/Input/TextInput.vue.d.ts +31 -13
  68. package/dist/components/InputDatePicker/InputDatePicker.vue.d.ts +192 -37
  69. package/dist/components/InputNext/InputNext.vue.d.ts +3 -3
  70. package/dist/components/Modal/Modal.vue.d.ts +2 -2
  71. package/dist/components/ModalDialog/ModalDialog.vue.d.ts +10 -10
  72. package/dist/components/ModalDialog/ModalDialog.vue.d.ts.map +1 -1
  73. package/dist/components/ModalNext/ModalNext.vue.d.ts +189 -34
  74. package/dist/components/ModalUpload/ModalUpload.vue.d.ts +20 -14
  75. package/dist/components/MultiSelect/MultiSelect.vue.d.ts +7 -7
  76. package/dist/components/Pagination/Pagination.vue.d.ts +6 -6
  77. package/dist/components/ProgressBar/ProgressBar.vue.d.ts +1 -1
  78. package/dist/components/Radio/Radio.vue.d.ts +2 -2
  79. package/dist/components/SelectSmart/SelectSmart.vue.d.ts +45 -26
  80. package/dist/components/SelectSmart/SelectSmartMultipleHeader.vue.d.ts +7 -7
  81. package/dist/components/SelectSmart/SelectSmartOption.vue.d.ts +4 -4
  82. package/dist/components/SelectTime/index.vue.d.ts +31 -13
  83. package/dist/components/Slider/Slider.vue.d.ts +1 -1
  84. package/dist/components/StarRating/StarRating.vue.d.ts +1 -1
  85. package/dist/components/Switch/Switch.vue.d.ts +2 -2
  86. package/dist/components/Tab/Tab.vue.d.ts +1 -1
  87. package/dist/components/TableNext/TableBodyCell.vue.d.ts +2 -2
  88. package/dist/components/TableNext/TablePagination.vue.d.ts +6 -6
  89. package/dist/components/TabsExpanded/TabsExpanded.vue.d.ts +1 -1
  90. package/dist/components/Tag/BrandTag.vue.d.ts +2 -2
  91. package/dist/components/Tag/DefaultTag.vue.d.ts +2 -2
  92. package/dist/components/Tag/IndicatorTag.vue.d.ts +1 -1
  93. package/dist/components/Tag/Tag.vue.d.ts +7 -7
  94. package/dist/components/TemplatePreview/TemplatePreview.vue.d.ts +9 -0
  95. package/dist/components/TemplatePreview/TemplatePreview.vue.d.ts.map +1 -0
  96. package/dist/components/TemplatePreview/TemplatePreviewModal.vue.d.ts +15 -0
  97. package/dist/components/TemplatePreview/TemplatePreviewModal.vue.d.ts.map +1 -0
  98. package/dist/components/TextArea/TextArea.vue.d.ts +38 -32
  99. package/dist/components/TextArea/TextArea.vue.d.ts.map +1 -1
  100. package/dist/components/Tour/Tour.vue.d.ts +6 -6
  101. package/dist/components/Tour/TourPopover.vue.d.ts +6 -6
  102. package/dist/components/UploadArea/UploadArea.vue.d.ts +13 -7
  103. package/dist/components/index.d.ts +2071 -767
  104. package/dist/components/index.d.ts.map +1 -1
  105. package/dist/{es-a07e7553.mjs → es-a147ef18.mjs} +1 -1
  106. package/dist/{index-93aafec9.mjs → index-802ab669.mjs} +8035 -7832
  107. package/dist/{pt-br-a81c613f.mjs → pt-br-cdc64aa4.mjs} +1 -1
  108. package/dist/style.css +1 -1
  109. package/dist/unnnic.mjs +123 -119
  110. package/dist/unnnic.umd.js +42 -41
  111. package/package.json +2 -2
  112. package/src/assets/img/previews/doc-preview.png +0 -0
  113. package/src/assets/img/previews/image-preview.png +0 -0
  114. package/src/assets/img/previews/video-preview.png +0 -0
  115. package/src/components/Button/Button.vue +57 -108
  116. package/src/components/Button/types.ts +0 -1
  117. package/src/components/DataTable/index.vue +26 -14
  118. package/src/components/DropArea/DropArea.vue +26 -2
  119. package/src/components/Dropdown/Dropdown.vue +6 -0
  120. package/src/components/Dropdown/__tests__/Dropdown.spec.js +57 -0
  121. package/src/components/FormElement/FormElement.vue +50 -90
  122. package/src/components/Input/BaseInput.vue +10 -12
  123. package/src/components/Input/Input.scss +17 -20
  124. package/src/components/Input/Input.vue +86 -28
  125. package/src/components/Input/TextInput.vue +27 -35
  126. package/src/components/Input/__test__/TextInput.spec.js +5 -5
  127. package/src/components/Input/__test__/__snapshots__/Input.spec.js.snap +12 -3
  128. package/src/components/Input/__test__/__snapshots__/TextInput.spec.js.snap +1 -1
  129. package/src/components/ModalDialog/ModalDialog.vue +27 -29
  130. package/src/components/ModalDialog/__tests__/__snapshots__/ModalDialog.spec.js.snap +1 -1
  131. package/src/components/SelectSmart/SelectSmart.vue +3 -1
  132. package/src/components/SelectSmart/__tests__/SelectSmart.spec.js +45 -0
  133. package/src/components/TableNext/__test__/__snapshots__/TableNext.spec.js.snap +2 -2
  134. package/src/components/TableNext/__test__/__snapshots__/TablePagination.spec.js.snap +2 -2
  135. package/src/components/TemplatePreview/TemplatePreview.vue +249 -0
  136. package/src/components/TemplatePreview/TemplatePreviewModal.vue +51 -0
  137. package/src/components/TemplatePreview/types.d.ts +16 -0
  138. package/src/components/TextArea/TextArea.vue +14 -9
  139. package/src/components/TextArea/__test__/__snapshots__/TextArea.spec.js.snap +7 -2
  140. package/src/components/index.ts +11 -3
  141. package/src/stories/Button.stories.js +1 -10
  142. package/src/stories/DataTable.stories.js +2 -2
  143. package/src/stories/Input.stories.js +17 -3
  144. package/src/stories/TemplatePreview.stories.js +94 -0
  145. package/src/stories/TemplatePreviewModal.stories.js +110 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weni/unnnic-system",
3
- "version": "3.2.5",
3
+ "version": "3.2.7-alpha.0",
4
4
  "type": "commonjs",
5
5
  "files": [
6
6
  "dist",
@@ -100,4 +100,4 @@
100
100
  "vue-eslint-parser": "^9.4.2",
101
101
  "vue-tsc": "^3.0.5"
102
102
  }
103
- }
103
+ }
@@ -6,20 +6,16 @@
6
6
  :class="[
7
7
  'unnnic-button',
8
8
  `unnnic-button--size-${size}`,
9
- `unnnic-button--${type}`,
9
+ `unnnic-button--${buttonType}`,
10
10
  iconCenter ? `unnnic-button--icon-on-center` : null,
11
11
  float ? `unnnic-button--float` : null,
12
12
  ]"
13
13
  >
14
- <UnnnicIcon
14
+ <UnnnicIconLoading
15
15
  v-if="loading"
16
- icon="loading-circle-1"
17
16
  :scheme="iconScheme"
18
17
  :size="iconSize"
19
- :filled="iconsFilled"
20
18
  :style="{ position: 'absolute' }"
21
- class="rotation"
22
- :next="next"
23
19
  data-testid="icon-loading"
24
20
  />
25
21
 
@@ -72,6 +68,7 @@
72
68
  <script setup lang="ts">
73
69
  import { computed, watch, useSlots } from 'vue';
74
70
  import UnnnicIcon from '../Icon.vue';
71
+ import UnnnicIconLoading from '../IconLoading/IconLoading.vue';
75
72
  import type { ButtonProps, ButtonSize, ButtonType } from './types';
76
73
  import type { SchemeColor } from '@/types/scheme-colors';
77
74
 
@@ -102,8 +99,8 @@ const buttonDisabled = computed(() => {
102
99
  });
103
100
 
104
101
  const iconSize = computed(() => {
105
- if (props.size === 'small') return 'sm';
106
- return 'md';
102
+ if (props.size === 'extra-large') return 'lg';
103
+ return 'ant';
107
104
  });
108
105
 
109
106
  const hasText = computed(() => {
@@ -120,12 +117,11 @@ const iconScheme = computed((): SchemeColor => {
120
117
  primary: 'neutral-white',
121
118
  secondary: 'neutral-dark',
122
119
  tertiary: 'neutral-dark',
123
- alternative: 'neutral-white',
124
120
  warning: 'neutral-white',
125
121
  attention: 'neutral-white',
126
122
  };
127
123
 
128
- return typeToSchemeMap[props.type] || 'neutral-white';
124
+ return typeToSchemeMap[buttonType.value] || 'neutral-white';
129
125
  });
130
126
 
131
127
  const isSizePropValid = computed(() => {
@@ -136,16 +132,21 @@ const isSizePropValid = computed(() => {
136
132
  );
137
133
  });
138
134
 
135
+ const buttonType = computed(() => {
136
+ return {
137
+ 'alternative': 'tertiary',
138
+ }[props.type] || props.type;
139
+ });
140
+
139
141
  const isTypePropValid = computed(() => {
140
142
  const validTypes: ButtonType[] = [
141
143
  'primary',
142
144
  'secondary',
143
145
  'tertiary',
144
- 'alternative',
145
146
  'warning',
146
147
  'attention',
147
148
  ];
148
- return validTypes.includes(props.type);
149
+ return validTypes.includes(buttonType.value);
149
150
  });
150
151
 
151
152
  const validateProps = () => {
@@ -159,6 +160,7 @@ const validateProps = () => {
159
160
 
160
161
  if (!isTypePropValid.value) {
161
162
  errorMessage += ' Invalid type prop.';
163
+ errorMessage += ' Please provide one of the following types: primary, secondary, tertiary, warning, attention. Alternative is discontinued and it was forced renamed to tertiary.';
162
164
  }
163
165
 
164
166
  throw new Error(errorMessage);
@@ -196,13 +198,12 @@ watch(
196
198
  display: inline-flex;
197
199
  align-items: center;
198
200
  justify-content: center;
199
- border-radius: $unnnic-border-radius-sm;
201
+ border-radius: $unnnic-radius-2;
200
202
  border: 0;
201
203
  outline: none;
202
204
  overflow: hidden;
203
205
  white-space: nowrap;
204
- font-weight: $unnnic-font-weight-regular;
205
- font-family: $unnnic-font-family-secondary;
206
+ font: $unnnic-font-action;
206
207
  cursor: pointer;
207
208
  position: relative;
208
209
 
@@ -216,129 +217,91 @@ watch(
216
217
  }
217
218
  }
218
219
 
220
+ &--primary,
221
+ &--warning,
222
+ &--attention {
223
+ color: $unnnic-color-fg-inverted;
224
+ }
225
+
226
+ &--secondary,
227
+ &--tertiary {
228
+ color: $unnnic-color-fg-emphasized;
229
+ }
230
+
219
231
  &--primary {
220
- background-color: $unnnic-color-weni-600;
221
- color: $unnnic-color-neutral-white;
232
+ background-color: $unnnic-color-bg-active;
222
233
 
223
234
  &:hover:enabled {
224
- background-color: $unnnic-color-weni-700;
235
+ background-color: $unnnic-color-teal-700;
225
236
  }
226
237
 
227
238
  &:active:enabled {
228
- background-color: $unnnic-color-weni-800;
239
+ background-color: $unnnic-color-teal-800;
229
240
  }
230
241
  }
231
242
 
232
243
  &--secondary {
233
- background-color: $unnnic-color-neutral-white;
234
- color: $unnnic-color-neutral-dark;
244
+ background-color: $unnnic-color-bg-base;
235
245
  box-shadow: inset 0 0 0 $unnnic-border-width-thinner
236
- $unnnic-color-neutral-cleanest;
246
+ $unnnic-color-border-base;
237
247
 
238
248
  &:hover:enabled {
239
- background-color: $unnnic-color-neutral-light;
240
- }
241
-
242
- &:disabled {
243
- box-shadow: none;
249
+ background-color: $unnnic-color-gray-50;
244
250
  }
245
251
 
246
252
  &:active:enabled {
247
- background-color: $unnnic-color-neutral-soft;
248
- }
249
- }
250
-
251
- &--tertiary {
252
- background-color: transparent;
253
- color: $unnnic-color-neutral-dark;
254
-
255
- &:hover:enabled {
256
- background-color: $unnnic-color-neutral-light;
253
+ background-color: $unnnic-color-gray-100;
257
254
  }
258
255
 
259
256
  &:disabled {
260
- color: $unnnic-color-neutral-clean;
261
- cursor: not-allowed;
262
- }
263
-
264
- &:active:enabled {
265
- background-color: $unnnic-color-neutral-soft;
257
+ box-shadow: none;
266
258
  }
267
259
  }
268
260
 
269
- &--alternative {
270
- background-color: $unnnic-color-weni-50;
271
- color: $unnnic-color-weni-800;
272
-
273
- :deep(svg .primary) {
274
- fill: $unnnic-color-weni-800;
275
- }
276
-
277
- :deep(svg .primary-stroke) {
278
- stroke: $unnnic-color-weni-800;
279
- }
261
+ &--tertiary {
262
+ background-color: transparent;
280
263
 
281
264
  &:hover:enabled {
282
- background-color: $unnnic-color-weni-100;
283
- }
284
-
285
- &:disabled {
286
- :deep(svg .primary) {
287
- fill: $unnnic-color-neutral-clean;
288
- }
289
-
290
- :deep(svg .primary-stroke) {
291
- stroke: $unnnic-color-neutral-clean;
292
- }
265
+ background-color: rgba($unnnic-color-gray-400, 0.1);
293
266
  }
294
267
 
295
268
  &:active:enabled {
296
- background-color: $unnnic-color-weni-200;
297
- color: $unnnic-color-weni-900;
298
-
299
- :deep(svg .primary) {
300
- fill: $unnnic-color-weni-900;
301
- }
302
-
303
- :deep(svg .primary-stroke) {
304
- stroke: $unnnic-color-weni-900;
305
- }
269
+ background-color: rgba($unnnic-color-gray-400, 0.2);
306
270
  }
307
271
  }
308
272
 
309
273
  &--warning {
310
- background-color: $unnnic-color-aux-red-500;
274
+ background-color: $unnnic-color-red-500;
311
275
  color: $unnnic-color-neutral-white;
312
276
 
313
277
  &:hover:enabled {
314
- background-color: $unnnic-color-aux-red-700;
278
+ background-color: $unnnic-color-red-600;
315
279
  }
316
280
 
317
281
  &:active:enabled {
318
- background-color: $unnnic-color-aux-red-900;
282
+ background-color: $unnnic-color-red-700;
319
283
  }
320
284
  }
321
285
 
322
286
  &--attention {
323
- background-color: $unnnic-color-aux-yellow-500;
324
- color: $unnnic-color-neutral-white;
287
+ background-color: $unnnic-color-yellow-500;
325
288
 
326
289
  &:hover:enabled {
327
- background-color: $unnnic-color-aux-yellow-700;
290
+ background-color: $unnnic-color-yellow-600;
328
291
  }
329
292
 
330
293
  &:active:enabled {
331
- background-color: $unnnic-color-aux-yellow-900;
294
+ background-color: $unnnic-color-yellow-700;
332
295
  }
333
296
  }
334
297
 
335
298
  &--primary:disabled,
336
299
  &--secondary:disabled,
337
- &--alternative:disabled,
300
+ &--tertiary:disabled,
338
301
  &--warning:disabled,
339
302
  &--attention:disabled {
340
- background-color: $unnnic-color-neutral-soft;
341
- color: $unnnic-color-neutral-clean;
303
+ background-color: $unnnic-color-bg-muted;
304
+ color: $unnnic-color-fg-muted;
342
305
  cursor: not-allowed;
343
306
  }
344
307
 
@@ -351,26 +314,12 @@ watch(
351
314
  box-shadow: $unnnic-shadow-level-near;
352
315
  }
353
316
 
354
- &--size {
355
- &-extra-large,
356
- &-large,
357
- &-small {
358
- padding: $unnnic-squish-xs;
359
- font-size: $unnnic-font-size-body-gt;
360
- line-height: ($unnnic-font-size-body-gt + $unnnic-line-height-medium);
361
- }
362
-
363
- &-extra-large {
364
- height: 58px;
365
- }
366
-
367
- &-large {
368
- height: 46px;
369
- }
317
+ &--size-large {
318
+ padding: $unnnic-space-3 $unnnic-space-4;
319
+ }
370
320
 
371
- &-small {
372
- height: 38px;
373
- }
321
+ &--size-small {
322
+ padding: $unnnic-space-2 $unnnic-space-4;
374
323
  }
375
324
  }
376
325
  </style>
@@ -388,8 +337,8 @@ watch(
388
337
  }
389
338
 
390
339
  &-large {
391
- height: 46px;
392
- width: 46px;
340
+ height: 45px;
341
+ width: 45px;
393
342
  }
394
343
 
395
344
  &-large,
@@ -404,8 +353,8 @@ watch(
404
353
 
405
354
  &-small {
406
355
  padding: $unnnic-inset-nano;
407
- height: 38px;
408
- width: 38px;
356
+ height: 37px;
357
+ width: 37px;
409
358
 
410
359
  .unnnic-icon {
411
360
  width: $unnnic-icon-size-ant;
@@ -4,7 +4,6 @@ export type ButtonType =
4
4
  | 'primary'
5
5
  | 'secondary'
6
6
  | 'tertiary'
7
- | 'alternative'
8
7
  | 'warning'
9
8
  | 'attention';
10
9
 
@@ -69,12 +69,19 @@
69
69
  'unnnic-data-table__body-row--loading',
70
70
  ]"
71
71
  >
72
- <img
73
- class="unnnic-data-table__body-cell--loading"
74
- data-testid="body-row-loading"
75
- src="../../assets/icons/weni-loading.svg"
76
- height="40"
77
- />
72
+ <td
73
+ :class="[
74
+ 'unnnic-data-table__body-cell',
75
+ `unnnic-data-table__body-cell--${size}`,
76
+ ]"
77
+ >
78
+ <img
79
+ class="unnnic-data-table__body-cell--loading"
80
+ data-testid="body-row-loading"
81
+ src="../../assets/icons/weni-loading.svg"
82
+ height="40"
83
+ />
84
+ </td>
78
85
  </tr>
79
86
  <template v-else-if="props.items.length">
80
87
  <tr
@@ -116,13 +123,16 @@
116
123
  </template>
117
124
  <tr
118
125
  v-else
119
- class="unnnic-data-table__body-row"
126
+ :class="[
127
+ 'unnnic-data-table__body-row',
128
+ 'unnnic-data-table__body-row--without-results',
129
+ ]"
120
130
  >
121
131
  <td
122
132
  v-if="slots['without-results']"
123
133
  :class="[
124
134
  'unnnic-data-table__body-cell',
125
- `unnnic-data-table__body-cell--${size}`,
135
+ `unnnic-data-table__body-cell--${size}`
126
136
  ]"
127
137
  >
128
138
  <slot name="without-results" />
@@ -197,7 +207,7 @@ defineOptions({
197
207
  const slots = useSlots();
198
208
 
199
209
  const emit = defineEmits<{
200
- 'update:sort': [sort: { header: string; order: string }];
210
+ 'update:sort': [sort: { header: string; itemKey: string; order: string }];
201
211
  itemClick: [item: DataTableItem];
202
212
  'update:page': [page: number];
203
213
  }>();
@@ -245,6 +255,7 @@ const headersItemsKeys: ComputedRef<string[]> = computed(() => {
245
255
 
246
256
  const sort = ref({
247
257
  header: '',
258
+ itemKey: '',
248
259
  order: '',
249
260
  });
250
261
 
@@ -262,8 +273,8 @@ const gridTemplateColumns: ComputedRef<string> = computed(() => {
262
273
  return columnSizes.join(' ');
263
274
  });
264
275
 
265
- const handleSort = (key: string, order: string) => {
266
- sort.value = { header: key, order };
276
+ const handleSort = (header: typeof sort.value, order: string) => {
277
+ sort.value = { ...header, order };
267
278
  emit('update:sort', sort.value);
268
279
  };
269
280
 
@@ -281,7 +292,7 @@ const handleClickHeader = (header: DataTableHeader) => {
281
292
  ? 'asc'
282
293
  : nextSortOrderMapper[sort.value.order];
283
294
 
284
- handleSort(nextSort === '' ? '' : header.title, nextSort);
295
+ handleSort(nextSort === '' ? { header: '', itemKey: '', order: '' } : { header: header.title, itemKey: header.itemKey, order: nextSort }, nextSort);
285
296
  };
286
297
 
287
298
  const handleClickRow = (item: DataTableItem) => {
@@ -398,7 +409,8 @@ $tableBorder: $unnnic-border-width-thinner solid $unnnic-color-neutral-soft;
398
409
 
399
410
  grid-template-columns: v-bind(gridTemplateColumns);
400
411
 
401
- &--loading {
412
+ &--loading,
413
+ &--without-results {
402
414
  grid-template-columns: 1fr;
403
415
  }
404
416
 
@@ -433,7 +445,7 @@ $tableBorder: $unnnic-border-width-thinner solid $unnnic-color-neutral-soft;
433
445
  }
434
446
 
435
447
  &-cell--loading {
436
- margin: $unnnic-spacing-xl 0;
448
+ margin: $unnnic-space-10 0;
437
449
  padding: 0;
438
450
 
439
451
  width: 100%;
@@ -11,7 +11,7 @@
11
11
  @dragleave.stop.prevent="dragleave"
12
12
  @dragend.stop.prevent="dragend"
13
13
  @drop.stop.prevent="drop"
14
- @click="() => $refs.file.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)) {
@@ -38,6 +38,10 @@ export default {
38
38
  type: Boolean,
39
39
  default: false,
40
40
  },
41
+ forceOpen: {
42
+ type: Boolean,
43
+ default: false,
44
+ },
41
45
  position: {
42
46
  type: String,
43
47
  default: 'bottom-left',
@@ -73,10 +77,12 @@ export default {
73
77
  },
74
78
  methods: {
75
79
  onClickTrigger() {
80
+ if (this.forceOpen) return;
76
81
  if (this.useOpenProp) this.$emit('update:open', !this.open);
77
82
  else this.active = !this.active;
78
83
  },
79
84
  onClickOutside() {
85
+ if (this.forceOpen) return;
80
86
  if (this.useOpenProp && this.open) {
81
87
  this.$emit('update:open', false);
82
88
  return;
@@ -95,4 +95,61 @@ describe('Dropdown.vue', () => {
95
95
  expect(wrapper.vm.active).toBe(false);
96
96
  });
97
97
  });
98
+
99
+ describe('ForceOpen Functionality', () => {
100
+ it('should not toggle dropdown on trigger click when forceOpen is true', async () => {
101
+ await wrapper.setProps({ forceOpen: true, open: false });
102
+ const initialActiveState = wrapper.vm.active;
103
+
104
+ const trigger = wrapper.find('[data-testid="dropdown-trigger"]');
105
+ await trigger.trigger('click');
106
+
107
+ expect(wrapper.vm.active).toBe(initialActiveState);
108
+ expect(wrapper.emitted('update:open')).toBeFalsy();
109
+ });
110
+
111
+ it('should not close dropdown on outside click when forceOpen is true', async () => {
112
+ await wrapper.setProps({ forceOpen: true, open: true });
113
+ expect(wrapper.vm.active).toBe(true);
114
+
115
+ await wrapper.vm.onClickOutside();
116
+
117
+ expect(wrapper.vm.active).toBe(true);
118
+ });
119
+
120
+ it('should not emit update:open when forceOpen is true and useOpenProp is true', async () => {
121
+ await wrapper.setProps({
122
+ forceOpen: true,
123
+ useOpenProp: true,
124
+ open: false
125
+ });
126
+
127
+ const trigger = wrapper.find('[data-testid="dropdown-trigger"]');
128
+ await trigger.trigger('click');
129
+
130
+ expect(wrapper.emitted('update:open')).toBeFalsy();
131
+ });
132
+
133
+ it('should not close dropdown via onClickOutside when forceOpen is true and useOpenProp is true', async () => {
134
+ await wrapper.setProps({
135
+ forceOpen: true,
136
+ useOpenProp: true,
137
+ open: true
138
+ });
139
+
140
+ await wrapper.vm.onClickOutside();
141
+
142
+ expect(wrapper.emitted('update:open')).toBeFalsy();
143
+ });
144
+
145
+ it('should allow normal behavior when forceOpen is false', async () => {
146
+ await wrapper.setProps({ forceOpen: false, open: false });
147
+
148
+ const trigger = wrapper.find('[data-testid="dropdown-trigger"]');
149
+ await trigger.trigger('click');
150
+
151
+ expect(wrapper.vm.active).toBe(true);
152
+ expect(wrapper.emitted('update:open')).toBeTruthy();
153
+ });
154
+ });
98
155
  });