@rotki/ui-library 2.21.0 → 2.22.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 (321) hide show
  1. package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js +1 -1
  2. package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
  3. package/dist/components/accordions/accordions/RuiAccordions.vue_vue_type_script_setup_true_lang.js +2 -2
  4. package/dist/components/accordions/accordions/RuiAccordions.vue_vue_type_script_setup_true_lang.js.map +1 -1
  5. package/dist/components/alerts/RuiAlert.vue_vue_type_script_setup_true_lang.js +1 -1
  6. package/dist/components/alerts/RuiAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
  7. package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js +1 -1
  8. package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  9. package/dist/components/avatars/RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js +1 -1
  10. package/dist/components/avatars/RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  11. package/dist/components/avatars/avatar-props.js +1 -1
  12. package/dist/components/avatars/avatar-props.js.map +1 -1
  13. package/dist/components/avatars/use-avatar-group.js.map +1 -1
  14. package/dist/components/buttons/button/RuiButton.js.map +1 -1
  15. package/dist/components/buttons/button/RuiButton.vue.d.ts +2 -2
  16. package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js +3 -3
  17. package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  18. package/dist/components/buttons/button/button-props.js.map +1 -1
  19. package/dist/components/buttons/button/button-styles.js.map +1 -1
  20. package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js +2 -2
  21. package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  22. package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js +3 -3
  23. package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  24. package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js +2 -2
  25. package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
  26. package/dist/components/calendar/RuiCalendarHeader.vue_vue_type_script_setup_true_lang.js +3 -3
  27. package/dist/components/calendar/RuiCalendarHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  28. package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js +3 -3
  29. package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  30. package/dist/components/calendar/state.js.map +1 -1
  31. package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js +1 -1
  32. package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  33. package/dist/components/cards/RuiCardHeader.vue_vue_type_script_setup_true_lang.js +1 -1
  34. package/dist/components/cards/RuiCardHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  35. package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js +1 -1
  36. package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  37. package/dist/components/chips/chip-props.js.map +1 -1
  38. package/dist/components/color-picker/RuiColorBoard.vue_vue_type_script_setup_true_lang.js +1 -1
  39. package/dist/components/color-picker/RuiColorBoard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  40. package/dist/components/color-picker/RuiColorDisplay.vue_vue_type_script_setup_true_lang.js +1 -1
  41. package/dist/components/color-picker/RuiColorDisplay.vue_vue_type_script_setup_true_lang.js.map +1 -1
  42. package/dist/components/color-picker/RuiColorHue.vue_vue_type_script_setup_true_lang.js +1 -1
  43. package/dist/components/color-picker/RuiColorHue.vue_vue_type_script_setup_true_lang.js.map +1 -1
  44. package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js +1 -1
  45. package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  46. package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js +1 -1
  47. package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  48. package/dist/components/color-picker/utils.js.map +1 -1
  49. package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js +2 -2
  50. package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  51. package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js +3 -3
  52. package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  53. package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js +2 -2
  54. package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  55. package/dist/components/date-time-picker/date-time-picker-styles.js.map +1 -1
  56. package/dist/components/date-time-picker/dayjs-setup.js.map +1 -1
  57. package/dist/components/date-time-picker/segment-config.js.map +1 -1
  58. package/dist/components/date-time-picker/segment-utils.js.map +1 -1
  59. package/dist/components/date-time-picker/timezones.js.map +1 -1
  60. package/dist/components/date-time-picker/types.js +1 -1
  61. package/dist/components/date-time-picker/types.js.map +1 -1
  62. package/dist/components/date-time-picker/use-date-time-selection.js +2 -2
  63. package/dist/components/date-time-picker/use-date-time-selection.js.map +1 -1
  64. package/dist/components/date-time-picker/use-input-handler.js.map +1 -1
  65. package/dist/components/date-time-picker/use-keyboard-handler.js.map +1 -1
  66. package/dist/components/date-time-picker/utils.js.map +1 -1
  67. package/dist/components/divider/RuiDivider.vue_vue_type_script_setup_true_lang.js +1 -1
  68. package/dist/components/divider/RuiDivider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  69. package/dist/components/forms/auto-complete/RuiAutoComplete.js.map +1 -1
  70. package/dist/components/forms/auto-complete/RuiAutoComplete.vue.d.ts +14 -1
  71. package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js +15 -5
  72. package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  73. package/dist/components/forms/auto-complete/auto-complete-styles.js.map +1 -1
  74. package/dist/components/forms/category-picker/RuiCategoryPicker.js +7 -0
  75. package/dist/components/forms/category-picker/RuiCategoryPicker.js.map +1 -0
  76. package/dist/components/forms/category-picker/RuiCategoryPicker.vue.d.ts +134 -0
  77. package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js +561 -0
  78. package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  79. package/dist/components/forms/category-picker/category-picker-styles.d.ts +432 -0
  80. package/dist/components/forms/category-picker/category-picker-styles.js +59 -0
  81. package/dist/components/forms/category-picker/category-picker-styles.js.map +1 -0
  82. package/dist/components/forms/check-control-styles.js.map +1 -1
  83. package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js +2 -2
  84. package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  85. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js +2 -2
  86. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  87. package/dist/components/forms/checkbox/checkbox-group/context.js.map +1 -1
  88. package/dist/components/forms/file-upload/RuiFileUpload.js.map +1 -1
  89. package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js +5 -5
  90. package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
  91. package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js +2 -2
  92. package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
  93. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue_vue_type_script_setup_true_lang.js +2 -2
  94. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  95. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js +2 -2
  96. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  97. package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js +2 -2
  98. package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  99. package/dist/components/forms/select/RuiSimpleSelect.vue_vue_type_script_setup_true_lang.js +2 -2
  100. package/dist/components/forms/select/RuiSimpleSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  101. package/dist/components/forms/select/menu-select-styles.js.map +1 -1
  102. package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js +2 -2
  103. package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  104. package/dist/components/forms/slider/slider-styles.js.map +1 -1
  105. package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js +2 -2
  106. package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  107. package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js +3 -3
  108. package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  109. package/dist/components/forms/text-area/text-area-styles.js.map +1 -1
  110. package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js +3 -3
  111. package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  112. package/dist/components/forms/text-field/text-field-styles.js.map +1 -1
  113. package/dist/components/forms/text-input-styles.js.map +1 -1
  114. package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js +1 -1
  115. package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js.map +1 -1
  116. package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js +1 -1
  117. package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  118. package/dist/components/index.d.ts +3 -2
  119. package/dist/components/index.js +3 -2
  120. package/dist/components/loaders/RuiSkeletonBase.vue_vue_type_script_setup_true_lang.js +1 -1
  121. package/dist/components/loaders/RuiSkeletonBase.vue_vue_type_script_setup_true_lang.js.map +1 -1
  122. package/dist/components/loaders/RuiSkeletonLoader.vue_vue_type_script_setup_true_lang.js +1 -1
  123. package/dist/components/loaders/RuiSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  124. package/dist/components/loaders/skeleton-type.js.map +1 -1
  125. package/dist/components/logos/RuiLogo.vue_vue_type_script_setup_true_lang.js +1 -1
  126. package/dist/components/logos/RuiLogo.vue_vue_type_script_setup_true_lang.js.map +1 -1
  127. package/dist/components/logos/use-logo-sources.js.map +1 -1
  128. package/dist/components/overlays/badge/RuiBadge.vue_vue_type_script_setup_true_lang.js +1 -1
  129. package/dist/components/overlays/badge/RuiBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
  130. package/dist/components/overlays/badge/badge-props.js.map +1 -1
  131. package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue_vue_type_script_setup_true_lang.js +2 -2
  132. package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue_vue_type_script_setup_true_lang.js.map +1 -1
  133. package/dist/components/overlays/dialog/RuiDialog.vue_vue_type_script_setup_true_lang.js +3 -3
  134. package/dist/components/overlays/dialog/RuiDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  135. package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js +2 -2
  136. package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  137. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js +3 -3
  138. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  139. package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js +2 -2
  140. package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js.map +1 -1
  141. package/dist/components/overlays/tooltip/RuiTooltip.vue_vue_type_script_setup_true_lang.js +1 -1
  142. package/dist/components/overlays/tooltip/RuiTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  143. package/dist/components/overlays/tooltip/tooltip-styles.js.map +1 -1
  144. package/dist/components/progress/RuiProgress.vue_vue_type_script_setup_true_lang.js +1 -1
  145. package/dist/components/progress/RuiProgress.vue_vue_type_script_setup_true_lang.js.map +1 -1
  146. package/dist/components/progress/progress-props.js.map +1 -1
  147. package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js +2 -2
  148. package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  149. package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js +1 -1
  150. package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  151. package/dist/components/steppers/RuiStepperCustomIcon.vue_vue_type_script_setup_true_lang.js +1 -1
  152. package/dist/components/steppers/RuiStepperCustomIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  153. package/dist/components/steppers/RuiStepperIcon.vue_vue_type_script_setup_true_lang.js +1 -1
  154. package/dist/components/steppers/RuiStepperIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  155. package/dist/components/steppers/footer-stepper-variant.js.map +1 -1
  156. package/dist/components/tables/RuiDataTable.js.map +1 -1
  157. package/dist/components/tables/RuiDataTable.vue.d.ts +23 -2
  158. package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js +186 -217
  159. package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  160. package/dist/components/tables/RuiExpandButton.vue_vue_type_script_setup_true_lang.js +1 -1
  161. package/dist/components/tables/RuiExpandButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  162. package/dist/components/tables/RuiTableEmptyState.vue_vue_type_script_setup_true_lang.js +1 -1
  163. package/dist/components/tables/RuiTableEmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
  164. package/dist/components/tables/RuiTableHead.js.map +1 -1
  165. package/dist/components/tables/RuiTableHead.vue.d.ts +11 -1
  166. package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js +1 -2
  167. package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js.map +1 -1
  168. package/dist/components/tables/RuiTablePagination.js.map +1 -1
  169. package/dist/components/tables/RuiTablePagination.vue.d.ts +5 -0
  170. package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js +24 -8
  171. package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  172. package/dist/components/tables/data-table/RuiDataTableBody.js +7 -0
  173. package/dist/components/tables/data-table/RuiDataTableBody.js.map +1 -0
  174. package/dist/components/tables/data-table/RuiDataTableBody.vue.d.ts +55 -0
  175. package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js +78 -0
  176. package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js.map +1 -0
  177. package/dist/components/tables/data-table/RuiDataTableCell.js +7 -0
  178. package/dist/components/tables/data-table/RuiDataTableCell.js.map +1 -0
  179. package/dist/components/tables/data-table/RuiDataTableCell.vue.d.ts +30 -0
  180. package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js +54 -0
  181. package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js.map +1 -0
  182. package/dist/components/tables/data-table/RuiDataTableEmptyRow.js +7 -0
  183. package/dist/components/tables/data-table/RuiDataTableEmptyRow.js.map +1 -0
  184. package/dist/components/tables/data-table/RuiDataTableEmptyRow.vue.d.ts +19 -0
  185. package/dist/components/tables/data-table/RuiDataTableEmptyRow.vue_vue_type_script_setup_true_lang.js +43 -0
  186. package/dist/components/tables/data-table/RuiDataTableEmptyRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
  187. package/dist/components/tables/data-table/RuiDataTableExpandedRow.js +7 -0
  188. package/dist/components/tables/data-table/RuiDataTableExpandedRow.js.map +1 -0
  189. package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue.d.ts +26 -0
  190. package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js +31 -0
  191. package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
  192. package/dist/components/tables/data-table/RuiDataTableGroupRow.js +7 -0
  193. package/dist/components/tables/data-table/RuiDataTableGroupRow.js.map +1 -0
  194. package/dist/components/tables/data-table/RuiDataTableGroupRow.vue.d.ts +32 -0
  195. package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js +85 -0
  196. package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
  197. package/dist/components/tables/data-table/RuiDataTableLoadingRow.js +7 -0
  198. package/dist/components/tables/data-table/RuiDataTableLoadingRow.js.map +1 -0
  199. package/dist/components/tables/data-table/RuiDataTableLoadingRow.vue.d.ts +3 -0
  200. package/dist/components/tables/data-table/RuiDataTableLoadingRow.vue_vue_type_script_setup_true_lang.js +26 -0
  201. package/dist/components/tables/data-table/RuiDataTableLoadingRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
  202. package/dist/components/tables/data-table/RuiDataTableMobileSort.js +7 -0
  203. package/dist/components/tables/data-table/RuiDataTableMobileSort.js.map +1 -0
  204. package/dist/components/tables/data-table/RuiDataTableMobileSort.vue.d.ts +33 -0
  205. package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js +101 -0
  206. package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js.map +1 -0
  207. package/dist/components/tables/data-table/RuiDataTableRow.js +7 -0
  208. package/dist/components/tables/data-table/RuiDataTableRow.js.map +1 -0
  209. package/dist/components/tables/data-table/RuiDataTableRow.vue.d.ts +31 -0
  210. package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js +142 -0
  211. package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
  212. package/dist/components/tables/data-table/context.d.ts +73 -0
  213. package/dist/components/tables/data-table/context.js +100 -0
  214. package/dist/components/tables/data-table/context.js.map +1 -0
  215. package/dist/components/tables/data-table-styles.d.ts +30 -1
  216. package/dist/components/tables/data-table-styles.js +9 -2
  217. package/dist/components/tables/data-table-styles.js.map +1 -1
  218. package/dist/components/tables/table-props.d.ts +5 -0
  219. package/dist/components/tables/table-props.js +5 -1
  220. package/dist/components/tables/table-props.js.map +1 -1
  221. package/dist/components/tables/use-pagination-navigation.js.map +1 -1
  222. package/dist/components/tabs/tab/RuiTab.vue_vue_type_script_setup_true_lang.js +1 -1
  223. package/dist/components/tabs/tab/RuiTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
  224. package/dist/components/tabs/tab/use-tab-link.js.map +1 -1
  225. package/dist/components/tabs/tab-item/RuiTabItem.vue_vue_type_script_setup_true_lang.js +1 -1
  226. package/dist/components/tabs/tab-item/RuiTabItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  227. package/dist/components/tabs/tab-items/RuiTabItems.js.map +1 -1
  228. package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js +2 -2
  229. package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js.map +1 -1
  230. package/dist/components/tabs/tab-props.js.map +1 -1
  231. package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js +2 -2
  232. package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  233. package/dist/components/tabs/tabs/use-tab-routing.js +1 -1
  234. package/dist/components/tabs/tabs/use-tab-routing.js.map +1 -1
  235. package/dist/components/tabs/tabs/use-tab-scroll.js.map +1 -1
  236. package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js +2 -2
  237. package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  238. package/dist/components/time-picker/time-picker-styles.js.map +1 -1
  239. package/dist/composables/breakpoint.js.map +1 -1
  240. package/dist/composables/defaults/table.d.ts +12 -0
  241. package/dist/composables/defaults/table.js.map +1 -1
  242. package/dist/composables/dropdown-menu.js.map +1 -1
  243. package/dist/composables/floating.js +1 -1
  244. package/dist/composables/floating.js.map +1 -1
  245. package/dist/composables/forms/auto-complete/focus.js.map +1 -1
  246. package/dist/composables/forms/auto-complete/index.js +5 -4
  247. package/dist/composables/forms/auto-complete/keyboard-navigation.js.map +1 -1
  248. package/dist/composables/forms/auto-complete/search.d.ts +6 -1
  249. package/dist/composables/forms/auto-complete/search.js +12 -1
  250. package/dist/composables/forms/auto-complete/search.js.map +1 -1
  251. package/dist/composables/forms/auto-complete/value.js.map +1 -1
  252. package/dist/composables/forms/category-picker/use-category-picker.d.ts +76 -0
  253. package/dist/composables/forms/category-picker/use-category-picker.js +141 -0
  254. package/dist/composables/forms/category-picker/use-category-picker.js.map +1 -0
  255. package/dist/composables/forms/use-prepend-append-width.js.map +1 -1
  256. package/dist/composables/icons.js.map +1 -1
  257. package/dist/composables/popper.js.map +1 -1
  258. package/dist/composables/sticky-header.js.map +1 -1
  259. package/dist/composables/tables/data-table/columns.d.ts +7 -1
  260. package/dist/composables/tables/data-table/columns.js +18 -10
  261. package/dist/composables/tables/data-table/columns.js.map +1 -1
  262. package/dist/composables/tables/data-table/expansion.js.map +1 -1
  263. package/dist/composables/tables/data-table/grouping.d.ts +4 -6
  264. package/dist/composables/tables/data-table/grouping.js +38 -24
  265. package/dist/composables/tables/data-table/grouping.js.map +1 -1
  266. package/dist/composables/tables/data-table/pagination.d.ts +4 -4
  267. package/dist/composables/tables/data-table/pagination.js +63 -21
  268. package/dist/composables/tables/data-table/pagination.js.map +1 -1
  269. package/dist/composables/tables/data-table/selection.js +16 -6
  270. package/dist/composables/tables/data-table/selection.js.map +1 -1
  271. package/dist/composables/tables/data-table/sort.d.ts +4 -3
  272. package/dist/composables/tables/data-table/sort.js +78 -40
  273. package/dist/composables/tables/data-table/sort.js.map +1 -1
  274. package/dist/composables/tables/data-table/types.d.ts +3 -1
  275. package/dist/composables/tables/data-table/types.js +6 -2
  276. package/dist/composables/tables/data-table/types.js.map +1 -1
  277. package/dist/composables/theme.js.map +1 -1
  278. package/dist/composables/timeout-manager.js.map +1 -1
  279. package/dist/composables/use-rui-i18n.js.map +1 -1
  280. package/dist/consts/colors.js.map +1 -1
  281. package/dist/consts/time-accuracy.js.map +1 -1
  282. package/dist/i18n/keys.js.map +1 -1
  283. package/dist/icons/icons_1.d.ts +12 -12
  284. package/dist/icons/icons_1.js +140 -157
  285. package/dist/icons/icons_1.js.map +1 -1
  286. package/dist/icons/icons_2.d.ts +13 -13
  287. package/dist/icons/icons_2.js +128 -149
  288. package/dist/icons/icons_2.js.map +1 -1
  289. package/dist/icons/icons_3.d.ts +18 -18
  290. package/dist/icons/icons_3.js +244 -282
  291. package/dist/icons/icons_3.js.map +1 -1
  292. package/dist/icons/icons_4.d.ts +251 -6
  293. package/dist/icons/icons_4.js +3016 -75
  294. package/dist/icons/icons_4.js.map +1 -1
  295. package/dist/icons/icons_5.d.ts +20 -0
  296. package/dist/icons/icons_5.js +221 -0
  297. package/dist/icons/icons_5.js.map +1 -0
  298. package/dist/icons/index.d.ts +2 -1
  299. package/dist/icons/index.js +297 -32
  300. package/dist/icons/index.js.map +1 -1
  301. package/dist/index.js +8 -6
  302. package/dist/index.js.map +1 -1
  303. package/dist/library-icons.json +1 -0
  304. package/dist/style.css +152 -0
  305. package/dist/theme/index.js.map +1 -1
  306. package/dist/types/stepper.js.map +1 -1
  307. package/dist/types/theme.js.map +1 -1
  308. package/dist/utils/assert.js.map +1 -1
  309. package/dist/utils/blockie.js.map +1 -1
  310. package/dist/utils/form-text-detail.js.map +1 -1
  311. package/dist/utils/helpers.js.map +1 -1
  312. package/dist/utils/is-equal.js.map +1 -1
  313. package/dist/utils/tv.js.map +1 -1
  314. package/dist/vite-plugin/index.js +6 -5
  315. package/dist/vite-plugin/index.js.map +1 -1
  316. package/dist/vite-plugin/scanner.d.ts +1 -1
  317. package/dist/vite-plugin/scanner.js +10 -7
  318. package/dist/vite-plugin/scanner.js.map +1 -1
  319. package/dist/vite-plugin/types.d.ts +9 -0
  320. package/dist/web-types.json +2042 -1108
  321. package/package.json +35 -35
@@ -1 +1 @@
1
- {"version":3,"file":"RuiTimePicker.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/time-picker/RuiTimePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, ref, type StyleValue, watch } from 'vue';\nimport { timePickerStyles } from '@/components/time-picker/time-picker-styles';\nimport { TimeAccuracy } from '@/consts/time-accuracy';\nimport { assert } from '@/utils/assert';\n\nexport type TimePickerSelection = 'hour' | 'minute' | 'second' | 'millisecond';\n\nexport interface RuiTimePickerProps {\n accuracy?: TimeAccuracy;\n borderless?: boolean;\n}\n\nconst modelValue = defineModel<Date | undefined>({ required: true });\n\nconst selectedHour = defineModel<number | undefined>('hour');\nconst selectedMinute = defineModel<number | undefined>('minute');\nconst selectedSecond = defineModel<number | undefined>('second');\nconst selectedMillisecond = defineModel<number | undefined>('millisecond');\nconst editMode = defineModel<TimePickerSelection>('selection', { default: 'hour' });\n\nconst { accuracy = TimeAccuracy.MINUTE, borderless = false } = defineProps<RuiTimePickerProps>();\n\nconst ui = timePickerStyles();\n\nconst FULL_CIRCLE = 360;\nconst TWELVE_HOURS = 12;\n\nconst totalItemsPerMode: Record<TimePickerSelection, number> = {\n hour: 12,\n minute: 60,\n second: 60,\n millisecond: 1000,\n};\n\nconst intervals: Record<TimePickerSelection, number> = {\n hour: 1,\n minute: 5,\n second: 5,\n millisecond: 100,\n};\n\nconst isDragging = ref<boolean>(false);\nconst clockFace = useTemplateRef<InstanceType<typeof HTMLDivElement>>('clockFace');\n\nconst showSecond = computed<boolean>(\n () => accuracy === TimeAccuracy.SECOND || accuracy === TimeAccuracy.MILLISECOND,\n);\nconst showMillisecond = computed<boolean>(() => accuracy === TimeAccuracy.MILLISECOND);\n\nconst period = computed<'PM' | 'AM'>(() =>\n isDefined(selectedHour) && get(selectedHour) >= TWELVE_HOURS ? 'PM' : 'AM',\n);\n\nconst displayHour = computed<number | undefined>(() => {\n if (!isDefined(selectedHour)) {\n return undefined;\n }\n const hourValue = get(selectedHour);\n const hour = hourValue % TWELVE_HOURS;\n return hour === 0 ? TWELVE_HOURS : hour;\n});\n\nconst editedValue = computed<number | undefined>(() => {\n const mode = get(editMode);\n if (mode === 'hour') {\n return get(displayHour);\n }\n else if (mode === 'minute') {\n return get(selectedMinute);\n }\n else if (mode === 'second') {\n return get(selectedSecond);\n }\n else {\n return get(selectedMillisecond);\n }\n});\n\nconst displayClockHandCircle = computed<boolean>(() => {\n const mode = get(editMode);\n if (mode === 'hour' || !isDefined(editedValue)) {\n return false;\n }\n else {\n const interval = intervals[mode];\n const value = get(editedValue);\n return value % interval !== 0;\n }\n});\n\nconst dotStyle = computed<StyleValue>(() => ({\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n}));\n\nconst clockHandStyle = computed<StyleValue>(() => {\n if (!isDefined(editedValue)) {\n return {};\n }\n const currentValue = get(editedValue);\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = currentValue * (FULL_CIRCLE / totalItems);\n\n return {\n height: '36%',\n top: '14%',\n left: '50%',\n transformOrigin: 'bottom center',\n transform: `translateX(-50%) rotate(${angle}deg)`,\n zIndex: 10,\n };\n});\n\nconst clockHandCircleStyle = computed<StyleValue>(() => {\n if (!isDefined(editedValue)) {\n return {};\n }\n const radius = '38%';\n const currentValue = get(editedValue);\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = currentValue * (FULL_CIRCLE / totalItems);\n\n const radians = (angle * Math.PI) / 180;\n\n const x = 50 + parseFloat(radius) * Math.cos(radians - Math.PI / 2);\n const y = 50 + parseFloat(radius) * Math.sin(radians - Math.PI / 2);\n\n return {\n position: 'absolute',\n top: `${y}%`,\n left: `${x}%`,\n width: '10px',\n height: '10px',\n borderRadius: '50%',\n transform: 'translate(-50%, -50%)',\n zIndex: 11,\n };\n});\n\nconst clockNumbers = computed<number[]>(() => {\n const mode = get(editMode);\n const interval = intervals[mode];\n const total = totalItemsPerMode[mode];\n const numbers = generateNumbers(total, interval);\n if (mode === 'hour') {\n numbers[0] = 12;\n }\n return numbers;\n});\n\nfunction getModelHours(): number | undefined {\n return isDefined(modelValue) ? new Date(get(modelValue)).getHours() : undefined;\n}\n\nfunction getModelMinutes(): number | undefined {\n return isDefined(modelValue) ? new Date(get(modelValue)).getMinutes() : undefined;\n}\n\nfunction getModelSeconds(): number | undefined {\n const acceptedAccuracy: TimeAccuracy[] = [TimeAccuracy.SECOND, TimeAccuracy.MILLISECOND];\n return acceptedAccuracy.includes(accuracy) && isDefined(modelValue)\n ? new Date(get(modelValue)).getSeconds()\n : undefined;\n}\n\nfunction getModelMilliseconds(): number | undefined {\n return accuracy === TimeAccuracy.MILLISECOND && isDefined(modelValue)\n ? new Date(get(modelValue)).getMilliseconds()\n : undefined;\n}\n\nfunction generateNumbers(total: number, interval: number): number[] {\n const numbers: number[] = [];\n for (let i = 0; i < total; i += interval) {\n numbers.push(i);\n }\n return numbers;\n}\n\nfunction formatValue(value?: number, padding = 2): string {\n return value !== undefined ? value.toString().padStart(padding, '0') : '-'.repeat(padding);\n}\n\nfunction numberStyle(num: number): StyleValue {\n const radius = '38%';\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = num * (FULL_CIRCLE / totalItems) - 90;\n\n const radians = (angle * Math.PI) / 180;\n const x = 50 + parseFloat(radius) * Math.cos(radians);\n const y = 50 + parseFloat(radius) * Math.sin(radians);\n\n return {\n top: `${y}%`,\n left: `${x}%`,\n transform: 'translate(-50%, -50%)',\n };\n}\n\nfunction isSelectedNumber(num: number): boolean {\n if (!isDefined(editedValue)) {\n return false;\n }\n const mode = get(editMode);\n if (mode === 'hour') {\n return get(displayHour) === num;\n }\n else {\n const value = get(editedValue);\n const interval = intervals[mode];\n return value === num || (value % interval === 0 && value === num);\n }\n}\n\nfunction toggleAmPm(): void {\n if (!isDefined(selectedHour)) {\n return;\n }\n if (get(selectedHour) < TWELVE_HOURS) {\n set(selectedHour, get(selectedHour) + TWELVE_HOURS);\n }\n else {\n set(selectedHour, get(selectedHour) - TWELVE_HOURS);\n }\n\n updateModelValue();\n}\n\nfunction startDrag(event: MouseEvent | TouchEvent): void {\n event.preventDefault();\n set(isDragging, true);\n\n if (!isDefined(clockFace))\n return;\n\n const rect = get(clockFace).getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n let rafId: number | null = null;\n\n const applyMove = (clientX: number, clientY: number): void => {\n const x = clientX - centerX;\n const y = clientY - centerY;\n\n let angle = Math.atan2(y, x) * (180 / Math.PI) + 90;\n if (angle < 0)\n angle += FULL_CIRCLE;\n\n const mode = get(editMode);\n const unit =\n Math.round(angle / (FULL_CIRCLE / totalItemsPerMode[mode])) % totalItemsPerMode[mode];\n if (mode === 'hour') {\n let hour = unit;\n if (hour === 0)\n hour = TWELVE_HOURS;\n\n if (get(period) === 'PM' && hour < TWELVE_HOURS) {\n hour += TWELVE_HOURS;\n }\n else if (get(period) === 'AM' && hour === TWELVE_HOURS) {\n hour = 0;\n }\n\n set(selectedHour, hour);\n }\n else if (mode === 'minute') {\n set(selectedMinute, unit);\n }\n else if (mode === 'second') {\n set(selectedSecond, unit);\n }\n else {\n set(selectedMillisecond, unit);\n }\n\n updateModelValue();\n };\n\n const handleMove = (moveEvent: MouseEvent | TouchEvent): void => {\n if (!get(isDragging))\n return;\n\n if (rafId !== null)\n return;\n\n let clientX: number;\n let clientY: number;\n\n if ('touches' in moveEvent) {\n const touch = moveEvent.touches[0];\n assert(touch);\n clientX = touch.clientX;\n clientY = touch.clientY;\n }\n else {\n clientX = moveEvent.clientX;\n clientY = moveEvent.clientY;\n }\n\n rafId = requestAnimationFrame(() => {\n applyMove(clientX, clientY);\n rafId = null;\n });\n };\n\n const handleEnd = (): void => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n set(isDragging, false);\n document.removeEventListener('mousemove', handleMove);\n document.removeEventListener('touchmove', handleMove);\n document.removeEventListener('mouseup', handleEnd);\n document.removeEventListener('touchend', handleEnd);\n\n if (get(editMode) === 'hour') {\n set(editMode, 'minute');\n }\n else if (get(showSecond) && get(editMode) === 'minute') {\n set(editMode, 'second');\n }\n else if (get(showMillisecond) && get(editMode) === 'second') {\n set(editMode, 'millisecond');\n }\n };\n\n document.addEventListener('mousemove', handleMove);\n document.addEventListener('touchmove', handleMove);\n document.addEventListener('mouseup', handleEnd);\n document.addEventListener('touchend', handleEnd);\n\n // Apply initial position synchronously for immediate feedback\n const initialEvent = event;\n let clientX: number;\n let clientY: number;\n if ('touches' in initialEvent) {\n const touch = initialEvent.touches[0];\n assert(touch);\n clientX = touch.clientX;\n clientY = touch.clientY;\n }\n else {\n clientX = initialEvent.clientX;\n clientY = initialEvent.clientY;\n }\n applyMove(clientX, clientY);\n}\n\nfunction selectByClick(num: number): void {\n const mode = get(editMode);\n if (mode === 'hour') {\n let newHour = num;\n\n if (get(period) === 'PM' && newHour < TWELVE_HOURS) {\n newHour += TWELVE_HOURS;\n }\n\n set(selectedHour, newHour);\n set(editMode, 'minute');\n }\n else if (mode === 'minute') {\n set(selectedMinute, num);\n if (get(showSecond))\n set(editMode, 'second');\n }\n else if (mode === 'second') {\n set(selectedSecond, num);\n if (get(showMillisecond)) {\n set(editMode, 'millisecond');\n }\n }\n else if (mode === 'millisecond') {\n set(selectedMillisecond, num);\n }\n\n updateModelValue();\n}\n\nfunction updateModelValue(): void {\n if (!(isDefined(selectedHour) && isDefined(selectedMinute))) {\n return;\n }\n nextTick(() => {\n const date = isDefined(modelValue) ? new Date(get(modelValue)) : new Date();\n date.setHours(get(selectedHour));\n date.setMinutes(get(selectedMinute));\n date.setSeconds(get(selectedSecond) ?? 0);\n date.setMilliseconds(get(selectedMillisecond) ?? 0);\n set(modelValue, date);\n });\n}\n\nwatch(\n modelValue,\n () => {\n set(selectedHour, getModelHours());\n set(selectedMinute, getModelMinutes());\n set(selectedSecond, getModelSeconds());\n set(selectedMillisecond, getModelMilliseconds());\n },\n);\n\nonMounted(() => {\n set(selectedHour, getModelHours());\n set(selectedMinute, getModelMinutes());\n set(selectedSecond, getModelSeconds());\n set(selectedMillisecond, getModelMilliseconds());\n});\n</script>\n\n<template>\n <div\n role=\"group\"\n aria-label=\"Time picker\"\n :class=\"ui.root({ bordered: !borderless })\"\n >\n <div :class=\"ui.digitalDisplay()\">\n <div class=\"flex justify-center items-center gap-1\">\n <div\n role=\"button\"\n aria-label=\"Select hours\"\n :class=\"ui.digit({ active: editMode === 'hour' })\"\n @click=\"editMode = 'hour'\"\n >\n {{ formatValue(displayHour) }}\n </div>\n <div class=\"text-2xl font-semibold\">\n :\n </div>\n <div\n role=\"button\"\n aria-label=\"Select minutes\"\n :class=\"ui.digit({ active: editMode === 'minute' })\"\n @click=\"editMode = 'minute'\"\n >\n {{ formatValue(selectedMinute) }}\n </div>\n <div\n v-if=\"showSecond\"\n class=\"text-2xl font-semibold\"\n >\n :\n </div>\n <div\n v-if=\"showSecond\"\n role=\"button\"\n aria-label=\"Select seconds\"\n :class=\"ui.digit({ active: editMode === 'second' })\"\n @click=\"editMode = 'second'\"\n >\n {{ formatValue(selectedSecond) }}\n </div>\n\n <div\n v-if=\"showMillisecond\"\n class=\"text-lg font-semibold\"\n >\n .\n </div>\n\n <div\n v-if=\"showMillisecond\"\n role=\"button\"\n aria-label=\"Select milliseconds\"\n :class=\"ui.digit({ active: editMode === 'millisecond', class: '!text-lg' })\"\n @click=\"editMode = 'millisecond'\"\n >\n {{ formatValue(selectedMillisecond, 3) }}\n </div>\n <div class=\"text-xl\">\n <div\n role=\"button\"\n aria-label=\"Toggle AM/PM\"\n class=\"rui-time-picker-period cursor-pointer\"\n @click=\"toggleAmPm()\"\n >\n {{ period }}\n </div>\n </div>\n </div>\n </div>\n\n <div\n ref=\"clockFace\"\n role=\"listbox\"\n :aria-label=\"`Select ${editMode}`\"\n :class=\"ui.clockFace()\"\n @mousedown=\"startDrag($event)\"\n @touchstart=\"startDrag($event)\"\n >\n <div\n :class=\"ui.centerDot()\"\n :style=\"dotStyle\"\n />\n\n <div\n :class=\"ui.clockHand()\"\n :style=\"clockHandStyle\"\n />\n\n <div\n v-if=\"displayClockHandCircle\"\n :class=\"ui.clockHandCircle()\"\n :style=\"clockHandCircleStyle\"\n />\n\n <div\n v-for=\"num in clockNumbers\"\n :key=\"`num-${num}`\"\n role=\"option\"\n :aria-selected=\"isSelectedNumber(num)\"\n :class=\"[\n ui.clockNumber({ selected: isSelectedNumber(num) }),\n `rui-${editMode}-${num.toString().padStart(2, '0')}`,\n ]\"\n :style=\"numberStyle(num)\"\n @click=\"selectByClick(num)\"\n >\n {{ num }}\n </div>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"RuiTimePicker.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/time-picker/RuiTimePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, ref, type StyleValue, watch } from 'vue';\nimport { timePickerStyles } from '@/components/time-picker/time-picker-styles';\nimport { TimeAccuracy } from '@/consts/time-accuracy';\nimport { assert } from '@/utils/assert';\n\nexport type TimePickerSelection = 'hour' | 'minute' | 'second' | 'millisecond';\n\nexport interface RuiTimePickerProps {\n accuracy?: TimeAccuracy;\n borderless?: boolean;\n}\n\nconst modelValue = defineModel<Date | undefined>({ required: true });\n\nconst selectedHour = defineModel<number | undefined>('hour');\nconst selectedMinute = defineModel<number | undefined>('minute');\nconst selectedSecond = defineModel<number | undefined>('second');\nconst selectedMillisecond = defineModel<number | undefined>('millisecond');\nconst editMode = defineModel<TimePickerSelection>('selection', { default: 'hour' });\n\nconst { accuracy = TimeAccuracy.MINUTE, borderless = false } = defineProps<RuiTimePickerProps>();\n\nconst ui = timePickerStyles();\n\nconst FULL_CIRCLE = 360;\nconst TWELVE_HOURS = 12;\n\nconst totalItemsPerMode: Record<TimePickerSelection, number> = {\n hour: 12,\n minute: 60,\n second: 60,\n millisecond: 1000,\n};\n\nconst intervals: Record<TimePickerSelection, number> = {\n hour: 1,\n minute: 5,\n second: 5,\n millisecond: 100,\n};\n\nconst isDragging = ref<boolean>(false);\nconst clockFace = useTemplateRef<InstanceType<typeof HTMLDivElement>>('clockFace');\n\nconst showSecond = computed<boolean>(\n () => accuracy === TimeAccuracy.SECOND || accuracy === TimeAccuracy.MILLISECOND,\n);\nconst showMillisecond = computed<boolean>(() => accuracy === TimeAccuracy.MILLISECOND);\n\nconst period = computed<'PM' | 'AM'>(() =>\n isDefined(selectedHour) && get(selectedHour) >= TWELVE_HOURS ? 'PM' : 'AM',\n);\n\nconst displayHour = computed<number | undefined>(() => {\n if (!isDefined(selectedHour)) {\n return undefined;\n }\n const hourValue = get(selectedHour);\n const hour = hourValue % TWELVE_HOURS;\n return hour === 0 ? TWELVE_HOURS : hour;\n});\n\nconst editedValue = computed<number | undefined>(() => {\n const mode = get(editMode);\n if (mode === 'hour') {\n return get(displayHour);\n }\n else if (mode === 'minute') {\n return get(selectedMinute);\n }\n else if (mode === 'second') {\n return get(selectedSecond);\n }\n else {\n return get(selectedMillisecond);\n }\n});\n\nconst displayClockHandCircle = computed<boolean>(() => {\n const mode = get(editMode);\n if (mode === 'hour' || !isDefined(editedValue)) {\n return false;\n }\n else {\n const interval = intervals[mode];\n const value = get(editedValue);\n return value % interval !== 0;\n }\n});\n\nconst dotStyle = computed<StyleValue>(() => ({\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n}));\n\nconst clockHandStyle = computed<StyleValue>(() => {\n if (!isDefined(editedValue)) {\n return {};\n }\n const currentValue = get(editedValue);\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = currentValue * (FULL_CIRCLE / totalItems);\n\n return {\n height: '36%',\n top: '14%',\n left: '50%',\n transformOrigin: 'bottom center',\n transform: `translateX(-50%) rotate(${angle}deg)`,\n zIndex: 10,\n };\n});\n\nconst clockHandCircleStyle = computed<StyleValue>(() => {\n if (!isDefined(editedValue)) {\n return {};\n }\n const radius = '38%';\n const currentValue = get(editedValue);\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = currentValue * (FULL_CIRCLE / totalItems);\n\n const radians = (angle * Math.PI) / 180;\n\n const x = 50 + parseFloat(radius) * Math.cos(radians - Math.PI / 2);\n const y = 50 + parseFloat(radius) * Math.sin(radians - Math.PI / 2);\n\n return {\n position: 'absolute',\n top: `${y}%`,\n left: `${x}%`,\n width: '10px',\n height: '10px',\n borderRadius: '50%',\n transform: 'translate(-50%, -50%)',\n zIndex: 11,\n };\n});\n\nconst clockNumbers = computed<number[]>(() => {\n const mode = get(editMode);\n const interval = intervals[mode];\n const total = totalItemsPerMode[mode];\n const numbers = generateNumbers(total, interval);\n if (mode === 'hour') {\n numbers[0] = 12;\n }\n return numbers;\n});\n\nfunction getModelHours(): number | undefined {\n return isDefined(modelValue) ? new Date(get(modelValue)).getHours() : undefined;\n}\n\nfunction getModelMinutes(): number | undefined {\n return isDefined(modelValue) ? new Date(get(modelValue)).getMinutes() : undefined;\n}\n\nfunction getModelSeconds(): number | undefined {\n const acceptedAccuracy: TimeAccuracy[] = [TimeAccuracy.SECOND, TimeAccuracy.MILLISECOND];\n return acceptedAccuracy.includes(accuracy) && isDefined(modelValue)\n ? new Date(get(modelValue)).getSeconds()\n : undefined;\n}\n\nfunction getModelMilliseconds(): number | undefined {\n return accuracy === TimeAccuracy.MILLISECOND && isDefined(modelValue)\n ? new Date(get(modelValue)).getMilliseconds()\n : undefined;\n}\n\nfunction generateNumbers(total: number, interval: number): number[] {\n const numbers: number[] = [];\n for (let i = 0; i < total; i += interval) {\n numbers.push(i);\n }\n return numbers;\n}\n\nfunction formatValue(value?: number, padding = 2): string {\n return value !== undefined ? value.toString().padStart(padding, '0') : '-'.repeat(padding);\n}\n\nfunction numberStyle(num: number): StyleValue {\n const radius = '38%';\n const totalItems = totalItemsPerMode[get(editMode)];\n const angle = num * (FULL_CIRCLE / totalItems) - 90;\n\n const radians = (angle * Math.PI) / 180;\n const x = 50 + parseFloat(radius) * Math.cos(radians);\n const y = 50 + parseFloat(radius) * Math.sin(radians);\n\n return {\n top: `${y}%`,\n left: `${x}%`,\n transform: 'translate(-50%, -50%)',\n };\n}\n\nfunction isSelectedNumber(num: number): boolean {\n if (!isDefined(editedValue)) {\n return false;\n }\n const mode = get(editMode);\n if (mode === 'hour') {\n return get(displayHour) === num;\n }\n else {\n const value = get(editedValue);\n const interval = intervals[mode];\n return value === num || (value % interval === 0 && value === num);\n }\n}\n\nfunction toggleAmPm(): void {\n if (!isDefined(selectedHour)) {\n return;\n }\n if (get(selectedHour) < TWELVE_HOURS) {\n set(selectedHour, get(selectedHour) + TWELVE_HOURS);\n }\n else {\n set(selectedHour, get(selectedHour) - TWELVE_HOURS);\n }\n\n updateModelValue();\n}\n\nfunction startDrag(event: MouseEvent | TouchEvent): void {\n event.preventDefault();\n set(isDragging, true);\n\n if (!isDefined(clockFace))\n return;\n\n const rect = get(clockFace).getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n let rafId: number | null = null;\n\n const applyMove = (clientX: number, clientY: number): void => {\n const x = clientX - centerX;\n const y = clientY - centerY;\n\n let angle = Math.atan2(y, x) * (180 / Math.PI) + 90;\n if (angle < 0)\n angle += FULL_CIRCLE;\n\n const mode = get(editMode);\n const unit =\n Math.round(angle / (FULL_CIRCLE / totalItemsPerMode[mode])) % totalItemsPerMode[mode];\n if (mode === 'hour') {\n let hour = unit;\n if (hour === 0)\n hour = TWELVE_HOURS;\n\n if (get(period) === 'PM' && hour < TWELVE_HOURS) {\n hour += TWELVE_HOURS;\n }\n else if (get(period) === 'AM' && hour === TWELVE_HOURS) {\n hour = 0;\n }\n\n set(selectedHour, hour);\n }\n else if (mode === 'minute') {\n set(selectedMinute, unit);\n }\n else if (mode === 'second') {\n set(selectedSecond, unit);\n }\n else {\n set(selectedMillisecond, unit);\n }\n\n updateModelValue();\n };\n\n const handleMove = (moveEvent: MouseEvent | TouchEvent): void => {\n if (!get(isDragging))\n return;\n\n if (rafId !== null)\n return;\n\n let clientX: number;\n let clientY: number;\n\n if ('touches' in moveEvent) {\n const touch = moveEvent.touches[0];\n assert(touch);\n clientX = touch.clientX;\n clientY = touch.clientY;\n }\n else {\n clientX = moveEvent.clientX;\n clientY = moveEvent.clientY;\n }\n\n rafId = requestAnimationFrame(() => {\n applyMove(clientX, clientY);\n rafId = null;\n });\n };\n\n const handleEnd = (): void => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n set(isDragging, false);\n document.removeEventListener('mousemove', handleMove);\n document.removeEventListener('touchmove', handleMove);\n document.removeEventListener('mouseup', handleEnd);\n document.removeEventListener('touchend', handleEnd);\n\n if (get(editMode) === 'hour') {\n set(editMode, 'minute');\n }\n else if (get(showSecond) && get(editMode) === 'minute') {\n set(editMode, 'second');\n }\n else if (get(showMillisecond) && get(editMode) === 'second') {\n set(editMode, 'millisecond');\n }\n };\n\n document.addEventListener('mousemove', handleMove);\n document.addEventListener('touchmove', handleMove);\n document.addEventListener('mouseup', handleEnd);\n document.addEventListener('touchend', handleEnd);\n\n // Apply initial position synchronously for immediate feedback\n const initialEvent = event;\n let clientX: number;\n let clientY: number;\n if ('touches' in initialEvent) {\n const touch = initialEvent.touches[0];\n assert(touch);\n clientX = touch.clientX;\n clientY = touch.clientY;\n }\n else {\n clientX = initialEvent.clientX;\n clientY = initialEvent.clientY;\n }\n applyMove(clientX, clientY);\n}\n\nfunction selectByClick(num: number): void {\n const mode = get(editMode);\n if (mode === 'hour') {\n let newHour = num;\n\n if (get(period) === 'PM' && newHour < TWELVE_HOURS) {\n newHour += TWELVE_HOURS;\n }\n\n set(selectedHour, newHour);\n set(editMode, 'minute');\n }\n else if (mode === 'minute') {\n set(selectedMinute, num);\n if (get(showSecond))\n set(editMode, 'second');\n }\n else if (mode === 'second') {\n set(selectedSecond, num);\n if (get(showMillisecond)) {\n set(editMode, 'millisecond');\n }\n }\n else if (mode === 'millisecond') {\n set(selectedMillisecond, num);\n }\n\n updateModelValue();\n}\n\nfunction updateModelValue(): void {\n if (!(isDefined(selectedHour) && isDefined(selectedMinute))) {\n return;\n }\n nextTick(() => {\n const date = isDefined(modelValue) ? new Date(get(modelValue)) : new Date();\n date.setHours(get(selectedHour));\n date.setMinutes(get(selectedMinute));\n date.setSeconds(get(selectedSecond) ?? 0);\n date.setMilliseconds(get(selectedMillisecond) ?? 0);\n set(modelValue, date);\n });\n}\n\nwatch(\n modelValue,\n () => {\n set(selectedHour, getModelHours());\n set(selectedMinute, getModelMinutes());\n set(selectedSecond, getModelSeconds());\n set(selectedMillisecond, getModelMilliseconds());\n },\n);\n\nonMounted(() => {\n set(selectedHour, getModelHours());\n set(selectedMinute, getModelMinutes());\n set(selectedSecond, getModelSeconds());\n set(selectedMillisecond, getModelMilliseconds());\n});\n</script>\n\n<template>\n <div\n role=\"group\"\n aria-label=\"Time picker\"\n :class=\"ui.root({ bordered: !borderless })\"\n >\n <div :class=\"ui.digitalDisplay()\">\n <div class=\"flex justify-center items-center gap-1\">\n <div\n role=\"button\"\n aria-label=\"Select hours\"\n :class=\"ui.digit({ active: editMode === 'hour' })\"\n @click=\"editMode = 'hour'\"\n >\n {{ formatValue(displayHour) }}\n </div>\n <div class=\"text-2xl font-semibold\">\n :\n </div>\n <div\n role=\"button\"\n aria-label=\"Select minutes\"\n :class=\"ui.digit({ active: editMode === 'minute' })\"\n @click=\"editMode = 'minute'\"\n >\n {{ formatValue(selectedMinute) }}\n </div>\n <div\n v-if=\"showSecond\"\n class=\"text-2xl font-semibold\"\n >\n :\n </div>\n <div\n v-if=\"showSecond\"\n role=\"button\"\n aria-label=\"Select seconds\"\n :class=\"ui.digit({ active: editMode === 'second' })\"\n @click=\"editMode = 'second'\"\n >\n {{ formatValue(selectedSecond) }}\n </div>\n\n <div\n v-if=\"showMillisecond\"\n class=\"text-lg font-semibold\"\n >\n .\n </div>\n\n <div\n v-if=\"showMillisecond\"\n role=\"button\"\n aria-label=\"Select milliseconds\"\n :class=\"ui.digit({ active: editMode === 'millisecond', class: '!text-lg' })\"\n @click=\"editMode = 'millisecond'\"\n >\n {{ formatValue(selectedMillisecond, 3) }}\n </div>\n <div class=\"text-xl\">\n <div\n role=\"button\"\n aria-label=\"Toggle AM/PM\"\n class=\"rui-time-picker-period cursor-pointer\"\n @click=\"toggleAmPm()\"\n >\n {{ period }}\n </div>\n </div>\n </div>\n </div>\n\n <div\n ref=\"clockFace\"\n role=\"listbox\"\n :aria-label=\"`Select ${editMode}`\"\n :class=\"ui.clockFace()\"\n @mousedown=\"startDrag($event)\"\n @touchstart=\"startDrag($event)\"\n >\n <div\n :class=\"ui.centerDot()\"\n :style=\"dotStyle\"\n />\n\n <div\n :class=\"ui.clockHand()\"\n :style=\"clockHandStyle\"\n />\n\n <div\n v-if=\"displayClockHandCircle\"\n :class=\"ui.clockHandCircle()\"\n :style=\"clockHandCircleStyle\"\n />\n\n <div\n v-for=\"num in clockNumbers\"\n :key=\"`num-${num}`\"\n role=\"option\"\n :aria-selected=\"isSelectedNumber(num)\"\n :class=\"[\n ui.clockNumber({ selected: isSelectedNumber(num) }),\n `rui-${editMode}-${num.toString().padStart(2, '0')}`,\n ]\"\n :style=\"numberStyle(num)\"\n @click=\"selectByClick(num)\"\n >\n {{ num }}\n </div>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"time-picker-styles.js","names":[],"sources":["../../../src/components/time-picker/time-picker-styles.ts"],"sourcesContent":["import { tv } from '@/utils/tv';\n\nexport const timePickerStyles = tv({\n slots: {\n root: 'bg-white overflow-hidden text-rui-text p-3 dark:bg-rui-grey-900',\n digitalDisplay: 'mb-2 text-center',\n digit: 'text-2xl font-semibold cursor-pointer',\n clockFace: 'relative rounded-full w-64 h-64 mx-auto border border-rui-grey-200 dark:border-rui-grey-800',\n centerDot: 'absolute rounded-full bg-rui-primary w-3 h-3',\n clockHand: 'absolute w-[1.5px] bg-rui-primary rounded-full',\n clockHandCircle: 'absolute border-2 border-rui-primary',\n clockNumber: [\n 'absolute text-center text-sm font-medium w-8 h-8',\n 'flex items-center justify-center',\n 'hover:bg-rui-primary-lighter cursor-pointer rounded-full',\n ].join(' '),\n },\n variants: {\n bordered: {\n true: {\n root: 'rounded-md shadow-sm border border-rui-grey-200 dark:border-rui-grey-800',\n },\n },\n active: {\n true: {\n digit: 'text-rui-primary',\n },\n },\n selected: {\n true: {\n clockNumber: 'bg-rui-primary text-rui-dark-text dark:text-rui-light-text z-10 font-bold',\n },\n },\n },\n});\n"],"mappings":";;AAEA,IAAa,mBAAmB,GAAG;CACjC,OAAO;EACL,MAAM;EACN,gBAAgB;EAChB,OAAO;EACP,WAAW;EACX,WAAW;EACX,WAAW;EACX,iBAAiB;EACjB,aAAa;GACX;GACA;GACA;GACD,CAAC,KAAK,IAAI;EACZ;CACD,UAAU;EACR,UAAU,EACR,MAAM,EACJ,MAAM,4EACP,EACF;EACD,QAAQ,EACN,MAAM,EACJ,OAAO,oBACR,EACF;EACD,UAAU,EACR,MAAM,EACJ,aAAa,6EACd,EACF;EACF;CACF,CAAC"}
1
+ {"version":3,"file":"time-picker-styles.js","names":[],"sources":["../../../src/components/time-picker/time-picker-styles.ts"],"sourcesContent":["import { tv } from '@/utils/tv';\n\nexport const timePickerStyles = tv({\n slots: {\n root: 'bg-white overflow-hidden text-rui-text p-3 dark:bg-rui-grey-900',\n digitalDisplay: 'mb-2 text-center',\n digit: 'text-2xl font-semibold cursor-pointer',\n clockFace: 'relative rounded-full w-64 h-64 mx-auto border border-rui-grey-200 dark:border-rui-grey-800',\n centerDot: 'absolute rounded-full bg-rui-primary w-3 h-3',\n clockHand: 'absolute w-[1.5px] bg-rui-primary rounded-full',\n clockHandCircle: 'absolute border-2 border-rui-primary',\n clockNumber: [\n 'absolute text-center text-sm font-medium w-8 h-8',\n 'flex items-center justify-center',\n 'hover:bg-rui-primary-lighter cursor-pointer rounded-full',\n ].join(' '),\n },\n variants: {\n bordered: {\n true: {\n root: 'rounded-md shadow-sm border border-rui-grey-200 dark:border-rui-grey-800',\n },\n },\n active: {\n true: {\n digit: 'text-rui-primary',\n },\n },\n selected: {\n true: {\n clockNumber: 'bg-rui-primary text-rui-dark-text dark:text-rui-light-text z-10 font-bold',\n },\n },\n },\n});\n"],"mappings":";;AAEA,IAAa,mBAAmB,GAAG;CACjC,OAAO;EACL,MAAM;EACN,gBAAgB;EAChB,OAAO;EACP,WAAW;EACX,WAAW;EACX,WAAW;EACX,iBAAiB;EACjB,aAAa;GACX;GACA;GACA;EACF,CAAC,CAAC,KAAK,GAAG;CACZ;CACA,UAAU;EACR,UAAU,EACR,MAAM,EACJ,MAAM,2EACR,EACF;EACA,QAAQ,EACN,MAAM,EACJ,OAAO,mBACT,EACF;EACA,UAAU,EACR,MAAM,EACJ,aAAa,4EACf,EACF;CACF;AACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"breakpoint.js","names":[],"sources":["../../src/composables/breakpoint.ts"],"sourcesContent":["import type { Ref } from 'vue';\nimport { breakpointsTailwind } from '@vueuse/core';\nimport { camelCase } from 'scule';\nimport { assert } from '@/utils/assert';\n\nexport function useBreakpoint() {\n const { width } = useWindowSize();\n\n const breakpointList = {\n xs: 0,\n ...breakpointsTailwind,\n } as const;\n\n type Breakpoint = keyof typeof breakpointList;\n\n const breakpoints = useBreakpoints(breakpointList);\n\n const getKeys = Object.keys as <T extends object>(obj: T) => Array<keyof T>;\n\n const list = getKeys(breakpointList);\n\n const rawSizes: [Breakpoint, Ref<boolean>][] = list.map((breakpoint, index) => {\n if (index < list.length - 1) {\n const nextBreakpoint = list[index + 1];\n assert(nextBreakpoint);\n return [breakpoint, breakpoints.between(breakpoint, nextBreakpoint)];\n }\n return [breakpoint, breakpoints[breakpoint]];\n });\n\n const sizes = rawSizes.map(([breakpoint, value]) => [camelCase(`is_${breakpoint}`), value]);\n\n const sizesUp = list.map(breakpoint => [\n camelCase(`is_${breakpoint}_and_up`),\n breakpoints.greaterOrEqual(breakpoint),\n ]);\n\n const sizesDown = list.map(breakpoint => [\n camelCase(`is_${breakpoint}_and_down`),\n breakpoints.smaller(breakpoint),\n ]);\n\n const name = computed<string>(() => rawSizes.find(item => get(item[1]))?.[0] || '');\n\n return {\n ...Object.fromEntries(sizes),\n ...Object.fromEntries(sizesUp),\n ...Object.fromEntries(sizesDown),\n name,\n width,\n };\n}\n"],"mappings":";;;;;;AAKA,SAAgB,gBAAgB;CAC9B,MAAM,EAAE,UAAU,eAAe;CAEjC,MAAM,iBAAiB;EACrB,IAAI;EACJ,GAAG;EACJ;CAID,MAAM,cAAc,eAAe,eAAe;CAElD,MAAM,UAAU,OAAO;CAEvB,MAAM,OAAO,QAAQ,eAAe;CAEpC,MAAM,WAAyC,KAAK,KAAK,YAAY,UAAU;AAC7E,MAAI,QAAQ,KAAK,SAAS,GAAG;GAC3B,MAAM,iBAAiB,KAAK,QAAQ;AACpC,UAAO,eAAe;AACtB,UAAO,CAAC,YAAY,YAAY,QAAQ,YAAY,eAAe,CAAC;;AAEtE,SAAO,CAAC,YAAY,YAAY,YAAY;GAC5C;CAEF,MAAM,QAAQ,SAAS,KAAK,CAAC,YAAY,WAAW,CAAC,UAAU,MAAM,aAAa,EAAE,MAAM,CAAC;CAE3F,MAAM,UAAU,KAAK,KAAI,eAAc,CACrC,UAAU,MAAM,WAAW,SAAS,EACpC,YAAY,eAAe,WAAW,CACvC,CAAC;CAEF,MAAM,YAAY,KAAK,KAAI,eAAc,CACvC,UAAU,MAAM,WAAW,WAAW,EACtC,YAAY,QAAQ,WAAW,CAChC,CAAC;CAEF,MAAM,OAAO,eAAuB,SAAS,MAAK,SAAQ,MAAI,KAAK,GAAG,CAAC,GAAG,MAAM,GAAG;AAEnF,QAAO;EACL,GAAG,OAAO,YAAY,MAAM;EAC5B,GAAG,OAAO,YAAY,QAAQ;EAC9B,GAAG,OAAO,YAAY,UAAU;EAChC;EACA;EACD"}
1
+ {"version":3,"file":"breakpoint.js","names":[],"sources":["../../src/composables/breakpoint.ts"],"sourcesContent":["import type { Ref } from 'vue';\nimport { breakpointsTailwind } from '@vueuse/core';\nimport { camelCase } from 'scule';\nimport { assert } from '@/utils/assert';\n\nexport function useBreakpoint() {\n const { width } = useWindowSize();\n\n const breakpointList = {\n xs: 0,\n ...breakpointsTailwind,\n } as const;\n\n type Breakpoint = keyof typeof breakpointList;\n\n const breakpoints = useBreakpoints(breakpointList);\n\n const getKeys = Object.keys as <T extends object>(obj: T) => Array<keyof T>;\n\n const list = getKeys(breakpointList);\n\n const rawSizes: [Breakpoint, Ref<boolean>][] = list.map((breakpoint, index) => {\n if (index < list.length - 1) {\n const nextBreakpoint = list[index + 1];\n assert(nextBreakpoint);\n return [breakpoint, breakpoints.between(breakpoint, nextBreakpoint)];\n }\n return [breakpoint, breakpoints[breakpoint]];\n });\n\n const sizes = rawSizes.map(([breakpoint, value]) => [camelCase(`is_${breakpoint}`), value]);\n\n const sizesUp = list.map(breakpoint => [\n camelCase(`is_${breakpoint}_and_up`),\n breakpoints.greaterOrEqual(breakpoint),\n ]);\n\n const sizesDown = list.map(breakpoint => [\n camelCase(`is_${breakpoint}_and_down`),\n breakpoints.smaller(breakpoint),\n ]);\n\n const name = computed<string>(() => rawSizes.find(item => get(item[1]))?.[0] || '');\n\n return {\n ...Object.fromEntries(sizes),\n ...Object.fromEntries(sizesUp),\n ...Object.fromEntries(sizesDown),\n name,\n width,\n };\n}\n"],"mappings":";;;;;;AAKA,SAAgB,gBAAgB;CAC9B,MAAM,EAAE,UAAU,cAAc;CAEhC,MAAM,iBAAiB;EACrB,IAAI;EACJ,GAAG;CACL;CAIA,MAAM,cAAc,eAAe,cAAc;CAEjD,MAAM,UAAU,OAAO;CAEvB,MAAM,OAAO,QAAQ,cAAc;CAEnC,MAAM,WAAyC,KAAK,KAAK,YAAY,UAAU;EAC7E,IAAI,QAAQ,KAAK,SAAS,GAAG;GAC3B,MAAM,iBAAiB,KAAK,QAAQ;GACpC,OAAO,cAAc;GACrB,OAAO,CAAC,YAAY,YAAY,QAAQ,YAAY,cAAc,CAAC;EACrE;EACA,OAAO,CAAC,YAAY,YAAY,WAAW;CAC7C,CAAC;CAED,MAAM,QAAQ,SAAS,KAAK,CAAC,YAAY,WAAW,CAAC,UAAU,MAAM,YAAY,GAAG,KAAK,CAAC;CAE1F,MAAM,UAAU,KAAK,KAAI,eAAc,CACrC,UAAU,MAAM,WAAW,QAAQ,GACnC,YAAY,eAAe,UAAU,CACvC,CAAC;CAED,MAAM,YAAY,KAAK,KAAI,eAAc,CACvC,UAAU,MAAM,WAAW,UAAU,GACrC,YAAY,QAAQ,UAAU,CAChC,CAAC;CAED,MAAM,OAAO,eAAuB,SAAS,MAAK,SAAQ,MAAI,KAAK,EAAE,CAAC,CAAC,GAAG,MAAM,EAAE;CAElF,OAAO;EACL,GAAG,OAAO,YAAY,KAAK;EAC3B,GAAG,OAAO,YAAY,OAAO;EAC7B,GAAG,OAAO,YAAY,SAAS;EAC/B;EACA;CACF;AACF"}
@@ -4,6 +4,18 @@ export interface TableOptions {
4
4
  globalItemsPerPage: MaybeRef<boolean>;
5
5
  limits: MaybeRef<number[]>;
6
6
  stickyOffset: MaybeRef<number>;
7
+ /**
8
+ * Global default width (px) below which every table switches to its stacked
9
+ * mobile card layout. A table's own `mobileBreakpoint` prop overrides this.
10
+ * Leave unset to keep the mobile layout opt-in per table.
11
+ */
12
+ mobileBreakpoint?: MaybeRef<number>;
13
+ /**
14
+ * Whether the mobile breakpoint is measured against the browser viewport
15
+ * (`viewport`, default) or each table's own container width (`container`).
16
+ * A table's own `mobileBreakpointBasis` prop overrides this.
17
+ */
18
+ mobileBreakpointBasis?: MaybeRef<'viewport' | 'container'>;
7
19
  }
8
20
  export declare const TableSymbol: InjectionKey<TableOptions>;
9
21
  export declare function createTableDefaults(options?: Partial<TableOptions>): TableOptions;
@@ -1 +1 @@
1
- {"version":3,"file":"table.js","names":[],"sources":["../../../src/composables/defaults/table.ts"],"sourcesContent":["import type { InjectionKey, MaybeRef, Ref } from 'vue';\n\nexport interface TableOptions {\n itemsPerPage: Ref<number>;\n globalItemsPerPage: MaybeRef<boolean>;\n limits: MaybeRef<number[]>;\n stickyOffset: MaybeRef<number>;\n}\n\nexport const TableSymbol: InjectionKey<TableOptions> = Symbol.for('rui:table');\n\nexport function createTableDefaults(options?: Partial<TableOptions>): TableOptions {\n return {\n globalItemsPerPage: false,\n itemsPerPage: ref(10),\n limits: [10, 25, 50, 100],\n stickyOffset: ref(0),\n ...options,\n };\n}\n\nexport function useTable() {\n const options = inject(TableSymbol);\n\n if (!options)\n throw new Error('Could not find rui table options injection');\n\n return options;\n}\n"],"mappings":";;AASA,IAAa,cAA0C,OAAO,IAAI,YAAY;AAE9E,SAAgB,oBAAoB,SAA+C;AACjF,QAAO;EACL,oBAAoB;EACpB,cAAc,IAAI,GAAG;EACrB,QAAQ;GAAC;GAAI;GAAI;GAAI;GAAI;EACzB,cAAc,IAAI,EAAE;EACpB,GAAG;EACJ;;AAGH,SAAgB,WAAW;CACzB,MAAM,UAAU,OAAO,YAAY;AAEnC,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,6CAA6C;AAE/D,QAAO"}
1
+ {"version":3,"file":"table.js","names":[],"sources":["../../../src/composables/defaults/table.ts"],"sourcesContent":["import type { InjectionKey, MaybeRef, Ref } from 'vue';\n\nexport interface TableOptions {\n itemsPerPage: Ref<number>;\n globalItemsPerPage: MaybeRef<boolean>;\n limits: MaybeRef<number[]>;\n stickyOffset: MaybeRef<number>;\n /**\n * Global default width (px) below which every table switches to its stacked\n * mobile card layout. A table's own `mobileBreakpoint` prop overrides this.\n * Leave unset to keep the mobile layout opt-in per table.\n */\n mobileBreakpoint?: MaybeRef<number>;\n /**\n * Whether the mobile breakpoint is measured against the browser viewport\n * (`viewport`, default) or each table's own container width (`container`).\n * A table's own `mobileBreakpointBasis` prop overrides this.\n */\n mobileBreakpointBasis?: MaybeRef<'viewport' | 'container'>;\n}\n\nexport const TableSymbol: InjectionKey<TableOptions> = Symbol.for('rui:table');\n\nexport function createTableDefaults(options?: Partial<TableOptions>): TableOptions {\n return {\n globalItemsPerPage: false,\n itemsPerPage: ref(10),\n limits: [10, 25, 50, 100],\n stickyOffset: ref(0),\n ...options,\n };\n}\n\nexport function useTable() {\n const options = inject(TableSymbol);\n\n if (!options)\n throw new Error('Could not find rui table options injection');\n\n return options;\n}\n"],"mappings":";;AAqBA,IAAa,cAA0C,OAAO,IAAI,WAAW;AAE7E,SAAgB,oBAAoB,SAA+C;CACjF,OAAO;EACL,oBAAoB;EACpB,cAAc,IAAI,EAAE;EACpB,QAAQ;GAAC;GAAI;GAAI;GAAI;EAAG;EACxB,cAAc,IAAI,CAAC;EACnB,GAAG;CACL;AACF;AAEA,SAAgB,WAAW;CACzB,MAAM,UAAU,OAAO,WAAW;CAElC,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,4CAA4C;CAE9D,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"dropdown-menu.js","names":[],"sources":["../../src/composables/dropdown-menu.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref, TemplateRef } from 'vue';\n\nexport type KeyOfType<T, V> = T extends string | number | boolean | symbol | null | undefined\n ? never\n : V extends object\n ? keyof T\n : keyof {\n [P in keyof T as T[P] extends V ? P : V extends T[P] ? P : never]: any;\n };\n\nexport interface DropdownItemAttr<TValue, TItem> {\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem | ((item: TItem) => string);\n}\n\nexport type GroupBy<TItem> = keyof TItem | ((item: TItem) => string);\n\nexport type ItemDisabled<TItem> = keyof TItem | ((item: TItem) => boolean);\n\nexport interface DropdownOptionGroup<TItem> {\n group: string;\n items: TItem[];\n}\n\nexport interface DropdownOptions<TValue, TItem> {\n options: MaybeRefOrGetter<TItem[]>;\n dense?: MaybeRefOrGetter<boolean>;\n disabled?: MaybeRefOrGetter<boolean>;\n value: Ref<TItem | TItem[] | undefined>;\n menuRef: Ref<HTMLElement> | TemplateRef<HTMLElement>;\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem | ((item: TItem) => string);\n appendWidth?: number;\n prependWidth?: number;\n itemHeight?: number;\n overscan?: number;\n autoSelectFirst?: boolean;\n setValue?: (val: TItem) => void;\n hideSelected?: boolean;\n isOpen?: Ref<boolean>;\n getText?: (item: TItem) => string | undefined;\n getIdentifier?: (item: TItem) => any;\n groupBy?: MaybeRefOrGetter<GroupBy<TItem> | undefined>;\n itemDisabled?: MaybeRefOrGetter<ItemDisabled<TItem> | undefined>;\n}\n\nexport function useDropdownOptionProperty<TValue, TItem>({\n keyAttr,\n textAttr,\n}: DropdownItemAttr<TValue, TItem>) {\n function getText(item: TItem): string | undefined {\n if (textAttr) {\n if (typeof textAttr === 'function')\n return textAttr(item);\n else return item[textAttr]?.toString();\n }\n\n return item?.toString();\n }\n\n function getIdentifier(\n item: TItem,\n ): TItem | TItem[KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>] {\n if (keyAttr)\n return item[keyAttr];\n\n return item;\n }\n\n return {\n getIdentifier,\n getText,\n };\n}\n\nfunction toSelectedArray<TItem>(val: TItem | TItem[] | undefined): TItem[] {\n if (Array.isArray(val))\n return val;\n if (val !== null && val !== undefined)\n return [val];\n return [];\n}\n\nexport function useDropdownMenu<TValue, TItem>({\n appendWidth,\n autoSelectFirst,\n dense,\n disabled = false,\n getIdentifier: externalGetIdentifier,\n getText: externalGetText,\n hideSelected,\n isOpen: externalIsOpen,\n itemHeight = 48,\n keyAttr,\n menuRef: _menuRef,\n options: allOptions,\n overscan = 5,\n prependWidth,\n setValue,\n textAttr,\n value,\n groupBy,\n itemDisabled,\n}: DropdownOptions<TValue, TItem>) {\n const { getIdentifier: defaultGetIdentifier, getText: defaultGetText } = useDropdownOptionProperty({\n keyAttr,\n textAttr,\n });\n\n const getIdentifier = externalGetIdentifier ?? defaultGetIdentifier;\n const getText = externalGetText ?? defaultGetText;\n\n const activeIdentifiers = computed<Set<any>>(() => {\n const val = get(value);\n const selected: TItem[] = toSelectedArray(val);\n const identifiers = new Set<any>();\n for (const item of selected) {\n identifiers.add(getIdentifier(item));\n }\n return identifiers;\n });\n\n function isActiveItem(item: TItem): boolean {\n return get(activeIdentifiers).has(getIdentifier(item));\n }\n\n const options = computed<TItem[]>(() => {\n const options = toValue(allOptions);\n if (!hideSelected)\n return options;\n\n return options.filter(item => !isActiveItem(item));\n });\n\n function getGroupKey(item: TItem): string {\n const group = toValue(groupBy);\n if (!group)\n return '';\n\n if (typeof group === 'function')\n return group(item);\n\n return String(item[group] ?? '');\n }\n\n function isItemDisabled(item: TItem): boolean {\n const itemDisabledValue = toValue(itemDisabled);\n if (!itemDisabledValue)\n return false;\n\n if (typeof itemDisabledValue === 'function')\n return itemDisabledValue(item);\n\n return Boolean(item[itemDisabledValue]);\n }\n\n const isGrouped = computed<boolean>(() => toValue(groupBy) !== undefined);\n\n const groupedOptions = computed<DropdownOptionGroup<TItem>[]>(() => {\n if (!get(isGrouped))\n return [];\n\n const buckets = new Map<string, TItem[]>();\n for (const item of get(options)) {\n const key = getGroupKey(item);\n const list = buckets.get(key);\n if (list)\n list.push(item);\n else\n buckets.set(key, [item]);\n }\n\n return Array.from(buckets.entries()).map(([group, items]) => ({ group, items }));\n });\n\n const { containerProps, list, scrollTo, wrapperProps } = useVirtualList<TItem>(options, {\n itemHeight,\n overscan,\n });\n\n const renderedData = useArrayMap(list, ({ data, index: _index }) => ({ _index, item: data }));\n\n const isOpen = externalIsOpen ?? shallowRef<boolean>(false);\n\n const valueKey = computed(() => {\n const selected = get(value);\n if (!keyAttr || !selected)\n return selected;\n return Array.isArray(selected) ? selected.map(item => item[keyAttr]) : selected[keyAttr];\n });\n\n const highlightedIndex: Ref<number> = ref(get(autoSelectFirst) ? 0 : -1);\n const userNavigated = shallowRef<boolean>(false);\n\n const optionWidthBounds = computed<{ min: number; max: number }>(() => {\n let min = 0;\n let max = 0;\n for (const option of get(options)) {\n const length = getText(option)?.toString()?.length ?? 0;\n if (min === 0 && max === 0) {\n min = length;\n max = length;\n }\n else if (length < min) {\n min = length;\n }\n else if (length > max) {\n max = length;\n }\n }\n return { min, max };\n });\n\n const menuWidth = computed<string>(() => {\n const { min, max } = get(optionWidthBounds);\n const maxWidth = 30;\n const paddingX = 1.5;\n const fontMultiplier = toValue(dense) ? 12 : 13;\n const difference = max - min;\n\n function computeValue(width: number): string {\n const additionalWidths =\n (prependWidth ? prependWidth + 0.5 : 0) + (appendWidth ? appendWidth + 0.5 : 0);\n return `${Math.min((width * fontMultiplier) / 16 + paddingX + additionalWidths, maxWidth)}rem`;\n }\n\n if (difference <= 5)\n return computeValue(max);\n\n return computeValue(min + difference / 2);\n });\n\n function toggle(state: boolean = false): void {\n set(isOpen, state);\n }\n\n function itemIndexInValue(item: TItem): number {\n const val = get(value);\n const selected: TItem[] = toSelectedArray(val);\n\n if (selected.length === 0)\n return -1;\n\n const itemId = getIdentifier(item);\n return selected.findIndex(selectedItem => getIdentifier(selectedItem) === itemId);\n }\n\n function scrollHighlightedIntoView(): void {\n get(_menuRef)\n ?.querySelector<HTMLElement>('[data-highlighted=\"true\"]')\n ?.scrollIntoView({ block: 'nearest' });\n }\n\n async function adjustScrollByHighlightedIndex(): Promise<void> {\n const index = get(highlightedIndex);\n if (index === -1)\n return;\n\n await nextTick();\n if (get(_menuRef)?.querySelector('[data-highlighted=\"true\"]')) {\n scrollHighlightedIntoView();\n return;\n }\n\n // Highlighted item is outside the virtual list's rendered window —\n // kick the virtual scroll to render it, then nudge it fully into view.\n scrollTo(index);\n await nextTick();\n scrollHighlightedIntoView();\n }\n\n async function updateOpen(open: boolean): Promise<void> {\n if (!open)\n return;\n\n const val = get(value);\n\n // Set highlighted index to active item\n if ((Array.isArray(val) && val.length > 0) || (val !== null && val !== undefined)) {\n const index = get(options).findIndex(isActiveItem);\n if (index > -1)\n set(highlightedIndex, index);\n }\n\n await adjustScrollByHighlightedIndex();\n }\n\n watch([isOpen, () => toValue(disabled)], async ([open, _]) => {\n await updateOpen(open);\n });\n\n watch(highlightedIndex, async () => {\n await adjustScrollByHighlightedIndex();\n });\n\n watch(options, async () => {\n set(userNavigated, false);\n if (get(highlightedIndex) !== -1) {\n if (get(autoSelectFirst)) {\n set(highlightedIndex, 0);\n await adjustScrollByHighlightedIndex();\n }\n else {\n set(highlightedIndex, -1);\n scrollTo(0);\n }\n }\n else {\n scrollTo(0);\n }\n });\n\n watch(isOpen, (open) => {\n if (!open)\n set(userNavigated, false);\n });\n\n const moveHighlight = (up: boolean): void => {\n if (!get(isOpen)) {\n toggle(true);\n return;\n }\n\n set(userNavigated, true);\n\n const items = get(options);\n const total = items.length;\n if (total === 0)\n return;\n\n const move = up ? -1 : 1;\n let position = get(highlightedIndex);\n\n for (let step = 0; step < total; step++) {\n position += move;\n if (position >= total)\n position = 0;\n else if (position < 0)\n position = total - 1;\n\n const candidate = items[position];\n if (candidate !== undefined && !isItemDisabled(candidate)) {\n set(highlightedIndex, position);\n return;\n }\n }\n };\n\n const applyHighlighted = (): void => {\n if (!setValue || !get(isOpen))\n return;\n\n const highlightedIndexVal = get(highlightedIndex);\n if (highlightedIndexVal === -1)\n return;\n\n const entry = get(options)[highlightedIndexVal];\n if (entry !== undefined && !isItemDisabled(entry))\n setValue(entry);\n };\n\n return {\n applyHighlighted,\n containerProps,\n getIdentifier,\n getText,\n groupedOptions,\n highlightedIndex,\n isActiveItem,\n isGrouped,\n isItemDisabled,\n isOpen,\n itemIndexInValue,\n menuWidth,\n moveHighlight,\n optionsWithSelectedHidden: options,\n renderedData,\n toggle,\n userNavigated,\n valueKey,\n wrapperProps,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"dropdown-menu.js","names":[],"sources":["../../src/composables/dropdown-menu.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref, TemplateRef } from 'vue';\n\nexport type KeyOfType<T, V> = T extends string | number | boolean | symbol | null | undefined\n ? never\n : V extends object\n ? keyof T\n : keyof {\n [P in keyof T as T[P] extends V ? P : V extends T[P] ? P : never]: any;\n };\n\nexport interface DropdownItemAttr<TValue, TItem> {\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem | ((item: TItem) => string);\n}\n\nexport type GroupBy<TItem> = keyof TItem | ((item: TItem) => string);\n\nexport type ItemDisabled<TItem> = keyof TItem | ((item: TItem) => boolean);\n\nexport interface DropdownOptionGroup<TItem> {\n group: string;\n items: TItem[];\n}\n\nexport interface DropdownOptions<TValue, TItem> {\n options: MaybeRefOrGetter<TItem[]>;\n dense?: MaybeRefOrGetter<boolean>;\n disabled?: MaybeRefOrGetter<boolean>;\n value: Ref<TItem | TItem[] | undefined>;\n menuRef: Ref<HTMLElement> | TemplateRef<HTMLElement>;\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem | ((item: TItem) => string);\n appendWidth?: number;\n prependWidth?: number;\n itemHeight?: number;\n overscan?: number;\n autoSelectFirst?: boolean;\n setValue?: (val: TItem) => void;\n hideSelected?: boolean;\n isOpen?: Ref<boolean>;\n getText?: (item: TItem) => string | undefined;\n getIdentifier?: (item: TItem) => any;\n groupBy?: MaybeRefOrGetter<GroupBy<TItem> | undefined>;\n itemDisabled?: MaybeRefOrGetter<ItemDisabled<TItem> | undefined>;\n}\n\nexport function useDropdownOptionProperty<TValue, TItem>({\n keyAttr,\n textAttr,\n}: DropdownItemAttr<TValue, TItem>) {\n function getText(item: TItem): string | undefined {\n if (textAttr) {\n if (typeof textAttr === 'function')\n return textAttr(item);\n else return item[textAttr]?.toString();\n }\n\n return item?.toString();\n }\n\n function getIdentifier(\n item: TItem,\n ): TItem | TItem[KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>] {\n if (keyAttr)\n return item[keyAttr];\n\n return item;\n }\n\n return {\n getIdentifier,\n getText,\n };\n}\n\nfunction toSelectedArray<TItem>(val: TItem | TItem[] | undefined): TItem[] {\n if (Array.isArray(val))\n return val;\n if (val !== null && val !== undefined)\n return [val];\n return [];\n}\n\nexport function useDropdownMenu<TValue, TItem>({\n appendWidth,\n autoSelectFirst,\n dense,\n disabled = false,\n getIdentifier: externalGetIdentifier,\n getText: externalGetText,\n hideSelected,\n isOpen: externalIsOpen,\n itemHeight = 48,\n keyAttr,\n menuRef: _menuRef,\n options: allOptions,\n overscan = 5,\n prependWidth,\n setValue,\n textAttr,\n value,\n groupBy,\n itemDisabled,\n}: DropdownOptions<TValue, TItem>) {\n const { getIdentifier: defaultGetIdentifier, getText: defaultGetText } = useDropdownOptionProperty({\n keyAttr,\n textAttr,\n });\n\n const getIdentifier = externalGetIdentifier ?? defaultGetIdentifier;\n const getText = externalGetText ?? defaultGetText;\n\n const activeIdentifiers = computed<Set<any>>(() => {\n const val = get(value);\n const selected: TItem[] = toSelectedArray(val);\n const identifiers = new Set<any>();\n for (const item of selected) {\n identifiers.add(getIdentifier(item));\n }\n return identifiers;\n });\n\n function isActiveItem(item: TItem): boolean {\n return get(activeIdentifiers).has(getIdentifier(item));\n }\n\n const options = computed<TItem[]>(() => {\n const options = toValue(allOptions);\n if (!hideSelected)\n return options;\n\n return options.filter(item => !isActiveItem(item));\n });\n\n function getGroupKey(item: TItem): string {\n const group = toValue(groupBy);\n if (!group)\n return '';\n\n if (typeof group === 'function')\n return group(item);\n\n return String(item[group] ?? '');\n }\n\n function isItemDisabled(item: TItem): boolean {\n const itemDisabledValue = toValue(itemDisabled);\n if (!itemDisabledValue)\n return false;\n\n if (typeof itemDisabledValue === 'function')\n return itemDisabledValue(item);\n\n return Boolean(item[itemDisabledValue]);\n }\n\n const isGrouped = computed<boolean>(() => toValue(groupBy) !== undefined);\n\n const groupedOptions = computed<DropdownOptionGroup<TItem>[]>(() => {\n if (!get(isGrouped))\n return [];\n\n const buckets = new Map<string, TItem[]>();\n for (const item of get(options)) {\n const key = getGroupKey(item);\n const list = buckets.get(key);\n if (list)\n list.push(item);\n else\n buckets.set(key, [item]);\n }\n\n return Array.from(buckets.entries()).map(([group, items]) => ({ group, items }));\n });\n\n const { containerProps, list, scrollTo, wrapperProps } = useVirtualList<TItem>(options, {\n itemHeight,\n overscan,\n });\n\n const renderedData = useArrayMap(list, ({ data, index: _index }) => ({ _index, item: data }));\n\n const isOpen = externalIsOpen ?? shallowRef<boolean>(false);\n\n const valueKey = computed(() => {\n const selected = get(value);\n if (!keyAttr || !selected)\n return selected;\n return Array.isArray(selected) ? selected.map(item => item[keyAttr]) : selected[keyAttr];\n });\n\n const highlightedIndex: Ref<number> = ref(get(autoSelectFirst) ? 0 : -1);\n const userNavigated = shallowRef<boolean>(false);\n\n const optionWidthBounds = computed<{ min: number; max: number }>(() => {\n let min = 0;\n let max = 0;\n for (const option of get(options)) {\n const length = getText(option)?.toString()?.length ?? 0;\n if (min === 0 && max === 0) {\n min = length;\n max = length;\n }\n else if (length < min) {\n min = length;\n }\n else if (length > max) {\n max = length;\n }\n }\n return { min, max };\n });\n\n const menuWidth = computed<string>(() => {\n const { min, max } = get(optionWidthBounds);\n const maxWidth = 30;\n const paddingX = 1.5;\n const fontMultiplier = toValue(dense) ? 12 : 13;\n const difference = max - min;\n\n function computeValue(width: number): string {\n const additionalWidths =\n (prependWidth ? prependWidth + 0.5 : 0) + (appendWidth ? appendWidth + 0.5 : 0);\n return `${Math.min((width * fontMultiplier) / 16 + paddingX + additionalWidths, maxWidth)}rem`;\n }\n\n if (difference <= 5)\n return computeValue(max);\n\n return computeValue(min + difference / 2);\n });\n\n function toggle(state: boolean = false): void {\n set(isOpen, state);\n }\n\n function itemIndexInValue(item: TItem): number {\n const val = get(value);\n const selected: TItem[] = toSelectedArray(val);\n\n if (selected.length === 0)\n return -1;\n\n const itemId = getIdentifier(item);\n return selected.findIndex(selectedItem => getIdentifier(selectedItem) === itemId);\n }\n\n function scrollHighlightedIntoView(): void {\n get(_menuRef)\n ?.querySelector<HTMLElement>('[data-highlighted=\"true\"]')\n ?.scrollIntoView({ block: 'nearest' });\n }\n\n async function adjustScrollByHighlightedIndex(): Promise<void> {\n const index = get(highlightedIndex);\n if (index === -1)\n return;\n\n await nextTick();\n if (get(_menuRef)?.querySelector('[data-highlighted=\"true\"]')) {\n scrollHighlightedIntoView();\n return;\n }\n\n // Highlighted item is outside the virtual list's rendered window —\n // kick the virtual scroll to render it, then nudge it fully into view.\n scrollTo(index);\n await nextTick();\n scrollHighlightedIntoView();\n }\n\n async function updateOpen(open: boolean): Promise<void> {\n if (!open)\n return;\n\n const val = get(value);\n\n // Set highlighted index to active item\n if ((Array.isArray(val) && val.length > 0) || (val !== null && val !== undefined)) {\n const index = get(options).findIndex(isActiveItem);\n if (index > -1)\n set(highlightedIndex, index);\n }\n\n await adjustScrollByHighlightedIndex();\n }\n\n watch([isOpen, () => toValue(disabled)], async ([open, _]) => {\n await updateOpen(open);\n });\n\n watch(highlightedIndex, async () => {\n await adjustScrollByHighlightedIndex();\n });\n\n watch(options, async () => {\n set(userNavigated, false);\n if (get(highlightedIndex) !== -1) {\n if (get(autoSelectFirst)) {\n set(highlightedIndex, 0);\n await adjustScrollByHighlightedIndex();\n }\n else {\n set(highlightedIndex, -1);\n scrollTo(0);\n }\n }\n else {\n scrollTo(0);\n }\n });\n\n watch(isOpen, (open) => {\n if (!open)\n set(userNavigated, false);\n });\n\n const moveHighlight = (up: boolean): void => {\n if (!get(isOpen)) {\n toggle(true);\n return;\n }\n\n set(userNavigated, true);\n\n const items = get(options);\n const total = items.length;\n if (total === 0)\n return;\n\n const move = up ? -1 : 1;\n let position = get(highlightedIndex);\n\n for (let step = 0; step < total; step++) {\n position += move;\n if (position >= total)\n position = 0;\n else if (position < 0)\n position = total - 1;\n\n const candidate = items[position];\n if (candidate !== undefined && !isItemDisabled(candidate)) {\n set(highlightedIndex, position);\n return;\n }\n }\n };\n\n const applyHighlighted = (): void => {\n if (!setValue || !get(isOpen))\n return;\n\n const highlightedIndexVal = get(highlightedIndex);\n if (highlightedIndexVal === -1)\n return;\n\n const entry = get(options)[highlightedIndexVal];\n if (entry !== undefined && !isItemDisabled(entry))\n setValue(entry);\n };\n\n return {\n applyHighlighted,\n containerProps,\n getIdentifier,\n getText,\n groupedOptions,\n highlightedIndex,\n isActiveItem,\n isGrouped,\n isItemDisabled,\n isOpen,\n itemIndexInValue,\n menuWidth,\n moveHighlight,\n optionsWithSelectedHidden: options,\n renderedData,\n toggle,\n userNavigated,\n valueKey,\n wrapperProps,\n };\n}\n"],"mappings":"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"}
@@ -162,6 +162,6 @@ function useFloating(options, disabled = false, openDelay = 0, closeDelay = 0, v
162
162
  };
163
163
  }
164
164
  //#endregion
165
- export { Placement, Strategy, useFloating };
165
+ export { DEFAULT_FLOATING_OPTIONS, Placement, Strategy, useFloating };
166
166
 
167
167
  //# sourceMappingURL=floating.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"floating.js","names":[],"sources":["../../src/composables/floating.ts"],"sourcesContent":["import {\n arrow,\n autoUpdate,\n computePosition,\n type ComputePositionReturn,\n flip,\n type VirtualElement as FloatingVirtualElement,\n type Middleware,\n offset,\n shift,\n} from '@floating-ui/dom';\nimport { type MaybeElement, unrefElement } from '@vueuse/core';\nimport { type MaybeRefOrGetter, onMounted, type Ref, ref, watchEffect } from 'vue';\nimport { useTimeoutManager } from './timeout-manager';\n\ntype VirtualElement = FloatingVirtualElement;\n\nexport const Placement = {\n bottom: 'bottom',\n bottomEnd: 'bottom-end',\n bottomStart: 'bottom-start',\n left: 'left',\n leftEnd: 'left-end',\n leftStart: 'left-start',\n right: 'right',\n rightEnd: 'right-end',\n rightStart: 'right-start',\n top: 'top',\n topEnd: 'top-end',\n topStart: 'top-start',\n} as const;\n\nexport type Placement = (typeof Placement)[keyof typeof Placement];\n\nexport const Strategy = {\n absolute: 'absolute',\n fixed: 'fixed',\n} as const;\n\nexport type Strategy = (typeof Strategy)[keyof typeof Strategy];\n\nexport interface FloatingOptions {\n /** Preferred placement relative to the reference element. @default Placement.bottom */\n placement?: Placement;\n /** CSS positioning strategy. @default Strategy.absolute */\n strategy?: Strategy;\n /** Main-axis and/or cross-axis offset from the reference element. @default 2 */\n offset?: number | { mainAxis?: number; crossAxis?: number };\n /** Whether to flip to the opposite side when overflowing. @default true */\n flip?: boolean;\n /** Padding from viewport edges for shift middleware. @default 8 */\n shiftPadding?: number;\n /** Whether to auto-update position on scroll/resize. @default true */\n autoUpdate?: boolean | { scroll?: boolean; resize?: boolean };\n}\n\nexport const DEFAULT_FLOATING_OPTIONS: Required<FloatingOptions> = {\n autoUpdate: true,\n flip: true,\n offset: 2,\n placement: Placement.bottom,\n shiftPadding: 8,\n strategy: Strategy.absolute,\n};\n\nexport interface UseFloatingReturn {\n currentPlacement: Readonly<Ref<Placement>>;\n leavePending: Ref<boolean>;\n onClose: (immediate?: boolean) => void;\n onLeaveComplete: () => void;\n onLeavePending: () => void;\n onOpen: (immediate?: boolean) => void;\n open: Ref<boolean>;\n popover: Ref<MaybeElement>;\n reference: Ref<HTMLElement | undefined>;\n updatePosition: () => Promise<void>;\n visible: Ref<boolean>;\n}\n\nfunction buildMiddleware(opts: FloatingOptions, arrowEl: HTMLElement | null): Middleware[] {\n const mw: Middleware[] = [];\n\n const off = opts.offset ?? DEFAULT_FLOATING_OPTIONS.offset;\n if (typeof off === 'number') {\n mw.push(offset(off));\n }\n else {\n const defaultOffset = typeof DEFAULT_FLOATING_OPTIONS.offset === 'number' ? DEFAULT_FLOATING_OPTIONS.offset : 0;\n mw.push(offset({ mainAxis: off.mainAxis ?? defaultOffset, crossAxis: off.crossAxis ?? 0 }));\n }\n\n if (opts.flip !== false)\n mw.push(flip());\n\n mw.push(shift({ padding: opts.shiftPadding ?? DEFAULT_FLOATING_OPTIONS.shiftPadding }));\n\n if (arrowEl)\n mw.push(arrow({ element: arrowEl, padding: 4 }));\n\n return mw;\n}\n\nfunction applyArrowStyles(arrowEl: HTMLElement | null, result: ComputePositionReturn): void {\n const arrowData = result.middlewareData.arrow;\n if (!arrowEl || !arrowData)\n return;\n\n Object.assign(arrowEl.style, {\n left: arrowData.x != null ? `${arrowData.x}px` : '',\n top: arrowData.y != null ? `${arrowData.y}px` : '',\n });\n}\n\nexport function useFloating(\n options: MaybeRefOrGetter<FloatingOptions>,\n disabled: MaybeRefOrGetter<boolean> = false,\n openDelay: MaybeRefOrGetter<number> = 0,\n closeDelay: MaybeRefOrGetter<number> = 0,\n virtualReference?: MaybeRefOrGetter<Element | VirtualElement | undefined>,\n): UseFloatingReturn {\n const reference = ref<HTMLElement>();\n const popover = ref<MaybeElement>();\n const open = shallowRef<boolean>(false);\n const visible = shallowRef<boolean>(false);\n const leavePending = shallowRef<boolean>(false);\n const currentPlacement = shallowRef<Placement>(toValue(options).placement ?? DEFAULT_FLOATING_OPTIONS.placement);\n\n let cleanupAutoUpdate: (() => void) | null = null;\n\n const openTimeoutManager = useTimeoutManager();\n const closeTimeoutManager = useTimeoutManager();\n\n function onLeaveComplete(): void {\n set(visible, false);\n }\n\n function onOpen(immediate: boolean = false): void {\n if (toValue(disabled))\n return;\n\n closeTimeoutManager.clear();\n\n set(leavePending, false);\n if (!openTimeoutManager.isActive()) {\n set(visible, true);\n\n openTimeoutManager.create(\n () => {\n set(open, true);\n },\n immediate ? 0 : toValue(openDelay),\n );\n }\n }\n\n function onClose(immediate: boolean = false): void {\n if (toValue(disabled))\n return;\n\n openTimeoutManager.clear();\n\n if (!closeTimeoutManager.isActive()) {\n closeTimeoutManager.create(\n () => {\n if (!get(open))\n onLeaveComplete();\n\n set(open, false);\n },\n immediate ? 0 : toValue(closeDelay),\n );\n }\n }\n\n function onLeavePending(): void {\n set(leavePending, true);\n }\n\n function getValidElements(): { popoverEl: HTMLElement; referenceEl: Element | VirtualElement } | null {\n if (!get(popover) || (!get(reference) && !toValue(virtualReference)))\n return null;\n\n const popoverEl = unrefElement(popover);\n const referenceEl = toValue(virtualReference) || unrefElement(reference);\n\n if (!(popoverEl instanceof HTMLElement) || !referenceEl)\n return null;\n\n return { popoverEl, referenceEl };\n }\n\n async function updatePosition(): Promise<void> {\n const elements = getValidElements();\n if (!elements)\n return;\n\n const { popoverEl, referenceEl } = elements;\n const opts = toValue(options);\n const arrowEl = popoverEl.querySelector<HTMLElement>('[data-id=\"arrow\"]');\n const strategy = opts.strategy ?? DEFAULT_FLOATING_OPTIONS.strategy;\n\n const result = await computePosition(referenceEl, popoverEl, {\n middleware: buildMiddleware(opts, arrowEl),\n placement: opts.placement ?? DEFAULT_FLOATING_OPTIONS.placement,\n strategy,\n });\n\n Object.assign(popoverEl.style, {\n left: `${result.x}px`,\n position: strategy,\n top: `${result.y}px`,\n });\n\n set(currentPlacement, result.placement);\n applyArrowStyles(arrowEl, result);\n }\n\n function startAutoUpdate(): void {\n stopAutoUpdate();\n const elements = getValidElements();\n if (!elements)\n return;\n\n const { popoverEl, referenceEl } = elements;\n const opts = toValue(options);\n const autoUpdateOpt = opts.autoUpdate ?? DEFAULT_FLOATING_OPTIONS.autoUpdate;\n\n if (autoUpdateOpt === false)\n return;\n\n const autoUpdateOptions = typeof autoUpdateOpt === 'object'\n ? {\n ancestorResize: autoUpdateOpt.resize ?? true,\n ancestorScroll: autoUpdateOpt.scroll ?? true,\n elementResize: true,\n }\n : undefined;\n\n cleanupAutoUpdate = autoUpdate(\n referenceEl,\n popoverEl,\n () => { updatePosition().catch(() => {}); },\n autoUpdateOptions,\n );\n }\n\n function stopAutoUpdate(): void {\n cleanupAutoUpdate?.();\n cleanupAutoUpdate = null;\n }\n\n onMounted(() => {\n watchEffect((onCleanup) => {\n startAutoUpdate();\n onCleanup(stopAutoUpdate);\n });\n });\n\n return {\n currentPlacement: readonly(currentPlacement),\n leavePending, // eslint-disable-line @rotki/composable-return-readonly -- written by consumer transition hooks\n onClose,\n onLeaveComplete,\n onLeavePending,\n onOpen,\n open, // eslint-disable-line @rotki/composable-return-readonly -- v-model bound by consumers\n popover, // eslint-disable-line @rotki/composable-return-readonly -- template ref bound by consumers\n reference, // eslint-disable-line @rotki/composable-return-readonly -- template ref bound by consumers\n updatePosition,\n visible, // eslint-disable-line @rotki/composable-return-readonly -- used as v-if condition by consumers\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"floating.js","names":[],"sources":["../../src/composables/floating.ts"],"sourcesContent":["import {\n arrow,\n autoUpdate,\n computePosition,\n type ComputePositionReturn,\n flip,\n type VirtualElement as FloatingVirtualElement,\n type Middleware,\n offset,\n shift,\n} from '@floating-ui/dom';\nimport { type MaybeElement, unrefElement } from '@vueuse/core';\nimport { type MaybeRefOrGetter, onMounted, type Ref, ref, watchEffect } from 'vue';\nimport { useTimeoutManager } from './timeout-manager';\n\ntype VirtualElement = FloatingVirtualElement;\n\nexport const Placement = {\n bottom: 'bottom',\n bottomEnd: 'bottom-end',\n bottomStart: 'bottom-start',\n left: 'left',\n leftEnd: 'left-end',\n leftStart: 'left-start',\n right: 'right',\n rightEnd: 'right-end',\n rightStart: 'right-start',\n top: 'top',\n topEnd: 'top-end',\n topStart: 'top-start',\n} as const;\n\nexport type Placement = (typeof Placement)[keyof typeof Placement];\n\nexport const Strategy = {\n absolute: 'absolute',\n fixed: 'fixed',\n} as const;\n\nexport type Strategy = (typeof Strategy)[keyof typeof Strategy];\n\nexport interface FloatingOptions {\n /** Preferred placement relative to the reference element. @default Placement.bottom */\n placement?: Placement;\n /** CSS positioning strategy. @default Strategy.absolute */\n strategy?: Strategy;\n /** Main-axis and/or cross-axis offset from the reference element. @default 2 */\n offset?: number | { mainAxis?: number; crossAxis?: number };\n /** Whether to flip to the opposite side when overflowing. @default true */\n flip?: boolean;\n /** Padding from viewport edges for shift middleware. @default 8 */\n shiftPadding?: number;\n /** Whether to auto-update position on scroll/resize. @default true */\n autoUpdate?: boolean | { scroll?: boolean; resize?: boolean };\n}\n\nexport const DEFAULT_FLOATING_OPTIONS: Required<FloatingOptions> = {\n autoUpdate: true,\n flip: true,\n offset: 2,\n placement: Placement.bottom,\n shiftPadding: 8,\n strategy: Strategy.absolute,\n};\n\nexport interface UseFloatingReturn {\n currentPlacement: Readonly<Ref<Placement>>;\n leavePending: Ref<boolean>;\n onClose: (immediate?: boolean) => void;\n onLeaveComplete: () => void;\n onLeavePending: () => void;\n onOpen: (immediate?: boolean) => void;\n open: Ref<boolean>;\n popover: Ref<MaybeElement>;\n reference: Ref<HTMLElement | undefined>;\n updatePosition: () => Promise<void>;\n visible: Ref<boolean>;\n}\n\nfunction buildMiddleware(opts: FloatingOptions, arrowEl: HTMLElement | null): Middleware[] {\n const mw: Middleware[] = [];\n\n const off = opts.offset ?? DEFAULT_FLOATING_OPTIONS.offset;\n if (typeof off === 'number') {\n mw.push(offset(off));\n }\n else {\n const defaultOffset = typeof DEFAULT_FLOATING_OPTIONS.offset === 'number' ? DEFAULT_FLOATING_OPTIONS.offset : 0;\n mw.push(offset({ mainAxis: off.mainAxis ?? defaultOffset, crossAxis: off.crossAxis ?? 0 }));\n }\n\n if (opts.flip !== false)\n mw.push(flip());\n\n mw.push(shift({ padding: opts.shiftPadding ?? DEFAULT_FLOATING_OPTIONS.shiftPadding }));\n\n if (arrowEl)\n mw.push(arrow({ element: arrowEl, padding: 4 }));\n\n return mw;\n}\n\nfunction applyArrowStyles(arrowEl: HTMLElement | null, result: ComputePositionReturn): void {\n const arrowData = result.middlewareData.arrow;\n if (!arrowEl || !arrowData)\n return;\n\n Object.assign(arrowEl.style, {\n left: arrowData.x != null ? `${arrowData.x}px` : '',\n top: arrowData.y != null ? `${arrowData.y}px` : '',\n });\n}\n\nexport function useFloating(\n options: MaybeRefOrGetter<FloatingOptions>,\n disabled: MaybeRefOrGetter<boolean> = false,\n openDelay: MaybeRefOrGetter<number> = 0,\n closeDelay: MaybeRefOrGetter<number> = 0,\n virtualReference?: MaybeRefOrGetter<Element | VirtualElement | undefined>,\n): UseFloatingReturn {\n const reference = ref<HTMLElement>();\n const popover = ref<MaybeElement>();\n const open = shallowRef<boolean>(false);\n const visible = shallowRef<boolean>(false);\n const leavePending = shallowRef<boolean>(false);\n const currentPlacement = shallowRef<Placement>(toValue(options).placement ?? DEFAULT_FLOATING_OPTIONS.placement);\n\n let cleanupAutoUpdate: (() => void) | null = null;\n\n const openTimeoutManager = useTimeoutManager();\n const closeTimeoutManager = useTimeoutManager();\n\n function onLeaveComplete(): void {\n set(visible, false);\n }\n\n function onOpen(immediate: boolean = false): void {\n if (toValue(disabled))\n return;\n\n closeTimeoutManager.clear();\n\n set(leavePending, false);\n if (!openTimeoutManager.isActive()) {\n set(visible, true);\n\n openTimeoutManager.create(\n () => {\n set(open, true);\n },\n immediate ? 0 : toValue(openDelay),\n );\n }\n }\n\n function onClose(immediate: boolean = false): void {\n if (toValue(disabled))\n return;\n\n openTimeoutManager.clear();\n\n if (!closeTimeoutManager.isActive()) {\n closeTimeoutManager.create(\n () => {\n if (!get(open))\n onLeaveComplete();\n\n set(open, false);\n },\n immediate ? 0 : toValue(closeDelay),\n );\n }\n }\n\n function onLeavePending(): void {\n set(leavePending, true);\n }\n\n function getValidElements(): { popoverEl: HTMLElement; referenceEl: Element | VirtualElement } | null {\n if (!get(popover) || (!get(reference) && !toValue(virtualReference)))\n return null;\n\n const popoverEl = unrefElement(popover);\n const referenceEl = toValue(virtualReference) || unrefElement(reference);\n\n if (!(popoverEl instanceof HTMLElement) || !referenceEl)\n return null;\n\n return { popoverEl, referenceEl };\n }\n\n async function updatePosition(): Promise<void> {\n const elements = getValidElements();\n if (!elements)\n return;\n\n const { popoverEl, referenceEl } = elements;\n const opts = toValue(options);\n const arrowEl = popoverEl.querySelector<HTMLElement>('[data-id=\"arrow\"]');\n const strategy = opts.strategy ?? DEFAULT_FLOATING_OPTIONS.strategy;\n\n const result = await computePosition(referenceEl, popoverEl, {\n middleware: buildMiddleware(opts, arrowEl),\n placement: opts.placement ?? DEFAULT_FLOATING_OPTIONS.placement,\n strategy,\n });\n\n Object.assign(popoverEl.style, {\n left: `${result.x}px`,\n position: strategy,\n top: `${result.y}px`,\n });\n\n set(currentPlacement, result.placement);\n applyArrowStyles(arrowEl, result);\n }\n\n function startAutoUpdate(): void {\n stopAutoUpdate();\n const elements = getValidElements();\n if (!elements)\n return;\n\n const { popoverEl, referenceEl } = elements;\n const opts = toValue(options);\n const autoUpdateOpt = opts.autoUpdate ?? DEFAULT_FLOATING_OPTIONS.autoUpdate;\n\n if (autoUpdateOpt === false)\n return;\n\n const autoUpdateOptions = typeof autoUpdateOpt === 'object'\n ? {\n ancestorResize: autoUpdateOpt.resize ?? true,\n ancestorScroll: autoUpdateOpt.scroll ?? true,\n elementResize: true,\n }\n : undefined;\n\n cleanupAutoUpdate = autoUpdate(\n referenceEl,\n popoverEl,\n () => { updatePosition().catch(() => {}); },\n autoUpdateOptions,\n );\n }\n\n function stopAutoUpdate(): void {\n cleanupAutoUpdate?.();\n cleanupAutoUpdate = null;\n }\n\n onMounted(() => {\n watchEffect((onCleanup) => {\n startAutoUpdate();\n onCleanup(stopAutoUpdate);\n });\n });\n\n return {\n currentPlacement: readonly(currentPlacement),\n leavePending, // eslint-disable-line @rotki/composable-return-readonly -- written by consumer transition hooks\n onClose,\n onLeaveComplete,\n onLeavePending,\n onOpen,\n open, // eslint-disable-line @rotki/composable-return-readonly -- v-model bound by consumers\n popover, // eslint-disable-line @rotki/composable-return-readonly -- template ref bound by consumers\n reference, // eslint-disable-line @rotki/composable-return-readonly -- template ref bound by consumers\n updatePosition,\n visible, // eslint-disable-line @rotki/composable-return-readonly -- used as v-if condition by consumers\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"focus.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/focus.ts"],"sourcesContent":["import type { ComputedRef, MaybeRefOrGetter, Ref, TemplateRef } from 'vue';\n\nexport interface UseAutoCompleteFocusOptions {\n /** Whether custom (free-text) values are allowed. */\n customValue: MaybeRefOrGetter<boolean>;\n /** Whether to apply the current value as the search text when focused. */\n shouldApplyValueAsSearch: MaybeRefOrGetter<boolean>;\n /** Whether the autocomplete is disabled. */\n disabled: MaybeRefOrGetter<boolean>;\n}\n\nexport interface UseAutoCompleteFocusDeps {\n activatorFocused: Ref<boolean>;\n activatorFocusedWithin: Ref<boolean>;\n focusedValueIndex: Ref<number>;\n internalSearch: Ref<string>;\n isOpen: Ref<boolean>;\n justOpened: Ref<boolean>;\n menuWrapperFocusedWithin: Ref<boolean>;\n searchInputFocused: Ref<boolean>;\n textInput: Ref<HTMLInputElement | undefined> | TemplateRef<HTMLInputElement>;\n setSearchAsValue: () => void;\n updateInternalSearch: (value?: string) => void;\n}\n\nexport interface UseAutoCompleteFocusReturn {\n anyFocused: ComputedRef<boolean>;\n inputClass: ComputedRef<string>;\n onActivatorFocused: () => Promise<void>;\n onInputFocused: () => void;\n setInputFocus: () => Promise<void>;\n}\n\nexport function useAutoCompleteFocus(\n options: UseAutoCompleteFocusOptions,\n deps: UseAutoCompleteFocusDeps,\n): UseAutoCompleteFocusReturn {\n const anyFocused = computed<boolean>(\n () => get(deps.activatorFocusedWithin) || get(deps.menuWrapperFocusedWithin),\n );\n\n const inputClass = computed<string>(() => {\n const isFocused = get(anyFocused);\n const isDisabled = toValue(options.disabled);\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n const hasSearch = get(deps.internalSearch);\n\n if ((!isFocused || isDisabled) && !shouldApply)\n return 'w-0 h-0';\n if (hasSearch)\n return 'flex-1 min-w-[4rem]';\n return 'flex-1 min-w-0';\n });\n\n async function setInputFocus(): Promise<void> {\n await nextTick(() => {\n set(deps.searchInputFocused, true);\n });\n }\n\n async function onActivatorFocused(): Promise<void> {\n await nextTick(() => {\n if (!get(deps.activatorFocused)) {\n set(deps.searchInputFocused, true);\n }\n });\n }\n\n function onInputFocused(): void {\n set(deps.focusedValueIndex, -1);\n\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n if (shouldApply) {\n const textInput = get(deps.textInput);\n textInput?.select();\n }\n\n if (!get(deps.isOpen)) {\n set(deps.justOpened, true);\n }\n }\n\n // Capture the search value immediately when focus is lost, before the debounced\n // handler fires. Other watchers (value.ts) may clear internalSearch when isOpen\n // changes, so we need to preserve it for the custom value blur flow.\n let pendingCustomSearch = '';\n\n watch(anyFocused, (focused) => {\n if (!focused && toValue(options.customValue)) {\n pendingCustomSearch = get(deps.internalSearch);\n }\n });\n\n // Close menu if the activator is not focused anymore\n // Using debounced to avoid the menu closing momentarily while focus switches.\n watchDebounced(\n anyFocused,\n (focused) => {\n if (!focused) {\n set(deps.isOpen, false);\n\n const customValue = toValue(options.customValue);\n const searchToUse = pendingCustomSearch;\n pendingCustomSearch = '';\n\n if (customValue && searchToUse) {\n deps.updateInternalSearch(searchToUse);\n deps.setSearchAsValue();\n }\n\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n if (!shouldApply) {\n deps.updateInternalSearch();\n }\n }\n },\n {\n debounce: 100,\n maxWait: 200,\n },\n );\n\n return {\n anyFocused,\n inputClass,\n onActivatorFocused,\n onInputFocused,\n setInputFocus,\n };\n}\n"],"mappings":";;;;AAiCA,SAAgB,qBACd,SACA,MAC4B;CAC5B,MAAM,aAAa,eACX,MAAI,KAAK,uBAAuB,IAAI,MAAI,KAAK,yBAAyB,CAC7E;CAED,MAAM,aAAa,eAAuB;EACxC,MAAM,YAAY,MAAI,WAAW;EACjC,MAAM,aAAa,QAAQ,QAAQ,SAAS;EAC5C,MAAM,cAAc,QAAQ,QAAQ,yBAAyB;EAC7D,MAAM,YAAY,MAAI,KAAK,eAAe;AAE1C,OAAK,CAAC,aAAa,eAAe,CAAC,YACjC,QAAO;AACT,MAAI,UACF,QAAO;AACT,SAAO;GACP;CAEF,eAAe,gBAA+B;AAC5C,QAAM,eAAe;AACnB,SAAI,KAAK,oBAAoB,KAAK;IAClC;;CAGJ,eAAe,qBAAoC;AACjD,QAAM,eAAe;AACnB,OAAI,CAAC,MAAI,KAAK,iBAAiB,CAC7B,OAAI,KAAK,oBAAoB,KAAK;IAEpC;;CAGJ,SAAS,iBAAuB;AAC9B,QAAI,KAAK,mBAAmB,GAAG;AAG/B,MADoB,QAAQ,QAAQ,yBAAyB,CAEzC,OAAI,KAAK,UAAU,EAC1B,QAAQ;AAGrB,MAAI,CAAC,MAAI,KAAK,OAAO,CACnB,OAAI,KAAK,YAAY,KAAK;;CAO9B,IAAI,sBAAsB;AAE1B,OAAM,aAAa,YAAY;AAC7B,MAAI,CAAC,WAAW,QAAQ,QAAQ,YAAY,CAC1C,uBAAsB,MAAI,KAAK,eAAe;GAEhD;AAIF,gBACE,aACC,YAAY;AACX,MAAI,CAAC,SAAS;AACZ,SAAI,KAAK,QAAQ,MAAM;GAEvB,MAAM,cAAc,QAAQ,QAAQ,YAAY;GAChD,MAAM,cAAc;AACpB,yBAAsB;AAEtB,OAAI,eAAe,aAAa;AAC9B,SAAK,qBAAqB,YAAY;AACtC,SAAK,kBAAkB;;AAIzB,OAAI,CADgB,QAAQ,QAAQ,yBAAyB,CAE3D,MAAK,sBAAsB;;IAIjC;EACE,UAAU;EACV,SAAS;EACV,CACF;AAED,QAAO;EACL;EACA;EACA;EACA;EACA;EACD"}
1
+ {"version":3,"file":"focus.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/focus.ts"],"sourcesContent":["import type { ComputedRef, MaybeRefOrGetter, Ref, TemplateRef } from 'vue';\n\nexport interface UseAutoCompleteFocusOptions {\n /** Whether custom (free-text) values are allowed. */\n customValue: MaybeRefOrGetter<boolean>;\n /** Whether to apply the current value as the search text when focused. */\n shouldApplyValueAsSearch: MaybeRefOrGetter<boolean>;\n /** Whether the autocomplete is disabled. */\n disabled: MaybeRefOrGetter<boolean>;\n}\n\nexport interface UseAutoCompleteFocusDeps {\n activatorFocused: Ref<boolean>;\n activatorFocusedWithin: Ref<boolean>;\n focusedValueIndex: Ref<number>;\n internalSearch: Ref<string>;\n isOpen: Ref<boolean>;\n justOpened: Ref<boolean>;\n menuWrapperFocusedWithin: Ref<boolean>;\n searchInputFocused: Ref<boolean>;\n textInput: Ref<HTMLInputElement | undefined> | TemplateRef<HTMLInputElement>;\n setSearchAsValue: () => void;\n updateInternalSearch: (value?: string) => void;\n}\n\nexport interface UseAutoCompleteFocusReturn {\n anyFocused: ComputedRef<boolean>;\n inputClass: ComputedRef<string>;\n onActivatorFocused: () => Promise<void>;\n onInputFocused: () => void;\n setInputFocus: () => Promise<void>;\n}\n\nexport function useAutoCompleteFocus(\n options: UseAutoCompleteFocusOptions,\n deps: UseAutoCompleteFocusDeps,\n): UseAutoCompleteFocusReturn {\n const anyFocused = computed<boolean>(\n () => get(deps.activatorFocusedWithin) || get(deps.menuWrapperFocusedWithin),\n );\n\n const inputClass = computed<string>(() => {\n const isFocused = get(anyFocused);\n const isDisabled = toValue(options.disabled);\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n const hasSearch = get(deps.internalSearch);\n\n if ((!isFocused || isDisabled) && !shouldApply)\n return 'w-0 h-0';\n if (hasSearch)\n return 'flex-1 min-w-[4rem]';\n return 'flex-1 min-w-0';\n });\n\n async function setInputFocus(): Promise<void> {\n await nextTick(() => {\n set(deps.searchInputFocused, true);\n });\n }\n\n async function onActivatorFocused(): Promise<void> {\n await nextTick(() => {\n if (!get(deps.activatorFocused)) {\n set(deps.searchInputFocused, true);\n }\n });\n }\n\n function onInputFocused(): void {\n set(deps.focusedValueIndex, -1);\n\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n if (shouldApply) {\n const textInput = get(deps.textInput);\n textInput?.select();\n }\n\n if (!get(deps.isOpen)) {\n set(deps.justOpened, true);\n }\n }\n\n // Capture the search value immediately when focus is lost, before the debounced\n // handler fires. Other watchers (value.ts) may clear internalSearch when isOpen\n // changes, so we need to preserve it for the custom value blur flow.\n let pendingCustomSearch = '';\n\n watch(anyFocused, (focused) => {\n if (!focused && toValue(options.customValue)) {\n pendingCustomSearch = get(deps.internalSearch);\n }\n });\n\n // Close menu if the activator is not focused anymore\n // Using debounced to avoid the menu closing momentarily while focus switches.\n watchDebounced(\n anyFocused,\n (focused) => {\n if (!focused) {\n set(deps.isOpen, false);\n\n const customValue = toValue(options.customValue);\n const searchToUse = pendingCustomSearch;\n pendingCustomSearch = '';\n\n if (customValue && searchToUse) {\n deps.updateInternalSearch(searchToUse);\n deps.setSearchAsValue();\n }\n\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n if (!shouldApply) {\n deps.updateInternalSearch();\n }\n }\n },\n {\n debounce: 100,\n maxWait: 200,\n },\n );\n\n return {\n anyFocused,\n inputClass,\n onActivatorFocused,\n onInputFocused,\n setInputFocus,\n };\n}\n"],"mappings":";;;;AAiCA,SAAgB,qBACd,SACA,MAC4B;CAC5B,MAAM,aAAa,eACX,MAAI,KAAK,sBAAsB,KAAK,MAAI,KAAK,wBAAwB,CAC7E;CAEA,MAAM,aAAa,eAAuB;EACxC,MAAM,YAAY,MAAI,UAAU;EAChC,MAAM,aAAa,QAAQ,QAAQ,QAAQ;EAC3C,MAAM,cAAc,QAAQ,QAAQ,wBAAwB;EAC5D,MAAM,YAAY,MAAI,KAAK,cAAc;EAEzC,KAAK,CAAC,aAAa,eAAe,CAAC,aACjC,OAAO;EACT,IAAI,WACF,OAAO;EACT,OAAO;CACT,CAAC;CAED,eAAe,gBAA+B;EAC5C,MAAM,eAAe;GACnB,MAAI,KAAK,oBAAoB,IAAI;EACnC,CAAC;CACH;CAEA,eAAe,qBAAoC;EACjD,MAAM,eAAe;GACnB,IAAI,CAAC,MAAI,KAAK,gBAAgB,GAC5B,MAAI,KAAK,oBAAoB,IAAI;EAErC,CAAC;CACH;CAEA,SAAS,iBAAuB;EAC9B,MAAI,KAAK,mBAAmB,EAAE;EAG9B,IADoB,QAAQ,QAAQ,wBAChC,GAEF,MADsB,KAAK,SAC3B,CAAA,EAAW,OAAO;EAGpB,IAAI,CAAC,MAAI,KAAK,MAAM,GAClB,MAAI,KAAK,YAAY,IAAI;CAE7B;CAKA,IAAI,sBAAsB;CAE1B,MAAM,aAAa,YAAY;EAC7B,IAAI,CAAC,WAAW,QAAQ,QAAQ,WAAW,GACzC,sBAAsB,MAAI,KAAK,cAAc;CAEjD,CAAC;CAID,eACE,aACC,YAAY;EACX,IAAI,CAAC,SAAS;GACZ,MAAI,KAAK,QAAQ,KAAK;GAEtB,MAAM,cAAc,QAAQ,QAAQ,WAAW;GAC/C,MAAM,cAAc;GACpB,sBAAsB;GAEtB,IAAI,eAAe,aAAa;IAC9B,KAAK,qBAAqB,WAAW;IACrC,KAAK,iBAAiB;GACxB;GAGA,IAAI,CADgB,QAAQ,QAAQ,wBAC/B,GACH,KAAK,qBAAqB;EAE9B;CACF,GACA;EACE,UAAU;EACV,SAAS;CACX,CACF;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;CACF;AACF"}
@@ -1,4 +1,5 @@
1
- import "./focus.js";
2
- import "./keyboard-navigation.js";
3
- import "./search.js";
4
- import "./value.js";
1
+ import { useAutoCompleteFocus } from "./focus.js";
2
+ import { useAutoCompleteKeyboardNavigation } from "./keyboard-navigation.js";
3
+ import { useAutoCompleteSearch } from "./search.js";
4
+ import { useAutoCompleteValue } from "./value.js";
5
+ export { useAutoCompleteFocus, useAutoCompleteKeyboardNavigation, useAutoCompleteSearch, useAutoCompleteValue };
@@ -1 +1 @@
1
- {"version":3,"file":"keyboard-navigation.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/keyboard-navigation.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref, TemplateRef } from 'vue';\nimport { get, set } from '@vueuse/shared';\n\nexport interface UseAutoCompleteKeyboardNavigationOptions {\n /** Whether multiple items can be selected. */\n multiple: MaybeRefOrGetter<boolean>;\n /** Whether custom (free-text) values are allowed. */\n customValue: MaybeRefOrGetter<boolean>;\n /** Whether selected values are displayed as chips. */\n chips: MaybeRefOrGetter<boolean>;\n}\n\nexport interface UseAutoCompleteKeyboardNavigationDeps<TItem> {\n internalSearch: Ref<string>;\n value: Ref<TItem[]>;\n filteredOptions: Ref<TItem[]>;\n isOpen: Ref<boolean>;\n highlightedIndex: Ref<number>;\n userNavigated: Ref<boolean>;\n searchInputFocused: Ref<boolean>;\n applyHighlighted: () => void;\n clear: () => void;\n removeValue: (item: TItem) => void;\n setSearchAsValue: () => void;\n getText: (item: TItem) => string | undefined;\n activator: Ref<HTMLElement | undefined> | TemplateRef<HTMLElement>;\n}\n\nexport interface UseAutoCompleteKeyboardNavigationReturn {\n focusedValueIndex: Ref<number>;\n moveSelectedValueHighlight: (event: KeyboardEvent, next: boolean) => void;\n onEnter: (event: KeyboardEvent) => void;\n onTab: (event: KeyboardEvent) => void;\n onInputDeletePressed: () => void;\n setValueFocus: (index: number) => void;\n}\n\nexport function useAutoCompleteKeyboardNavigation<TItem>(\n options: UseAutoCompleteKeyboardNavigationOptions,\n deps: UseAutoCompleteKeyboardNavigationDeps<TItem>,\n): UseAutoCompleteKeyboardNavigationReturn {\n const focusedValueIndex = ref<number>(-1);\n\n function setValueFocus(index: number): void {\n set(focusedValueIndex, index);\n }\n\n function moveSelectedValueHighlight(event: KeyboardEvent, next: boolean): void {\n const multiple = toValue(options.multiple);\n const internalSearchValue = get(deps.internalSearch);\n\n if (!multiple || internalSearchValue.length > 0)\n return;\n\n event.preventDefault();\n const total = get(deps.value).length;\n\n let current = get(focusedValueIndex);\n\n if (current === -1) {\n set(focusedValueIndex, next ? 0 : total - 1);\n return;\n }\n\n const move = next ? 1 : -1;\n current += move;\n\n if (current < 0 || current >= total) {\n set(focusedValueIndex, -1);\n set(deps.searchInputFocused, true);\n }\n else {\n set(focusedValueIndex, current);\n }\n }\n\n function highlightedMatchesSearch(filteredOptions: TItem[], highlightedIndex: number, search: string): boolean {\n if (highlightedIndex < 0 || highlightedIndex >= filteredOptions.length)\n return false;\n\n const option = filteredOptions[highlightedIndex];\n if (typeof option === 'string')\n return option === search;\n\n if (option && typeof option === 'object')\n return (deps.getText(option) ?? '') === search;\n\n return false;\n }\n\n function applyCustomValue(event: KeyboardEvent, multiple: boolean): void {\n deps.setSearchAsValue();\n if (!multiple)\n set(deps.isOpen, false);\n event.preventDefault();\n }\n\n function submitClosestForm(): void {\n const activator = get(deps.activator);\n const form = activator?.closest('form');\n form?.dispatchEvent(new Event('submit'));\n }\n\n function tryApplyHighlight(event: KeyboardEvent): boolean {\n const filteredOptions = get(deps.filteredOptions);\n const highlightedIndex = get(deps.highlightedIndex);\n if (highlightedIndex <= -1 || filteredOptions.length === 0)\n return false;\n\n deps.applyHighlighted();\n event.preventDefault();\n return true;\n }\n\n function tryApplyCustom(event: KeyboardEvent, requireEmptyOptions: boolean): boolean {\n const customValue = toValue(options.customValue);\n const internalSearch = get(deps.internalSearch);\n if (!customValue || !internalSearch)\n return false;\n\n const filteredOptions = get(deps.filteredOptions);\n if (requireEmptyOptions) {\n if (filteredOptions.length > 0)\n return false;\n }\n else {\n const highlightedIndex = get(deps.highlightedIndex);\n if (highlightedMatchesSearch(filteredOptions, highlightedIndex, internalSearch))\n return false;\n }\n\n applyCustomValue(event, toValue(options.multiple));\n return true;\n }\n\n function handleOpenMenuEnter(event: KeyboardEvent): boolean {\n // Prefer the user's explicit navigation.\n if (get(deps.userNavigated) && tryApplyHighlight(event))\n return true;\n\n // Fall back to a typed custom value when it differs from the highlight.\n if (tryApplyCustom(event, false))\n return true;\n\n // Use the (auto-)highlighted option if there is one.\n if (tryApplyHighlight(event))\n return true;\n\n // No options matched but custom values are allowed — accept the typed text.\n return tryApplyCustom(event, true);\n }\n\n function onEnter(event: KeyboardEvent): void {\n if (get(deps.isOpen)) {\n if (handleOpenMenuEnter(event))\n return;\n\n // Menu is open but no actionable selection (e.g. typed text with no\n // matches and customValue=false, or no highlighted option). Swallow\n // Enter so it does not bubble up and submit a surrounding form.\n event.preventDefault();\n return;\n }\n\n // Nothing selected, menu closed: open menu\n if (get(deps.value).length === 0) {\n set(deps.isOpen, true);\n return event.preventDefault();\n }\n\n // Menu closed with a value selected: let Enter submit the parent form.\n submitClosestForm();\n }\n\n function onTab(event: KeyboardEvent): void {\n const isOpen = get(deps.isOpen);\n const filteredOptions = get(deps.filteredOptions);\n const highlightedIndex = get(deps.highlightedIndex);\n const multiple = toValue(options.multiple);\n\n if (isOpen && filteredOptions.length > 0 && highlightedIndex > -1 && !multiple) {\n deps.applyHighlighted();\n event.preventDefault();\n }\n }\n\n function onInputDeletePressed(): void {\n const internalSearch = get(deps.internalSearch);\n const value = get(deps.value);\n const total = value.length;\n const multiple = toValue(options.multiple);\n\n if (!internalSearch && total > 0) {\n if (multiple) {\n if (toValue(options.chips)) {\n set(focusedValueIndex, total - 1);\n }\n else {\n const lastItem = value[total - 1];\n if (lastItem !== undefined)\n deps.removeValue(lastItem);\n }\n }\n else {\n deps.clear();\n }\n }\n }\n\n // Watch value changes to reset focused index\n watch(deps.value, () => {\n setValueFocus(-1);\n });\n\n // Watch focused value index to handle chip focus\n watch(focusedValueIndex, async (index) => {\n const multiple = toValue(options.multiple);\n if (index === -1 || !multiple)\n return;\n\n await nextTick(() => {\n const activator = get(deps.activator);\n const element = activator?.querySelector<HTMLElement>(`[data-index=\"${index}\"]`);\n element?.focus();\n });\n });\n\n return {\n // eslint-disable-next-line @rotki/composable-return-readonly -- written by focus.ts onInputFocused\n focusedValueIndex,\n moveSelectedValueHighlight,\n onEnter,\n onInputDeletePressed,\n onTab,\n setValueFocus,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"keyboard-navigation.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/keyboard-navigation.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref, TemplateRef } from 'vue';\nimport { get, set } from '@vueuse/shared';\n\nexport interface UseAutoCompleteKeyboardNavigationOptions {\n /** Whether multiple items can be selected. */\n multiple: MaybeRefOrGetter<boolean>;\n /** Whether custom (free-text) values are allowed. */\n customValue: MaybeRefOrGetter<boolean>;\n /** Whether selected values are displayed as chips. */\n chips: MaybeRefOrGetter<boolean>;\n}\n\nexport interface UseAutoCompleteKeyboardNavigationDeps<TItem> {\n internalSearch: Ref<string>;\n value: Ref<TItem[]>;\n filteredOptions: Ref<TItem[]>;\n isOpen: Ref<boolean>;\n highlightedIndex: Ref<number>;\n userNavigated: Ref<boolean>;\n searchInputFocused: Ref<boolean>;\n applyHighlighted: () => void;\n clear: () => void;\n removeValue: (item: TItem) => void;\n setSearchAsValue: () => void;\n getText: (item: TItem) => string | undefined;\n activator: Ref<HTMLElement | undefined> | TemplateRef<HTMLElement>;\n}\n\nexport interface UseAutoCompleteKeyboardNavigationReturn {\n focusedValueIndex: Ref<number>;\n moveSelectedValueHighlight: (event: KeyboardEvent, next: boolean) => void;\n onEnter: (event: KeyboardEvent) => void;\n onTab: (event: KeyboardEvent) => void;\n onInputDeletePressed: () => void;\n setValueFocus: (index: number) => void;\n}\n\nexport function useAutoCompleteKeyboardNavigation<TItem>(\n options: UseAutoCompleteKeyboardNavigationOptions,\n deps: UseAutoCompleteKeyboardNavigationDeps<TItem>,\n): UseAutoCompleteKeyboardNavigationReturn {\n const focusedValueIndex = ref<number>(-1);\n\n function setValueFocus(index: number): void {\n set(focusedValueIndex, index);\n }\n\n function moveSelectedValueHighlight(event: KeyboardEvent, next: boolean): void {\n const multiple = toValue(options.multiple);\n const internalSearchValue = get(deps.internalSearch);\n\n if (!multiple || internalSearchValue.length > 0)\n return;\n\n event.preventDefault();\n const total = get(deps.value).length;\n\n let current = get(focusedValueIndex);\n\n if (current === -1) {\n set(focusedValueIndex, next ? 0 : total - 1);\n return;\n }\n\n const move = next ? 1 : -1;\n current += move;\n\n if (current < 0 || current >= total) {\n set(focusedValueIndex, -1);\n set(deps.searchInputFocused, true);\n }\n else {\n set(focusedValueIndex, current);\n }\n }\n\n function highlightedMatchesSearch(filteredOptions: TItem[], highlightedIndex: number, search: string): boolean {\n if (highlightedIndex < 0 || highlightedIndex >= filteredOptions.length)\n return false;\n\n const option = filteredOptions[highlightedIndex];\n if (typeof option === 'string')\n return option === search;\n\n if (option && typeof option === 'object')\n return (deps.getText(option) ?? '') === search;\n\n return false;\n }\n\n function applyCustomValue(event: KeyboardEvent, multiple: boolean): void {\n deps.setSearchAsValue();\n if (!multiple)\n set(deps.isOpen, false);\n event.preventDefault();\n }\n\n function submitClosestForm(): void {\n const activator = get(deps.activator);\n const form = activator?.closest('form');\n form?.dispatchEvent(new Event('submit'));\n }\n\n function tryApplyHighlight(event: KeyboardEvent): boolean {\n const filteredOptions = get(deps.filteredOptions);\n const highlightedIndex = get(deps.highlightedIndex);\n if (highlightedIndex <= -1 || filteredOptions.length === 0)\n return false;\n\n deps.applyHighlighted();\n event.preventDefault();\n return true;\n }\n\n function tryApplyCustom(event: KeyboardEvent, requireEmptyOptions: boolean): boolean {\n const customValue = toValue(options.customValue);\n const internalSearch = get(deps.internalSearch);\n if (!customValue || !internalSearch)\n return false;\n\n const filteredOptions = get(deps.filteredOptions);\n if (requireEmptyOptions) {\n if (filteredOptions.length > 0)\n return false;\n }\n else {\n const highlightedIndex = get(deps.highlightedIndex);\n if (highlightedMatchesSearch(filteredOptions, highlightedIndex, internalSearch))\n return false;\n }\n\n applyCustomValue(event, toValue(options.multiple));\n return true;\n }\n\n function handleOpenMenuEnter(event: KeyboardEvent): boolean {\n // Prefer the user's explicit navigation.\n if (get(deps.userNavigated) && tryApplyHighlight(event))\n return true;\n\n // Fall back to a typed custom value when it differs from the highlight.\n if (tryApplyCustom(event, false))\n return true;\n\n // Use the (auto-)highlighted option if there is one.\n if (tryApplyHighlight(event))\n return true;\n\n // No options matched but custom values are allowed — accept the typed text.\n return tryApplyCustom(event, true);\n }\n\n function onEnter(event: KeyboardEvent): void {\n if (get(deps.isOpen)) {\n if (handleOpenMenuEnter(event))\n return;\n\n // Menu is open but no actionable selection (e.g. typed text with no\n // matches and customValue=false, or no highlighted option). Swallow\n // Enter so it does not bubble up and submit a surrounding form.\n event.preventDefault();\n return;\n }\n\n // Nothing selected, menu closed: open menu\n if (get(deps.value).length === 0) {\n set(deps.isOpen, true);\n return event.preventDefault();\n }\n\n // Menu closed with a value selected: let Enter submit the parent form.\n submitClosestForm();\n }\n\n function onTab(event: KeyboardEvent): void {\n const isOpen = get(deps.isOpen);\n const filteredOptions = get(deps.filteredOptions);\n const highlightedIndex = get(deps.highlightedIndex);\n const multiple = toValue(options.multiple);\n\n if (isOpen && filteredOptions.length > 0 && highlightedIndex > -1 && !multiple) {\n deps.applyHighlighted();\n event.preventDefault();\n }\n }\n\n function onInputDeletePressed(): void {\n const internalSearch = get(deps.internalSearch);\n const value = get(deps.value);\n const total = value.length;\n const multiple = toValue(options.multiple);\n\n if (!internalSearch && total > 0) {\n if (multiple) {\n if (toValue(options.chips)) {\n set(focusedValueIndex, total - 1);\n }\n else {\n const lastItem = value[total - 1];\n if (lastItem !== undefined)\n deps.removeValue(lastItem);\n }\n }\n else {\n deps.clear();\n }\n }\n }\n\n // Watch value changes to reset focused index\n watch(deps.value, () => {\n setValueFocus(-1);\n });\n\n // Watch focused value index to handle chip focus\n watch(focusedValueIndex, async (index) => {\n const multiple = toValue(options.multiple);\n if (index === -1 || !multiple)\n return;\n\n await nextTick(() => {\n const activator = get(deps.activator);\n const element = activator?.querySelector<HTMLElement>(`[data-index=\"${index}\"]`);\n element?.focus();\n });\n });\n\n return {\n // eslint-disable-next-line @rotki/composable-return-readonly -- written by focus.ts onInputFocused\n focusedValueIndex,\n moveSelectedValueHighlight,\n onEnter,\n onInputDeletePressed,\n onTab,\n setValueFocus,\n };\n}\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { MaybeRefOrGetter, Ref } from 'vue';
2
+ import type { GroupBy } from '../../../composables/dropdown-menu.js';
2
3
  export interface UseAutoCompleteSearchOptions<TItem> {
3
4
  /** The property used as the unique identifier for each item. */
4
5
  keyAttr?: MaybeRefOrGetter<keyof TItem | undefined>;
@@ -7,13 +8,17 @@ export interface UseAutoCompleteSearchOptions<TItem> {
7
8
  /** Whether to disable client-side filtering of options. */
8
9
  noFilter?: MaybeRefOrGetter<boolean>;
9
10
  /** Custom filter function to match items against the search query. */
10
- filter?: MaybeRefOrGetter<((item: TItem, queryText: string) => boolean) | undefined>;
11
+ filter?: MaybeRefOrGetter<((item: TItem, queryText: string, group?: string) => boolean) | undefined>;
11
12
  /** Whether custom (free-text) values are allowed. */
12
13
  customValue?: MaybeRefOrGetter<boolean>;
13
14
  /** Whether to hide the custom value option from the dropdown. */
14
15
  hideCustomValue?: MaybeRefOrGetter<boolean>;
15
16
  /** Whether to return the full item object instead of just the key. */
16
17
  returnObject?: MaybeRefOrGetter<boolean>;
18
+ /** How items are grouped, used to resolve group labels for filtering. */
19
+ groupBy?: MaybeRefOrGetter<GroupBy<TItem> | undefined>;
20
+ /** When true and `groupBy` is set, the default filter also matches the resolved group label. */
21
+ searchIncludesGroupLabel?: MaybeRefOrGetter<boolean>;
17
22
  }
18
23
  export interface UseAutoCompleteSearchReturn<TItem> {
19
24
  internalSearch: Readonly<Ref<string>>;
@@ -20,6 +20,11 @@ function useAutoCompleteSearch(options, searchModel, opts) {
20
20
  tokenCache.set(text, token);
21
21
  return token;
22
22
  };
23
+ const resolveGroup = (item, groupBy) => {
24
+ if (!groupBy) return void 0;
25
+ if (typeof groupBy === "function") return groupBy(item);
26
+ return String(item?.[groupBy] ?? "");
27
+ };
23
28
  const filteredOptions = computed(() => {
24
29
  const search = get$1(debouncedInternalSearch);
25
30
  const optionsValue = toValue(options);
@@ -27,11 +32,17 @@ function useAutoCompleteSearch(options, searchModel, opts) {
27
32
  const keyAttr = toValue(opts.keyAttr);
28
33
  const textAttr = toValue(opts.textAttr);
29
34
  const filter = toValue(opts.filter);
35
+ const groupBy = toValue(opts.groupBy);
36
+ const searchIncludesGroupLabel = toValue(opts.searchIncludesGroupLabel);
30
37
  const searchToken = getCachedTextToken(search);
31
- const filtered = filter ? optionsValue.filter((item) => filter(item, search)) : optionsValue.filter((item) => {
38
+ const filtered = filter ? optionsValue.filter((item) => filter(item, search, resolveGroup(item, groupBy))) : optionsValue.filter((item) => {
32
39
  if (!item) return false;
33
40
  const keywords = [getCachedTextToken(keyAttr ? String(item[keyAttr]) : item.toString())];
34
41
  if (textAttr && typeof item === "object") keywords.push(getCachedTextToken(String(item[textAttr])));
42
+ if (searchIncludesGroupLabel && groupBy) {
43
+ const group = resolveGroup(item, groupBy);
44
+ if (group) keywords.push(getCachedTextToken(group));
45
+ }
35
46
  return keywords.some((keyword) => keyword.includes(searchToken));
36
47
  });
37
48
  const customValue = toValue(opts.customValue);
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/search.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref } from 'vue';\nimport { get, set } from '@vueuse/shared';\nimport { getTextToken } from '@/utils/helpers';\n\nexport interface UseAutoCompleteSearchOptions<TItem> {\n /** The property used as the unique identifier for each item. */\n keyAttr?: MaybeRefOrGetter<keyof TItem | undefined>;\n /** The property used to display text for each item. */\n textAttr?: MaybeRefOrGetter<keyof TItem | undefined>;\n /** Whether to disable client-side filtering of options. */\n noFilter?: MaybeRefOrGetter<boolean>;\n /** Custom filter function to match items against the search query. */\n filter?: MaybeRefOrGetter<((item: TItem, queryText: string) => boolean) | undefined>;\n /** Whether custom (free-text) values are allowed. */\n customValue?: MaybeRefOrGetter<boolean>;\n /** Whether to hide the custom value option from the dropdown. */\n hideCustomValue?: MaybeRefOrGetter<boolean>;\n /** Whether to return the full item object instead of just the key. */\n returnObject?: MaybeRefOrGetter<boolean>;\n}\n\nexport interface UseAutoCompleteSearchReturn<TItem> {\n internalSearch: Readonly<Ref<string>>;\n debouncedInternalSearch: Readonly<Ref<string>>;\n filteredOptions: Readonly<Ref<TItem[]>>;\n justOpened: Ref<boolean>;\n updateInternalSearch: (value?: string) => void;\n textValueToProperValue: (val: any, returnObject?: boolean) => TItem;\n}\n\nexport function useAutoCompleteSearch<TItem>(\n options: MaybeRefOrGetter<TItem[]>,\n searchModel: Ref<string>, // eslint-disable-line @rotki/composable-input-flexibility -- needs write access\n opts: UseAutoCompleteSearchOptions<TItem>,\n): UseAutoCompleteSearchReturn<TItem> {\n const internalSearch = shallowRef<string>('');\n const debouncedInternalSearch = refDebounced(internalSearch, 50);\n const justOpened = shallowRef<boolean>(false);\n\n // Memoize token computation to avoid repeated string processing.\n // Map iteration order is insertion order, so deleting the first key\n // gives us simple LRU eviction without a separate data structure.\n const MAX_CACHE_SIZE = 100;\n const tokenCache = new Map<string, string>();\n const getCachedTextToken = (text: string): string => {\n const cached = tokenCache.get(text);\n if (cached !== undefined)\n return cached;\n\n if (tokenCache.size >= MAX_CACHE_SIZE) {\n const oldest = tokenCache.keys().next().value;\n if (oldest !== undefined)\n tokenCache.delete(oldest);\n }\n\n const token = getTextToken(text);\n tokenCache.set(text, token);\n return token;\n };\n\n const filteredOptions = computed<TItem[]>(() => {\n const search = get(debouncedInternalSearch);\n const optionsValue = toValue(options);\n\n const noFilter = toValue(opts.noFilter);\n if (noFilter || !search || get(justOpened))\n return optionsValue;\n\n const keyAttr = toValue(opts.keyAttr);\n const textAttr = toValue(opts.textAttr);\n const filter = toValue(opts.filter);\n\n // Cache the search token once\n const searchToken = getCachedTextToken(search);\n\n const filtered = filter\n ? optionsValue.filter(item => filter(item, search))\n : optionsValue.filter((item) => {\n if (!item)\n return false;\n\n const keywords: string[] = [getCachedTextToken(keyAttr ? String((item as any)[keyAttr]) : item.toString())];\n\n if (textAttr && typeof item === 'object')\n keywords.push(getCachedTextToken(String((item as any)[textAttr])));\n\n return keywords.some(keyword => keyword.includes(searchToken));\n });\n\n const customValue = toValue(opts.customValue);\n const hideCustomValue = toValue(opts.hideCustomValue);\n if (!customValue || hideCustomValue || !search) {\n return filtered;\n }\n\n // Use a more efficient check for custom value inclusion\n const isCustomValueIncluded = filtered.some((item) => {\n if (!item) {\n return false;\n }\n\n const val = textAttr ? (item as any)[textAttr] : item.toString();\n return val === search;\n });\n\n if (isCustomValueIncluded) {\n return filtered;\n }\n\n return [textValueToProperValue(search, {\n keyAttr,\n returnObject: toValue(opts.returnObject),\n textAttr,\n }), ...filtered];\n });\n\n function textValueToProperValue(val: any, options: { keyAttr?: keyof TItem; textAttr?: keyof TItem; returnObject?: boolean }): TItem {\n const { keyAttr, returnObject, textAttr } = options;\n if (!keyAttr || returnObject)\n return val;\n\n return {\n [keyAttr]: val,\n ...(\n textAttr\n ? { [textAttr]: val }\n : {}\n ),\n } as TItem;\n }\n\n function updateInternalSearch(value: string = ''): void {\n set(searchModel, value);\n set(internalSearch, value);\n }\n\n watch(searchModel, (search) => {\n set(internalSearch, search);\n }, { immediate: true });\n\n // Clear token cache when component unmounts to prevent memory leaks\n onUnmounted(() => {\n tokenCache.clear();\n });\n\n return {\n debouncedInternalSearch,\n filteredOptions,\n internalSearch: readonly(internalSearch),\n justOpened, // eslint-disable-line @rotki/composable-return-readonly -- written by focus.ts onInputFocused and component setValue\n textValueToProperValue: (val: any, returnObjectOverride: boolean = false) => textValueToProperValue(val, {\n keyAttr: toValue(opts.keyAttr),\n returnObject: returnObjectOverride || toValue(opts.returnObject),\n textAttr: toValue(opts.textAttr),\n }),\n updateInternalSearch,\n };\n}\n"],"mappings":";;;;;AA8BA,SAAgB,sBACd,SACA,aACA,MACoC;CACpC,MAAM,iBAAiB,WAAmB,GAAG;CAC7C,MAAM,0BAA0B,aAAa,gBAAgB,GAAG;CAChE,MAAM,aAAa,WAAoB,MAAM;CAK7C,MAAM,iBAAiB;CACvB,MAAM,6BAAa,IAAI,KAAqB;CAC5C,MAAM,sBAAsB,SAAyB;EACnD,MAAM,SAAS,WAAW,IAAI,KAAK;AACnC,MAAI,WAAW,KAAA,EACb,QAAO;AAET,MAAI,WAAW,QAAQ,gBAAgB;GACrC,MAAM,SAAS,WAAW,MAAM,CAAC,MAAM,CAAC;AACxC,OAAI,WAAW,KAAA,EACb,YAAW,OAAO,OAAO;;EAG7B,MAAM,QAAQ,aAAa,KAAK;AAChC,aAAW,IAAI,MAAM,MAAM;AAC3B,SAAO;;CAGT,MAAM,kBAAkB,eAAwB;EAC9C,MAAM,SAAS,MAAI,wBAAwB;EAC3C,MAAM,eAAe,QAAQ,QAAQ;AAGrC,MADiB,QAAQ,KAAK,SAAS,IACvB,CAAC,UAAU,MAAI,WAAW,CACxC,QAAO;EAET,MAAM,UAAU,QAAQ,KAAK,QAAQ;EACrC,MAAM,WAAW,QAAQ,KAAK,SAAS;EACvC,MAAM,SAAS,QAAQ,KAAK,OAAO;EAGnC,MAAM,cAAc,mBAAmB,OAAO;EAE9C,MAAM,WAAW,SACb,aAAa,QAAO,SAAQ,OAAO,MAAM,OAAO,CAAC,GACjD,aAAa,QAAQ,SAAS;AAC5B,OAAI,CAAC,KACH,QAAO;GAET,MAAM,WAAqB,CAAC,mBAAmB,UAAU,OAAQ,KAAa,SAAS,GAAG,KAAK,UAAU,CAAC,CAAC;AAE3G,OAAI,YAAY,OAAO,SAAS,SAC9B,UAAS,KAAK,mBAAmB,OAAQ,KAAa,UAAU,CAAC,CAAC;AAEpE,UAAO,SAAS,MAAK,YAAW,QAAQ,SAAS,YAAY,CAAC;IAC9D;EAEN,MAAM,cAAc,QAAQ,KAAK,YAAY;EAC7C,MAAM,kBAAkB,QAAQ,KAAK,gBAAgB;AACrD,MAAI,CAAC,eAAe,mBAAmB,CAAC,OACtC,QAAO;AAaT,MAT8B,SAAS,MAAM,SAAS;AACpD,OAAI,CAAC,KACH,QAAO;AAIT,WADY,WAAY,KAAa,YAAY,KAAK,UAAU,MACjD;IACf,CAGA,QAAO;AAGT,SAAO,CAAC,uBAAuB,QAAQ;GACrC;GACA,cAAc,QAAQ,KAAK,aAAa;GACxC;GACD,CAAC,EAAE,GAAG,SAAS;GAChB;CAEF,SAAS,uBAAuB,KAAU,SAA2F;EACnI,MAAM,EAAE,SAAS,cAAc,aAAa;AAC5C,MAAI,CAAC,WAAW,aACd,QAAO;AAET,SAAO;IACJ,UAAU;GACX,GACE,WACI,GAAG,WAAW,KAAK,GACnB,EAAA;GAEP;;CAGH,SAAS,qBAAqB,QAAgB,IAAU;AACtD,QAAI,aAAa,MAAM;AACvB,QAAI,gBAAgB,MAAM;;AAG5B,OAAM,cAAc,WAAW;AAC7B,QAAI,gBAAgB,OAAO;IAC1B,EAAE,WAAW,MAAM,CAAC;AAGvB,mBAAkB;AAChB,aAAW,OAAO;GAClB;AAEF,QAAO;EACL;EACA;EACA,gBAAgB,SAAS,eAAe;EACxC;EACA,yBAAyB,KAAU,uBAAgC,UAAU,uBAAuB,KAAK;GACvG,SAAS,QAAQ,KAAK,QAAQ;GAC9B,cAAc,wBAAwB,QAAQ,KAAK,aAAa;GAChE,UAAU,QAAQ,KAAK,SAAA;GACxB,CAAC;EACF;EACD"}
1
+ {"version":3,"file":"search.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/search.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref } from 'vue';\nimport type { GroupBy } from '@/composables/dropdown-menu';\nimport { get, set } from '@vueuse/shared';\nimport { getTextToken } from '@/utils/helpers';\n\nexport interface UseAutoCompleteSearchOptions<TItem> {\n /** The property used as the unique identifier for each item. */\n keyAttr?: MaybeRefOrGetter<keyof TItem | undefined>;\n /** The property used to display text for each item. */\n textAttr?: MaybeRefOrGetter<keyof TItem | undefined>;\n /** Whether to disable client-side filtering of options. */\n noFilter?: MaybeRefOrGetter<boolean>;\n /** Custom filter function to match items against the search query. */\n filter?: MaybeRefOrGetter<((item: TItem, queryText: string, group?: string) => boolean) | undefined>;\n /** Whether custom (free-text) values are allowed. */\n customValue?: MaybeRefOrGetter<boolean>;\n /** Whether to hide the custom value option from the dropdown. */\n hideCustomValue?: MaybeRefOrGetter<boolean>;\n /** Whether to return the full item object instead of just the key. */\n returnObject?: MaybeRefOrGetter<boolean>;\n /** How items are grouped, used to resolve group labels for filtering. */\n groupBy?: MaybeRefOrGetter<GroupBy<TItem> | undefined>;\n /** When true and `groupBy` is set, the default filter also matches the resolved group label. */\n searchIncludesGroupLabel?: MaybeRefOrGetter<boolean>;\n}\n\nexport interface UseAutoCompleteSearchReturn<TItem> {\n internalSearch: Readonly<Ref<string>>;\n debouncedInternalSearch: Readonly<Ref<string>>;\n filteredOptions: Readonly<Ref<TItem[]>>;\n justOpened: Ref<boolean>;\n updateInternalSearch: (value?: string) => void;\n textValueToProperValue: (val: any, returnObject?: boolean) => TItem;\n}\n\nexport function useAutoCompleteSearch<TItem>(\n options: MaybeRefOrGetter<TItem[]>,\n searchModel: Ref<string>, // eslint-disable-line @rotki/composable-input-flexibility -- needs write access\n opts: UseAutoCompleteSearchOptions<TItem>,\n): UseAutoCompleteSearchReturn<TItem> {\n const internalSearch = shallowRef<string>('');\n const debouncedInternalSearch = refDebounced(internalSearch, 50);\n const justOpened = shallowRef<boolean>(false);\n\n // Memoize token computation to avoid repeated string processing.\n // Map iteration order is insertion order, so deleting the first key\n // gives us simple LRU eviction without a separate data structure.\n const MAX_CACHE_SIZE = 100;\n const tokenCache = new Map<string, string>();\n const getCachedTextToken = (text: string): string => {\n const cached = tokenCache.get(text);\n if (cached !== undefined)\n return cached;\n\n if (tokenCache.size >= MAX_CACHE_SIZE) {\n const oldest = tokenCache.keys().next().value;\n if (oldest !== undefined)\n tokenCache.delete(oldest);\n }\n\n const token = getTextToken(text);\n tokenCache.set(text, token);\n return token;\n };\n\n // Resolve the group label for an item. Mirrors `getGroupKey` in\n // dropdown-menu.ts so the filter can match against the same labels the\n // rendered group headers show.\n const resolveGroup = (item: TItem, groupBy: GroupBy<TItem> | undefined): string | undefined => {\n if (!groupBy)\n return undefined;\n\n if (typeof groupBy === 'function')\n return groupBy(item);\n\n return String((item as any)?.[groupBy] ?? '');\n };\n\n const filteredOptions = computed<TItem[]>(() => {\n const search = get(debouncedInternalSearch);\n const optionsValue = toValue(options);\n\n const noFilter = toValue(opts.noFilter);\n if (noFilter || !search || get(justOpened))\n return optionsValue;\n\n const keyAttr = toValue(opts.keyAttr);\n const textAttr = toValue(opts.textAttr);\n const filter = toValue(opts.filter);\n const groupBy = toValue(opts.groupBy);\n const searchIncludesGroupLabel = toValue(opts.searchIncludesGroupLabel);\n\n // Cache the search token once\n const searchToken = getCachedTextToken(search);\n\n const filtered = filter\n ? optionsValue.filter(item => filter(item, search, resolveGroup(item, groupBy)))\n : optionsValue.filter((item) => {\n if (!item)\n return false;\n\n const keywords: string[] = [getCachedTextToken(keyAttr ? String((item as any)[keyAttr]) : item.toString())];\n\n if (textAttr && typeof item === 'object')\n keywords.push(getCachedTextToken(String((item as any)[textAttr])));\n\n // Widen the match to the group label so a query like \"trade\" surfaces\n // every item under a \"Trade\" section, even when the items themselves\n // (e.g. \"Swap\") don't contain the query.\n if (searchIncludesGroupLabel && groupBy) {\n const group = resolveGroup(item, groupBy);\n if (group)\n keywords.push(getCachedTextToken(group));\n }\n\n return keywords.some(keyword => keyword.includes(searchToken));\n });\n\n const customValue = toValue(opts.customValue);\n const hideCustomValue = toValue(opts.hideCustomValue);\n if (!customValue || hideCustomValue || !search) {\n return filtered;\n }\n\n // Use a more efficient check for custom value inclusion\n const isCustomValueIncluded = filtered.some((item) => {\n if (!item) {\n return false;\n }\n\n const val = textAttr ? (item as any)[textAttr] : item.toString();\n return val === search;\n });\n\n if (isCustomValueIncluded) {\n return filtered;\n }\n\n return [textValueToProperValue(search, {\n keyAttr,\n returnObject: toValue(opts.returnObject),\n textAttr,\n }), ...filtered];\n });\n\n function textValueToProperValue(val: any, options: { keyAttr?: keyof TItem; textAttr?: keyof TItem; returnObject?: boolean }): TItem {\n const { keyAttr, returnObject, textAttr } = options;\n if (!keyAttr || returnObject)\n return val;\n\n return {\n [keyAttr]: val,\n ...(\n textAttr\n ? { [textAttr]: val }\n : {}\n ),\n } as TItem;\n }\n\n function updateInternalSearch(value: string = ''): void {\n set(searchModel, value);\n set(internalSearch, value);\n }\n\n watch(searchModel, (search) => {\n set(internalSearch, search);\n }, { immediate: true });\n\n // Clear token cache when component unmounts to prevent memory leaks\n onUnmounted(() => {\n tokenCache.clear();\n });\n\n return {\n debouncedInternalSearch,\n filteredOptions,\n internalSearch: readonly(internalSearch),\n justOpened, // eslint-disable-line @rotki/composable-return-readonly -- written by focus.ts onInputFocused and component setValue\n textValueToProperValue: (val: any, returnObjectOverride: boolean = false) => textValueToProperValue(val, {\n keyAttr: toValue(opts.keyAttr),\n returnObject: returnObjectOverride || toValue(opts.returnObject),\n textAttr: toValue(opts.textAttr),\n }),\n updateInternalSearch,\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"value.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/value.ts"],"sourcesContent":["import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';\nimport { get, set } from '@vueuse/shared';\nimport { assert } from '@/utils/assert';\n\nexport interface UseAutoCompleteValueOptions<TItem> {\n /** The property used as the unique identifier for each item. */\n keyAttr?: MaybeRefOrGetter<keyof TItem | undefined>;\n /** Whether to return the full item object instead of just the key. */\n returnObject?: MaybeRefOrGetter<boolean>;\n /** Whether custom (free-text) values are allowed. */\n customValue?: MaybeRefOrGetter<boolean>;\n}\n\nexport interface UseAutoCompleteValueReturn<TItem> {\n value: ComputedRef<TItem[]>;\n setSelected: (selected: TItem[]) => void;\n}\n\nexport interface UseAutoCompleteValueDeps<TItem> {\n getIdentifier: (item: TItem) => any;\n getText: (item: TItem) => string | undefined;\n textValueToProperValue: (val: any, returnObject?: boolean) => TItem;\n shouldApplyValueAsSearch: MaybeRefOrGetter<boolean>;\n isOpen: MaybeRefOrGetter<boolean>;\n multiple: MaybeRefOrGetter<boolean>;\n updateInternalSearch: (value?: string) => void;\n}\n\nexport function useAutoCompleteValue<TValue, TItem>(\n modelValue: Ref<TValue | undefined>, // eslint-disable-line @rotki/composable-input-flexibility -- needs write access\n options: MaybeRefOrGetter<TItem[]>,\n opts: UseAutoCompleteValueOptions<TItem>,\n deps: UseAutoCompleteValueDeps<TItem>,\n): UseAutoCompleteValueReturn<TItem> {\n // Create maps for O(1) lookup performance\n const optionsMap = computed<Map<any, TItem>>(() => {\n const map = new Map<any, TItem>();\n const optionsData = toValue(options);\n for (const item of optionsData) {\n map.set(deps.getIdentifier(item), item);\n }\n return map;\n });\n\n function convertModelValueToArray(modelValueData: TValue | undefined): any[] {\n if (modelValueData === null || modelValueData === undefined)\n return [];\n return Array.isArray(modelValueData) ? modelValueData : [modelValueData];\n }\n\n function filterValues(\n valueArray: any[],\n optionsMapData: Map<any, TItem>,\n customValue: boolean,\n returnObject: boolean,\n getKey: (val: any) => any,\n ): TItem[] {\n const filtered: TItem[] = [];\n for (const val of valueArray) {\n const inOptions = optionsMapData.get(getKey(val));\n if (inOptions !== undefined)\n filtered.push(inOptions);\n else if (customValue)\n filtered.push(deps.textValueToProperValue(val, returnObject));\n }\n return filtered;\n }\n\n function processReturnObjectValue(\n modelValueData: TValue | undefined,\n optionsMapData: Map<any, TItem>,\n returnObject: boolean,\n customValue: boolean,\n ): TItem[] {\n const multipleValue = Array.isArray(modelValueData);\n const valueArray = convertModelValueToArray(modelValueData);\n const filtered = filterValues(valueArray, optionsMapData, customValue, returnObject, val => deps.getIdentifier(val));\n\n if (multipleValue || filtered.length === 0)\n return filtered;\n\n const val = filtered[0];\n assert(val !== undefined && val !== null);\n return [val];\n }\n\n function processStandardValue(\n modelValueData: TValue | undefined,\n optionsMapData: Map<any, TItem>,\n returnObject: boolean,\n customValue: boolean,\n ): TItem[] {\n const valueArray = convertModelValueToArray(modelValueData);\n return filterValues(valueArray, optionsMapData, customValue, returnObject, val => val);\n }\n\n function onUpdateModelValue(value: TValue | undefined): void {\n set(modelValue, value);\n }\n\n function setSelected(selected: TItem[]): void {\n const keyAttr = toValue(opts.keyAttr);\n const returnObject = toValue(opts.returnObject);\n const selection = keyAttr && !returnObject ? selected.map(item => item[keyAttr]) : selected;\n\n if (toValue(deps.multiple))\n return onUpdateModelValue(selection as TValue);\n\n if (selection.length === 0)\n return onUpdateModelValue(undefined);\n\n return onUpdateModelValue(selection[0] as TValue);\n }\n\n const value = computed<TItem[]>({\n get: () => {\n const modelValueData = get(modelValue);\n const keyAttr = toValue(opts.keyAttr);\n const returnObject = toValue(opts.returnObject) ?? false;\n const customValue = toValue(opts.customValue) ?? false;\n const optionsMapData = get(optionsMap);\n\n if (keyAttr && returnObject)\n return processReturnObjectValue(modelValueData, optionsMapData, returnObject, customValue);\n\n return processStandardValue(modelValueData, optionsMapData, returnObject, customValue);\n },\n set: (selected: TItem[]): void => {\n setSelected(selected);\n },\n });\n\n // Watching `value` (not `modelValue`) so the search text resyncs once\n // `options` arrives later and the lookup can finally resolve.\n watch([value, () => toValue(deps.isOpen)], () => {\n if (toValue(deps.isOpen) || !toValue(deps.shouldApplyValueAsSearch))\n return;\n\n const currentValue = get(value);\n if (toValue(deps.multiple) || currentValue.length === 0) {\n deps.updateInternalSearch();\n }\n else {\n const firstItem = currentValue[0];\n assert(firstItem !== undefined && firstItem !== null);\n deps.updateInternalSearch(deps.getText(firstItem));\n }\n }, { immediate: true });\n\n return {\n setSelected,\n value,\n };\n}\n"],"mappings":";;;;AA4BA,SAAgB,qBACd,YACA,SACA,MACA,MACmC;CAEnC,MAAM,aAAa,eAAgC;EACjD,MAAM,sBAAM,IAAI,KAAiB;EACjC,MAAM,cAAc,QAAQ,QAAQ;AACpC,OAAK,MAAM,QAAQ,YACjB,KAAI,IAAI,KAAK,cAAc,KAAK,EAAE,KAAK;AAEzC,SAAO;GACP;CAEF,SAAS,yBAAyB,gBAA2C;AAC3E,MAAI,mBAAmB,QAAQ,mBAAmB,KAAA,EAChD,QAAO,EAAE;AACX,SAAO,MAAM,QAAQ,eAAe,GAAG,iBAAiB,CAAC,eAAe;;CAG1E,SAAS,aACP,YACA,gBACA,aACA,cACA,QACS;EACT,MAAM,WAAoB,EAAE;AAC5B,OAAK,MAAM,OAAO,YAAY;GAC5B,MAAM,YAAY,eAAe,IAAI,OAAO,IAAI,CAAC;AACjD,OAAI,cAAc,KAAA,EAChB,UAAS,KAAK,UAAU;YACjB,YACP,UAAS,KAAK,KAAK,uBAAuB,KAAK,aAAa,CAAC;;AAEjE,SAAO;;CAGT,SAAS,yBACP,gBACA,gBACA,cACA,aACS;EACT,MAAM,gBAAgB,MAAM,QAAQ,eAAe;EAEnD,MAAM,WAAW,aADE,yBAAyB,eAAe,EACjB,gBAAgB,aAAa,eAAc,QAAO,KAAK,cAAc,IAAI,CAAC;AAEpH,MAAI,iBAAiB,SAAS,WAAW,EACvC,QAAO;EAET,MAAM,MAAM,SAAS;AACrB,SAAO,QAAQ,KAAA,KAAa,QAAQ,KAAK;AACzC,SAAO,CAAC,IAAI;;CAGd,SAAS,qBACP,gBACA,gBACA,cACA,aACS;AAET,SAAO,aADY,yBAAyB,eAAe,EAC3B,gBAAgB,aAAa,eAAc,QAAO,IAAI;;CAGxF,SAAS,mBAAmB,OAAiC;AAC3D,MAAI,YAAY,MAAM;;CAGxB,SAAS,YAAY,UAAyB;EAC5C,MAAM,UAAU,QAAQ,KAAK,QAAQ;EACrC,MAAM,eAAe,QAAQ,KAAK,aAAa;EAC/C,MAAM,YAAY,WAAW,CAAC,eAAe,SAAS,KAAI,SAAQ,KAAK,SAAS,GAAG;AAEnF,MAAI,QAAQ,KAAK,SAAS,CACxB,QAAO,mBAAmB,UAAoB;AAEhD,MAAI,UAAU,WAAW,EACvB,QAAO,mBAAmB,KAAA,EAAU;AAEtC,SAAO,mBAAmB,UAAU,GAAa;;CAGnD,MAAM,QAAQ,SAAkB;EAC9B,WAAW;GACT,MAAM,iBAAiB,IAAI,WAAW;GACtC,MAAM,UAAU,QAAQ,KAAK,QAAQ;GACrC,MAAM,eAAe,QAAQ,KAAK,aAAa,IAAI;GACnD,MAAM,cAAc,QAAQ,KAAK,YAAY,IAAI;GACjD,MAAM,iBAAiB,IAAI,WAAW;AAEtC,OAAI,WAAW,aACb,QAAO,yBAAyB,gBAAgB,gBAAgB,cAAc,YAAY;AAE5F,UAAO,qBAAqB,gBAAgB,gBAAgB,cAAc,YAAY;;EAExF,MAAM,aAA4B;AAChC,eAAY,SAAS;;EAExB,CAAC;AAIF,OAAM,CAAC,aAAa,QAAQ,KAAK,OAAO,CAAC,QAAQ;AAC/C,MAAI,QAAQ,KAAK,OAAO,IAAI,CAAC,QAAQ,KAAK,yBAAyB,CACjE;EAEF,MAAM,eAAe,IAAI,MAAM;AAC/B,MAAI,QAAQ,KAAK,SAAS,IAAI,aAAa,WAAW,EACpD,MAAK,sBAAsB;OAExB;GACH,MAAM,YAAY,aAAa;AAC/B,UAAO,cAAc,KAAA,KAAa,cAAc,KAAK;AACrD,QAAK,qBAAqB,KAAK,QAAQ,UAAU,CAAC;;IAEnD,EAAE,WAAW,MAAM,CAAC;AAEvB,QAAO;EACL;EACA;EACD"}
1
+ {"version":3,"file":"value.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/value.ts"],"sourcesContent":["import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';\nimport { get, set } from '@vueuse/shared';\nimport { assert } from '@/utils/assert';\n\nexport interface UseAutoCompleteValueOptions<TItem> {\n /** The property used as the unique identifier for each item. */\n keyAttr?: MaybeRefOrGetter<keyof TItem | undefined>;\n /** Whether to return the full item object instead of just the key. */\n returnObject?: MaybeRefOrGetter<boolean>;\n /** Whether custom (free-text) values are allowed. */\n customValue?: MaybeRefOrGetter<boolean>;\n}\n\nexport interface UseAutoCompleteValueReturn<TItem> {\n value: ComputedRef<TItem[]>;\n setSelected: (selected: TItem[]) => void;\n}\n\nexport interface UseAutoCompleteValueDeps<TItem> {\n getIdentifier: (item: TItem) => any;\n getText: (item: TItem) => string | undefined;\n textValueToProperValue: (val: any, returnObject?: boolean) => TItem;\n shouldApplyValueAsSearch: MaybeRefOrGetter<boolean>;\n isOpen: MaybeRefOrGetter<boolean>;\n multiple: MaybeRefOrGetter<boolean>;\n updateInternalSearch: (value?: string) => void;\n}\n\nexport function useAutoCompleteValue<TValue, TItem>(\n modelValue: Ref<TValue | undefined>, // eslint-disable-line @rotki/composable-input-flexibility -- needs write access\n options: MaybeRefOrGetter<TItem[]>,\n opts: UseAutoCompleteValueOptions<TItem>,\n deps: UseAutoCompleteValueDeps<TItem>,\n): UseAutoCompleteValueReturn<TItem> {\n // Create maps for O(1) lookup performance\n const optionsMap = computed<Map<any, TItem>>(() => {\n const map = new Map<any, TItem>();\n const optionsData = toValue(options);\n for (const item of optionsData) {\n map.set(deps.getIdentifier(item), item);\n }\n return map;\n });\n\n function convertModelValueToArray(modelValueData: TValue | undefined): any[] {\n if (modelValueData === null || modelValueData === undefined)\n return [];\n return Array.isArray(modelValueData) ? modelValueData : [modelValueData];\n }\n\n function filterValues(\n valueArray: any[],\n optionsMapData: Map<any, TItem>,\n customValue: boolean,\n returnObject: boolean,\n getKey: (val: any) => any,\n ): TItem[] {\n const filtered: TItem[] = [];\n for (const val of valueArray) {\n const inOptions = optionsMapData.get(getKey(val));\n if (inOptions !== undefined)\n filtered.push(inOptions);\n else if (customValue)\n filtered.push(deps.textValueToProperValue(val, returnObject));\n }\n return filtered;\n }\n\n function processReturnObjectValue(\n modelValueData: TValue | undefined,\n optionsMapData: Map<any, TItem>,\n returnObject: boolean,\n customValue: boolean,\n ): TItem[] {\n const multipleValue = Array.isArray(modelValueData);\n const valueArray = convertModelValueToArray(modelValueData);\n const filtered = filterValues(valueArray, optionsMapData, customValue, returnObject, val => deps.getIdentifier(val));\n\n if (multipleValue || filtered.length === 0)\n return filtered;\n\n const val = filtered[0];\n assert(val !== undefined && val !== null);\n return [val];\n }\n\n function processStandardValue(\n modelValueData: TValue | undefined,\n optionsMapData: Map<any, TItem>,\n returnObject: boolean,\n customValue: boolean,\n ): TItem[] {\n const valueArray = convertModelValueToArray(modelValueData);\n return filterValues(valueArray, optionsMapData, customValue, returnObject, val => val);\n }\n\n function onUpdateModelValue(value: TValue | undefined): void {\n set(modelValue, value);\n }\n\n function setSelected(selected: TItem[]): void {\n const keyAttr = toValue(opts.keyAttr);\n const returnObject = toValue(opts.returnObject);\n const selection = keyAttr && !returnObject ? selected.map(item => item[keyAttr]) : selected;\n\n if (toValue(deps.multiple))\n return onUpdateModelValue(selection as TValue);\n\n if (selection.length === 0)\n return onUpdateModelValue(undefined);\n\n return onUpdateModelValue(selection[0] as TValue);\n }\n\n const value = computed<TItem[]>({\n get: () => {\n const modelValueData = get(modelValue);\n const keyAttr = toValue(opts.keyAttr);\n const returnObject = toValue(opts.returnObject) ?? false;\n const customValue = toValue(opts.customValue) ?? false;\n const optionsMapData = get(optionsMap);\n\n if (keyAttr && returnObject)\n return processReturnObjectValue(modelValueData, optionsMapData, returnObject, customValue);\n\n return processStandardValue(modelValueData, optionsMapData, returnObject, customValue);\n },\n set: (selected: TItem[]): void => {\n setSelected(selected);\n },\n });\n\n // Watching `value` (not `modelValue`) so the search text resyncs once\n // `options` arrives later and the lookup can finally resolve.\n watch([value, () => toValue(deps.isOpen)], () => {\n if (toValue(deps.isOpen) || !toValue(deps.shouldApplyValueAsSearch))\n return;\n\n const currentValue = get(value);\n if (toValue(deps.multiple) || currentValue.length === 0) {\n deps.updateInternalSearch();\n }\n else {\n const firstItem = currentValue[0];\n assert(firstItem !== undefined && firstItem !== null);\n deps.updateInternalSearch(deps.getText(firstItem));\n }\n }, { immediate: true });\n\n return {\n setSelected,\n value,\n };\n}\n"],"mappings":";;;;AA4BA,SAAgB,qBACd,YACA,SACA,MACA,MACmC;CAEnC,MAAM,aAAa,eAAgC;EACjD,MAAM,sBAAM,IAAI,IAAgB;EAChC,MAAM,cAAc,QAAQ,OAAO;EACnC,KAAK,MAAM,QAAQ,aACjB,IAAI,IAAI,KAAK,cAAc,IAAI,GAAG,IAAI;EAExC,OAAO;CACT,CAAC;CAED,SAAS,yBAAyB,gBAA2C;EAC3E,IAAI,mBAAmB,QAAQ,mBAAmB,KAAA,GAChD,OAAO,CAAC;EACV,OAAO,MAAM,QAAQ,cAAc,IAAI,iBAAiB,CAAC,cAAc;CACzE;CAEA,SAAS,aACP,YACA,gBACA,aACA,cACA,QACS;EACT,MAAM,WAAoB,CAAC;EAC3B,KAAK,MAAM,OAAO,YAAY;GAC5B,MAAM,YAAY,eAAe,IAAI,OAAO,GAAG,CAAC;GAChD,IAAI,cAAc,KAAA,GAChB,SAAS,KAAK,SAAS;QACpB,IAAI,aACP,SAAS,KAAK,KAAK,uBAAuB,KAAK,YAAY,CAAC;EAChE;EACA,OAAO;CACT;CAEA,SAAS,yBACP,gBACA,gBACA,cACA,aACS;EACT,MAAM,gBAAgB,MAAM,QAAQ,cAAc;EAElD,MAAM,WAAW,aADE,yBAAyB,cACd,GAAY,gBAAgB,aAAa,eAAc,QAAO,KAAK,cAAc,GAAG,CAAC;EAEnH,IAAI,iBAAiB,SAAS,WAAW,GACvC,OAAO;EAET,MAAM,MAAM,SAAS;EACrB,OAAO,QAAQ,KAAA,KAAa,QAAQ,IAAI;EACxC,OAAO,CAAC,GAAG;CACb;CAEA,SAAS,qBACP,gBACA,gBACA,cACA,aACS;EAET,OAAO,aADY,yBAAyB,cACxB,GAAY,gBAAgB,aAAa,eAAc,QAAO,GAAG;CACvF;CAEA,SAAS,mBAAmB,OAAiC;EAC3D,IAAI,YAAY,KAAK;CACvB;CAEA,SAAS,YAAY,UAAyB;EAC5C,MAAM,UAAU,QAAQ,KAAK,OAAO;EACpC,MAAM,eAAe,QAAQ,KAAK,YAAY;EAC9C,MAAM,YAAY,WAAW,CAAC,eAAe,SAAS,KAAI,SAAQ,KAAK,QAAQ,IAAI;EAEnF,IAAI,QAAQ,KAAK,QAAQ,GACvB,OAAO,mBAAmB,SAAmB;EAE/C,IAAI,UAAU,WAAW,GACvB,OAAO,mBAAmB,KAAA,CAAS;EAErC,OAAO,mBAAmB,UAAU,EAAY;CAClD;CAEA,MAAM,QAAQ,SAAkB;EAC9B,WAAW;GACT,MAAM,iBAAiB,IAAI,UAAU;GACrC,MAAM,UAAU,QAAQ,KAAK,OAAO;GACpC,MAAM,eAAe,QAAQ,KAAK,YAAY,KAAK;GACnD,MAAM,cAAc,QAAQ,KAAK,WAAW,KAAK;GACjD,MAAM,iBAAiB,IAAI,UAAU;GAErC,IAAI,WAAW,cACb,OAAO,yBAAyB,gBAAgB,gBAAgB,cAAc,WAAW;GAE3F,OAAO,qBAAqB,gBAAgB,gBAAgB,cAAc,WAAW;EACvF;EACA,MAAM,aAA4B;GAChC,YAAY,QAAQ;EACtB;CACF,CAAC;CAID,MAAM,CAAC,aAAa,QAAQ,KAAK,MAAM,CAAC,SAAS;EAC/C,IAAI,QAAQ,KAAK,MAAM,KAAK,CAAC,QAAQ,KAAK,wBAAwB,GAChE;EAEF,MAAM,eAAe,IAAI,KAAK;EAC9B,IAAI,QAAQ,KAAK,QAAQ,KAAK,aAAa,WAAW,GACpD,KAAK,qBAAqB;OAEvB;GACH,MAAM,YAAY,aAAa;GAC/B,OAAO,cAAc,KAAA,KAAa,cAAc,IAAI;GACpD,KAAK,qBAAqB,KAAK,QAAQ,SAAS,CAAC;EACnD;CACF,GAAG,EAAE,WAAW,KAAK,CAAC;CAEtB,OAAO;EACL;EACA;CACF;AACF"}