@dative-gpi/foundation-shared-components 1.0.27 → 1.0.28-remove-deprecated2

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 (265) hide show
  1. package/components/FSBreadcrumbs.vue +1 -0
  2. package/components/FSButton.vue +10 -10
  3. package/components/FSCalendar.vue +52 -14
  4. package/components/FSCalendarTwin.vue +96 -40
  5. package/components/FSCard.vue +28 -7
  6. package/components/FSCardPlaceholder.vue +8 -5
  7. package/components/FSChip.vue +12 -2
  8. package/components/FSClickable.vue +20 -12
  9. package/components/FSClock.vue +16 -7
  10. package/components/FSColorIcon.vue +23 -5
  11. package/components/FSDialog.vue +2 -1
  12. package/components/FSDialogContent.vue +12 -11
  13. package/components/FSDialogForm.vue +22 -2
  14. package/components/FSDialogFormBody.vue +51 -32
  15. package/components/FSDialogMultiFormBody.vue +79 -56
  16. package/components/FSDialogRemove.vue +7 -7
  17. package/components/FSDialogSubmit.vue +20 -11
  18. package/components/FSEditImage.vue +1 -1
  19. package/components/FSEditImageUI.vue +20 -10
  20. package/components/FSFadeOut.vue +44 -18
  21. package/components/FSForm.vue +10 -8
  22. package/components/FSGrid.vue +1 -1
  23. package/components/FSIcon.vue +2 -1
  24. package/components/FSIconCard.vue +21 -4
  25. package/components/FSImage.vue +12 -4
  26. package/components/FSImageUI.vue +8 -15
  27. package/components/FSLink.vue +25 -9
  28. package/components/FSLoader.vue +28 -11
  29. package/components/FSOptionGroup.vue +51 -3
  30. package/components/FSRouterLink.vue +42 -0
  31. package/components/FSSlideGroup.vue +19 -5
  32. package/components/FSSpan.vue +9 -2
  33. package/components/FSSwitch.vue +57 -27
  34. package/components/FSTab.vue +15 -13
  35. package/components/FSTabs.vue +32 -7
  36. package/components/FSTag.vue +14 -3
  37. package/components/FSTagGroup.vue +1 -1
  38. package/components/FSText.vue +4 -2
  39. package/components/FSWindow.vue +128 -4
  40. package/components/FSWrapGroup.vue +13 -1
  41. package/components/agenda/FSAgenda.vue +223 -0
  42. package/components/agenda/FSAgendaDialogCalendar.vue +76 -0
  43. package/components/agenda/FSAgendaHeader.vue +215 -0
  44. package/components/agenda/FSAgendaHorizontalEvent.vue +174 -0
  45. package/components/agenda/FSAgendaHorizontalTimeLineMarker.vue +46 -0
  46. package/components/agenda/FSAgendaHoursCol.vue +103 -0
  47. package/components/agenda/FSAgendaHoursRow.vue +164 -0
  48. package/components/agenda/FSAgendaVerticalEvent.vue +160 -0
  49. package/components/agenda/FSAgendaVerticalTimeLineMarker.vue +46 -0
  50. package/components/agenda/FSDayAgenda.vue +199 -0
  51. package/components/agenda/FSMonthAgenda.vue +252 -0
  52. package/components/agenda/FSSelectAgendaMode.vue +54 -0
  53. package/components/agenda/FSWeekAgenda.vue +323 -0
  54. package/components/autocompletes/FSAutoCompleteAddress.vue +22 -20
  55. package/components/autocompletes/FSAutocompleteLanguage.vue +24 -39
  56. package/components/autocompletes/FSAutocompleteTimeZone.vue +26 -38
  57. package/components/buttons/FSButtonAdd.vue +1 -1
  58. package/components/buttons/FSButtonAddLabel.vue +1 -1
  59. package/components/buttons/FSButtonCancel.vue +1 -1
  60. package/components/buttons/FSButtonCancelLabel.vue +1 -1
  61. package/components/buttons/FSButtonCopy.vue +28 -0
  62. package/components/buttons/FSButtonCopyIcon.vue +28 -0
  63. package/components/buttons/FSButtonCopyLabel.vue +27 -0
  64. package/components/buttons/FSButtonCopyMini.vue +28 -0
  65. package/components/buttons/FSButtonDragIcon.vue +27 -0
  66. package/components/buttons/FSButtonDuplicate.vue +1 -1
  67. package/components/buttons/FSButtonDuplicateLabel.vue +1 -1
  68. package/components/buttons/FSButtonEdit.vue +1 -1
  69. package/components/buttons/FSButtonEditLabel.vue +1 -1
  70. package/components/buttons/FSButtonFile.vue +1 -1
  71. package/components/buttons/FSButtonFileLabel.vue +1 -1
  72. package/components/buttons/FSButtonNext.vue +1 -1
  73. package/components/buttons/FSButtonNextLabel.vue +1 -1
  74. package/components/buttons/FSButtonPrevious.vue +1 -1
  75. package/components/buttons/FSButtonPreviousLabel.vue +1 -1
  76. package/components/buttons/FSButtonRedo.vue +1 -1
  77. package/components/buttons/FSButtonRedoLabel.vue +1 -1
  78. package/components/buttons/FSButtonRemove.vue +1 -1
  79. package/components/buttons/FSButtonRemoveLabel.vue +1 -1
  80. package/components/buttons/FSButtonSave.vue +1 -1
  81. package/components/buttons/FSButtonSaveLabel.vue +1 -1
  82. package/components/buttons/FSButtonSearch.vue +1 -1
  83. package/components/buttons/FSButtonSearchLabel.vue +1 -1
  84. package/components/buttons/FSButtonUndo.vue +1 -1
  85. package/components/buttons/FSButtonUndoLabel.vue +1 -1
  86. package/components/buttons/FSButtonUpdate.vue +1 -1
  87. package/components/buttons/FSButtonUpdateLabel.vue +1 -1
  88. package/components/buttons/FSButtonValidate.vue +1 -1
  89. package/components/buttons/FSButtonValidateLabel.vue +1 -1
  90. package/components/calendar/FSSimpleCalendar.vue +145 -0
  91. package/components/calendar/FSSimpleCalendarHeader.vue +60 -0
  92. package/components/calendar/FSSimpleMonthSelector.vue +138 -0
  93. package/components/deviceOrganisations/FSConnectivity.vue +11 -1
  94. package/components/deviceOrganisations/FSConnectivityCard.vue +19 -47
  95. package/components/deviceOrganisations/FSStatus.vue +11 -1
  96. package/components/deviceOrganisations/FSStatusCard.vue +35 -61
  97. package/components/deviceOrganisations/FSStatusesCarousel.vue +1 -0
  98. package/components/deviceOrganisations/FSStatusesRow.vue +9 -3
  99. package/components/deviceOrganisations/FSWorstAlert.vue +30 -37
  100. package/components/deviceOrganisations/FSWorstAlertCard.vue +36 -85
  101. package/components/fields/FSAutocompleteField.vue +516 -341
  102. package/components/fields/FSAutocompleteTag.vue +100 -0
  103. package/components/fields/FSBaseField.vue +44 -27
  104. package/components/fields/FSColorField.vue +42 -39
  105. package/components/fields/FSCommentField.vue +105 -0
  106. package/components/fields/FSDateField.vue +2 -2
  107. package/components/fields/FSDateRangeField.vue +3 -2
  108. package/components/fields/FSDateTimeField.vue +4 -3
  109. package/components/fields/FSDateTimeRangeField.vue +8 -6
  110. package/components/fields/FSEntityFieldUI.vue +271 -0
  111. package/components/fields/FSGradientField.vue +27 -33
  112. package/components/fields/FSIconField.vue +0 -1
  113. package/components/fields/FSMagicConfigField.vue +15 -7
  114. package/components/fields/FSMagicField.vue +9 -4
  115. package/components/fields/FSNumberField.vue +13 -6
  116. package/components/fields/FSRichTextField.vue +102 -52
  117. package/components/fields/FSSearchField.vue +9 -115
  118. package/components/fields/FSSelectField.vue +489 -252
  119. package/components/fields/FSTagField.vue +1 -1
  120. package/components/fields/FSTermField.vue +33 -11
  121. package/components/fields/FSTextArea.vue +26 -7
  122. package/components/fields/FSTextField.vue +19 -10
  123. package/components/fields/FSTimeRangeField.vue +304 -0
  124. package/components/fields/FSTimeStepField.vue +3 -3
  125. package/components/fields/FSTranslateField.vue +4 -3
  126. package/components/fields/FSTranslateRichTextField.vue +15 -10
  127. package/components/fields/FSTranslateTextArea.vue +233 -0
  128. package/components/fields/FSTreeViewField.vue +3 -3
  129. package/components/fields/periodicField/FSPeriodicDailyField.vue +120 -0
  130. package/components/fields/periodicField/FSPeriodicField.vue +131 -0
  131. package/components/fields/periodicField/FSPeriodicMonthlyField.vue +222 -0
  132. package/components/fields/periodicField/FSPeriodicWeeklyField.vue +120 -0
  133. package/components/fields/periodicField/FSPeriodicYearlyField.vue +144 -0
  134. package/components/lists/FSDataTableUI.vue +148 -89
  135. package/components/lists/FSDraggable.vue +2 -2
  136. package/components/lists/FSFilterButton.vue +23 -28
  137. package/components/lists/FSHeaderButton.vue +4 -4
  138. package/components/lists/FSHiddenButton.vue +11 -15
  139. package/components/lists/FSLoadDataTable.vue +10 -7
  140. package/components/lists/FSSimpleList.vue +234 -0
  141. package/components/lists/FSSimpleListItem.vue +132 -0
  142. package/components/map/FSMap.vue +280 -399
  143. package/components/map/FSMapFeatureGroup.vue +51 -0
  144. package/components/map/FSMapLayerButton.vue +5 -5
  145. package/components/map/FSMapMarker.vue +120 -0
  146. package/components/map/FSMapMarkerClusterGroup.vue +72 -0
  147. package/components/map/FSMapOverlay.vue +70 -82
  148. package/components/map/FSMapPolygon.vue +81 -0
  149. package/components/map/FSMapTileLayer.vue +50 -0
  150. package/components/map/keys.ts +4 -0
  151. package/components/selects/FSSelectAutoRefresh.vue +9 -9
  152. package/components/selects/FSSelectDashboardVariableType.vue +5 -4
  153. package/components/selects/FSSelectDateSetting.vue +3 -2
  154. package/components/selects/FSSelectDays.vue +9 -9
  155. package/components/selects/FSSelectListMode.vue +51 -0
  156. package/components/selects/FSSelectMonths.vue +67 -0
  157. package/components/selects/chartSelectors/FSAggregationSelector.vue +52 -0
  158. package/components/selects/chartSelectors/FSAxisTypeSelector.vue +49 -0
  159. package/components/selects/chartSelectors/FSDisplayAsSelector.vue +53 -0
  160. package/components/selects/chartSelectors/FSFilterTypeSelector.vue +54 -0
  161. package/components/selects/chartSelectors/FSHeatmapRuleSelector.vue +54 -0
  162. package/components/selects/chartSelectors/FSOperationOnSelector.vue +53 -0
  163. package/components/selects/chartSelectors/FSPlanningTypeSelector.vue +53 -0
  164. package/components/selects/chartSelectors/FSPlotPerSelector.vue +52 -0
  165. package/components/selects/chartSelectors/FSSelectEntityType.vue +59 -0
  166. package/components/selects/chartSelectors/FSSerieTypeSelector.vue +53 -0
  167. package/components/tiles/FSAlertTileUI.vue +90 -0
  168. package/components/tiles/FSChartTile.vue +73 -0
  169. package/components/tiles/FSChartTileUI.vue +111 -0
  170. package/components/tiles/FSCommentTileUI.vue +174 -0
  171. package/components/tiles/FSDeviceOrganisationTileUI.vue +6 -0
  172. package/components/tiles/FSGroupTileUI.vue +2 -2
  173. package/components/tiles/FSLoadTile.vue +2 -0
  174. package/components/tiles/FSLocationTileUI.vue +192 -0
  175. package/components/tiles/FSModelTileUI.vue +18 -0
  176. package/components/tiles/FSSimpleTileUI.vue +9 -4
  177. package/components/tiles/FSTile.vue +93 -74
  178. package/components/tiles/FSUserOrganisationTileUI.vue +1 -1
  179. package/components/toggleSets/FSToggleSetPosition.vue +2 -2
  180. package/components/views/FSBaseView.vue +64 -0
  181. package/components/views/FSEntityView.vue +12 -140
  182. package/components/views/FSSimpleView.vue +29 -0
  183. package/components/views/desktop/FSBaseDefaultDesktopView.vue +134 -0
  184. package/components/views/desktop/FSBaseDesktopView.vue +53 -0
  185. package/components/views/desktop/FSBaseEntityDesktopView.vue +208 -0
  186. package/components/views/mobile/FSBaseDefaultMobileView.vue +132 -0
  187. package/components/views/mobile/FSBaseEntityMobileView.vue +198 -0
  188. package/components/views/mobile/FSBaseMobileView.vue +53 -0
  189. package/composables/useAddress.ts +2 -2
  190. package/composables/useBreakpoints.ts +39 -3
  191. package/composables/useColors.ts +3 -2
  192. package/composables/useMagicFieldProvider.ts +1 -0
  193. package/models/agenda.ts +9 -0
  194. package/models/deviceAlerts.ts +1 -1
  195. package/models/deviceConnectivities.ts +1 -1
  196. package/models/index.ts +1 -0
  197. package/models/magicFields.ts +1 -0
  198. package/models/map.ts +2 -2
  199. package/models/rules.ts +5 -5
  200. package/models/tables.ts +5 -2
  201. package/models/variableNode.ts +8 -5
  202. package/package.json +5 -5
  203. package/styles/components/fs_agenda.scss +36 -0
  204. package/styles/components/fs_agenda_event.scss +41 -0
  205. package/styles/components/fs_agenda_hours_col.scss +4 -0
  206. package/styles/components/fs_agenda_hours_row.scss +5 -0
  207. package/styles/components/fs_agenda_time_line_marker.scss +19 -0
  208. package/styles/components/fs_autocomplete_field.scss +0 -13
  209. package/styles/components/fs_breadcrumbs.scss +6 -12
  210. package/styles/components/fs_card.scss +0 -1
  211. package/styles/components/fs_clickable.scss +7 -14
  212. package/styles/components/fs_clock.scss +0 -10
  213. package/styles/components/fs_color_field.scss +1 -4
  214. package/styles/components/fs_data_table.scss +6 -9
  215. package/styles/components/fs_dialog.scss +7 -17
  216. package/styles/components/fs_edit_image.scss +8 -0
  217. package/styles/components/fs_fade_out.scss +11 -2
  218. package/styles/components/fs_filter_button.scss +1 -6
  219. package/styles/components/fs_gradient_field.scss +11 -11
  220. package/styles/components/fs_hidden_button.scss +2 -7
  221. package/styles/components/fs_image_card.scss +1 -1
  222. package/styles/components/fs_magic_config_field.scss +1 -2
  223. package/styles/components/fs_map.scss +36 -30
  224. package/styles/components/fs_meta_field.scss +3 -5
  225. package/styles/components/fs_option_group.scss +15 -5
  226. package/styles/components/fs_rich_text_field.scss +1 -9
  227. package/styles/components/fs_select_date_settings.scss +3 -0
  228. package/styles/components/fs_select_field.scss +0 -13
  229. package/styles/components/fs_slide_group.scss +7 -0
  230. package/styles/components/fs_span.scss +2 -1
  231. package/styles/components/fs_switch.scss +1 -0
  232. package/styles/components/fs_tabs.scss +10 -24
  233. package/styles/components/fs_tag.scss +3 -19
  234. package/styles/components/fs_text_area.scss +13 -17
  235. package/styles/components/fs_tile.scss +21 -15
  236. package/styles/components/fs_window.scss +7 -0
  237. package/styles/components/fs_wrap_group.scss +7 -0
  238. package/styles/components/index.scss +5 -5
  239. package/styles/globals/index.scss +1 -5
  240. package/styles/globals/overrides.scss +17 -57
  241. package/styles/globals/text_fonts.scss +18 -66
  242. package/tools/alertsTools.ts +69 -0
  243. package/tools/chartsTools.ts +427 -0
  244. package/tools/index.ts +3 -0
  245. package/tools/timeRangeTools.ts +125 -0
  246. package/utils/filter.ts +18 -0
  247. package/utils/index.ts +1 -0
  248. package/utils/leafletMarkers.ts +9 -3
  249. package/utils/sort.ts +2 -2
  250. package/utils/statuses.ts +1 -1
  251. package/utils/time.ts +17 -17
  252. package/components/autocompletes/FSAutocompleteTag.vue +0 -138
  253. package/components/fields/FSTimeSlotField.vue +0 -250
  254. package/components/map/FSMapEditPointAddressOverlay.vue +0 -164
  255. package/components/views/FSEntityHeader.vue +0 -350
  256. package/components/views/FSListHeader.vue +0 -83
  257. package/components/views/FSListView.vue +0 -83
  258. package/components/views/FSSkeletonView.vue +0 -100
  259. package/styles/components/fs_icon_field.scss +0 -12
  260. package/styles/components/fs_map_overlay.scss +0 -38
  261. package/styles/components/fs_tag_field.scss +0 -8
  262. package/styles/components/fs_time_field.scss +0 -12
  263. package/styles/components/fs_timeslot_field.scss +0 -12
  264. package/styles/globals/breakpoints.scss +0 -20
  265. package/styles/globals/fixes.scss +0 -5
@@ -1,253 +1,383 @@
1
1
  <template>
2
- <template
2
+ <FSCol
3
3
  v-if="$props.loading"
4
4
  >
5
- <FSCol>
6
- <FSLoader
7
- v-if="!$props.hideHeader"
8
- variant="text-overline"
9
- />
10
- <FSLoader
11
- v-if="$props.loading"
12
- width="100%"
13
- :height="['40px', '36px']"
14
- />
15
- </FSCol>
16
- </template>
17
- <template
18
- v-else
5
+ <FSLoader
6
+ v-if="!$props.hideHeader"
7
+ variant="text-overline"
8
+ />
9
+ <FSLoader
10
+ v-if="$props.loading"
11
+ width="100%"
12
+ :height="['40px', '36px']"
13
+ />
14
+ </FSCol>
15
+ <FSCol
16
+ v-else-if="isExtraSmall"
19
17
  >
20
- <template
21
- v-if="isExtraSmall"
18
+ <FSTextField
19
+ :validationValue="$props.modelValue"
20
+ :description="$props.description"
21
+ :hideHeader="$props.hideHeader"
22
+ :clearable="$props.clearable"
23
+ :editable="$props.editable"
24
+ :required="$props.required"
25
+ :label="$props.label"
26
+ :rules="$props.rules"
27
+ :messages="messages"
28
+ :readonly="true"
29
+ :modelValue="mobileValue"
30
+ @click="openMobileOverlay"
31
+ v-bind="$attrs"
22
32
  >
23
- <FSTextField
24
- :validationValue="$props.modelValue"
25
- :description="$props.description"
26
- :hideHeader="$props.hideHeader"
27
- :clearable="$props.clearable"
28
- :editable="$props.editable"
29
- :required="$props.required"
30
- :label="$props.label"
31
- :rules="$props.rules"
32
- :messages="messages"
33
- :readonly="true"
34
- :modelValue="mobileValue"
35
- @update:modelValue="$emit('update:modelValue', $event)"
36
- @click="openMobileOverlay"
37
- v-bind="$attrs"
33
+ <template
34
+ v-for="(_, name) in $slots"
35
+ v-slot:[name]="slotData"
38
36
  >
39
- <template
40
- v-for="(_, name) in $slots"
41
- v-slot:[name]="slotData"
42
- >
43
- <slot
44
- :name="name"
45
- v-bind="slotData"
46
- />
47
- </template>
48
- <template
49
- v-if="mobileSelectionProps"
50
- #prepend-inner
37
+ <slot
38
+ :name="name"
39
+ v-bind="slotData"
40
+ />
41
+ </template>
42
+ <template
43
+ #prepend-inner
44
+ >
45
+ <slot
46
+ v-if="selectedItem && showExtra"
47
+ name="item-prepend"
48
+ v-bind="{ item: selectedItem }"
49
+ />
50
+ </template>
51
+ <template
52
+ #clear
53
+ >
54
+ <FSRow
55
+ :wrap="false"
51
56
  >
52
57
  <slot
53
- name="selection-mobile"
54
- v-bind="mobileSelectionProps"
58
+ v-if="selectedItem && showExtra"
59
+ name="item-append"
60
+ v-bind="{ item: selectedItem }"
55
61
  />
56
- </template>
57
- <template
58
- #append-inner
59
- >
60
62
  <slot
61
- name="append-inner"
63
+ name="clear"
62
64
  >
63
65
  <FSButton
64
- icon="mdi-chevron-down"
66
+ v-if="$props.clearable && $props.editable && !!$props.modelValue"
67
+ icon="mdi-close"
65
68
  variant="icon"
66
- :editable="$props.editable"
67
69
  :color="ColorEnum.Dark"
68
- @click="openMobileOverlay"
70
+ @click="onClear"
69
71
  />
70
72
  </slot>
71
- </template>
72
- </FSTextField>
73
- <FSDialogMenu
74
- v-model="dialog"
73
+ </FSRow>
74
+ </template>
75
+ <template
76
+ #append-inner
75
77
  >
76
- <template
77
- #body
78
+ <FSButton
79
+ icon="mdi-chevron-down"
80
+ variant="icon"
81
+ :editable="$props.editable"
82
+ :color="ColorEnum.Dark"
83
+ @click="openMobileOverlay"
84
+ />
85
+ </template>
86
+ </FSTextField>
87
+ <FSSlideGroup
88
+ v-if="$props.multiple && Array.isArray($props.modelValue)"
89
+ >
90
+ <FSCard
91
+ v-for="(item, index) in $props.items.filter((item: any) => $props.modelValue.includes(item[$props.itemValue!]))"
92
+ variant="standard"
93
+ :height="['40px', '36px']"
94
+ :color="ColorEnum.Light"
95
+ :border="false"
96
+ :key="index"
97
+ >
98
+ <FSRow
99
+ align="center-left"
100
+ padding="0 8px"
101
+ :wrap="false"
78
102
  >
79
- <FSSearchField
80
- :hideHeader="true"
81
- v-model="search"
103
+ <slot
104
+ name="item-prepend"
105
+ v-bind="{ item }"
82
106
  />
83
- <FSFadeOut
84
- :height="height"
107
+ <FSSpan>
108
+ {{ item[$props.itemTitle!] }}
109
+ </FSSpan>
110
+ <slot
111
+ name="item-append"
112
+ v-bind="{ item }"
113
+ />
114
+ <FSButton
115
+ icon="mdi-close"
116
+ variant="icon"
117
+ :color="ColorEnum.Dark"
118
+ @click="() => onCheckboxChange(item[$props.itemValue!])"
119
+ />
120
+ </FSRow>
121
+ </FSCard>
122
+ </FSSlideGroup>
123
+ <FSDialogMenu
124
+ v-model="dialog"
125
+ >
126
+ <template
127
+ #body
128
+ >
129
+ <FSSearchField
130
+ :clearable="$props.clearable"
131
+ :hideHeader="true"
132
+ v-model="search"
133
+ />
134
+ <FSFadeOut
135
+ :maxHeight="maxHeight"
136
+ >
137
+ <FSCol
138
+ gap="12px"
85
139
  >
86
- <FSCol
87
- v-if="$props.multiple"
88
- gap="12px"
140
+ <FSRow
141
+ v-for="(item, index) in searchItems"
142
+ :key="index"
89
143
  >
90
- <FSRow
91
- v-for="(item, index) in searchItems"
92
- :key="index"
144
+ <FSCheckbox
145
+ v-if="$props.multiple"
146
+ :label="item[$props.itemTitle!]"
147
+ :editable="$props.editable"
148
+ :modelValue="$props.modelValue?.includes(item[$props.itemValue!])"
149
+ @update:modelValue="() => onCheckboxChange(item[$props.itemValue!])"
93
150
  >
94
- <FSCheckbox
95
- :label="item[$props.itemTitle]"
96
- :editable="$props.editable"
97
- :modelValue="$props.modelValue?.includes(item[$props.itemValue])"
98
- @update:modelValue="() => onCheckboxChange(item[$props.itemValue])"
151
+ <template
152
+ #label="{ font }"
99
153
  >
100
- <template
101
- #label="{ font }"
154
+ <FSRow
155
+ align="center-left"
156
+ :wrap="false"
102
157
  >
103
158
  <slot
104
- name="item-label"
105
- v-bind="mobileItemProps(item, font)"
159
+ name="item-prepend"
160
+ v-bind="{ item }"
106
161
  />
107
- </template>
108
- </FSCheckbox>
109
- </FSRow>
110
- </FSCol>
111
- <FSRadioGroup
112
- v-else
113
- gap="12px"
114
- :values="searchItems.map((item: any) => ({ value: item[$props.itemValue], label: item[$props.itemTitle], item: item }))"
115
- :editable="$props.editable"
116
- :modelValue="$props.modelValue"
117
- @update:modelValue="onRadioChange"
118
- >
119
- <template
120
- #label="{ item, font }"
162
+ <FSSpan
163
+ :font="font"
164
+ >
165
+ {{ item[$props.itemTitle!] }}
166
+ </FSSpan>
167
+ </FSRow>
168
+ </template>
169
+ </FSCheckbox>
170
+ <FSRadio
171
+ v-else
172
+ :selected="$props.modelValue === item[$props.itemValue!]"
173
+ :label="item[$props.itemTitle!]"
174
+ :editable="$props.editable"
175
+ :item="item"
176
+ :modelValue="item[$props.itemValue!]"
177
+ @update:modelValue="() => onRadioChange(item[$props.itemValue!])"
178
+ >
179
+ <template
180
+ #label="{ font }"
181
+ >
182
+ <FSRow
183
+ align="center-left"
184
+ :wrap="false"
185
+ >
186
+ <slot
187
+ name="item-prepend"
188
+ v-bind="{ item }"
189
+ />
190
+ <FSSpan
191
+ :font="font"
192
+ >
193
+ {{ item[$props.itemTitle!] }}
194
+ </FSSpan>
195
+ </FSRow>
196
+ </template>
197
+ </FSRadio>
198
+ <FSRow
199
+ align="center-right"
121
200
  >
122
201
  <slot
123
- name="item-label"
124
- v-bind="mobileItemProps(item, font)"
202
+ name="item-append"
203
+ v-bind="{ item }"
125
204
  />
126
- </template>
127
- </FSRadioGroup>
128
- </FSFadeOut>
129
- </template>
130
- </FSDialogMenu>
131
- </template>
132
- <template
205
+ </FSRow>
206
+ </FSRow>
207
+ </FSCol>
208
+ </FSFadeOut>
209
+ <FSRow
210
+ v-if="allowAddItem"
211
+ padding="4px 3px"
212
+ >
213
+ <FSButton
214
+ variant="icon"
215
+ :label="$tr('autocomplete-field.add-item', 'Add new item')"
216
+ :color="ColorEnum.Primary"
217
+ @click="$emit('add:item', search)"
218
+ />
219
+ </FSRow>
220
+ <FSRow
221
+ v-if="!allowAddItem && searchItems.length === 0"
222
+ padding="4px 3px"
223
+ >
224
+ <FSSpan>
225
+ {{ $tr("ui.common.no-data", "No data") }}
226
+ </FSSpan>
227
+ </FSRow>
228
+ </template>
229
+ </FSDialogMenu>
230
+ </FSCol>
231
+ <FSBaseField
232
+ v-else
233
+ :description="$props.description"
234
+ :hideHeader="$props.hideHeader"
235
+ :required="$props.required"
236
+ :editable="$props.editable"
237
+ :label="$props.label"
238
+ :messages="messages"
239
+ >
240
+ <FSToggleSet
241
+ v-if="$props.toggleSet"
242
+ :editable="$props.editable"
243
+ :multiple="$props.multiple"
244
+ :required="$props.required"
245
+ :values="$props.items"
246
+ :rules="$props.rules"
247
+ :modelValue="$props.modelValue"
248
+ @update:modelValue="$emit('update:modelValue', $event)"
249
+ v-bind="$attrs"
250
+ >
251
+ <template
252
+ v-for="(_, name) in toggleSetSlots"
253
+ v-slot:[name]="slotData"
254
+ >
255
+ <slot
256
+ :name="`toggle-set-${name}`"
257
+ v-bind="slotData"
258
+ />
259
+ </template>
260
+ </FSToggleSet>
261
+ <FSCol
133
262
  v-else
134
263
  >
135
- <FSBaseField
136
- :description="$props.description"
137
- :hideHeader="$props.hideHeader"
138
- :required="$props.required"
139
- :editable="$props.editable"
140
- :label="$props.label"
141
- :messages="messages"
264
+ <v-autocomplete
265
+ class="fs-autocomplete-field"
266
+ variant="outlined"
267
+ :clearable="$props.clearable && $props.editable && !!$props.modelValue"
268
+ :itemTitle="$props.itemTitle"
269
+ :itemValue="$props.itemValue"
270
+ :readonly="!$props.editable"
271
+ :multiple="$props.multiple"
272
+ :validateOn="validateOn"
273
+ :autoSelectFirst="true"
274
+ :persistentClear="true"
275
+ :listProps="listStyle"
276
+ :returnObject="false"
277
+ :items="$props.items"
278
+ :rules="$props.rules"
279
+ :hideDetails="true"
280
+ :menuIcon="null"
281
+ :style="style"
282
+ :modelValue="$props.modelValue"
283
+ @update:modelValue="onSingleChange"
284
+ @click="onClick"
285
+ @blur="onBlur"
286
+ v-model:search="search"
287
+ v-bind="$attrs"
142
288
  >
143
- <FSToggleSet
144
- v-if="$props.toggleSet"
145
- :editable="$props.editable"
146
- :multiple="$props.multiple"
147
- :required="$props.required"
148
- :values="$props.items"
149
- :rules="$props.rules"
150
- :modelValue="$props.modelValue"
151
- @update:modelValue="$emit('update:modelValue', $event)"
152
- v-bind="$attrs"
289
+ <template
290
+ v-for="(_, name) in autocompleteSlots"
291
+ v-slot:[name]="slotData"
153
292
  >
154
- <template
155
- v-for="(_, name) in toggleSetSlots"
156
- v-slot:[name]="slotData"
157
- >
158
- <slot
159
- :name="`toggle-set-${name}`"
160
- v-bind="slotData"
161
- />
162
- </template>
163
- </FSToggleSet>
164
- <v-autocomplete
165
- v-else
166
- class="fs-autocomplete-field"
167
- variant="outlined"
168
- :clearable="$props.clearable && $props.editable && !!$props.modelValue"
169
- :itemTitle="$props.itemTitle"
170
- :itemValue="$props.itemValue"
171
- :readonly="!$props.editable"
172
- :multiple="$props.multiple"
173
- :validateOn="validateOn"
174
- :autoSelectFirst="true"
175
- :persistentClear="true"
176
- :listProps="listStyle"
177
- :returnObject="false"
178
- :items="$props.items"
179
- :rules="$props.rules"
180
- :hideDetails="true"
181
- :menuIcon="null"
182
- :class="classes"
183
- :style="style"
184
- :modelValue="$props.modelValue"
185
- @update:modelValue="$emit('update:modelValue', $event)"
186
- @click="onClick"
187
- v-model:search="search"
188
- v-bind="$attrs"
293
+ <slot
294
+ :name="`autocomplete-${name}`"
295
+ v-bind="slotData"
296
+ />
297
+ </template>
298
+ <template
299
+ #item="{ props, item }"
189
300
  >
190
- <template
191
- v-for="(_, name) in autocompleteSlots"
192
- v-slot:[name]="slotData"
301
+ <v-list-item
302
+ v-bind="{ ...props, title: '' }"
193
303
  >
194
- <slot
195
- :name="`autocomplete-${name}`"
196
- v-bind="slotData"
197
- />
198
- </template>
199
- <template
200
- #item="{ props, item }"
201
- >
202
- <v-list-item
203
- v-bind="{ ...props, title: '' }"
304
+ <FSRow
305
+ align="center-left"
306
+ :wrap="false"
204
307
  >
205
- <FSRow
206
- align="center-left"
308
+ <FSCheckbox
309
+ v-if="$props.multiple"
310
+ :modelValue="$props.modelValue?.includes(item.raw[$props.itemValue!])"
311
+ @click="props.onClick"
207
312
  >
208
- <FSCheckbox
209
- v-if="$props.multiple"
210
- :modelValue="$props.modelValue?.includes(item.raw[$props.itemValue])"
211
- @click="props.onClick"
313
+ <template
314
+ #label="{ font }"
212
315
  >
213
- <template
214
- #label="{ font }"
316
+ <slot
317
+ name="item-prepend"
318
+ v-bind="{ item: item.raw }"
319
+ />
320
+ <FSSpan
321
+ :font="font"
215
322
  >
216
- <slot
217
- name="item-label"
218
- v-bind="{ item, font }"
219
- >
220
- <FSSpan
221
- :font="font"
222
- >
223
- {{ item.raw[$props.itemTitle] }}
224
- </FSSpan>
225
- </slot>
226
- </template>
227
- </FSCheckbox>
323
+ {{ item.raw[$props.itemTitle!] }}
324
+ </FSSpan>
325
+ </template>
326
+ </FSCheckbox>
327
+ <template
328
+ v-else
329
+ >
330
+ <slot
331
+ name="item-prepend"
332
+ v-bind="{ item: item.raw }"
333
+ />
228
334
  <FSSpan
229
- v-else
335
+ :font="$props.modelValue === item.raw[$props.itemTitle!] ? 'text-button' : 'text-body'"
230
336
  >
231
- <slot
232
- name="item-label"
233
- v-bind="{
234
- item,
235
- font: $props.modelValue === item.raw[$props.itemTitle] ? 'text-button' : 'text-body'
236
- }"
237
- >
238
- <FSSpan
239
- :font="$props.modelValue === item.raw[$props.itemTitle] ? 'text-button' : 'text-body'"
240
- >
241
- {{ item.raw[$props.itemTitle] }}
242
- </FSSpan>
243
- </slot>
337
+ {{ item.raw[$props.itemTitle!] }}
244
338
  </FSSpan>
339
+ </template>
340
+ <FSRow
341
+ align="center-right"
342
+ >
343
+ <slot
344
+ name="item-append"
345
+ v-bind="{ item: item.raw }"
346
+ />
245
347
  </FSRow>
246
- </v-list-item>
247
- </template>
248
- <template
249
- #clear
348
+ </FSRow>
349
+ </v-list-item>
350
+ </template>
351
+ <template
352
+ #prepend-inner
353
+ >
354
+ <slot
355
+ v-if="selectedItem && showExtra"
356
+ name="item-prepend"
357
+ v-bind="{ item: selectedItem }"
358
+ />
359
+ </template>
360
+ <template
361
+ v-if="$props.multiple"
362
+ #selection="{ index }"
363
+ >
364
+ <FSSpan
365
+ v-if="index === $props.modelValue.length - 1 && showExtra"
366
+ >
367
+ {{ $props.placeholder }}
368
+ </FSSpan>
369
+ </template>
370
+ <template
371
+ #clear
372
+ >
373
+ <FSRow
374
+ :wrap="false"
250
375
  >
376
+ <slot
377
+ v-if="selectedItem && showExtra"
378
+ name="item-append"
379
+ v-bind="{ item: selectedItem }"
380
+ />
251
381
  <slot
252
382
  name="clear"
253
383
  >
@@ -256,71 +386,101 @@
256
386
  icon="mdi-close"
257
387
  variant="icon"
258
388
  :color="ColorEnum.Dark"
259
- @click="$emit('update:modelValue', null)"
389
+ @click="onClear"
260
390
  />
261
391
  </slot>
262
- </template>
263
- <template
264
- #append-inner
392
+ </FSRow>
393
+ </template>
394
+ <template
395
+ #append-inner
396
+ >
397
+ <slot
398
+ name="append-inner"
265
399
  >
266
- <slot
267
- name="append-inner"
268
- >
269
- <FSButton
270
- icon="mdi-chevron-down"
271
- variant="icon"
272
- :editable="$props.editable"
273
- :color="ColorEnum.Dark"
274
- />
275
- </slot>
276
- </template>
277
- <template
278
- #append-item
400
+ <FSButton
401
+ icon="mdi-chevron-down"
402
+ variant="icon"
403
+ :editable="$props.editable"
404
+ :color="ColorEnum.Dark"
405
+ />
406
+ </slot>
407
+ </template>
408
+ <template
409
+ #append-item
410
+ >
411
+ <FSRow
412
+ v-if="allowAddItem"
413
+ padding="15px"
279
414
  >
280
- <FSRow
281
- v-if="showSearch && !searchItems.map((item: any) => item[$props.itemTitle]).some(s=>s.toLowerCase() == search.toLowerCase())"
282
- padding="17px"
283
- >
284
- <FSButton
285
- v-if="search && search.trim().length > 0"
286
- variant="icon"
287
- :label="$tr('ui.common.add', 'Add this item')"
288
- :color="ColorEnum.Primary"
289
- @click="$emit('add:item', search)"
290
- />
291
- </FSRow>
292
- </template>
293
- <template
294
- #no-data
415
+ <FSButton
416
+ variant="icon"
417
+ :label="$tr('autocomplete-field.add-item', 'Add new item')"
418
+ :color="ColorEnum.Primary"
419
+ @click="$emit('add:item', search)"
420
+ />
421
+ </FSRow>
422
+ </template>
423
+ <template
424
+ #no-data
425
+ >
426
+ <FSRow
427
+ v-if="!allowAddItem"
428
+ padding="15px"
295
429
  >
296
- <template
297
- v-if="showSearch"
298
- >
299
- </template>
300
- <FSRow
301
- v-else
302
- padding="17px"
303
- >
304
- <FSSpan>
305
- {{ $tr("ui.common.no-data", "No data") }}
306
- </FSSpan>
307
- </FSRow>
308
- </template>
309
- </v-autocomplete>
310
- </FSBaseField>
311
- </template>
312
- </template>
430
+ <FSSpan>
431
+ {{ $tr("ui.common.no-data", "No data") }}
432
+ </FSSpan>
433
+ </FSRow>
434
+ </template>
435
+ </v-autocomplete>
436
+ <FSSlideGroup
437
+ v-if="$props.multiple && Array.isArray($props.modelValue)"
438
+ >
439
+ <FSCard
440
+ v-for="(item, index) in $props.items.filter((item: any) => $props.modelValue.includes(item[$props.itemValue!]))"
441
+ variant="standard"
442
+ :height="['40px', '36px']"
443
+ :color="ColorEnum.Light"
444
+ :border="false"
445
+ :key="index"
446
+ >
447
+ <FSRow
448
+ align="center-left"
449
+ padding="0 8px"
450
+ >
451
+ <slot
452
+ name="item-prepend"
453
+ v-bind="{ item }"
454
+ />
455
+ <FSSpan>
456
+ {{ item[$props.itemTitle!] }}
457
+ </FSSpan>
458
+ <slot
459
+ name="item-append"
460
+ v-bind="{ item }"
461
+ />
462
+ <FSButton
463
+ icon="mdi-close"
464
+ variant="icon"
465
+ :color="ColorEnum.Dark"
466
+ @click="() => onCheckboxChange(item[$props.itemValue!])"
467
+ />
468
+ </FSRow>
469
+ </FSCard>
470
+ </FSSlideGroup>
471
+ </FSCol>
472
+ </FSBaseField>
313
473
  </template>
314
474
 
315
475
  <script lang="ts">
316
- import { computed, defineComponent, type PropType, ref, type StyleValue } from "vue";
476
+ import { computed, defineComponent, type PropType, ref, type Slot, type StyleValue, watch } from "vue";
317
477
 
318
478
  import { useBreakpoints, useColors, useRules, useSlots } from "@dative-gpi/foundation-shared-components/composables";
319
479
  import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
320
480
 
321
481
  import FSSearchField from "./FSSearchField.vue";
322
482
  import FSDialogMenu from "../FSDialogMenu.vue";
323
- import FSRadioGroup from "../FSRadioGroup.vue";
483
+ import FSSlideGroup from "../FSSlideGroup.vue";
324
484
  import FSToggleSet from "../FSToggleSet.vue";
325
485
  import FSBaseField from "./FSBaseField.vue";
326
486
  import FSTextField from "./FSTextField.vue";
@@ -328,6 +488,8 @@ import FSCheckbox from "../FSCheckbox.vue";
328
488
  import FSFadeOut from "../FSFadeOut.vue";
329
489
  import FSButton from "../FSButton.vue";
330
490
  import FSLoader from "../FSLoader.vue";
491
+ import FSRadio from "../FSRadio.vue";
492
+ import FSCard from "../FSCard.vue";
331
493
  import FSSpan from "../FSSpan.vue";
332
494
  import FSCol from "../FSCol.vue";
333
495
  import FSRow from "../FSRow.vue";
@@ -338,7 +500,7 @@ export default defineComponent({
338
500
  components: {
339
501
  FSSearchField,
340
502
  FSDialogMenu,
341
- FSRadioGroup,
503
+ FSSlideGroup,
342
504
  FSBaseField,
343
505
  FSTextField,
344
506
  FSToggleSet,
@@ -346,6 +508,8 @@ export default defineComponent({
346
508
  FSFadeOut,
347
509
  FSButton,
348
510
  FSLoader,
511
+ FSRadio,
512
+ FSCard,
349
513
  FSSpan,
350
514
  FSCol,
351
515
  FSRow
@@ -356,6 +520,11 @@ export default defineComponent({
356
520
  required: false,
357
521
  default: null
358
522
  },
523
+ placeholder: {
524
+ type: String as PropType<string | null>,
525
+ required: false,
526
+ default: null
527
+ },
359
528
  description: {
360
529
  type: String as PropType<string | null>,
361
530
  required: false,
@@ -433,7 +602,7 @@ export default defineComponent({
433
602
  },
434
603
  emits: ["update:modelValue", "update:search", "add:item"],
435
604
  setup: (props, { emit }) => {
436
- const { isExtraSmall, isMobileSized } = useBreakpoints();
605
+ const { fontStyles, isExtraSmall, isMobileSized } = useBreakpoints();
437
606
  const { validateOn, getMessages } = useRules();
438
607
  const { getColors } = useColors();
439
608
  const { slots } = useSlots();
@@ -448,123 +617,106 @@ export default defineComponent({
448
617
 
449
618
  const dialog = ref(false);
450
619
  const search = ref("");
620
+ const showExtra = ref(true);
451
621
 
452
622
  const style = computed((): StyleValue => {
453
623
  if (!props.editable) {
454
624
  return {
455
- "--fs-autocomplete-field-cursor": "default",
456
- "--fs-autocomplete-field-border-color": lights.base,
457
- "--fs-autocomplete-field-color": lights.dark,
458
- "--fs-autocomplete-field-active-border-color": lights.base
625
+ "--fs-autocomplete-field-cursor" : "default",
626
+ "--fs-autocomplete-field-border-color" : lights.base,
627
+ "--fs-autocomplete-field-color" : lights.dark,
628
+ "--fs-autocomplete-field-active-border-color": lights.base,
629
+ "--fs-base-field-input-height" : isMobileSized.value ? "34px" : "38px",
630
+ ...fontStyles.value
459
631
  };
460
632
  }
461
633
  return {
462
- "--fs-autocomplete-field-cursor": "text",
463
- "--fs-autocomplete-field-background-color": backgrounds.base,
634
+ "--fs-autocomplete-field-cursor" : "text",
635
+ "--fs-autocomplete-field-background-color" : backgrounds.base,
464
636
  "--fs-autocomplete-field-no-data-background-color": lights.light,
465
- "--fs-autocomplete-field-border-color": lights.dark,
466
- "--fs-autocomplete-field-color": darks.base,
467
- "--fs-autocomplete-field-active-border-color": darks.dark,
468
- "--fs-autocomplete-field-error-color": errors.base,
469
- "--fs-autocomplete-field-error-border-color": errors.base
637
+ "--fs-autocomplete-field-border-color" : lights.dark,
638
+ "--fs-autocomplete-field-color" : darks.base,
639
+ "--fs-autocomplete-field-active-border-color" : darks.dark,
640
+ "--fs-autocomplete-field-error-color" : errors.base,
641
+ "--fs-autocomplete-field-error-border-color" : errors.base,
642
+ "--fs-base-field-input-height" : isMobileSized.value ? "34px" : "38px",
643
+ ...fontStyles.value
470
644
  };
471
645
  });
472
646
 
473
- const autocompleteSlots = computed((): any => {
474
- return Object.keys(slots).filter(k => k.startsWith("autocomplete-")).reduce((acc, key) => {
647
+ const autocompleteSlots = computed((): { [key: string]: Slot<any> } => {
648
+ return Object.keys(slots).filter(k => k.startsWith("autocomplete-")).reduce((acc: { [key: string]: Slot<any> }, key) => {
475
649
  acc[key.substring("autocomplete-".length)] = slots[key];
476
650
  return acc;
477
651
  }, {});
478
652
  });
479
653
 
480
- const toggleSetSlots = computed((): any => {
481
- return Object.keys(slots).filter(k => k.startsWith("toggle-set-")).reduce((acc, key) => {
654
+ const toggleSetSlots = computed((): { [key: string]: Slot<any> } => {
655
+ return Object.keys(slots).filter(k => k.startsWith("toggle-set-")).reduce((acc: { [key: string]: Slot<any> }, key) => {
482
656
  acc[key.substring("toggle-set-".length)] = slots[key];
483
657
  return acc;
484
658
  }, {});
485
659
  });
486
660
 
487
- const listStyle = computed((): any => {
661
+ const listStyle = computed((): { style: StyleValue } => {
488
662
  return {
489
663
  style: style.value
490
664
  };
491
665
  });
492
666
 
493
- const classes = computed((): string[] => {
494
- const classNames = ["fs-autocomplete-field"];
495
- if (props.multiple) {
496
- classNames.push("fs-autocomplete-multiple-field");
497
- }
498
- return classNames;
499
- });
500
-
501
667
  const messages = computed((): string[] => props.messages ?? getMessages(props.modelValue, props.rules));
502
668
 
503
- const searchItems = computed(() => {
669
+ const searchItems = computed((): any[] => {
504
670
  return props.items.filter((item: any) => {
505
671
  return item[props.itemTitle].toLowerCase().includes(search.value.toLowerCase());
506
672
  });
507
673
  });
508
674
 
509
- const height = computed(() => {
510
- const other = 8 + 8 // Paddings
511
- + (isMobileSized ? 36 : 40) + 8; // Header
512
- return `calc(100vh - 40px - ${other}px)`;
675
+ const selectedItem = computed((): any => {
676
+ if (props.multiple) {
677
+ return null;
678
+ }
679
+ if (Array.isArray(props.modelValue) && props.modelValue.length > 0) {
680
+ return props.items.find((item: any) => item[props.itemValue] === props.modelValue[0]) ?? null;
681
+ }
682
+ else if (props.modelValue) {
683
+ return props.items.find((item: any) => item[props.itemValue] === props.modelValue) ?? null;
684
+ }
685
+ return null;
513
686
  });
514
687
 
515
- const mobileValue = computed((): string | null => {
516
- if (props.multiple) {
517
- if (Array.isArray(props.modelValue)) {
518
- return props.modelValue.map((value: any) => {
519
- const item = props.items.find((item: object) => item[props.itemValue] === value);
520
- if (item) {
521
- return item[props.itemTitle];
522
- }
523
- }).filter(value => !!value).join(", ");
524
- }
688
+ const selectedItems = computed((): any[] => {
689
+ if (Array.isArray(props.modelValue) && props.modelValue.length > 0) {
690
+ return props.items.filter((item: any) => props.modelValue.includes(item[props.itemValue]));
525
691
  }
526
- if (props.modelValue) {
527
- const item = props.items.find((item: object) => item[props.itemValue] === props.modelValue);
692
+ else if (props.modelValue) {
693
+ const item = props.items.find((item: any) => item[props.itemValue] === props.modelValue);
528
694
  if (item) {
529
- return item[props.itemTitle];
695
+ return [item];
530
696
  }
531
697
  }
532
- return null;
698
+ return [];
533
699
  });
534
700
 
535
- const mobileSelectionProps = computed((): any | null => {
536
- const item = props.items.find((item: any) => item[props.itemValue] === props.modelValue);
537
- if (item) {
538
- return {
539
- item: {
540
- title: "",
541
- value: item[props.itemValue],
542
- props: {
543
- title: item[props.itemTitle],
544
- value: item[props.itemValue]
545
- },
546
- raw: { ...item }
547
- },
548
- font: "text-body"
549
- };
550
- }
551
- return null;
701
+ const allowAddItem = computed((): boolean => {
702
+ return props.showSearch && search.value.trim().length > 0;
552
703
  });
553
704
 
554
- const mobileItemProps = (item: any, font: "text-body" | "text-button" | null): any => {
555
- return {
556
- item: {
557
- title: "",
558
- value: item[props.itemValue],
559
- props: {
560
- title: item[props.itemTitle],
561
- value: item[props.itemValue]
562
- },
563
- raw: { ...item }
564
- },
565
- font
705
+ const maxHeight = computed(() => {
706
+ const other = 8 + 8 // Paddings
707
+ + (isMobileSized.value ? 36 : 40) + 8; // Header
708
+ return `calc(100vh - 40px - ${other}px)`;
709
+ });
710
+
711
+ const mobileValue = computed((): string | null => {
712
+ if (props.multiple && Array.isArray(props.modelValue) && props.modelValue.length > 0) {
713
+ return props.placeholder;
566
714
  }
567
- };
715
+ if (selectedItem.value) {
716
+ return selectedItem.value[props.itemTitle];
717
+ }
718
+ return null;
719
+ });
568
720
 
569
721
  const openMobileOverlay = () => {
570
722
  if (!props.editable) {
@@ -600,34 +752,57 @@ export default defineComponent({
600
752
  }
601
753
  };
602
754
 
603
- const onClick = () => {
604
- if (props.modelValue && !props.multiple) {
605
- search.value="";
606
- }
755
+ const onSingleChange = (value: string) => {
756
+ emit("update:modelValue", value);
757
+ if (value && !Array.isArray(value)) {
758
+ showExtra.value = true;
759
+ }
760
+ };
761
+
762
+ const onClear = () => {
763
+ emit("update:modelValue", null);
764
+ search.value = "";
607
765
  };
608
766
 
767
+ const onClick = (): void => {
768
+ search.value = "";
769
+ showExtra.value = false;
770
+ };
771
+
772
+ const onBlur = () => {
773
+ showExtra.value = true;
774
+ };
775
+
776
+ watch(search, () => {
777
+ emit("update:search", search.value);
778
+ });
779
+
609
780
  return {
610
- mobileSelectionProps,
611
781
  autocompleteSlots,
612
782
  toggleSetSlots,
783
+ selectedItems,
613
784
  isExtraSmall,
785
+ allowAddItem,
786
+ selectedItem,
614
787
  mobileValue,
615
788
  searchItems,
616
789
  validateOn,
617
790
  ColorEnum,
618
791
  listStyle,
792
+ maxHeight,
793
+ showExtra,
619
794
  messages,
620
- classes,
621
795
  dialog,
622
- height,
623
796
  search,
624
797
  slots,
625
798
  style,
626
799
  openMobileOverlay,
627
800
  onCheckboxChange,
628
- mobileItemProps,
801
+ onSingleChange,
629
802
  onRadioChange,
630
- onClick
803
+ onClear,
804
+ onClick,
805
+ onBlur
631
806
  };
632
807
  }
633
808
  });