@weni/unnnic-system 3.4.0 → 3.4.1-alpha.1

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 (236) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/dist/components/Accordion/Accordion.vue.d.ts +1 -1
  3. package/dist/components/Alert/Alert.vue.d.ts +18 -119
  4. package/dist/components/Alert/Alert.vue.d.ts.map +1 -1
  5. package/dist/components/Alert/Version1dot1.vue.d.ts +2 -38
  6. package/dist/components/Alert/Version1dot1.vue.d.ts.map +1 -1
  7. package/dist/components/AudioRecorder/AudioHandler.vue.d.ts +2 -2
  8. package/dist/components/AudioRecorder/AudioPlayer.vue.d.ts +1 -1
  9. package/dist/components/AudioRecorder/AudioRecorder.vue.d.ts +5 -5
  10. package/dist/components/AvatarIcon/AvatarIcon.vue.d.ts +2 -2
  11. package/dist/components/Banner/Banner.vue.d.ts +1 -1
  12. package/dist/components/Banner/InfoBanner.vue.d.ts +1 -1
  13. package/dist/components/Breadcrumb/Breadcrumb.vue.d.ts +1 -1
  14. package/dist/components/Button/Button.vue.d.ts +2 -2
  15. package/dist/components/Button/Button.vue.d.ts.map +1 -1
  16. package/dist/components/Button/ButtonIcon.vue.d.ts +1 -1
  17. package/dist/components/Button/types.d.ts +1 -1
  18. package/dist/components/Button/types.d.ts.map +1 -1
  19. package/dist/components/Card/AccountCard.vue.d.ts +3 -3
  20. package/dist/components/Card/BlankCard.vue.d.ts +1 -1
  21. package/dist/components/Card/Card.vue.d.ts +21 -21
  22. package/dist/components/Card/CardCompany.vue.d.ts +8 -8
  23. package/dist/components/Card/CardData.vue.d.ts +1 -1
  24. package/dist/components/Card/CardStatusesContainer.vue.d.ts +4 -4
  25. package/dist/components/Card/ContentCard.vue.d.ts +2 -2
  26. package/dist/components/Card/DashCard.vue.d.ts +4 -4
  27. package/dist/components/Card/DefaultCard.vue.d.ts +1 -1
  28. package/dist/components/Card/MarketplaceCard.vue.d.ts +2 -2
  29. package/dist/components/Card/SimpleCard.vue.d.ts +3 -3
  30. package/dist/components/Card/StatusCard.vue.d.ts +2 -2
  31. package/dist/components/Card/TitleCard.vue.d.ts +2 -2
  32. package/dist/components/CardImage/CardImage.vue.d.ts +24 -33
  33. package/dist/components/CardInformation/CardInformation.vue.d.ts +4 -4
  34. package/dist/components/CardProject/CardProject.vue.d.ts +3 -3
  35. package/dist/components/Carousel/Carousel.vue.d.ts +11 -11
  36. package/dist/components/Carousel/TagCarousel.vue.d.ts +9 -9
  37. package/dist/components/ChartBar/ChartBar.vue.d.ts +8 -8
  38. package/dist/components/ChartLine/ChartLine.vue.d.ts +1 -1
  39. package/dist/components/ChatText/ChatText.vue.d.ts +2 -2
  40. package/dist/components/ChatsContact/ChatsContact.vue.d.ts +31 -40
  41. package/dist/components/ChatsDashboardTagLive/ChatsDashboardTagLive.vue.d.ts +1 -1
  42. package/dist/components/ChatsHeader/ChatsHeader.vue.d.ts +1 -1
  43. package/dist/components/ChatsHeader/ChatsHeader.vue.d.ts.map +1 -1
  44. package/dist/components/ChatsMessage/ChatsMessage.vue.d.ts +5 -5
  45. package/dist/components/ChatsMessage/ChatsMessageStatusBackdrop.vue.d.ts +2 -2
  46. package/dist/components/ChatsNavbar/ChatsNavbar.vue.d.ts +1 -1
  47. package/dist/components/ChatsUserAvatar/ChatsUserAvatar.vue.d.ts +2 -2
  48. package/dist/components/Checkbox/Checkbox.vue.d.ts +19 -28
  49. package/dist/components/Checkbox/Checkbox.vue.d.ts.map +1 -1
  50. package/dist/components/CheckboxGroup/CheckboxGroup.vue.d.ts +28 -0
  51. package/dist/components/CheckboxGroup/CheckboxGroup.vue.d.ts.map +1 -0
  52. package/dist/components/Comment/Comment.vue.d.ts +1 -1
  53. package/dist/components/DataArea/DataArea.vue.d.ts +2 -2
  54. package/dist/components/DataTable/index.vue.d.ts +1 -1
  55. package/dist/components/DataTable/index.vue.d.ts.map +1 -1
  56. package/dist/components/DateFilter/DateFilter.vue.d.ts +176 -29
  57. package/dist/components/DatePicker/DatePicker.vue.d.ts +8 -8
  58. package/dist/components/Drawer/Drawer.vue.d.ts +7 -7
  59. package/dist/components/Dropdown/Dropdown.vue.d.ts +1 -1
  60. package/dist/components/Dropdown/LanguageSelect.vue.d.ts +3 -3
  61. package/dist/components/Flag.vue.d.ts +2 -2
  62. package/dist/components/FormElement/FormElement.vue.d.ts +38 -32
  63. package/dist/components/FormElement/FormElement.vue.d.ts.map +1 -1
  64. package/dist/components/Icon.vue.d.ts +1 -1
  65. package/dist/components/IconLoading/IconLoading.vue.d.ts +1 -1
  66. package/dist/components/ImportCard/ImportCard.vue.d.ts +7 -7
  67. package/dist/components/Input/BaseInput.vue.d.ts +32 -1
  68. package/dist/components/Input/BaseInput.vue.d.ts.map +1 -1
  69. package/dist/components/Input/Input.vue.d.ts +176 -29
  70. package/dist/components/Input/Input.vue.d.ts.map +1 -1
  71. package/dist/components/Input/TextInput.vue.d.ts +83 -14
  72. package/dist/components/Input/TextInput.vue.d.ts.map +1 -1
  73. package/dist/components/InputDatePicker/InputDatePicker.vue.d.ts +186 -39
  74. package/dist/components/InputNext/InputNext.vue.d.ts +4 -4
  75. package/dist/components/Label/Label.vue.d.ts +9 -15
  76. package/dist/components/Label/Label.vue.d.ts.map +1 -1
  77. package/dist/components/Modal/Modal.vue.d.ts +2 -2
  78. package/dist/components/ModalDialog/ModalDialog.vue.d.ts +9 -9
  79. package/dist/components/ModalDialog/ModalDialog.vue.d.ts.map +1 -1
  80. package/dist/components/ModalNext/ModalNext.vue.d.ts +184 -37
  81. package/dist/components/ModalUpload/ModalUpload.vue.d.ts +14 -14
  82. package/dist/components/MoodRating/MoodRating.vue.d.ts +1 -1
  83. package/dist/components/MultiSelect/MultiSelect.vue.d.ts +20 -14
  84. package/dist/components/Pagination/Pagination.vue.d.ts +6 -6
  85. package/dist/components/ProgressBar/ProgressBar.vue.d.ts +1 -1
  86. package/dist/components/Radio/Radio.vue.d.ts +8 -6
  87. package/dist/components/Radio/Radio.vue.d.ts.map +1 -1
  88. package/dist/components/SelectSmart/SelectSmart.vue.d.ts +113 -53
  89. package/dist/components/SelectSmart/SelectSmartMultipleHeader.vue.d.ts +8 -8
  90. package/dist/components/SelectSmart/SelectSmartOption.vue.d.ts +20 -29
  91. package/dist/components/SelectSmart/SelectSmartOption.vue.d.ts.map +1 -1
  92. package/dist/components/SelectTime/index.vue.d.ts +83 -14
  93. package/dist/components/SkeletonLoading/skeletonTheme.vue.d.ts +1 -1
  94. package/dist/components/Slider/Slider.vue.d.ts +2 -2
  95. package/dist/components/StarRating/StarRating.vue.d.ts +1 -1
  96. package/dist/components/Switch/Switch.vue.d.ts +24 -25
  97. package/dist/components/Switch/Switch.vue.d.ts.map +1 -1
  98. package/dist/components/Tab/Tab.vue.d.ts +13 -2
  99. package/dist/components/TableNext/TableBodyCell.vue.d.ts +2 -2
  100. package/dist/components/TableNext/TablePagination.vue.d.ts +6 -6
  101. package/dist/components/TabsExpanded/TabsExpanded.vue.d.ts +1 -1
  102. package/dist/components/Tag/BrandTag.vue.d.ts +2 -2
  103. package/dist/components/Tag/DefaultTag.vue.d.ts +2 -2
  104. package/dist/components/Tag/IndicatorTag.vue.d.ts +2 -2
  105. package/dist/components/Tag/Tag.vue.d.ts +8 -8
  106. package/dist/components/TemplatePreview/TemplatePreview.vue.d.ts +9 -0
  107. package/dist/components/TemplatePreview/TemplatePreview.vue.d.ts.map +1 -0
  108. package/dist/components/TemplatePreview/TemplatePreviewModal.vue.d.ts +15 -0
  109. package/dist/components/TemplatePreview/TemplatePreviewModal.vue.d.ts.map +1 -0
  110. package/dist/components/TextArea/TextArea.vue.d.ts +38 -32
  111. package/dist/components/TextArea/TextArea.vue.d.ts.map +1 -1
  112. package/dist/components/Toast/Toast.vue.d.ts +16 -0
  113. package/dist/components/Toast/Toast.vue.d.ts.map +1 -0
  114. package/dist/components/Toast/ToastManager.d.ts +14 -0
  115. package/dist/components/Toast/ToastManager.d.ts.map +1 -0
  116. package/dist/components/Toast/types.d.ts +35 -0
  117. package/dist/components/Toast/types.d.ts.map +1 -0
  118. package/dist/components/ToolTip/ToolTip.vue.d.ts +1 -1
  119. package/dist/components/Tour/Tour.vue.d.ts +6 -6
  120. package/dist/components/Tour/TourPopover.vue.d.ts +6 -6
  121. package/dist/components/UploadArea/UploadArea.vue.d.ts +7 -7
  122. package/dist/components/index.d.ts +2590 -1258
  123. package/dist/components/index.d.ts.map +1 -1
  124. package/dist/components/ui/popover/Popover.vue.d.ts +23 -0
  125. package/dist/components/ui/popover/Popover.vue.d.ts.map +1 -0
  126. package/dist/components/ui/popover/PopoverContent.vue.d.ts +43 -0
  127. package/dist/components/ui/popover/PopoverContent.vue.d.ts.map +1 -0
  128. package/dist/components/ui/popover/PopoverTrigger.vue.d.ts +19 -0
  129. package/dist/components/ui/popover/PopoverTrigger.vue.d.ts.map +1 -0
  130. package/dist/components/ui/popover/index.d.ts +5 -0
  131. package/dist/components/ui/popover/index.d.ts.map +1 -0
  132. package/dist/{es-8265192e.mjs → es-eca523be.mjs} +1 -1
  133. package/dist/{index-832905fc.mjs → index-c84d6c3d.mjs} +18151 -11782
  134. package/dist/index.d.ts.map +1 -1
  135. package/dist/locales/en.json.d.ts +2 -1
  136. package/dist/locales/es.json.d.ts +2 -1
  137. package/dist/locales/pt_br.json.d.ts +2 -1
  138. package/dist/{pt-br-9ced3d4b.mjs → pt-br-dd7ba97f.mjs} +1 -1
  139. package/dist/style.css +1 -1
  140. package/dist/unnnic.mjs +177 -163
  141. package/dist/unnnic.umd.js +53 -50
  142. package/dist/utils/call.d.ts +2 -1
  143. package/dist/utils/call.d.ts.map +1 -1
  144. package/package.json +2 -1
  145. package/src/assets/icons/checkbox-checked-disabled.svg +3 -0
  146. package/src/assets/icons/checkbox-checked.svg +3 -0
  147. package/src/assets/icons/radio-checked.svg +3 -0
  148. package/src/assets/icons/switch-checked-disabled.svg +3 -0
  149. package/src/assets/icons/switch-checked.svg +3 -0
  150. package/src/assets/img/previews/doc-preview.png +0 -0
  151. package/src/assets/img/previews/image-preview.png +0 -0
  152. package/src/assets/img/previews/video-preview.png +0 -0
  153. package/src/assets/scss/scheme-colors.scss +115 -238
  154. package/src/assets/scss/tailwind.scss +15 -15
  155. package/src/components/Alert/Alert.vue +26 -135
  156. package/src/components/Alert/Version1dot1.vue +0 -36
  157. package/src/components/Alert/__tests__/__snapshots__/Alert.spec.js.snap +11 -7
  158. package/src/components/Alert/__tests__/__snapshots__/Version1dot1.spec.js.snap +2 -2
  159. package/src/components/Button/Button.vue +60 -108
  160. package/src/components/Button/types.ts +0 -1
  161. package/src/components/Checkbox/Checkbox.vue +88 -65
  162. package/src/components/Checkbox/__tests__/Checkbox.spec.js +6 -21
  163. package/src/components/CheckboxGroup/CheckboxGroup.vue +96 -0
  164. package/src/components/FormElement/FormElement.vue +51 -91
  165. package/src/components/Input/BaseInput.vue +31 -14
  166. package/src/components/Input/Input.scss +19 -21
  167. package/src/components/Input/Input.vue +94 -30
  168. package/src/components/Input/TextInput.vue +82 -58
  169. package/src/components/Input/__test__/TextInput.spec.js +5 -5
  170. package/src/components/Input/__test__/__snapshots__/Input.spec.js.snap +16 -3
  171. package/src/components/Input/__test__/__snapshots__/TextInput.spec.js.snap +7 -1
  172. package/src/components/Label/Label.vue +52 -21
  173. package/src/components/Label/__tests__/Label.spec.js +1 -1
  174. package/src/components/Label/__tests__/__snapshots__/Label.spec.js.snap +1 -1
  175. package/src/components/ModalDialog/ModalDialog.vue +1 -0
  176. package/src/components/ModalDialog/__tests__/__snapshots__/ModalDialog.spec.js.snap +1 -1
  177. package/src/components/Popover/__tests__/Popover.spec.js +147 -0
  178. package/src/components/Popover/__tests__/__snapshots__/Popover.spec.js.snap +8 -0
  179. package/src/components/Popover/index.vue +146 -0
  180. package/src/components/Radio/Radio.vue +80 -67
  181. package/src/components/Radio/__test__/Radio.spec.js +14 -20
  182. package/src/components/Radio/__test__/__snapshots__/Radio.spec.js.snap +3 -3
  183. package/src/components/RadioGroup/RadioGroup.vue +110 -0
  184. package/src/components/Select/SelectOption.vue +65 -0
  185. package/src/components/Select/__tests__/Select.spec.js +412 -0
  186. package/src/components/Select/__tests__/SelectItem.spec.js +330 -0
  187. package/src/components/Select/__tests__/SelectOption.spec.js +174 -0
  188. package/src/components/Select/__tests__/__snapshots__/Select.spec.js.snap +97 -0
  189. package/src/components/Select/__tests__/__snapshots__/SelectItem.spec.js.snap +15 -0
  190. package/src/components/Select/__tests__/__snapshots__/SelectOption.spec.js.snap +25 -0
  191. package/src/components/Select/index.vue +245 -0
  192. package/src/components/Switch/Switch.vue +91 -99
  193. package/src/components/Switch/__tests__/Switch.spec.js +8 -74
  194. package/src/components/Switch/__tests__/__snapshots__/Switch.spec.js.snap +3 -5
  195. package/src/components/Tab/Tab.vue +37 -23
  196. package/src/components/Tab/__test__/__snapshots__/Tab.spec.js.snap +1 -1
  197. package/src/components/TableNext/__test__/__snapshots__/TableNext.spec.js.snap +2 -2
  198. package/src/components/TableNext/__test__/__snapshots__/TablePagination.spec.js.snap +2 -2
  199. package/src/components/TemplatePreview/TemplatePreview.vue +252 -0
  200. package/src/components/TemplatePreview/TemplatePreviewModal.vue +51 -0
  201. package/src/components/TemplatePreview/types.d.ts +16 -0
  202. package/src/components/TextArea/TextArea.vue +13 -9
  203. package/src/components/TextArea/__test__/__snapshots__/TextArea.spec.js.snap +7 -2
  204. package/src/components/Toast/Toast.vue +236 -0
  205. package/src/components/Toast/ToastManager.ts +110 -0
  206. package/src/components/Toast/types.ts +57 -0
  207. package/src/components/index.ts +34 -4
  208. package/src/components/ui/popover/Popover.vue +15 -0
  209. package/src/components/ui/popover/PopoverContent.vue +98 -0
  210. package/src/components/ui/popover/PopoverTrigger.vue +12 -0
  211. package/src/components/ui/popover/index.ts +4 -0
  212. package/src/index.ts +1 -0
  213. package/src/locales/en.json +2 -1
  214. package/src/locales/es.json +2 -1
  215. package/src/locales/pt_br.json +2 -1
  216. package/src/stories/Alert.stories.js +6 -67
  217. package/src/stories/Button.stories.js +2 -17
  218. package/src/stories/Checkbox.stories.js +9 -10
  219. package/src/stories/CheckboxGroup.stories.js +104 -0
  220. package/src/stories/Input.stories.js +22 -3
  221. package/src/stories/Label.stories.js +7 -0
  222. package/src/stories/Popover.stories.js +306 -0
  223. package/src/stories/RadioGroup.stories.js +139 -0
  224. package/src/stories/Select.stories.js +158 -0
  225. package/src/stories/Switch.stories.js +4 -5
  226. package/src/stories/Tab.stories.js +11 -4
  227. package/src/stories/TemplatePreview.stories.js +94 -0
  228. package/src/stories/TemplatePreviewModal.stories.js +110 -0
  229. package/src/stories/Toast.mdx +123 -0
  230. package/src/stories/Toast.stories.js +126 -0
  231. package/src/types/scheme-colors.d.ts +1 -0
  232. package/src/utils/call.js +46 -18
  233. package/src/components/Alert/AlertBanner.vue +0 -182
  234. package/src/components/Alert/AlertCaller.vue +0 -49
  235. package/src/components/Alert/__tests__/AlertBanner.spec.js +0 -89
  236. package/src/components/Alert/__tests__/AlertCaller.spec.js +0 -98
@@ -0,0 +1,245 @@
1
+ <template>
2
+ <div
3
+ class="unnnic-select"
4
+ @keydown="handleKeyDown"
5
+ >
6
+ <UnnnicPopover
7
+ v-model="openPopover"
8
+ :popoverBalloonProps="{ maxHeight: calculatedMaxHeight }"
9
+ >
10
+ <template #trigger>
11
+ <UnnnicInput
12
+ :modelValue="inputValue"
13
+ class="unnnic-select__input"
14
+ readonly
15
+ :forceActiveStatus="openPopover"
16
+ :size="props.size"
17
+ :placeholder="props.placeholder"
18
+ :label="props.label"
19
+ :errors="props.errors"
20
+ :message="props.message"
21
+ :iconRight="openPopover ? 'keyboard_arrow_up' : 'keyboard_arrow_down'"
22
+ :disabled="props.disabled"
23
+ showClear
24
+ @clear="emit('update:modelValue', '')"
25
+ />
26
+ </template>
27
+ <template #content>
28
+ <div class="unnnic-select__content">
29
+ <UnnnicInput
30
+ v-if="props.enableSearch"
31
+ class="unnnic-select__input-search"
32
+ :modelValue="props.search"
33
+ :placeholder="$t('search')"
34
+ iconLeft="search"
35
+ @update:model-value="handleSearch"
36
+ />
37
+ <UnnnicSelectOption
38
+ v-for="(option, index) in filteredOptions"
39
+ :key="option[props.itemValue]"
40
+ :data-option-index="index"
41
+ :label="option[props.itemLabel]"
42
+ :active="
43
+ option[props.itemValue] === selectedItem?.[props.itemValue]
44
+ "
45
+ :focused="focusedOptionIndex === index"
46
+ :disabled="option.disabled"
47
+ @click="handleSelectOption(option)"
48
+ />
49
+ </div>
50
+ </template>
51
+ </UnnnicPopover>
52
+ </div>
53
+ </template>
54
+
55
+ <script setup lang="ts">
56
+ import { computed, ref, watch, nextTick } from 'vue';
57
+ import UnnnicInput from '../Input/Input.vue';
58
+ import UnnnicPopover from '../Popover/index.vue';
59
+ import UnnnicSelectOption from './SelectOption.vue';
60
+ import UnnnicI18n from '../../mixins/i18n';
61
+
62
+ defineOptions({
63
+ name: 'UnnnicSelect',
64
+ mixins: [UnnnicI18n],
65
+ });
66
+
67
+ interface SelectProps {
68
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
69
+ options: Array<{ [key: string]: any }>;
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
+ modelValue: any;
72
+ returnObject?: boolean;
73
+ itemLabel?: string;
74
+ itemValue?: string;
75
+ placeholder?: string;
76
+ label?: string;
77
+ type?: 'normal' | 'error';
78
+ errors?: string | Array<string>;
79
+ message?: string;
80
+ size?: 'sm' | 'md';
81
+ optionsLines?: number;
82
+ enableSearch?: boolean;
83
+ search?: string;
84
+ locale?: string;
85
+ disabled?: boolean;
86
+ }
87
+
88
+ const props = withDefaults(defineProps<SelectProps>(), {
89
+ size: 'md',
90
+ type: 'normal',
91
+ placeholder: '',
92
+ optionsLines: 5,
93
+ returnObject: false,
94
+ itemLabel: 'label',
95
+ itemValue: 'value',
96
+ locale: 'en',
97
+ enableSearch: false,
98
+ disabled: false,
99
+ });
100
+
101
+ const emit = defineEmits<{
102
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
103
+ 'update:modelValue': [value: any];
104
+ 'update:search': [value: string];
105
+ }>();
106
+
107
+ const openPopover = ref(false);
108
+
109
+ watch(openPopover, () => {
110
+ if (!openPopover.value) {
111
+ handleSearch('');
112
+ } else {
113
+ focusedOptionIndex.value = -1;
114
+ }
115
+
116
+ if (openPopover.value && props.modelValue) {
117
+ const selectedOptionIndex = props.options.findIndex(
118
+ (option) =>
119
+ option[props.itemValue] === selectedItem.value[props.itemValue],
120
+ );
121
+ scrollToOption(selectedOptionIndex, 'instant', 'center');
122
+ }
123
+ });
124
+
125
+ const handleKeyDown = (event) => {
126
+ const { key } = event;
127
+ const validKeys = ['ArrowUp', 'ArrowDown', 'Enter'];
128
+ if (validKeys.includes(key)) {
129
+ event.preventDefault();
130
+ if (key === 'ArrowUp') {
131
+ if (focusedOptionIndex.value === 0) return;
132
+ focusedOptionIndex.value--;
133
+ scrollToOption(focusedOptionIndex.value);
134
+ }
135
+ if (key === 'ArrowDown') {
136
+ if (focusedOptionIndex.value === filteredOptions.value.length - 1) return;
137
+ focusedOptionIndex.value++;
138
+ scrollToOption(focusedOptionIndex.value);
139
+ }
140
+ if (key === 'Enter') {
141
+ handleSelectOption(filteredOptions.value[focusedOptionIndex.value]);
142
+ }
143
+ }
144
+ };
145
+
146
+ const focusedOptionIndex = ref<number>(-1);
147
+
148
+ const scrollToOption = (
149
+ index: number,
150
+ behavior: 'smooth' | 'instant' = 'smooth',
151
+ block: 'center' | 'start' | 'end' | 'nearest' = 'center',
152
+ ) => {
153
+ nextTick(() => {
154
+ const option = document.querySelector(`[data-option-index="${index}"]`);
155
+ if (option) {
156
+ option.scrollIntoView({ behavior, block });
157
+ }
158
+ });
159
+ };
160
+
161
+ const calculatedMaxHeight = computed(() => {
162
+ if (!props.options || props.options.length === 0) return 'unset';
163
+ const popoverPadding = 32;
164
+ const popoverGap = 4;
165
+ // 37 = 21px (height) + 16px (padding)
166
+ const fieldsHeight = 37 * props.optionsLines;
167
+ const size =
168
+ fieldsHeight + popoverPadding + (popoverGap * props.optionsLines - 2);
169
+ return `${props.enableSearch ? size + 54 : size}px`;
170
+ });
171
+
172
+ const selectedItem = computed(() => {
173
+ if (props.returnObject) return props.modelValue;
174
+
175
+ return props.options.find(
176
+ (option) => option[props.itemValue] === props.modelValue,
177
+ );
178
+ });
179
+
180
+ const inputValue = computed(() => {
181
+ return selectedItem.value?.[props.itemLabel];
182
+ });
183
+
184
+ const handleSelectOption = (option) => {
185
+ if (
186
+ option[props.itemValue] === selectedItem.value?.[props.itemValue] ||
187
+ option.disabled
188
+ )
189
+ return;
190
+
191
+ emit(
192
+ 'update:modelValue',
193
+ props.returnObject ? option : option[props.itemValue],
194
+ );
195
+ openPopover.value = false;
196
+ };
197
+
198
+ const handleSearch = (value: string) => {
199
+ emit('update:search', value);
200
+ };
201
+
202
+ const filteredOptions = computed(() => {
203
+ if (!props.enableSearch || !props.search) return props.options;
204
+
205
+ return props.options.filter(
206
+ (option) =>
207
+ option[props.itemLabel]
208
+ .toLowerCase()
209
+ .includes(props.search?.toLowerCase()) ||
210
+ option[props.itemValue]
211
+ .toLowerCase()
212
+ .includes(props.search?.toLowerCase()),
213
+ );
214
+ });
215
+ </script>
216
+
217
+ <style lang="scss" scoped>
218
+ @use '@/assets/scss/unnnic' as *;
219
+
220
+ :deep(.unnnic-select__input) {
221
+ cursor: pointer;
222
+ }
223
+
224
+ :deep(.unnnic-select__input-search) {
225
+ > .icon-left {
226
+ color: $unnnic-color-fg-base;
227
+ }
228
+ }
229
+
230
+ :deep(.unnnic-select__input) {
231
+ > .icon-right {
232
+ color: $unnnic-color-fg-base;
233
+ }
234
+ }
235
+
236
+ .unnnic-select {
237
+ &__content {
238
+ display: flex;
239
+ flex-direction: column;
240
+ padding: 0;
241
+ margin: 0;
242
+ gap: $unnnic-space-1;
243
+ }
244
+ }
245
+ </style>
@@ -1,49 +1,43 @@
1
1
  <template>
2
- <div class="unnnic-switch">
3
- <div
4
- v-if="textLeft"
5
- data-test-id="switch-text-left"
6
- :class="[
7
- 'unnnic-switch__label',
8
- 'unnnic-switch__label__left',
9
- `unnnic-switch__label__${size}`,
10
- ]"
2
+ <div class="unnnic-switch-wrapper">
3
+ <label>
4
+ <input
5
+ class="unnnic-switch"
6
+ type="checkbox"
7
+ :disabled="disabled"
8
+ :checked="modelValue"
9
+ @change="toggleState"
10
+ v-bind="pick($attrs, ['id', 'name'])"
11
+ />
12
+
13
+ <p
14
+ v-if="label || textLeft || textRight"
15
+ :class="[
16
+ 'unnnic-switch__label',
17
+ { 'unnnic-switch__label--disabled': disabled },
18
+ ]"
19
+ data-testid="switch-label"
20
+ >
21
+ {{ label }}
22
+ {{ textLeft }}
23
+ {{ textRight }}
24
+ </p>
25
+ </label>
26
+
27
+ <p
28
+ v-if="helper"
29
+ class="unnnic-switch__helper"
11
30
  >
12
- {{ textLeft }}
13
- </div>
14
-
15
- <UnnnicIcon
16
- :class="{ 'unnnic-switch__icon': true, active: isActive }"
17
- :icon="currentIcon"
18
- :size="iconSize"
19
- :scheme="iconScheme"
20
- :lineHeight="iconLineHeight"
21
- :disabled="disabled"
22
- :clickable="!disabled"
23
- data-test-id="switch-icon"
24
- @click="toggleState"
25
- />
26
-
27
- <div
28
- v-if="textRight"
29
- data-test-id="switch-text-right"
30
- :class="[
31
- 'unnnic-switch__label',
32
- 'unnnic-switch__label__right',
33
- `unnnic-switch__label__${size}`,
34
- ]"
35
- >
36
- {{ textRight }}
37
- </div>
31
+ {{ helper }}
32
+ </p>
38
33
  </div>
39
34
  </template>
40
35
 
41
36
  <script>
42
- import UnnnicIcon from '../Icon.vue';
37
+ import { pick } from 'lodash';
43
38
 
44
39
  export default {
45
40
  name: 'UnnnicSwitch',
46
- components: { UnnnicIcon },
47
41
  props: {
48
42
  size: {
49
43
  type: String,
@@ -52,6 +46,17 @@ export default {
52
46
  return ['small', 'medium'].indexOf(value) !== -1;
53
47
  },
54
48
  },
49
+
50
+ label: {
51
+ type: String,
52
+ default: '',
53
+ },
54
+
55
+ helper: {
56
+ type: String,
57
+ default: '',
58
+ },
59
+
55
60
  textLeft: {
56
61
  type: String,
57
62
  default: '',
@@ -78,33 +83,6 @@ export default {
78
83
  isActive: false,
79
84
  };
80
85
  },
81
- computed: {
82
- currentIcon() {
83
- if (this.disabled) {
84
- return this.isActive
85
- ? 'switch-selected-disabled'
86
- : 'switch-default-disabled';
87
- }
88
-
89
- return 'switch-default';
90
- },
91
-
92
- iconSize() {
93
- return this.size === 'small' ? 'sm' : 'md';
94
- },
95
-
96
- iconScheme() {
97
- if (this.disabled) {
98
- return 'neutral-soft';
99
- }
100
-
101
- return this.isActive === false ? 'neutral-soft' : 'brand-weni';
102
- },
103
-
104
- iconLineHeight() {
105
- return this.size === 'small' ? 'sm' : '';
106
- },
107
- },
108
86
 
109
87
  watch: {
110
88
  modelValue: {
@@ -116,6 +94,8 @@ export default {
116
94
  },
117
95
 
118
96
  methods: {
97
+ pick,
98
+
119
99
  toggleState() {
120
100
  if (!this.disabled) {
121
101
  if (this.useVModel) {
@@ -133,51 +113,63 @@ export default {
133
113
  <style lang="scss" scoped>
134
114
  @use '@/assets/scss/unnnic' as *;
135
115
 
136
- .unnnic-switch {
137
- display: flex;
138
- flex-direction: row;
139
-
140
- &__label {
141
- font-family: $unnnic-font-family-secondary;
142
- font-weight: $unnnic-font-weight-regular;
143
- color: $unnnic-color-neutral-dark;
116
+ $switch-width: 38px;
117
+ $switch-height: 21px;
144
118
 
145
- margin: $unnnic-spacing-stack-nano 0;
146
- margin-right: $unnnic-inline-nano;
119
+ .unnnic-switch-wrapper {
120
+ display: flex;
121
+ flex-direction: column;
147
122
 
148
- &__small {
149
- font-size: $unnnic-font-size-body-md;
150
- line-height: $unnnic-font-size-body-md + $unnnic-line-height-md;
151
- }
123
+ label {
124
+ display: flex;
125
+ align-items: center;
126
+ column-gap: $unnnic-space-2;
127
+ }
128
+ }
152
129
 
153
- &__medium {
154
- font-size: $unnnic-font-size-body-gt;
155
- line-height: $unnnic-font-size-body-gt + $unnnic-line-height-md;
156
- }
130
+ .unnnic-switch {
131
+ appearance: none;
132
+ width: $switch-width;
133
+ height: $switch-height;
134
+ margin: 0;
135
+ background-color: $unnnic-color-bg-muted;
136
+ border-radius: $unnnic-radius-3;
137
+ box-sizing: border-box;
138
+ outline: none;
139
+
140
+ background-image: url('@/assets/icons/switch-checked.svg');
141
+ background-repeat: no-repeat;
142
+ background-position: 2px center;
143
+
144
+ transition:
145
+ 200ms linear background-position,
146
+ 200ms linear background-color;
147
+
148
+ &:checked {
149
+ background-color: $unnnic-color-bg-active;
150
+ background-position: 20px center;
157
151
  }
158
152
 
159
- &__icon {
160
- align-self: center;
161
- margin: $unnnic-spacing-stack-nano $unnnic-inline-nano;
153
+ &:disabled {
154
+ background-color: $unnnic-color-bg-muted;
155
+ background-image: url('@/assets/icons/switch-checked-disabled.svg');
156
+ }
162
157
 
163
- :deep(#default-circle) {
164
- transition: 0.2s linear transform;
165
- }
158
+ &__label {
159
+ margin: 0;
160
+ font: $unnnic-font-body;
161
+ color: $unnnic-color-fg-emphasized;
166
162
 
167
- &.active {
168
- :deep(#default-circle) {
169
- transform: translateX(45%);
170
- }
163
+ &--disabled {
164
+ color: $unnnic-color-fg-muted;
171
165
  }
172
166
  }
173
- }
174
167
 
175
- .unnnic-icon__size {
176
- &--md {
177
- width: 3 * $unnnic-font-size;
178
- }
179
- &--sm {
180
- width: 2 * $unnnic-font-size;
168
+ &__helper {
169
+ margin: 0;
170
+ margin-left: $switch-width + $unnnic-space-2;
171
+ font: $unnnic-font-caption-2;
172
+ color: $unnnic-color-fg-base;
181
173
  }
182
174
  }
183
175
  </style>
@@ -12,93 +12,27 @@ describe('Switch', () => {
12
12
  beforeEach(() => {
13
13
  wrapper = createWrapper({ modelValue: false });
14
14
  });
15
- it('should render the component correctly with default props', () => {
16
- expect(wrapper.exists()).toBe(true);
17
- expect(wrapper.findComponent({ name: 'UnnnicIcon' }).exists()).toBe(true);
18
- expect(wrapper.text()).toBe('');
19
- });
20
-
21
- it('should render the left text (textLeft) when provided', async () => {
22
- await wrapper.setProps({ textLeft: 'Left Text' });
23
-
24
- // This check ensures that the icon is placed before the switch text
25
- const switchChildren = wrapper.findComponent(Switch).element.children;
26
- expect(switchChildren[0].getAttribute('data-test-id')).toBe(
27
- 'switch-text-left',
28
- );
29
- expect(switchChildren[1].getAttribute('data-test-id')).toBe('switch-icon');
30
- });
31
15
 
32
- it('should render the right text (textRight) when provided', async () => {
33
- await wrapper.setProps({ textRight: 'Right Text' });
16
+ it('should render the label when provided', async () => {
17
+ await wrapper.setProps({ label: 'Label Text' });
34
18
 
35
19
  // This check ensures that the icon is placed after the switch text
36
- const switchChildren = wrapper.findComponent(Switch).element.children;
37
- expect(switchChildren[0].getAttribute('data-test-id')).toBe('switch-icon');
38
- expect(switchChildren[1].getAttribute('data-test-id')).toBe(
39
- 'switch-text-right',
40
- );
41
- });
42
-
43
- it('should render the correct icon when the switch is disabled/enabled', async () => {
44
- await wrapper.setProps({ disabled: true });
45
- const disabledIconComponent = wrapper.findComponent({ name: 'UnnnicIcon' });
46
- expect(disabledIconComponent.props('icon')).toBe('switch-default-disabled');
47
-
48
- await wrapper.setProps({ modelValue: true });
49
- const enabledIconComponent = wrapper.findComponent({ name: 'UnnnicIcon' });
50
- expect(enabledIconComponent.props('icon')).toBe('switch-selected-disabled');
51
- });
52
-
53
- it('should render the correct icon based on the isActive state', async () => {
54
- expect(wrapper.vm.isActive).toBe(false);
55
- await wrapper.setProps({ modelValue: true });
56
- expect(wrapper.vm.isActive).toBe(true);
57
- expect(wrapper.findComponent({ name: 'UnnnicIcon' }).props('icon')).toBe(
58
- 'switch-default',
59
- );
60
- });
61
-
62
- it('should render the correct icon size based on the size prop', async () => {
63
- await wrapper.setProps({ size: 'small' });
64
- expect(wrapper.findComponent({ name: 'UnnnicIcon' }).props('size')).toBe(
65
- 'sm',
66
- );
67
-
68
- await wrapper.setProps({ size: 'medium' });
69
- expect(wrapper.findComponent({ name: 'UnnnicIcon' }).props('size')).toBe(
70
- 'md',
71
- );
72
- });
73
-
74
- it('should change the icon color based on the state', async () => {
75
- expect(wrapper.findComponent({ name: 'UnnnicIcon' }).props('scheme')).toBe(
76
- 'neutral-soft',
77
- );
78
-
79
- await wrapper.setProps({ modelValue: true });
80
- expect(wrapper.findComponent({ name: 'UnnnicIcon' }).props('scheme')).toBe(
81
- 'brand-weni',
82
- );
83
-
84
- await wrapper.setProps({ disabled: true });
85
- expect(wrapper.findComponent({ name: 'UnnnicIcon' }).props('scheme')).toBe(
86
- 'neutral-soft',
87
- );
20
+ const switchLabel = wrapper.find('[data-testid="switch-label"]');
21
+ expect(switchLabel.text()).toBe('Label Text');
88
22
  });
89
23
 
90
24
  it('should toggle isActive state and emit the correct event when toggleState is called', async () => {
91
25
  const initialIsActive = wrapper.vm.isActive;
92
- const switchIcon = wrapper.findComponent('[ data-test-id="switch-icon"]');
93
- await switchIcon.trigger('click');
26
+ const switchInput = wrapper.find('input[type="checkbox"]');
27
+ await switchInput.trigger('change');
94
28
  expect(wrapper.emitted('update:model-value')).toBeTruthy();
95
29
  expect(wrapper.vm.isActive).toBe(!initialIsActive);
96
30
  });
97
31
 
98
32
  it('should not change state when disabled is true', async () => {
99
33
  await wrapper.setProps({ disabled: true });
100
- const switchIcon = wrapper.findComponent('[ data-test-id="switch-icon"]');
101
- await switchIcon.trigger('click');
34
+ const switchInput = wrapper.find('input[type="checkbox"]');
35
+ await switchInput.trigger('change');
102
36
  expect(wrapper.emitted('update:model-value')).toBeFalsy();
103
37
  expect(wrapper.vm.isActive).toBe(false);
104
38
  });
@@ -1,11 +1,9 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
3
  exports[`Switch > should match the snapshot 1`] = `
4
- "<div data-v-e4356c9d="" class="unnnic-switch">
5
- <!--v-if--><svg data-v-3d58a7dd="" data-v-26446d8e="" data-v-e4356c9d="" id="default" width="80" height="40" viewBox="0 0 80 40" xmlns="http://www.w3.org/2000/svg" class="unnnic-icon unnnic-icon__size--md unnnic--clickable unnnic-icon-scheme--neutral-soft unnnic-switch__icon" data-testid="old-map-icons" disabled="false" data-test-id="switch-icon">
6
- <rect data-v-3d58a7dd="" x="4.20013" y="2.10046" width="71.6" height="35.8" rx="17.9" class="primary"></rect>
7
- <circle data-v-3d58a7dd="" id="default-circle" cx="22.5" cy="20.0005" r="12.5" fill="white"></circle>
8
- </svg>
4
+ "<div data-v-e4356c9d="" class="unnnic-switch-wrapper"><label data-v-e4356c9d=""><input data-v-e4356c9d="" class="unnnic-switch" type="checkbox">
5
+ <!--v-if-->
6
+ </label>
9
7
  <!--v-if-->
10
8
  </div>"
11
9
  `;