@rotki/ui-library 2.24.0 → 2.25.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 (337) hide show
  1. package/README.md +1 -2
  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.map +1 -1
  4. package/dist/components/alerts/RuiAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
  5. package/dist/components/avatars/RuiAvatar.vue.d.ts +1 -1
  6. package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  7. package/dist/components/avatars/RuiAvatarGroup.js.map +1 -1
  8. package/dist/components/avatars/RuiAvatarGroup.vue.d.ts +1 -1
  9. package/dist/components/avatars/RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  10. package/dist/components/avatars/use-avatar-group.d.ts +1 -1
  11. package/dist/components/buttons/button/RuiButton.vue.d.ts +1 -1
  12. package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  13. package/dist/components/buttons/button/button-styles.d.ts +40 -2
  14. package/dist/components/buttons/button/button-styles.js +38 -0
  15. package/dist/components/buttons/button/button-styles.js.map +1 -1
  16. package/dist/components/buttons/button-group/RuiButtonGroup.js.map +1 -1
  17. package/dist/components/buttons/button-group/RuiButtonGroup.vue.d.ts +1 -1
  18. package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js +26 -14
  19. package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  20. package/dist/components/calendar/RuiCalendar.js.map +1 -1
  21. package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  22. package/dist/components/calendar/RuiCalendarGrid.js.map +1 -1
  23. package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js +7 -0
  24. package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
  25. package/dist/components/calendar/RuiCalendarHeader.vue.d.ts +1 -1
  26. package/dist/components/calendar/RuiCalendarHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  27. package/dist/components/calendar/RuiCalendarMenu.js.map +1 -1
  28. package/dist/components/calendar/RuiCalendarMenu.vue.d.ts +1 -1
  29. package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js +1 -0
  30. package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  31. package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  32. package/dist/components/cards/RuiCardHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  33. package/dist/components/chips/RuiChip.vue.d.ts +1 -1
  34. package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  35. package/dist/components/color-picker/RuiColorBoard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  36. package/dist/components/color-picker/RuiColorDisplay.vue_vue_type_script_setup_true_lang.js.map +1 -1
  37. package/dist/components/color-picker/RuiColorHue.vue_vue_type_script_setup_true_lang.js +2 -1
  38. package/dist/components/color-picker/RuiColorHue.vue_vue_type_script_setup_true_lang.js.map +1 -1
  39. package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  40. package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  41. package/dist/components/date-time-picker/RuiDateTimePicker.js.map +1 -1
  42. package/dist/components/date-time-picker/RuiDateTimePicker.vue.d.ts +2 -2
  43. package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js +54 -26
  44. package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  45. package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue.d.ts +2 -2
  46. package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  47. package/dist/components/date-time-picker/RuiTimezoneSelect.vue.d.ts +3 -3
  48. package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  49. package/dist/components/date-time-picker/date-time-picker-styles.d.ts +48 -3
  50. package/dist/components/date-time-picker/partial-time.d.ts +1 -1
  51. package/dist/components/date-time-picker/partial-time.js +17 -6
  52. package/dist/components/date-time-picker/partial-time.js.map +1 -1
  53. package/dist/components/date-time-picker/segment-config.d.ts +1 -1
  54. package/dist/components/date-time-picker/segment-utils.d.ts +2 -2
  55. package/dist/components/date-time-picker/segment-utils.js +17 -5
  56. package/dist/components/date-time-picker/segment-utils.js.map +1 -1
  57. package/dist/components/date-time-picker/timezones.js.map +1 -1
  58. package/dist/components/date-time-picker/use-date-bounds.d.ts +2 -1
  59. package/dist/components/date-time-picker/use-date-bounds.js +7 -3
  60. package/dist/components/date-time-picker/use-date-bounds.js.map +1 -1
  61. package/dist/components/date-time-picker/use-date-time-selection.d.ts +13 -13
  62. package/dist/components/date-time-picker/use-date-time-selection.js +96 -86
  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.d.ts +1 -1
  65. package/dist/components/date-time-picker/use-keyboard-handler.d.ts +2 -2
  66. package/dist/components/date-time-picker/use-keyboard-handler.js +52 -13
  67. package/dist/components/date-time-picker/use-keyboard-handler.js.map +1 -1
  68. package/dist/components/date-time-picker/utils.d.ts +1 -1
  69. package/dist/components/date-time-picker/utils.js.map +1 -1
  70. package/dist/components/divider/RuiDivider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  71. package/dist/components/forms/auto-complete/RuiAutoComplete.js.map +1 -1
  72. package/dist/components/forms/auto-complete/RuiAutoComplete.vue.d.ts +2 -2
  73. package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js +136 -158
  74. package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  75. package/dist/components/forms/auto-complete/RuiAutoCompleteOption.js +7 -0
  76. package/dist/components/forms/auto-complete/RuiAutoCompleteOption.js.map +1 -0
  77. package/dist/components/forms/auto-complete/RuiAutoCompleteOption.vue.d.ts +45 -0
  78. package/dist/components/forms/auto-complete/RuiAutoCompleteOption.vue_vue_type_script_setup_true_lang.js +58 -0
  79. package/dist/components/forms/auto-complete/RuiAutoCompleteOption.vue_vue_type_script_setup_true_lang.js.map +1 -0
  80. package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.js +7 -0
  81. package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.js.map +1 -0
  82. package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.vue.d.ts +70 -0
  83. package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.vue_vue_type_script_setup_true_lang.js +140 -0
  84. package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.vue_vue_type_script_setup_true_lang.js.map +1 -0
  85. package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.js +7 -0
  86. package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.js.map +1 -0
  87. package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.vue.d.ts +39 -0
  88. package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.vue_vue_type_script_setup_true_lang.js +56 -0
  89. package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.vue_vue_type_script_setup_true_lang.js.map +1 -0
  90. package/dist/components/forms/auto-complete/auto-complete-styles.d.ts +48 -3
  91. package/dist/components/forms/category-picker/RuiCategoryPicker.js.map +1 -1
  92. package/dist/components/forms/category-picker/RuiCategoryPicker.vue.d.ts +2 -2
  93. package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js +49 -5
  94. package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  95. package/dist/components/forms/category-picker/category-picker-styles.d.ts +69 -5
  96. package/dist/components/forms/category-picker/category-picker-styles.js +19 -0
  97. package/dist/components/forms/category-picker/category-picker-styles.js.map +1 -1
  98. package/dist/components/forms/check-control-styles.d.ts +2 -2
  99. package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  100. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  101. package/dist/components/forms/file-upload/RuiFileUpload.js.map +1 -1
  102. package/dist/components/forms/file-upload/RuiFileUpload.vue.d.ts +1 -1
  103. package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
  104. package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
  105. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.js.map +1 -1
  106. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  107. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue.d.ts +1 -1
  108. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  109. package/dist/components/forms/select/RuiMenuSelect.js.map +1 -1
  110. package/dist/components/forms/select/RuiMenuSelect.vue.d.ts +2 -2
  111. package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js +10 -8
  112. package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  113. package/dist/components/forms/select/RuiSimpleSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  114. package/dist/components/forms/select/menu-select-styles.d.ts +48 -3
  115. package/dist/components/forms/slider/RuiSlider.js.map +1 -1
  116. package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js +22 -12
  117. package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  118. package/dist/components/forms/slider/RuiSliderTicks.js +7 -0
  119. package/dist/components/forms/slider/RuiSliderTicks.js.map +1 -0
  120. package/dist/components/forms/slider/RuiSliderTicks.vue.d.ts +15 -0
  121. package/dist/components/forms/slider/RuiSliderTicks.vue_vue_type_script_setup_true_lang.js +59 -0
  122. package/dist/components/forms/slider/RuiSliderTicks.vue_vue_type_script_setup_true_lang.js.map +1 -0
  123. package/dist/components/forms/slider/slider-styles.d.ts +2 -2
  124. package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  125. package/dist/components/forms/text-area/RuiTextArea.vue.d.ts +1 -1
  126. package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  127. package/dist/components/forms/text-area/text-area-styles.d.ts +3 -3
  128. package/dist/components/forms/text-area/text-area-styles.js.map +1 -1
  129. package/dist/components/forms/text-field/RuiTextField.vue.d.ts +3 -3
  130. package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  131. package/dist/components/forms/text-field/text-field-styles.d.ts +37 -4
  132. package/dist/components/forms/text-field/text-field-styles.js +34 -1
  133. package/dist/components/forms/text-field/text-field-styles.js.map +1 -1
  134. package/dist/components/forms/text-input-styles.d.ts +20 -5
  135. package/dist/components/forms/text-input-styles.js +16 -1
  136. package/dist/components/forms/text-input-styles.js.map +1 -1
  137. package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js.map +1 -1
  138. package/dist/components/icons/RuiIcon.js.map +1 -1
  139. package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js +26 -0
  140. package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  141. package/dist/components/index.d.ts +57 -53
  142. package/dist/components/index.js +5 -1
  143. package/dist/components/loaders/RuiSkeletonBase.vue_vue_type_script_setup_true_lang.js.map +1 -1
  144. package/dist/components/loaders/RuiSkeletonLoader.vue.d.ts +2 -2
  145. package/dist/components/loaders/RuiSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  146. package/dist/components/logos/RuiLogo.vue_vue_type_script_setup_true_lang.js.map +1 -1
  147. package/dist/components/logos/use-logo-sources.d.ts +1 -1
  148. package/dist/components/logos/use-logo-sources.js +6 -1
  149. package/dist/components/logos/use-logo-sources.js.map +1 -1
  150. package/dist/components/overlays/badge/RuiBadge.vue.d.ts +1 -1
  151. package/dist/components/overlays/badge/RuiBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
  152. package/dist/components/overlays/bottom-sheet/RuiBottomSheet.js.map +1 -1
  153. package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue.d.ts +1 -0
  154. package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue_vue_type_script_setup_true_lang.js.map +1 -1
  155. package/dist/components/overlays/dialog/RuiDialog.js.map +1 -1
  156. package/dist/components/overlays/dialog/RuiDialog.vue.d.ts +2 -0
  157. package/dist/components/overlays/dialog/RuiDialog.vue_vue_type_script_setup_true_lang.js +15 -1
  158. package/dist/components/overlays/dialog/RuiDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  159. package/dist/components/overlays/menu/RuiMenu.js.map +1 -1
  160. package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js +20 -0
  161. package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  162. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.js.map +1 -1
  163. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  164. package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js.map +1 -1
  165. package/dist/components/overlays/tooltip/RuiTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  166. package/dist/components/overlays/tooltip/tooltip-styles.d.ts +2 -2
  167. package/dist/components/progress/RuiProgress.js.map +1 -1
  168. package/dist/components/progress/RuiProgress.vue.d.ts +3 -3
  169. package/dist/components/progress/RuiProgress.vue_vue_type_script_setup_true_lang.js.map +1 -1
  170. package/dist/components/steppers/RuiFooterStepper.vue.d.ts +1 -1
  171. package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  172. package/dist/components/steppers/RuiStepper.js.map +1 -1
  173. package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js +8 -0
  174. package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  175. package/dist/components/steppers/RuiStepperCustomIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  176. package/dist/components/steppers/RuiStepperIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  177. package/dist/components/tables/RuiDataTable.js.map +1 -1
  178. package/dist/components/tables/RuiDataTable.vue.d.ts +5 -6
  179. package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js +42 -22
  180. package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  181. package/dist/components/tables/RuiExpandButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  182. package/dist/components/tables/RuiTable.js +7 -0
  183. package/dist/components/tables/RuiTable.js.map +1 -0
  184. package/dist/components/tables/RuiTable.vue.d.ts +40 -0
  185. package/dist/components/tables/RuiTable.vue_vue_type_script_setup_true_lang.js +95 -0
  186. package/dist/components/tables/RuiTable.vue_vue_type_script_setup_true_lang.js.map +1 -0
  187. package/dist/components/tables/RuiTableEmptyState.js.map +1 -1
  188. package/dist/components/tables/RuiTableEmptyState.vue.d.ts +5 -0
  189. package/dist/components/tables/RuiTableEmptyState.vue_vue_type_script_setup_true_lang.js +25 -10
  190. package/dist/components/tables/RuiTableEmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
  191. package/dist/components/tables/RuiTableErrorState.js +7 -0
  192. package/dist/components/tables/RuiTableErrorState.js.map +1 -0
  193. package/dist/components/tables/RuiTableErrorState.vue.d.ts +28 -0
  194. package/dist/components/tables/RuiTableErrorState.vue_vue_type_script_setup_true_lang.js +44 -0
  195. package/dist/components/tables/RuiTableErrorState.vue_vue_type_script_setup_true_lang.js.map +1 -0
  196. package/dist/components/tables/RuiTableHead.js.map +1 -1
  197. package/dist/components/tables/RuiTableHead.vue.d.ts +5 -9
  198. package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js.map +1 -1
  199. package/dist/components/tables/RuiTableLoadingState.js +7 -0
  200. package/dist/components/tables/RuiTableLoadingState.js.map +1 -0
  201. package/dist/components/tables/RuiTableLoadingState.vue.d.ts +13 -0
  202. package/dist/components/tables/RuiTableLoadingState.vue_vue_type_script_setup_true_lang.js +40 -0
  203. package/dist/components/tables/RuiTableLoadingState.vue_vue_type_script_setup_true_lang.js.map +1 -0
  204. package/dist/components/tables/RuiTablePagination.vue.d.ts +1 -1
  205. package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js +2 -1
  206. package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  207. package/dist/components/tables/data-table/RuiDataTableBody.vue.d.ts +1 -1
  208. package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js.map +1 -1
  209. package/dist/components/tables/data-table/RuiDataTableCell.js.map +1 -1
  210. package/dist/components/tables/data-table/RuiDataTableCell.vue.d.ts +1 -1
  211. package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js +6 -0
  212. package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  213. package/dist/components/tables/data-table/RuiDataTableEmptyRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  214. package/dist/components/tables/data-table/RuiDataTableExpandedRow.js.map +1 -1
  215. package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js +6 -0
  216. package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  217. package/dist/components/tables/data-table/RuiDataTableGroupRow.js.map +1 -1
  218. package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js +5 -0
  219. package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  220. package/dist/components/tables/data-table/RuiDataTableLoadingRow.js.map +1 -1
  221. package/dist/components/tables/data-table/RuiDataTableLoadingRow.vue_vue_type_script_setup_true_lang.js +2 -6
  222. package/dist/components/tables/data-table/RuiDataTableLoadingRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  223. package/dist/components/tables/data-table/RuiDataTableMobileSort.js.map +1 -1
  224. package/dist/components/tables/data-table/RuiDataTableMobileSort.vue.d.ts +2 -2
  225. package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js +4 -0
  226. package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js.map +1 -1
  227. package/dist/components/tables/data-table/RuiDataTableRow.js.map +1 -1
  228. package/dist/components/tables/data-table/RuiDataTableRow.vue.d.ts +1 -1
  229. package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js +25 -0
  230. package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  231. package/dist/components/tables/data-table/context.d.ts +2 -3
  232. package/dist/components/tables/data-table/context.js.map +1 -1
  233. package/dist/components/tables/data-table-styles.d.ts +2 -5
  234. package/dist/components/tables/data-table-styles.js +1 -2
  235. package/dist/components/tables/data-table-styles.js.map +1 -1
  236. package/dist/components/tabs/tab/RuiTab.js.map +1 -1
  237. package/dist/components/tabs/tab/RuiTab.vue.d.ts +1 -1
  238. package/dist/components/tabs/tab/RuiTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
  239. package/dist/components/tabs/tab-item/RuiTabItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  240. package/dist/components/tabs/tab-items/RuiTabItems.js.map +1 -1
  241. package/dist/components/tabs/tab-items/RuiTabItems.vue.d.ts +9 -0
  242. package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js +16 -0
  243. package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js.map +1 -1
  244. package/dist/components/tabs/tabs/RuiTabs.js.map +1 -1
  245. package/dist/components/tabs/tabs/RuiTabs.vue.d.ts +6 -1
  246. package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js +12 -0
  247. package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  248. package/dist/components/tabs/tabs/use-tab-routing.d.ts +1 -1
  249. package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  250. package/dist/components/time-picker/time-picker-styles.d.ts +2 -2
  251. package/dist/composables/colors/index.d.ts +3 -3
  252. package/dist/composables/dropdown-menu.d.ts +2 -2
  253. package/dist/composables/dropdown-menu.js +26 -23
  254. package/dist/composables/dropdown-menu.js.map +1 -1
  255. package/dist/composables/floating.d.ts +7 -8
  256. package/dist/composables/floating.js +19 -14
  257. package/dist/composables/floating.js.map +1 -1
  258. package/dist/composables/forms/auto-complete/focus.js +5 -0
  259. package/dist/composables/forms/auto-complete/focus.js.map +1 -1
  260. package/dist/composables/forms/auto-complete/keyboard-navigation.js +12 -5
  261. package/dist/composables/forms/auto-complete/keyboard-navigation.js.map +1 -1
  262. package/dist/composables/forms/auto-complete/search.d.ts +1 -1
  263. package/dist/composables/forms/auto-complete/search.js +5 -0
  264. package/dist/composables/forms/auto-complete/search.js.map +1 -1
  265. package/dist/composables/forms/auto-complete/value.js.map +1 -1
  266. package/dist/composables/forms/category-picker/use-category-picker.d.ts +1 -1
  267. package/dist/composables/forms/category-picker/use-category-picker.js +1 -0
  268. package/dist/composables/forms/category-picker/use-category-picker.js.map +1 -1
  269. package/dist/composables/forms/use-prepend-append-width.d.ts +18 -3
  270. package/dist/composables/forms/use-prepend-append-width.js +18 -3
  271. package/dist/composables/forms/use-prepend-append-width.js.map +1 -1
  272. package/dist/composables/index.d.ts +4 -3
  273. package/dist/composables/index.js +2 -1
  274. package/dist/composables/overlay-stack.d.ts +52 -0
  275. package/dist/composables/overlay-stack.js +93 -0
  276. package/dist/composables/overlay-stack.js.map +1 -0
  277. package/dist/composables/sticky-header.js.map +1 -1
  278. package/dist/composables/tables/data-table/expansion.js +7 -0
  279. package/dist/composables/tables/data-table/expansion.js.map +1 -1
  280. package/dist/composables/tables/data-table/grouping.d.ts +1 -1
  281. package/dist/composables/tables/data-table/pagination.d.ts +2 -2
  282. package/dist/composables/tables/data-table/selection.d.ts +1 -1
  283. package/dist/composables/tables/data-table/selection.js +37 -34
  284. package/dist/composables/tables/data-table/selection.js.map +1 -1
  285. package/dist/composables/theme.d.ts +4 -2
  286. package/dist/composables/theme.js +18 -24
  287. package/dist/composables/theme.js.map +1 -1
  288. package/dist/i18n/keys.d.ts +1 -1
  289. package/dist/i18n/keys.js +1 -1
  290. package/dist/i18n/keys.js.map +1 -1
  291. package/dist/icons/icons_1.d.ts +8 -8
  292. package/dist/icons/icons_1.js +246 -223
  293. package/dist/icons/icons_1.js.map +1 -1
  294. package/dist/icons/icons_2.d.ts +26 -26
  295. package/dist/icons/icons_2.js +320 -400
  296. package/dist/icons/icons_2.js.map +1 -1
  297. package/dist/icons/icons_3.d.ts +46 -46
  298. package/dist/icons/icons_3.js +661 -706
  299. package/dist/icons/icons_3.js.map +1 -1
  300. package/dist/icons/icons_4.d.ts +63 -63
  301. package/dist/icons/icons_4.js +4347 -4480
  302. package/dist/icons/icons_4.js.map +1 -1
  303. package/dist/icons/icons_5.d.ts +60 -1
  304. package/dist/icons/icons_5.js +774 -31
  305. package/dist/icons/icons_5.js.map +1 -1
  306. package/dist/icons/index.d.ts +1 -1
  307. package/dist/icons/index.js +84 -25
  308. package/dist/icons/index.js.map +1 -1
  309. package/dist/index.js +11 -6
  310. package/dist/index.js.map +1 -1
  311. package/dist/style.css +83 -10
  312. package/dist/theme/index.js +1 -0
  313. package/dist/theme/index.js.map +1 -1
  314. package/dist/types/theme.d.ts +1 -1
  315. package/dist/utils/assert.js +2 -2
  316. package/dist/utils/assert.js.map +1 -1
  317. package/dist/utils/blockie.d.ts +4 -0
  318. package/dist/utils/blockie.js +8 -0
  319. package/dist/utils/blockie.js.map +1 -1
  320. package/dist/utils/helpers.d.ts +24 -18
  321. package/dist/utils/helpers.js +28 -21
  322. package/dist/utils/helpers.js.map +1 -1
  323. package/dist/utils/is-equal.d.ts +9 -0
  324. package/dist/utils/is-equal.js +22 -15
  325. package/dist/utils/is-equal.js.map +1 -1
  326. package/dist/utils/tv.d.ts +6 -2
  327. package/dist/utils/tv.js +30 -14
  328. package/dist/utils/tv.js.map +1 -1
  329. package/dist/vite-plugin/client.d.ts +1 -1
  330. package/dist/vite-plugin/index.js +29 -21
  331. package/dist/vite-plugin/index.js.map +1 -1
  332. package/dist/vite-plugin/scanner.d.ts +5 -2
  333. package/dist/vite-plugin/scanner.js +5 -2
  334. package/dist/vite-plugin/scanner.js.map +1 -1
  335. package/dist/vite-plugin/types.d.ts +4 -8
  336. package/dist/web-types.json +863 -50
  337. package/package.json +32 -33
@@ -16,8 +16,9 @@ interface DateBoundsOptions {
16
16
  interface DateBoundsReturn {
17
17
  minAllowedDate: ComputedRef<Date>;
18
18
  maxAllowedDate: ComputedRef<Date | undefined>;
19
- internalErrorMessages: Ref<string[]>;
19
+ internalErrorMessages: Readonly<Ref<string[]>>;
20
20
  isDateValid: (date: Dayjs) => boolean;
21
+ clearErrors: () => void;
21
22
  }
22
23
  /**
23
24
  * The range a picked date has to sit in, and the message explaining a date that
@@ -1,7 +1,7 @@
1
1
  import { useRuiI8n } from "../../composables/use-rui-i18n.js";
2
2
  import { RUI_I18N_KEYS } from "../../i18n/keys.js";
3
3
  import { resolveBound } from "./segment-utils.js";
4
- import { computed, ref } from "vue";
4
+ import { computed, ref, shallowReadonly } from "vue";
5
5
  import { get, set } from "@vueuse/shared";
6
6
  import dayjs from "dayjs";
7
7
  //#region src/components/date-time-picker/use-date-bounds.ts
@@ -23,10 +23,13 @@ function useDateBounds({ dateFormat, epochSeconds, maxDate, minDate, now }) {
23
23
  function formatBound(bound) {
24
24
  return dayjs(bound).format(get(dateFormat));
25
25
  }
26
+ function clearErrors() {
27
+ set(internalErrorMessages, []);
28
+ }
26
29
  function isDateValid(date) {
27
30
  const min = get(minAllowedDate);
28
31
  const max = get(maxAllowedDate);
29
- set(internalErrorMessages, []);
32
+ clearErrors();
30
33
  if (min && date.isBefore(min)) {
31
34
  const formatted = formatBound(min);
32
35
  const errorMessage = t(RUI_I18N_KEYS.dateTimePicker.dateBeforeMin, { date: formatted }, `Date cannot be before ${formatted}`);
@@ -44,7 +47,8 @@ function useDateBounds({ dateFormat, epochSeconds, maxDate, minDate, now }) {
44
47
  return true;
45
48
  }
46
49
  return {
47
- internalErrorMessages,
50
+ clearErrors,
51
+ internalErrorMessages: shallowReadonly(internalErrorMessages),
48
52
  isDateValid,
49
53
  maxAllowedDate,
50
54
  minAllowedDate
@@ -1 +1 @@
1
- {"version":3,"file":"use-date-bounds.js","names":[],"sources":["../../../src/components/date-time-picker/use-date-bounds.ts"],"sourcesContent":["import type { ComputedRef, Ref } from 'vue';\nimport dayjs, { type Dayjs } from 'dayjs';\nimport { resolveBound } from '@/components/date-time-picker/segment-utils';\nimport { useRuiI8n } from '@/composables/use-rui-i18n';\nimport { RUI_I18N_KEYS } from '@/i18n/keys';\n\ninterface DateBoundsOptions {\n minDate: Date | number | undefined;\n maxDate: Date | number | 'now' | undefined;\n /** Whether a numeric bound is stated in whole seconds rather than milliseconds. */\n epochSeconds: boolean;\n /**\n * The field's own format, so a bound named in an error message is written the\n * same way round as the value the user is looking at.\n */\n dateFormat: Ref<string>;\n /** The clock a `now` maximum follows, kept current by the caller. */\n now: Ref<Dayjs>;\n}\n\ninterface DateBoundsReturn {\n minAllowedDate: ComputedRef<Date>;\n maxAllowedDate: ComputedRef<Date | undefined>;\n internalErrorMessages: Ref<string[]>;\n isDateValid: (date: Dayjs) => boolean;\n}\n\n/**\n * The range a picked date has to sit in, and the message explaining a date that\n * does not.\n */\nexport function useDateBounds({\n dateFormat,\n epochSeconds,\n maxDate,\n minDate,\n now,\n}: DateBoundsOptions): DateBoundsReturn {\n const { t } = useRuiI8n();\n\n const internalErrorMessages = ref<string[]>([]);\n\n const minAllowedDate = computed<Date>(\n () => resolveBound(minDate, epochSeconds) ?? new Date(1970, 0, 1),\n );\n\n const maxAllowedDate = computed<Date | undefined>(\n () => (maxDate === 'now' ? get(now).toDate() : resolveBound(maxDate, epochSeconds)),\n );\n\n /**\n * Writes a bound the way the field writes its value. `toLocaleDateString()`\n * followed the browser locale and ignored the picker's own format, so a\n * day-first field could report its limit month-first, and it dropped the time\n * entirely, which left a mid-day bound unable to explain itself.\n */\n function formatBound(bound: Date): string {\n return dayjs(bound).format(get(dateFormat));\n }\n\n function isDateValid(date: Dayjs): boolean {\n const min = get(minAllowedDate);\n const max = get(maxAllowedDate);\n\n set(internalErrorMessages, []);\n\n if (min && date.isBefore(min)) {\n const formatted = formatBound(min);\n const errorMessage = t(RUI_I18N_KEYS.dateTimePicker.dateBeforeMin, {\n date: formatted,\n }, `Date cannot be before ${formatted}`);\n set(internalErrorMessages, [...get(internalErrorMessages), errorMessage]);\n return false;\n }\n\n if (max && date.isAfter(max)) {\n const formatted = formatBound(max);\n const nowError = t(RUI_I18N_KEYS.dateTimePicker.dateInFuture, 'The selected date cannot be in the future');\n const maxError = t(RUI_I18N_KEYS.dateTimePicker.dateAfterMax, { date: formatted }, `Date cannot be after ${formatted}`);\n const errorMessage = maxDate === 'now' ? nowError : maxError;\n set(internalErrorMessages, [...get(internalErrorMessages), errorMessage]);\n return false;\n }\n\n return true;\n }\n\n return {\n internalErrorMessages,\n isDateValid,\n maxAllowedDate,\n minAllowedDate,\n };\n}\n"],"mappings":";;;;;;;;;;;AA+BA,SAAgB,cAAc,EAC5B,YACA,cACA,SACA,SACA,OACsC;CACtC,MAAM,EAAE,MAAM,UAAU;CAExB,MAAM,wBAAwB,IAAc,CAAC,CAAC;CAE9C,MAAM,iBAAiB,eACf,aAAa,SAAS,YAAY,KAAK,IAAI,KAAK,MAAM,GAAG,CAAC,CAClE;CAEA,MAAM,iBAAiB,eACd,YAAY,QAAQ,IAAI,GAAG,CAAC,CAAC,OAAO,IAAI,aAAa,SAAS,YAAY,CACnF;;;;;;;CAQA,SAAS,YAAY,OAAqB;EACxC,OAAO,MAAM,KAAK,CAAC,CAAC,OAAO,IAAI,UAAU,CAAC;CAC5C;CAEA,SAAS,YAAY,MAAsB;EACzC,MAAM,MAAM,IAAI,cAAc;EAC9B,MAAM,MAAM,IAAI,cAAc;EAE9B,IAAI,uBAAuB,CAAC,CAAC;EAE7B,IAAI,OAAO,KAAK,SAAS,GAAG,GAAG;GAC7B,MAAM,YAAY,YAAY,GAAG;GACjC,MAAM,eAAe,EAAE,cAAc,eAAe,eAAe,EACjE,MAAM,UACR,GAAG,yBAAyB,WAAW;GACvC,IAAI,uBAAuB,CAAC,GAAG,IAAI,qBAAqB,GAAG,YAAY,CAAC;GACxE,OAAO;EACT;EAEA,IAAI,OAAO,KAAK,QAAQ,GAAG,GAAG;GAC5B,MAAM,YAAY,YAAY,GAAG;GACjC,MAAM,WAAW,EAAE,cAAc,eAAe,cAAc,2CAA2C;GACzG,MAAM,WAAW,EAAE,cAAc,eAAe,cAAc,EAAE,MAAM,UAAU,GAAG,wBAAwB,WAAW;GACtH,MAAM,eAAe,YAAY,QAAQ,WAAW;GACpD,IAAI,uBAAuB,CAAC,GAAG,IAAI,qBAAqB,GAAG,YAAY,CAAC;GACxE,OAAO;EACT;EAEA,OAAO;CACT;CAEA,OAAO;EACL;EACA;EACA;EACA;CACF;AACF"}
1
+ {"version":3,"file":"use-date-bounds.js","names":[],"sources":["../../../src/components/date-time-picker/use-date-bounds.ts"],"sourcesContent":["import type { ComputedRef, Ref } from 'vue';\nimport dayjs, { type Dayjs } from 'dayjs';\nimport { resolveBound } from '@/components/date-time-picker/segment-utils';\nimport { useRuiI8n } from '@/composables/use-rui-i18n';\nimport { RUI_I18N_KEYS } from '@/i18n/keys';\n\ninterface DateBoundsOptions {\n minDate: Date | number | undefined;\n maxDate: Date | number | 'now' | undefined;\n /** Whether a numeric bound is stated in whole seconds rather than milliseconds. */\n epochSeconds: boolean;\n /**\n * The field's own format, so a bound named in an error message is written the\n * same way round as the value the user is looking at.\n */\n dateFormat: Ref<string>;\n /** The clock a `now` maximum follows, kept current by the caller. */\n now: Ref<Dayjs>;\n}\n\ninterface DateBoundsReturn {\n minAllowedDate: ComputedRef<Date>;\n maxAllowedDate: ComputedRef<Date | undefined>;\n internalErrorMessages: Readonly<Ref<string[]>>;\n isDateValid: (date: Dayjs) => boolean;\n clearErrors: () => void;\n}\n\n/**\n * The range a picked date has to sit in, and the message explaining a date that\n * does not.\n */\nexport function useDateBounds({\n dateFormat,\n epochSeconds,\n maxDate,\n minDate,\n now,\n}: DateBoundsOptions): DateBoundsReturn {\n const { t } = useRuiI8n();\n\n const internalErrorMessages = ref<string[]>([]);\n\n const minAllowedDate = computed<Date>(\n () => resolveBound(minDate, epochSeconds) ?? new Date(1970, 0, 1),\n );\n\n const maxAllowedDate = computed<Date | undefined>(\n () => (maxDate === 'now' ? get(now).toDate() : resolveBound(maxDate, epochSeconds)),\n );\n\n /**\n * Writes a bound the way the field writes its value. `toLocaleDateString()`\n * followed the browser locale and ignored the picker's own format, so a\n * day-first field could report its limit month-first, and it dropped the time\n * entirely, which left a mid-day bound unable to explain itself.\n */\n function formatBound(bound: Date): string {\n return dayjs(bound).format(get(dateFormat));\n }\n\n function clearErrors(): void {\n set(internalErrorMessages, []);\n }\n\n function isDateValid(date: Dayjs): boolean {\n const min = get(minAllowedDate);\n const max = get(maxAllowedDate);\n\n clearErrors();\n\n if (min && date.isBefore(min)) {\n const formatted = formatBound(min);\n const errorMessage = t(RUI_I18N_KEYS.dateTimePicker.dateBeforeMin, {\n date: formatted,\n }, `Date cannot be before ${formatted}`);\n set(internalErrorMessages, [...get(internalErrorMessages), errorMessage]);\n return false;\n }\n\n if (max && date.isAfter(max)) {\n const formatted = formatBound(max);\n const nowError = t(RUI_I18N_KEYS.dateTimePicker.dateInFuture, 'The selected date cannot be in the future');\n const maxError = t(RUI_I18N_KEYS.dateTimePicker.dateAfterMax, { date: formatted }, `Date cannot be after ${formatted}`);\n const errorMessage = maxDate === 'now' ? nowError : maxError;\n set(internalErrorMessages, [...get(internalErrorMessages), errorMessage]);\n return false;\n }\n\n return true;\n }\n\n return {\n clearErrors,\n internalErrorMessages: shallowReadonly(internalErrorMessages),\n isDateValid,\n maxAllowedDate,\n minAllowedDate,\n };\n}\n"],"mappings":";;;;;;;;;;;AAgCA,SAAgB,cAAc,EAC5B,YACA,cACA,SACA,SACA,OACsC;CACtC,MAAM,EAAE,MAAM,UAAU;CAExB,MAAM,wBAAwB,IAAc,CAAC,CAAC;CAE9C,MAAM,iBAAiB,eACf,aAAa,SAAS,YAAY,KAAK,IAAI,KAAK,MAAM,GAAG,CAAC,CAClE;CAEA,MAAM,iBAAiB,eACd,YAAY,QAAQ,IAAI,GAAG,CAAC,CAAC,OAAO,IAAI,aAAa,SAAS,YAAY,CACnF;;;;;;;CAQA,SAAS,YAAY,OAAqB;EACxC,OAAO,MAAM,KAAK,CAAC,CAAC,OAAO,IAAI,UAAU,CAAC;CAC5C;CAEA,SAAS,cAAoB;EAC3B,IAAI,uBAAuB,CAAC,CAAC;CAC/B;CAEA,SAAS,YAAY,MAAsB;EACzC,MAAM,MAAM,IAAI,cAAc;EAC9B,MAAM,MAAM,IAAI,cAAc;EAE9B,YAAY;EAEZ,IAAI,OAAO,KAAK,SAAS,GAAG,GAAG;GAC7B,MAAM,YAAY,YAAY,GAAG;GACjC,MAAM,eAAe,EAAE,cAAc,eAAe,eAAe,EACjE,MAAM,UACR,GAAG,yBAAyB,WAAW;GACvC,IAAI,uBAAuB,CAAC,GAAG,IAAI,qBAAqB,GAAG,YAAY,CAAC;GACxE,OAAO;EACT;EAEA,IAAI,OAAO,KAAK,QAAQ,GAAG,GAAG;GAC5B,MAAM,YAAY,YAAY,GAAG;GACjC,MAAM,WAAW,EAAE,cAAc,eAAe,cAAc,2CAA2C;GACzG,MAAM,WAAW,EAAE,cAAc,eAAe,cAAc,EAAE,MAAM,UAAU,GAAG,wBAAwB,WAAW;GACtH,MAAM,eAAe,YAAY,QAAQ,WAAW;GACpD,IAAI,uBAAuB,CAAC,GAAG,IAAI,qBAAqB,GAAG,YAAY,CAAC;GACxE,OAAO;EACT;EAEA,OAAO;CACT;CAEA,OAAO;EACL;EACA,uBAAuB,gBAAgB,qBAAqB;EAC5D;EACA;EACA;CACF;AACF"}
@@ -1,9 +1,9 @@
1
1
  import type { ComputedRef, Ref, WritableComputedRef } from 'vue';
2
- import type { SegmentData } from '../../components/date-time-picker/types.js';
2
+ import type { SegmentData } from './types.js';
3
3
  import type { TimeAccuracy } from '../../consts/time-accuracy.js';
4
4
  import { type Dayjs } from 'dayjs';
5
- import { type PartialTimeMode } from '../../components/date-time-picker/partial-time.js';
6
- import '../../components/date-time-picker/dayjs-setup.js';
5
+ import { type PartialTimeMode } from './partial-time.js';
6
+ import './dayjs-setup.js';
7
7
  type DateTimeModelType = 'date' | 'epoch-ms' | 'epoch';
8
8
  type ModelValueType<T extends DateTimeModelType> = T extends 'date' ? Date | undefined : T extends 'epoch-ms' ? number | undefined : T extends 'epoch' ? number | undefined : Date | number | undefined;
9
9
  interface DateTimeSelectionOptions<T extends DateTimeModelType> {
@@ -22,19 +22,19 @@ interface DateTimeSelectionOptions<T extends DateTimeModelType> {
22
22
  partialTime?: PartialTimeMode;
23
23
  }
24
24
  interface DateTimeSelectionReturn {
25
- selectedYear: Ref<number | undefined>;
26
- selectedMonth: Ref<number | undefined>;
27
- selectedDay: Ref<number | undefined>;
28
- selectedHour: Ref<number | undefined>;
29
- selectedMinute: Ref<number | undefined>;
30
- selectedSecond: Ref<number | undefined>;
31
- selectedMillisecond: Ref<number | undefined>;
32
- selectedTimezone: Ref<string | undefined>;
25
+ modelYear: Ref<number | undefined>;
26
+ modelMonth: Ref<number | undefined>;
27
+ modelDay: Ref<number | undefined>;
28
+ modelHour: Ref<number | undefined>;
29
+ modelMinute: Ref<number | undefined>;
30
+ modelSecond: Ref<number | undefined>;
31
+ modelMillisecond: Ref<number | undefined>;
32
+ modelTimezone: Ref<string | undefined>;
33
33
  selectedDate: WritableComputedRef<Date | undefined>;
34
34
  selectedTime: WritableComputedRef<Date | undefined>;
35
35
  valueSet: ComputedRef<boolean>;
36
- internalErrorMessages: Ref<string[]>;
37
- now: Ref<Dayjs>;
36
+ internalErrorMessages: Readonly<Ref<string[]>>;
37
+ now: Readonly<Ref<Dayjs>>;
38
38
  segmentData: SegmentData;
39
39
  minAllowedDate: ComputedRef<Date>;
40
40
  maxAllowedDate: ComputedRef<Date | undefined>;
@@ -3,7 +3,7 @@ import { formatWallClock, guessTimezone, includeMilliseconds, includeSeconds } f
3
3
  import { buildDateTime, clampToBounds } from "./segment-utils.js";
4
4
  import { completePartialEntry } from "./partial-time.js";
5
5
  import { useDateBounds } from "./use-date-bounds.js";
6
- import { computed, nextTick, onMounted, ref, watch } from "vue";
6
+ import { computed, nextTick, onMounted, ref, shallowReadonly, watch } from "vue";
7
7
  import { isDefined, watchIgnorable } from "@vueuse/core";
8
8
  import { get as get$1, set as set$1 } from "@vueuse/shared";
9
9
  import dayjs from "dayjs";
@@ -11,16 +11,16 @@ import dayjs from "dayjs";
11
11
  var MILLISECONDS = 1e3;
12
12
  function useDateTimeSelection(options) {
13
13
  const { accuracy, allowEmpty, dateFormat, maxDate, minDate, modelValue, partialTime, type } = options;
14
- const selectedYear = ref();
15
- const selectedMonth = ref();
16
- const selectedDay = ref();
17
- const selectedHour = ref();
18
- const selectedMinute = ref();
19
- const selectedSecond = ref();
20
- const selectedMillisecond = ref();
21
- const selectedTimezone = ref(guessTimezone());
14
+ const modelYear = ref();
15
+ const modelMonth = ref();
16
+ const modelDay = ref();
17
+ const modelHour = ref();
18
+ const modelMinute = ref();
19
+ const modelSecond = ref();
20
+ const modelMillisecond = ref();
21
+ const modelTimezone = ref(guessTimezone());
22
22
  const now = ref(dayjs.tz(void 0, guessTimezone()));
23
- const { internalErrorMessages, isDateValid, maxAllowedDate, minAllowedDate } = useDateBounds({
23
+ const { clearErrors, internalErrorMessages, isDateValid, maxAllowedDate, minAllowedDate } = useDateBounds({
24
24
  dateFormat,
25
25
  epochSeconds: type === "epoch",
26
26
  maxDate,
@@ -28,54 +28,54 @@ function useDateTimeSelection(options) {
28
28
  now
29
29
  });
30
30
  const segmentData = {
31
- DD: selectedDay,
32
- HH: selectedHour,
33
- MM: selectedMonth,
34
- SSS: selectedMillisecond,
35
- YYYY: selectedYear,
36
- mm: selectedMinute,
37
- ss: selectedSecond
31
+ DD: modelDay,
32
+ HH: modelHour,
33
+ MM: modelMonth,
34
+ SSS: modelMillisecond,
35
+ YYYY: modelYear,
36
+ mm: modelMinute,
37
+ ss: modelSecond
38
38
  };
39
39
  const selectedDate = computed({
40
40
  get() {
41
- if (!(isDefined(selectedYear) && isDefined(selectedMonth) && isDefined(selectedDay))) return;
41
+ if (!(isDefined(modelYear) && isDefined(modelMonth) && isDefined(modelDay))) return;
42
42
  const date = /* @__PURE__ */ new Date();
43
- date.setFullYear(get$1(selectedYear));
43
+ date.setFullYear(get$1(modelYear));
44
44
  date.setDate(1);
45
- date.setMonth(get$1(selectedMonth) - 1);
46
- date.setDate(get$1(selectedDay));
45
+ date.setMonth(get$1(modelMonth) - 1);
46
+ date.setDate(get$1(modelDay));
47
47
  return date;
48
48
  },
49
49
  set(value) {
50
- set$1(selectedYear, value?.getFullYear());
51
- set$1(selectedMonth, value ? value.getMonth() + 1 : void 0);
52
- set$1(selectedDay, value?.getDate());
50
+ set$1(modelYear, value?.getFullYear());
51
+ set$1(modelMonth, value ? value.getMonth() + 1 : void 0);
52
+ set$1(modelDay, value?.getDate());
53
53
  }
54
54
  });
55
55
  const selectedTime = computed({
56
56
  get() {
57
- if (!(isDefined(selectedHour) && isDefined(selectedMinute))) return;
57
+ if (!(isDefined(modelHour) && isDefined(modelMinute))) return;
58
58
  const date = /* @__PURE__ */ new Date();
59
- date.setHours(get$1(selectedHour), get$1(selectedMinute), get$1(selectedSecond) ?? 0, get$1(selectedMillisecond) ?? 0);
59
+ date.setHours(get$1(modelHour), get$1(modelMinute), get$1(modelSecond) ?? 0, get$1(modelMillisecond) ?? 0);
60
60
  return date;
61
61
  },
62
62
  set(value) {
63
- set$1(selectedHour, value?.getHours());
64
- set$1(selectedMinute, value?.getMinutes());
65
- set$1(selectedSecond, value?.getSeconds());
66
- set$1(selectedMillisecond, value?.getMilliseconds());
63
+ set$1(modelHour, value?.getHours());
64
+ set$1(modelMinute, value?.getMinutes());
65
+ set$1(modelSecond, value?.getSeconds());
66
+ set$1(modelMillisecond, value?.getMilliseconds());
67
67
  }
68
68
  });
69
69
  const valueSet = computed(() => isDefined(selectedDate) && isDefined(selectedTime));
70
70
  function getDateTime() {
71
71
  return buildDateTime({
72
- day: get$1(selectedDay),
73
- hour: get$1(selectedHour),
74
- millisecond: get$1(selectedMillisecond),
75
- minute: get$1(selectedMinute),
76
- month: get$1(selectedMonth),
77
- second: get$1(selectedSecond),
78
- year: get$1(selectedYear)
72
+ day: get$1(modelDay),
73
+ hour: get$1(modelHour),
74
+ millisecond: get$1(modelMillisecond),
75
+ minute: get$1(modelMinute),
76
+ month: get$1(modelMonth),
77
+ second: get$1(modelSecond),
78
+ year: get$1(modelYear)
79
79
  }, accuracy);
80
80
  }
81
81
  function emitUpdate(updatedModel) {
@@ -85,37 +85,45 @@ function useDateTimeSelection(options) {
85
85
  "epoch-ms": () => updatedModel.valueOf()
86
86
  }[type]());
87
87
  }
88
+ /**
89
+ * Writes the segments back to the model.
90
+ *
91
+ * The segments are a wall-clock reading, so they are formatted and parsed in
92
+ * the selected timezone. Mutating a `dayjs.tz()` built from the old value
93
+ * instead would keep that value's UTC offset, and moving the date across a
94
+ * DST boundary then shifted the time by an hour.
95
+ */
88
96
  function updateModelValue() {
89
97
  if (!isDefined(selectedDate) || !isDefined(selectedTime)) return;
90
- const updatedModel = dayjs.tz(formatWallClock(get$1(selectedDate), get$1(selectedTime), accuracy), get$1(selectedTimezone));
98
+ const updatedModel = dayjs.tz(formatWallClock(get$1(selectedDate), get$1(selectedTime), accuracy), get$1(modelTimezone));
91
99
  if (!isDateValid(updatedModel)) return;
92
100
  emitUpdate(updatedModel);
93
101
  }
94
102
  function clear() {
95
- set$1(internalErrorMessages, []);
96
- set$1(selectedYear, void 0);
97
- set$1(selectedMonth, void 0);
98
- set$1(selectedDay, void 0);
99
- set$1(selectedHour, void 0);
100
- set$1(selectedMinute, void 0);
101
- set$1(selectedSecond, void 0);
102
- set$1(selectedMillisecond, void 0);
103
+ clearErrors();
104
+ set$1(modelYear, void 0);
105
+ set$1(modelMonth, void 0);
106
+ set$1(modelDay, void 0);
107
+ set$1(modelHour, void 0);
108
+ set$1(modelMinute, void 0);
109
+ set$1(modelSecond, void 0);
110
+ set$1(modelMillisecond, void 0);
103
111
  set$1(modelValue, void 0);
104
112
  }
105
113
  function clampToAllowed(date) {
106
114
  return clampToBounds(date, get$1(minAllowedDate), get$1(maxAllowedDate));
107
115
  }
108
116
  function applySegments(date) {
109
- set$1(selectedYear, date.year());
110
- set$1(selectedMonth, date.month() + 1);
111
- set$1(selectedDay, date.date());
112
- set$1(selectedHour, date.hour());
113
- set$1(selectedMinute, date.minute());
114
- set$1(selectedSecond, includeSeconds(accuracy) ? date.second() : 0);
115
- set$1(selectedMillisecond, includeMilliseconds(accuracy) ? date.millisecond() : 0);
117
+ set$1(modelYear, date.year());
118
+ set$1(modelMonth, date.month() + 1);
119
+ set$1(modelDay, date.date());
120
+ set$1(modelHour, date.hour());
121
+ set$1(modelMinute, date.minute());
122
+ set$1(modelSecond, includeSeconds(accuracy) ? date.second() : 0);
123
+ set$1(modelMillisecond, includeMilliseconds(accuracy) ? date.millisecond() : 0);
116
124
  }
117
125
  function setNow() {
118
- set$1(internalErrorMessages, []);
126
+ clearErrors();
119
127
  const date = dayjs();
120
128
  set$1(now, date);
121
129
  applySegments(clampToAllowed(date));
@@ -128,16 +136,16 @@ function useDateTimeSelection(options) {
128
136
  * time survives. Falls back to midnight when no time has been entered yet.
129
137
  */
130
138
  function setToday() {
131
- set$1(internalErrorMessages, []);
139
+ clearErrors();
132
140
  const date = dayjs();
133
141
  set$1(now, date);
134
142
  applySegments(clampToAllowed(buildDateTime({
135
143
  day: date.date(),
136
- hour: get$1(selectedHour) ?? 0,
137
- millisecond: get$1(selectedMillisecond) ?? 0,
138
- minute: get$1(selectedMinute) ?? 0,
144
+ hour: get$1(modelHour) ?? 0,
145
+ millisecond: get$1(modelMillisecond) ?? 0,
146
+ minute: get$1(modelMinute) ?? 0,
139
147
  month: date.month() + 1,
140
- second: get$1(selectedSecond) ?? 0,
148
+ second: get$1(modelSecond) ?? 0,
141
149
  year: date.year()
142
150
  }, accuracy, date)));
143
151
  nextTick(() => {
@@ -152,16 +160,16 @@ function useDateTimeSelection(options) {
152
160
  const minute = date.minute();
153
161
  const second = includeSeconds(accuracy) ? date.second() : void 0;
154
162
  const millisecond = includeMilliseconds(accuracy) ? date.millisecond() : void 0;
155
- if (get$1(selectedYear) !== year) set$1(selectedYear, year);
156
- if (get$1(selectedMonth) !== month) set$1(selectedMonth, month);
157
- if (get$1(selectedDay) !== day) set$1(selectedDay, day);
158
- if (get$1(selectedHour) !== hour) set$1(selectedHour, hour);
159
- if (get$1(selectedMinute) !== minute) set$1(selectedMinute, minute);
160
- if (get$1(selectedSecond) !== second) set$1(selectedSecond, second);
161
- if (get$1(selectedMillisecond) !== millisecond) set$1(selectedMillisecond, millisecond);
163
+ if (get$1(modelYear) !== year) set$1(modelYear, year);
164
+ if (get$1(modelMonth) !== month) set$1(modelMonth, month);
165
+ if (get$1(modelDay) !== day) set$1(modelDay, day);
166
+ if (get$1(modelHour) !== hour) set$1(modelHour, hour);
167
+ if (get$1(modelMinute) !== minute) set$1(modelMinute, minute);
168
+ if (get$1(modelSecond) !== second) set$1(modelSecond, second);
169
+ if (get$1(modelMillisecond) !== millisecond) set$1(modelMillisecond, millisecond);
162
170
  }
163
171
  const { ignoreUpdates } = watchIgnorable([selectedDate, selectedTime], ([newSelectedDate, newSelectedTime], [prevSelectedDate, prevSelectedTime]) => {
164
- const currentTimezone = get$1(selectedTimezone);
172
+ const currentTimezone = get$1(modelTimezone);
165
173
  const newDate = dayjs.tz(newSelectedDate, currentTimezone);
166
174
  const oldDate = dayjs.tz(prevSelectedDate, currentTimezone);
167
175
  const newTime = dayjs.tz(newSelectedTime, currentTimezone);
@@ -175,18 +183,20 @@ function useDateTimeSelection(options) {
175
183
  * a bare date can become a value. Called when the user is done with the field
176
184
  * rather than on every keystroke, since a segment still being typed is not
177
185
  * yet one they left out. The fill is written back into the field, so the
178
- * value it decided on is the one on screen.
186
+ * value it decided on is the one on screen, and into the model directly:
187
+ * running on blur and on enter, it would otherwise lose the value to a
188
+ * consumer that closes the field on that key before the watcher emits.
179
189
  */
180
190
  function commitPartialTime() {
181
191
  if (partialTime === void 0) return;
182
192
  const target = completePartialEntry({
183
- day: get$1(selectedDay),
184
- hour: get$1(selectedHour),
185
- millisecond: get$1(selectedMillisecond),
186
- minute: get$1(selectedMinute),
187
- month: get$1(selectedMonth),
188
- second: get$1(selectedSecond),
189
- year: get$1(selectedYear)
193
+ day: get$1(modelDay),
194
+ hour: get$1(modelHour),
195
+ millisecond: get$1(modelMillisecond),
196
+ minute: get$1(modelMinute),
197
+ month: get$1(modelMonth),
198
+ second: get$1(modelSecond),
199
+ year: get$1(modelYear)
190
200
  }, {
191
201
  accuracy,
192
202
  maxDate: get$1(maxAllowedDate),
@@ -200,12 +210,12 @@ function useDateTimeSelection(options) {
200
210
  function updateInternalModel(value) {
201
211
  ignoreUpdates(() => {
202
212
  const updatedValue = type === "epoch" && typeof value === "number" ? value * MILLISECONDS : value;
203
- const date = dayjs.tz(updatedValue, get$1(selectedTimezone));
213
+ const date = dayjs.tz(updatedValue, get$1(modelTimezone));
204
214
  isDateValid(date);
205
215
  updateSegments(date);
206
216
  });
207
217
  }
208
- watch(selectedTimezone, (newTimezone) => {
218
+ watch(modelTimezone, (newTimezone) => {
209
219
  if (newTimezone && isDefined(selectedDate) && isDefined(selectedTime)) {
210
220
  set$1(now, dayjs());
211
221
  updateModelValue();
@@ -228,18 +238,18 @@ function useDateTimeSelection(options) {
228
238
  isDateValid,
229
239
  maxAllowedDate,
230
240
  minAllowedDate,
231
- now,
241
+ modelDay,
242
+ modelHour,
243
+ modelMillisecond,
244
+ modelMinute,
245
+ modelMonth,
246
+ modelSecond,
247
+ modelTimezone,
248
+ modelYear,
249
+ now: shallowReadonly(now),
232
250
  segmentData,
233
251
  selectedDate,
234
- selectedDay,
235
- selectedHour,
236
- selectedMillisecond,
237
- selectedMinute,
238
- selectedMonth,
239
- selectedSecond,
240
252
  selectedTime,
241
- selectedTimezone,
242
- selectedYear,
243
253
  setNow,
244
254
  setToday,
245
255
  valueSet
@@ -1 +1 @@
1
- {"version":3,"file":"use-date-time-selection.js","names":[],"sources":["../../../src/components/date-time-picker/use-date-time-selection.ts"],"sourcesContent":["import type { ComputedRef, Ref, WritableComputedRef } from 'vue';\nimport type { SegmentData } from '@/components/date-time-picker/types';\nimport type { TimeAccuracy } from '@/consts/time-accuracy';\nimport dayjs, { type Dayjs } from 'dayjs';\nimport { completePartialEntry, type PartialTimeMode } from '@/components/date-time-picker/partial-time';\nimport { buildDateTime, clampToBounds } from '@/components/date-time-picker/segment-utils';\nimport { useDateBounds } from '@/components/date-time-picker/use-date-bounds';\nimport { formatWallClock, guessTimezone, includeMilliseconds, includeSeconds } from '@/components/date-time-picker/utils';\nimport '@/components/date-time-picker/dayjs-setup';\n\ntype DateTimeModelType = 'date' | 'epoch-ms' | 'epoch';\n\ntype ModelValueType<T extends DateTimeModelType> =\n T extends 'date' ? Date | undefined :\n T extends 'epoch-ms' ? number | undefined :\n T extends 'epoch' ? number | undefined :\n Date | number | undefined;\n\ninterface DateTimeSelectionOptions<T extends DateTimeModelType> {\n modelValue: Ref<ModelValueType<T>>;\n type: T;\n accuracy: TimeAccuracy;\n minDate: Date | number | undefined;\n maxDate: Date | number | 'now' | undefined;\n allowEmpty: boolean;\n /**\n * The field's own format, so a bound named in an error message is written the\n * same way round as the value the user is looking at.\n */\n dateFormat: Ref<string>;\n /** See {@link completePartialEntry}; unset, an incomplete entry is not a value. */\n partialTime?: PartialTimeMode;\n}\n\ninterface DateTimeSelectionReturn {\n selectedYear: Ref<number | undefined>;\n selectedMonth: Ref<number | undefined>;\n selectedDay: Ref<number | undefined>;\n selectedHour: Ref<number | undefined>;\n selectedMinute: Ref<number | undefined>;\n selectedSecond: Ref<number | undefined>;\n selectedMillisecond: Ref<number | undefined>;\n selectedTimezone: Ref<string | undefined>;\n selectedDate: WritableComputedRef<Date | undefined>;\n selectedTime: WritableComputedRef<Date | undefined>;\n valueSet: ComputedRef<boolean>;\n internalErrorMessages: Ref<string[]>;\n now: Ref<Dayjs>;\n segmentData: SegmentData;\n minAllowedDate: ComputedRef<Date>;\n maxAllowedDate: ComputedRef<Date | undefined>;\n getDateTime: () => Dayjs;\n setNow: () => void;\n setToday: () => void;\n commitPartialTime: () => void;\n clear: () => void;\n isDateValid: (date: Dayjs) => boolean;\n}\n\nconst MILLISECONDS = 1000;\n\nexport function useDateTimeSelection<T extends DateTimeModelType>(\n options: DateTimeSelectionOptions<T>,\n): DateTimeSelectionReturn {\n const {\n accuracy,\n allowEmpty,\n dateFormat,\n maxDate,\n minDate,\n modelValue,\n partialTime,\n type,\n } = options;\n\n const selectedYear = ref<number | undefined>();\n const selectedMonth = ref<number | undefined>();\n const selectedDay = ref<number | undefined>();\n\n const selectedHour = ref<number | undefined>();\n const selectedMinute = ref<number | undefined>();\n const selectedSecond = ref<number | undefined>();\n const selectedMillisecond = ref<number | undefined>();\n const selectedTimezone = ref<string | undefined>(guessTimezone());\n\n const now = ref<Dayjs>(dayjs.tz(undefined, guessTimezone()));\n\n const { internalErrorMessages, isDateValid, maxAllowedDate, minAllowedDate } = useDateBounds({\n dateFormat,\n epochSeconds: type === 'epoch',\n maxDate,\n minDate,\n now,\n });\n\n const segmentData: SegmentData = {\n DD: selectedDay,\n HH: selectedHour,\n MM: selectedMonth,\n SSS: selectedMillisecond,\n YYYY: selectedYear,\n mm: selectedMinute,\n ss: selectedSecond,\n };\n\n const selectedDate = computed<Date | undefined>({\n get() {\n if (!(isDefined(selectedYear) && isDefined(selectedMonth) && isDefined(selectedDay))) {\n return undefined;\n }\n const date = new Date();\n date.setFullYear(get(selectedYear));\n // Set day to 1 first to prevent month overflow when today's day > days in target month\n // e.g., if today is Dec 30 and we set month to Feb, day 30 would overflow to March\n date.setDate(1);\n date.setMonth(get(selectedMonth) - 1);\n date.setDate(get(selectedDay));\n return date;\n },\n set(value?: Date) {\n set(selectedYear, value?.getFullYear());\n set(selectedMonth, value ? value.getMonth() + 1 : undefined);\n set(selectedDay, value?.getDate());\n },\n });\n\n const selectedTime = computed<Date | undefined>({\n get() {\n if (!(isDefined(selectedHour) && isDefined(selectedMinute))) {\n return undefined;\n }\n const date = new Date();\n date.setHours(\n get(selectedHour),\n get(selectedMinute),\n get(selectedSecond) ?? 0,\n get(selectedMillisecond) ?? 0,\n );\n return date;\n },\n set(value?: Date) {\n set(selectedHour, value?.getHours());\n set(selectedMinute, value?.getMinutes());\n set(selectedSecond, value?.getSeconds());\n set(selectedMillisecond, value?.getMilliseconds());\n },\n });\n\n const valueSet = computed<boolean>(() => isDefined(selectedDate) && isDefined(selectedTime));\n\n function getDateTime(): Dayjs {\n return buildDateTime({\n day: get(selectedDay),\n hour: get(selectedHour),\n millisecond: get(selectedMillisecond),\n minute: get(selectedMinute),\n month: get(selectedMonth),\n second: get(selectedSecond),\n year: get(selectedYear),\n }, accuracy);\n }\n\n function emitUpdate(updatedModel: Dayjs): void {\n const typeMap = {\n 'date': () => updatedModel.toDate(),\n // an epoch is whole seconds; `millisecond` accuracy would otherwise emit a fraction\n 'epoch': () => Math.floor(updatedModel.valueOf() / MILLISECONDS),\n 'epoch-ms': () => updatedModel.valueOf(),\n } as const;\n\n set(modelValue, typeMap[type]() as ModelValueType<T>);\n }\n\n function updateModelValue(): void {\n if (!isDefined(selectedDate) || !isDefined(selectedTime)) {\n return;\n }\n\n // The segments are a wall-clock reading, so they are formatted and parsed\n // in the selected timezone. Mutating a `dayjs.tz()` built from the old\n // value instead would keep that value's UTC offset, and moving the date\n // across a DST boundary then shifted the time by an hour.\n const updatedModel = dayjs.tz(\n formatWallClock(get(selectedDate), get(selectedTime), accuracy),\n get(selectedTimezone),\n );\n\n if (!isDateValid(updatedModel)) {\n return;\n }\n\n emitUpdate(updatedModel);\n }\n\n function clear(): void {\n set(internalErrorMessages, []);\n set(selectedYear, undefined);\n set(selectedMonth, undefined);\n set(selectedDay, undefined);\n set(selectedHour, undefined);\n set(selectedMinute, undefined);\n set(selectedSecond, undefined);\n set(selectedMillisecond, undefined);\n set(modelValue, undefined as ModelValueType<T>);\n }\n\n function clampToAllowed(date: Dayjs): Dayjs {\n return clampToBounds(date, get(minAllowedDate), get(maxAllowedDate));\n }\n\n function applySegments(date: Dayjs): void {\n set(selectedYear, date.year());\n set(selectedMonth, date.month() + 1);\n set(selectedDay, date.date());\n set(selectedHour, date.hour());\n set(selectedMinute, date.minute());\n set(selectedSecond, includeSeconds(accuracy) ? date.second() : 0);\n set(selectedMillisecond, includeMilliseconds(accuracy) ? date.millisecond() : 0);\n }\n\n function setNow(): void {\n set(internalErrorMessages, []);\n\n const date = dayjs();\n set(now, date);\n applySegments(clampToAllowed(date));\n\n nextTick(() => {\n updateModelValue();\n });\n }\n\n /**\n * Moves the date part to today and leaves the time part alone, so a picked\n * time survives. Falls back to midnight when no time has been entered yet.\n */\n function setToday(): void {\n set(internalErrorMessages, []);\n\n const date = dayjs();\n set(now, date);\n\n const target = buildDateTime({\n day: date.date(),\n hour: get(selectedHour) ?? 0,\n millisecond: get(selectedMillisecond) ?? 0,\n minute: get(selectedMinute) ?? 0,\n month: date.month() + 1,\n second: get(selectedSecond) ?? 0,\n year: date.year(),\n }, accuracy, date);\n\n applySegments(clampToAllowed(target));\n\n nextTick(() => {\n updateModelValue();\n });\n }\n\n function updateSegments(date: Dayjs): void {\n const year = date.year();\n const month = date.month() + 1;\n const day = date.date();\n const hour = date.hour();\n const minute = date.minute();\n const second = includeSeconds(accuracy) ? date.second() : undefined;\n const millisecond = includeMilliseconds(accuracy) ? date.millisecond() : undefined;\n\n if (get(selectedYear) !== year)\n set(selectedYear, year);\n if (get(selectedMonth) !== month)\n set(selectedMonth, month);\n if (get(selectedDay) !== day)\n set(selectedDay, day);\n if (get(selectedHour) !== hour)\n set(selectedHour, hour);\n if (get(selectedMinute) !== minute)\n set(selectedMinute, minute);\n if (get(selectedSecond) !== second)\n set(selectedSecond, second);\n if (get(selectedMillisecond) !== millisecond)\n set(selectedMillisecond, millisecond);\n }\n\n const { ignoreUpdates } = watchIgnorable([selectedDate, selectedTime], ([newSelectedDate, newSelectedTime], [prevSelectedDate, prevSelectedTime]) => {\n const currentTimezone = get(selectedTimezone);\n const newDate = dayjs.tz(newSelectedDate, currentTimezone);\n const oldDate = dayjs.tz(prevSelectedDate, currentTimezone);\n const newTime = dayjs.tz(newSelectedTime, currentTimezone);\n const oldTime = dayjs.tz(prevSelectedTime, currentTimezone);\n\n if (newDate.isSame(oldDate) && newTime.isSame(oldTime)) {\n return;\n }\n\n set(now, dayjs());\n updateModelValue();\n });\n\n /**\n * Fills in the segments an incomplete entry never reached and commits it, so\n * a bare date can become a value. Called when the user is done with the field\n * rather than on every keystroke, since a segment still being typed is not\n * yet one they left out. The fill is written back into the field, so the\n * value it decided on is the one on screen.\n */\n function commitPartialTime(): void {\n if (partialTime === undefined)\n return;\n\n const target = completePartialEntry({\n day: get(selectedDay),\n hour: get(selectedHour),\n millisecond: get(selectedMillisecond),\n minute: get(selectedMinute),\n month: get(selectedMonth),\n second: get(selectedSecond),\n year: get(selectedYear),\n }, {\n accuracy,\n maxDate: get(maxAllowedDate),\n minDate: get(minAllowedDate),\n mode: partialTime,\n });\n\n if (!target)\n return;\n\n // The model is written here rather than left to the watcher: this runs on blur and on enter,\n // and a consumer that closes the field on that key would drop a value the watcher only emits\n // on the next tick.\n ignoreUpdates(() => applySegments(target));\n updateModelValue();\n }\n\n function updateInternalModel(value: ModelValueType<T>): void {\n ignoreUpdates(() => {\n const updatedValue = type === 'epoch' && typeof value === 'number'\n ? value * MILLISECONDS\n : value;\n const date = dayjs.tz(updatedValue, get(selectedTimezone));\n isDateValid(date);\n updateSegments(date);\n });\n }\n\n watch(selectedTimezone, (newTimezone: string | undefined) => {\n if (newTimezone && isDefined(selectedDate) && isDefined(selectedTime)) {\n set(now, dayjs());\n updateModelValue();\n }\n });\n\n watch(modelValue, (value) => {\n set(now, dayjs());\n if (value === undefined) {\n clear();\n }\n else {\n updateInternalModel(value);\n }\n });\n\n onMounted(() => {\n if (isDefined(modelValue)) {\n updateInternalModel(get(modelValue));\n }\n else if (!allowEmpty) {\n setNow();\n }\n });\n\n return {\n clear,\n commitPartialTime,\n getDateTime,\n internalErrorMessages,\n isDateValid,\n maxAllowedDate,\n minAllowedDate,\n now,\n segmentData,\n selectedDate,\n selectedDay,\n selectedHour,\n selectedMillisecond,\n selectedMinute,\n selectedMonth,\n selectedSecond,\n selectedTime,\n selectedTimezone,\n selectedYear,\n setNow,\n setToday,\n valueSet,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-date-time-selection.js","names":[],"sources":["../../../src/components/date-time-picker/use-date-time-selection.ts"],"sourcesContent":["import type { ComputedRef, Ref, WritableComputedRef } from 'vue';\nimport type { SegmentData } from '@/components/date-time-picker/types';\nimport type { TimeAccuracy } from '@/consts/time-accuracy';\nimport dayjs, { type Dayjs } from 'dayjs';\nimport { completePartialEntry, type PartialTimeMode } from '@/components/date-time-picker/partial-time';\nimport { buildDateTime, clampToBounds } from '@/components/date-time-picker/segment-utils';\nimport { useDateBounds } from '@/components/date-time-picker/use-date-bounds';\nimport { formatWallClock, guessTimezone, includeMilliseconds, includeSeconds } from '@/components/date-time-picker/utils';\nimport '@/components/date-time-picker/dayjs-setup';\n\ntype DateTimeModelType = 'date' | 'epoch-ms' | 'epoch';\n\ntype ModelValueType<T extends DateTimeModelType> =\n T extends 'date' ? Date | undefined :\n T extends 'epoch-ms' ? number | undefined :\n T extends 'epoch' ? number | undefined :\n Date | number | undefined;\n\ninterface DateTimeSelectionOptions<T extends DateTimeModelType> {\n modelValue: Ref<ModelValueType<T>>;\n type: T;\n accuracy: TimeAccuracy;\n minDate: Date | number | undefined;\n maxDate: Date | number | 'now' | undefined;\n allowEmpty: boolean;\n /**\n * The field's own format, so a bound named in an error message is written the\n * same way round as the value the user is looking at.\n */\n dateFormat: Ref<string>;\n /** See {@link completePartialEntry}; unset, an incomplete entry is not a value. */\n partialTime?: PartialTimeMode;\n}\n\ninterface DateTimeSelectionReturn {\n modelYear: Ref<number | undefined>;\n modelMonth: Ref<number | undefined>;\n modelDay: Ref<number | undefined>;\n modelHour: Ref<number | undefined>;\n modelMinute: Ref<number | undefined>;\n modelSecond: Ref<number | undefined>;\n modelMillisecond: Ref<number | undefined>;\n modelTimezone: Ref<string | undefined>;\n selectedDate: WritableComputedRef<Date | undefined>;\n selectedTime: WritableComputedRef<Date | undefined>;\n valueSet: ComputedRef<boolean>;\n internalErrorMessages: Readonly<Ref<string[]>>;\n now: Readonly<Ref<Dayjs>>;\n segmentData: SegmentData;\n minAllowedDate: ComputedRef<Date>;\n maxAllowedDate: ComputedRef<Date | undefined>;\n getDateTime: () => Dayjs;\n setNow: () => void;\n setToday: () => void;\n commitPartialTime: () => void;\n clear: () => void;\n isDateValid: (date: Dayjs) => boolean;\n}\n\nconst MILLISECONDS = 1000;\n\nexport function useDateTimeSelection<T extends DateTimeModelType>(\n options: DateTimeSelectionOptions<T>,\n): DateTimeSelectionReturn {\n const {\n accuracy,\n allowEmpty,\n dateFormat,\n maxDate,\n minDate,\n modelValue,\n partialTime,\n type,\n } = options;\n\n const modelYear = ref<number | undefined>();\n const modelMonth = ref<number | undefined>();\n const modelDay = ref<number | undefined>();\n\n const modelHour = ref<number | undefined>();\n const modelMinute = ref<number | undefined>();\n const modelSecond = ref<number | undefined>();\n const modelMillisecond = ref<number | undefined>();\n const modelTimezone = ref<string | undefined>(guessTimezone());\n\n const now = ref<Dayjs>(dayjs.tz(undefined, guessTimezone()));\n\n const { clearErrors, internalErrorMessages, isDateValid, maxAllowedDate, minAllowedDate } = useDateBounds({\n dateFormat,\n epochSeconds: type === 'epoch',\n maxDate,\n minDate,\n now,\n });\n\n const segmentData: SegmentData = {\n DD: modelDay,\n HH: modelHour,\n MM: modelMonth,\n SSS: modelMillisecond,\n YYYY: modelYear,\n mm: modelMinute,\n ss: modelSecond,\n };\n\n const selectedDate = computed<Date | undefined>({\n get() {\n if (!(isDefined(modelYear) && isDefined(modelMonth) && isDefined(modelDay))) {\n return undefined;\n }\n const date = new Date();\n date.setFullYear(get(modelYear));\n // Day 1 first, so a later month with fewer days cannot overflow into the next one\n date.setDate(1);\n date.setMonth(get(modelMonth) - 1);\n date.setDate(get(modelDay));\n return date;\n },\n set(value?: Date) {\n set(modelYear, value?.getFullYear());\n set(modelMonth, value ? value.getMonth() + 1 : undefined);\n set(modelDay, value?.getDate());\n },\n });\n\n const selectedTime = computed<Date | undefined>({\n get() {\n if (!(isDefined(modelHour) && isDefined(modelMinute))) {\n return undefined;\n }\n const date = new Date();\n date.setHours(\n get(modelHour),\n get(modelMinute),\n get(modelSecond) ?? 0,\n get(modelMillisecond) ?? 0,\n );\n return date;\n },\n set(value?: Date) {\n set(modelHour, value?.getHours());\n set(modelMinute, value?.getMinutes());\n set(modelSecond, value?.getSeconds());\n set(modelMillisecond, value?.getMilliseconds());\n },\n });\n\n const valueSet = computed<boolean>(() => isDefined(selectedDate) && isDefined(selectedTime));\n\n function getDateTime(): Dayjs {\n return buildDateTime({\n day: get(modelDay),\n hour: get(modelHour),\n millisecond: get(modelMillisecond),\n minute: get(modelMinute),\n month: get(modelMonth),\n second: get(modelSecond),\n year: get(modelYear),\n }, accuracy);\n }\n\n function emitUpdate(updatedModel: Dayjs): void {\n const typeMap = {\n 'date': () => updatedModel.toDate(),\n // an epoch is whole seconds; `millisecond` accuracy would otherwise emit a fraction\n 'epoch': () => Math.floor(updatedModel.valueOf() / MILLISECONDS),\n 'epoch-ms': () => updatedModel.valueOf(),\n } as const;\n\n set(modelValue, typeMap[type]() as ModelValueType<T>);\n }\n\n /**\n * Writes the segments back to the model.\n *\n * The segments are a wall-clock reading, so they are formatted and parsed in\n * the selected timezone. Mutating a `dayjs.tz()` built from the old value\n * instead would keep that value's UTC offset, and moving the date across a\n * DST boundary then shifted the time by an hour.\n */\n function updateModelValue(): void {\n if (!isDefined(selectedDate) || !isDefined(selectedTime)) {\n return;\n }\n\n const updatedModel = dayjs.tz(\n formatWallClock(get(selectedDate), get(selectedTime), accuracy),\n get(modelTimezone),\n );\n\n if (!isDateValid(updatedModel)) {\n return;\n }\n\n emitUpdate(updatedModel);\n }\n\n function clear(): void {\n clearErrors();\n set(modelYear, undefined);\n set(modelMonth, undefined);\n set(modelDay, undefined);\n set(modelHour, undefined);\n set(modelMinute, undefined);\n set(modelSecond, undefined);\n set(modelMillisecond, undefined);\n set(modelValue, undefined as ModelValueType<T>);\n }\n\n function clampToAllowed(date: Dayjs): Dayjs {\n return clampToBounds(date, get(minAllowedDate), get(maxAllowedDate));\n }\n\n function applySegments(date: Dayjs): void {\n set(modelYear, date.year());\n set(modelMonth, date.month() + 1);\n set(modelDay, date.date());\n set(modelHour, date.hour());\n set(modelMinute, date.minute());\n set(modelSecond, includeSeconds(accuracy) ? date.second() : 0);\n set(modelMillisecond, includeMilliseconds(accuracy) ? date.millisecond() : 0);\n }\n\n function setNow(): void {\n clearErrors();\n\n const date = dayjs();\n set(now, date);\n applySegments(clampToAllowed(date));\n\n nextTick(() => {\n updateModelValue();\n });\n }\n\n /**\n * Moves the date part to today and leaves the time part alone, so a picked\n * time survives. Falls back to midnight when no time has been entered yet.\n */\n function setToday(): void {\n clearErrors();\n\n const date = dayjs();\n set(now, date);\n\n const target = buildDateTime({\n day: date.date(),\n hour: get(modelHour) ?? 0,\n millisecond: get(modelMillisecond) ?? 0,\n minute: get(modelMinute) ?? 0,\n month: date.month() + 1,\n second: get(modelSecond) ?? 0,\n year: date.year(),\n }, accuracy, date);\n\n applySegments(clampToAllowed(target));\n\n nextTick(() => {\n updateModelValue();\n });\n }\n\n function updateSegments(date: Dayjs): void {\n const year = date.year();\n const month = date.month() + 1;\n const day = date.date();\n const hour = date.hour();\n const minute = date.minute();\n const second = includeSeconds(accuracy) ? date.second() : undefined;\n const millisecond = includeMilliseconds(accuracy) ? date.millisecond() : undefined;\n\n if (get(modelYear) !== year)\n set(modelYear, year);\n if (get(modelMonth) !== month)\n set(modelMonth, month);\n if (get(modelDay) !== day)\n set(modelDay, day);\n if (get(modelHour) !== hour)\n set(modelHour, hour);\n if (get(modelMinute) !== minute)\n set(modelMinute, minute);\n if (get(modelSecond) !== second)\n set(modelSecond, second);\n if (get(modelMillisecond) !== millisecond)\n set(modelMillisecond, millisecond);\n }\n\n const { ignoreUpdates } = watchIgnorable([selectedDate, selectedTime], ([newSelectedDate, newSelectedTime], [prevSelectedDate, prevSelectedTime]) => {\n const currentTimezone = get(modelTimezone);\n const newDate = dayjs.tz(newSelectedDate, currentTimezone);\n const oldDate = dayjs.tz(prevSelectedDate, currentTimezone);\n const newTime = dayjs.tz(newSelectedTime, currentTimezone);\n const oldTime = dayjs.tz(prevSelectedTime, currentTimezone);\n\n if (newDate.isSame(oldDate) && newTime.isSame(oldTime)) {\n return;\n }\n\n set(now, dayjs());\n updateModelValue();\n });\n\n /**\n * Fills in the segments an incomplete entry never reached and commits it, so\n * a bare date can become a value. Called when the user is done with the field\n * rather than on every keystroke, since a segment still being typed is not\n * yet one they left out. The fill is written back into the field, so the\n * value it decided on is the one on screen, and into the model directly:\n * running on blur and on enter, it would otherwise lose the value to a\n * consumer that closes the field on that key before the watcher emits.\n */\n function commitPartialTime(): void {\n if (partialTime === undefined)\n return;\n\n const target = completePartialEntry({\n day: get(modelDay),\n hour: get(modelHour),\n millisecond: get(modelMillisecond),\n minute: get(modelMinute),\n month: get(modelMonth),\n second: get(modelSecond),\n year: get(modelYear),\n }, {\n accuracy,\n maxDate: get(maxAllowedDate),\n minDate: get(minAllowedDate),\n mode: partialTime,\n });\n\n if (!target)\n return;\n\n ignoreUpdates(() => applySegments(target));\n updateModelValue();\n }\n\n function updateInternalModel(value: ModelValueType<T>): void {\n ignoreUpdates(() => {\n const updatedValue = type === 'epoch' && typeof value === 'number'\n ? value * MILLISECONDS\n : value;\n const date = dayjs.tz(updatedValue, get(modelTimezone));\n isDateValid(date);\n updateSegments(date);\n });\n }\n\n watch(modelTimezone, (newTimezone: string | undefined) => {\n if (newTimezone && isDefined(selectedDate) && isDefined(selectedTime)) {\n set(now, dayjs());\n updateModelValue();\n }\n });\n\n watch(modelValue, (value) => {\n set(now, dayjs());\n if (value === undefined) {\n clear();\n }\n else {\n updateInternalModel(value);\n }\n });\n\n onMounted(() => {\n if (isDefined(modelValue)) {\n updateInternalModel(get(modelValue));\n }\n else if (!allowEmpty) {\n setNow();\n }\n });\n\n return {\n clear,\n commitPartialTime,\n getDateTime,\n internalErrorMessages,\n isDateValid,\n maxAllowedDate,\n minAllowedDate,\n modelDay,\n modelHour,\n modelMillisecond,\n modelMinute,\n modelMonth,\n modelSecond,\n modelTimezone,\n modelYear,\n now: shallowReadonly(now),\n segmentData,\n selectedDate,\n selectedTime,\n setNow,\n setToday,\n valueSet,\n };\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { Dayjs } from 'dayjs';
2
2
  import type { Ref } from 'vue';
3
- import type { DateTimeSegmentType, SegmentData } from '../../components/date-time-picker/types.js';
3
+ import type { DateTimeSegmentType, SegmentData } from './types.js';
4
4
  import type { TimeAccuracy } from '../../consts/time-accuracy.js';
5
5
  export declare function useInputHandler(data: SegmentData, currentValue: Ref<number | undefined>): {
6
6
  getCurrent: (segment: DateTimeSegmentType) => number | undefined;
@@ -1,8 +1,8 @@
1
1
  import type { Dayjs } from 'dayjs';
2
2
  import type { Ref, ShallowRef } from 'vue';
3
3
  import type { TimeAccuracy } from '../../consts/time-accuracy.js';
4
- import { type Segment } from '../../components/date-time-picker/segment-config.js';
5
- import { type DateTimeSegmentType } from '../../components/date-time-picker/types.js';
4
+ import { type Segment } from './segment-config.js';
5
+ import { type DateTimeSegmentType } from './types.js';
6
6
  interface KeyboardHandlerOptions {
7
7
  dateFormat: Ref<string>;
8
8
  cursorPosition: Ref<number>;
@@ -92,12 +92,15 @@ function useKeyboardHandler(options) {
92
92
  }
93
93
  }
94
94
  }
95
- function handleDigitPressed(event, digit) {
96
- if (!(event.target instanceof HTMLInputElement)) return;
97
- const currentSegment = getCurrentSegment(event.target.selectionStart ?? 0);
98
- if (!currentSegment || isNaN(parseInt(digit))) return;
99
- const segmentType = currentSegment.type;
100
- if (!isDateTimeSegmentType(segmentType)) return;
95
+ /**
96
+ * Adds a typed digit to the segment under the caret, moving on to the next
97
+ * segment once this one can hold no more.
98
+ *
99
+ * @param segment - the segment the caret sits in
100
+ * @param segmentType - that segment's type, which states its value range
101
+ * @param digit - the digit that was typed
102
+ */
103
+ function applyDigit(segment, segmentType, digit) {
101
104
  const config = SEGMENT_CONFIG[segmentType];
102
105
  const combinedStr = `${get$1(currentValue) ?? ""}${digit}`;
103
106
  const combinedValue = parseInt(combinedStr);
@@ -105,10 +108,18 @@ function useKeyboardHandler(options) {
105
108
  const minValue = config.minValue ?? 0;
106
109
  if (combinedValue >= minValue && combinedValue <= config.maxValue) {
107
110
  setValue(segmentType, combinedValue);
108
- setCursorPosition(currentSegment);
111
+ setCursorPosition(segment);
109
112
  } else if (combinedValue < minValue && combinedStr.length < maxLength) set$1(currentValue, combinedValue);
110
113
  if (parseInt(`${combinedStr}0`) > config.maxValue || combinedStr.length >= maxLength) navigateSegments("ArrowRight");
111
114
  }
115
+ function handleDigitPressed(event, digit) {
116
+ if (!(event.target instanceof HTMLInputElement)) return;
117
+ const currentSegment = getCurrentSegment(event.target.selectionStart ?? 0);
118
+ if (!currentSegment || isNaN(parseInt(digit))) return;
119
+ const segmentType = currentSegment.type;
120
+ if (!isDateTimeSegmentType(segmentType)) return;
121
+ applyDigit(currentSegment, segmentType, digit);
122
+ }
112
123
  function handleKeyboardNavigation(event) {
113
124
  if (event.key === "ArrowUp") changeSegmentValue(true);
114
125
  else if (event.key === "ArrowDown") changeSegmentValue(false);
@@ -129,19 +140,38 @@ function useKeyboardHandler(options) {
129
140
  setCursorPosition(segment);
130
141
  }
131
142
  }
132
- function handleKeyDown(event) {
133
- if (disabled || readonly) return;
134
- const { key } = event;
135
- if (event.ctrlKey || event.metaKey || event.altKey) return;
143
+ /**
144
+ * Runs the picker's own handling for a key.
145
+ *
146
+ * @param event - the keydown being handled
147
+ * @param key - the key that was pressed
148
+ * @returns whether the picker handled it, which decides if the browser's own
149
+ * handling is kept: Tab moves out of the field, Escape closes the menu and
150
+ * Enter submits the surrounding form.
151
+ */
152
+ function dispatchKey(event, key) {
136
153
  if (key === "ArrowRight" || key === "ArrowLeft") navigateSegments(key);
137
154
  else if (key === "ArrowUp" || key === "ArrowDown") handleKeyboardNavigation(event);
138
155
  else if (key === "Backspace") handleBackspace(event);
139
156
  else if (key === "Delete") onInputDeletePressed(event);
140
157
  else if (/^\d$/.test(key)) handleDigitPressed(event, key);
141
- else return;
142
- event.preventDefault();
158
+ else return false;
159
+ return true;
160
+ }
161
+ function handleKeyDown(event) {
162
+ if (disabled || readonly) return;
163
+ if (event.ctrlKey || event.metaKey || event.altKey) return;
164
+ if (dispatchKey(event, event.key)) event.preventDefault();
143
165
  }
144
166
  let clickedSegment;
167
+ /**
168
+ * Captures the clicked segment on mousedown, which fires before focus.
169
+ *
170
+ * The in-progress digit buffer is reset because switching segments must not
171
+ * carry typed digits over, otherwise a leftover digit from another segment
172
+ * combines with the next keystroke (type "1" in HH, click mm, type "3" and
173
+ * mm would become 13 instead of 3).
174
+ */
145
175
  function handleMouseDown(event) {
146
176
  if (disabled || readonly || !(event.target instanceof HTMLInputElement)) return;
147
177
  const currentSegment = getCurrentSegment(getClickPosition(event, event.target, true));
@@ -168,6 +198,11 @@ function useKeyboardHandler(options) {
168
198
  const firstSegment = get$1(segmentPositions)[0];
169
199
  if (firstSegment) setCursorPosition(firstSegment);
170
200
  }
201
+ /**
202
+ * Restores the selection a click asked for, which opening the menu and the
203
+ * DOM updates that follow can lose. With no click to restore, focus selects
204
+ * the first segment, unless the user is already selecting text themselves.
205
+ */
171
206
  function handleFocus() {
172
207
  if (clickedSegment) {
173
208
  setCursorPosition(clickedSegment);
@@ -178,6 +213,10 @@ function useKeyboardHandler(options) {
178
213
  if (input && input.selectionStart !== input.selectionEnd) return;
179
214
  selectFirstSegment();
180
215
  }
216
+ /**
217
+ * Forgets the cursor position and the clicked segment, so re-focusing on
218
+ * another segment does not blink through the one left behind.
219
+ */
181
220
  function handleBlur() {
182
221
  set$1(cursorPosition, 0);
183
222
  set$1(currentValue, void 0);