@rotki/ui-library 3.2.0 → 3.3.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 (235) hide show
  1. package/dist/components/accordions/accordion/RuiAccordion.js.map +1 -1
  2. package/dist/components/accordions/accordion/RuiAccordion.vue.d.ts +4 -2
  3. package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
  4. package/dist/components/accordions/accordions/RuiAccordions.js.map +1 -1
  5. package/dist/components/accordions/accordions/RuiAccordions.vue.d.ts +26 -9
  6. package/dist/components/accordions/accordions/RuiAccordions.vue_vue_type_script_setup_true_lang.js +11 -10
  7. package/dist/components/accordions/accordions/RuiAccordions.vue_vue_type_script_setup_true_lang.js.map +1 -1
  8. package/dist/components/alerts/RuiAlert.js.map +1 -1
  9. package/dist/components/alerts/RuiAlert.vue.d.ts +4 -2
  10. package/dist/components/alerts/RuiAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
  11. package/dist/components/avatars/RuiAvatar.js.map +1 -1
  12. package/dist/components/avatars/RuiAvatar.vue.d.ts +4 -2
  13. package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  14. package/dist/components/avatars/RuiAvatarGroup.js.map +1 -1
  15. package/dist/components/avatars/RuiAvatarGroup.vue.d.ts +3 -2
  16. package/dist/components/avatars/RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  17. package/dist/components/buttons/button/RuiButton.js.map +1 -1
  18. package/dist/components/buttons/button/RuiButton.vue.d.ts +2 -1
  19. package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  20. package/dist/components/buttons/button-group/RuiButtonGroup.js.map +1 -1
  21. package/dist/components/buttons/button-group/RuiButtonGroup.vue.d.ts +10 -4
  22. package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js +7 -8
  23. package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  24. package/dist/components/calendar/RuiCalendarGrid.js.map +1 -1
  25. package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js +3 -3
  26. package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
  27. package/dist/components/calendar/RuiCalendarHeader.js.map +1 -1
  28. package/dist/components/calendar/RuiCalendarHeader.vue_vue_type_script_setup_true_lang.js +3 -3
  29. package/dist/components/calendar/RuiCalendarHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  30. package/dist/components/calendar/RuiCalendarMenu.js.map +1 -1
  31. package/dist/components/calendar/RuiCalendarMenu.vue.d.ts +3 -3
  32. package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js +7 -4
  33. package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  34. package/dist/components/calendar/state.d.ts +8 -1
  35. package/dist/components/calendar/state.js +13 -1
  36. package/dist/components/calendar/state.js.map +1 -1
  37. package/dist/components/cards/RuiCard.js.map +1 -1
  38. package/dist/components/cards/RuiCard.vue.d.ts +3 -1
  39. package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  40. package/dist/components/cards/RuiCardHeader.js.map +1 -1
  41. package/dist/components/cards/RuiCardHeader.vue.d.ts +3 -1
  42. package/dist/components/cards/RuiCardHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  43. package/dist/components/chips/RuiChip.js.map +1 -1
  44. package/dist/components/chips/RuiChip.vue.d.ts +4 -2
  45. package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  46. package/dist/components/color-picker/RuiColorPicker.js.map +1 -1
  47. package/dist/components/color-picker/RuiColorPicker.vue.d.ts +5 -2
  48. package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  49. package/dist/components/date-time-picker/RuiDateTimePicker.js.map +1 -1
  50. package/dist/components/date-time-picker/RuiDateTimePicker.vue.d.ts +39 -30
  51. package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js +8 -3
  52. package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  53. package/dist/components/date-time-picker/RuiDateTimePickerMenu.js.map +1 -1
  54. package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue.d.ts +2 -1
  55. package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  56. package/dist/components/date-time-picker/RuiTimezoneSelect.js.map +1 -1
  57. package/dist/components/date-time-picker/RuiTimezoneSelect.vue.d.ts +2 -1
  58. package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  59. package/dist/components/divider/RuiDivider.js.map +1 -1
  60. package/dist/components/divider/RuiDivider.vue.d.ts +3 -1
  61. package/dist/components/divider/RuiDivider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  62. package/dist/components/forms/auto-complete/RuiAutoComplete.js.map +1 -1
  63. package/dist/components/forms/auto-complete/RuiAutoComplete.vue.d.ts +11 -5
  64. package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js +5 -0
  65. package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  66. package/dist/components/forms/auto-complete/RuiAutoCompleteOption.js.map +1 -1
  67. package/dist/components/forms/auto-complete/RuiAutoCompleteOption.vue.d.ts +2 -1
  68. package/dist/components/forms/auto-complete/RuiAutoCompleteOption.vue_vue_type_script_setup_true_lang.js.map +1 -1
  69. package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.js.map +1 -1
  70. package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.vue.d.ts +2 -2
  71. package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.vue_vue_type_script_setup_true_lang.js.map +1 -1
  72. package/dist/components/forms/auto-complete/auto-complete-props.d.ts +0 -1
  73. package/dist/components/forms/category-picker/RuiCategoryPicker.js.map +1 -1
  74. package/dist/components/forms/category-picker/RuiCategoryPicker.vue.d.ts +2 -1
  75. package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  76. package/dist/components/forms/checkbox/RuiCheckbox.js.map +1 -1
  77. package/dist/components/forms/checkbox/RuiCheckbox.vue.d.ts +2 -1
  78. package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js +4 -1
  79. package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  80. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.js.map +1 -1
  81. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue.d.ts +2 -1
  82. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  83. package/dist/components/forms/file-upload/RuiFileUpload.js.map +1 -1
  84. package/dist/components/forms/file-upload/RuiFileUpload.vue.d.ts +36 -29
  85. package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js +5 -0
  86. package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
  87. package/dist/components/forms/radio-button/radio/RuiRadio.js.map +1 -1
  88. package/dist/components/forms/radio-button/radio/RuiRadio.vue.d.ts +5 -3
  89. package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js +7 -8
  90. package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
  91. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.js.map +1 -1
  92. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue.d.ts +5 -3
  93. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue_vue_type_script_setup_true_lang.js +9 -10
  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.js.map +1 -1
  96. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue.d.ts +9 -2
  97. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  98. package/dist/components/forms/select/RuiMenuSelect.js.map +1 -1
  99. package/dist/components/forms/select/RuiMenuSelect.vue.d.ts +10 -4
  100. package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js +5 -0
  101. package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  102. package/dist/components/forms/select/RuiSimpleSelect.js.map +1 -1
  103. package/dist/components/forms/select/RuiSimpleSelect.vue.d.ts +22 -11
  104. package/dist/components/forms/select/RuiSimpleSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  105. package/dist/components/forms/slider/RuiSlider.js.map +1 -1
  106. package/dist/components/forms/slider/RuiSlider.vue.d.ts +2 -1
  107. package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  108. package/dist/components/forms/switch/RuiSwitch.js.map +1 -1
  109. package/dist/components/forms/switch/RuiSwitch.vue.d.ts +2 -1
  110. package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  111. package/dist/components/forms/text-area/RuiTextArea.js.map +1 -1
  112. package/dist/components/forms/text-area/RuiTextArea.vue.d.ts +3 -1
  113. package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  114. package/dist/components/forms/text-field/RuiTextField.js.map +1 -1
  115. package/dist/components/forms/text-field/RuiTextField.vue.d.ts +3 -1
  116. package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  117. package/dist/components/icons/RuiIcon.js.map +1 -1
  118. package/dist/components/icons/RuiIcon.vue.d.ts +3 -1
  119. package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  120. package/dist/components/index.d.ts +2 -2
  121. package/dist/components/loaders/RuiSkeletonLoader.js.map +1 -1
  122. package/dist/components/loaders/RuiSkeletonLoader.vue.d.ts +3 -1
  123. package/dist/components/loaders/RuiSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  124. package/dist/components/logos/RuiLogo.js.map +1 -1
  125. package/dist/components/logos/RuiLogo.vue.d.ts +3 -1
  126. package/dist/components/logos/RuiLogo.vue_vue_type_script_setup_true_lang.js.map +1 -1
  127. package/dist/components/overlays/badge/RuiBadge.js.map +1 -1
  128. package/dist/components/overlays/badge/RuiBadge.vue.d.ts +3 -1
  129. package/dist/components/overlays/badge/RuiBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
  130. package/dist/components/overlays/bottom-sheet/RuiBottomSheet.js.map +1 -1
  131. package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue.d.ts +11 -5
  132. package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue_vue_type_script_setup_true_lang.js +6 -7
  133. package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue_vue_type_script_setup_true_lang.js.map +1 -1
  134. package/dist/components/overlays/dialog/RuiDialog.js.map +1 -1
  135. package/dist/components/overlays/dialog/RuiDialog.vue.d.ts +5 -3
  136. package/dist/components/overlays/dialog/RuiDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  137. package/dist/components/overlays/menu/RuiMenu.js.map +1 -1
  138. package/dist/components/overlays/menu/RuiMenu.vue.d.ts +2 -1
  139. package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  140. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.js.map +1 -1
  141. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue.d.ts +2 -1
  142. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  143. package/dist/components/overlays/notification/RuiNotification.js.map +1 -1
  144. package/dist/components/overlays/notification/RuiNotification.vue.d.ts +2 -1
  145. package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js.map +1 -1
  146. package/dist/components/overlays/tooltip/RuiTooltip.js.map +1 -1
  147. package/dist/components/overlays/tooltip/RuiTooltip.vue.d.ts +4 -2
  148. package/dist/components/overlays/tooltip/RuiTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  149. package/dist/components/progress/RuiProgress.js.map +1 -1
  150. package/dist/components/progress/RuiProgress.vue.d.ts +3 -1
  151. package/dist/components/progress/RuiProgress.vue_vue_type_script_setup_true_lang.js.map +1 -1
  152. package/dist/components/steppers/RuiFooterStepper.js.map +1 -1
  153. package/dist/components/steppers/RuiFooterStepper.vue.d.ts +2 -1
  154. package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  155. package/dist/components/steppers/RuiStepper.js.map +1 -1
  156. package/dist/components/steppers/RuiStepper.vue.d.ts +3 -1
  157. package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  158. package/dist/components/tables/RuiDataTable.js.map +1 -1
  159. package/dist/components/tables/RuiDataTable.vue.d.ts +14 -19
  160. package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js +25 -29
  161. package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  162. package/dist/components/tables/RuiExpandButton.js.map +1 -1
  163. package/dist/components/tables/RuiExpandButton.vue.d.ts +3 -1
  164. package/dist/components/tables/RuiExpandButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  165. package/dist/components/tables/RuiTable.js.map +1 -1
  166. package/dist/components/tables/RuiTable.vue.d.ts +4 -2
  167. package/dist/components/tables/RuiTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  168. package/dist/components/tables/RuiTableEmptyState.js.map +1 -1
  169. package/dist/components/tables/RuiTableEmptyState.vue.d.ts +3 -1
  170. package/dist/components/tables/RuiTableEmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
  171. package/dist/components/tables/RuiTableErrorState.js.map +1 -1
  172. package/dist/components/tables/RuiTableErrorState.vue.d.ts +4 -2
  173. package/dist/components/tables/RuiTableErrorState.vue_vue_type_script_setup_true_lang.js.map +1 -1
  174. package/dist/components/tables/RuiTableHead.js.map +1 -1
  175. package/dist/components/tables/RuiTableHead.vue.d.ts +3 -2
  176. package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js +3 -3
  177. package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js.map +1 -1
  178. package/dist/components/tables/RuiTableLoadingState.js.map +1 -1
  179. package/dist/components/tables/RuiTableLoadingState.vue.d.ts +3 -1
  180. package/dist/components/tables/RuiTableLoadingState.vue_vue_type_script_setup_true_lang.js.map +1 -1
  181. package/dist/components/tables/RuiTablePagination.js.map +1 -1
  182. package/dist/components/tables/RuiTablePagination.vue.d.ts +2 -1
  183. package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  184. package/dist/components/tables/data-table/RuiDataTableCell.js.map +1 -1
  185. package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js +2 -4
  186. package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  187. package/dist/components/tables/data-table/RuiDataTableMobileSort.js.map +1 -1
  188. package/dist/components/tables/data-table/RuiDataTableMobileSort.vue.d.ts +1 -1
  189. package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js +2 -3
  190. package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js.map +1 -1
  191. package/dist/components/tables/data-table/context.d.ts +6 -6
  192. package/dist/components/tables/data-table/context.js +1 -1
  193. package/dist/components/tables/data-table/context.js.map +1 -1
  194. package/dist/components/tables/table-props.d.ts +9 -0
  195. package/dist/components/tables/table-props.js +13 -1
  196. package/dist/components/tables/table-props.js.map +1 -1
  197. package/dist/components/tabs/tab/RuiTab.js.map +1 -1
  198. package/dist/components/tabs/tab/RuiTab.vue.d.ts +4 -2
  199. package/dist/components/tabs/tab/RuiTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
  200. package/dist/components/tabs/tab-item/RuiTabItem.js.map +1 -1
  201. package/dist/components/tabs/tab-item/RuiTabItem.vue.d.ts +3 -1
  202. package/dist/components/tabs/tab-item/RuiTabItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  203. package/dist/components/tabs/tab-items/RuiTabItems.js.map +1 -1
  204. package/dist/components/tabs/tab-items/RuiTabItems.vue.d.ts +5 -12
  205. package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js +8 -14
  206. package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js.map +1 -1
  207. package/dist/components/tabs/tabs/RuiTabs.js.map +1 -1
  208. package/dist/components/tabs/tabs/RuiTabs.vue.d.ts +26 -14
  209. package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js +11 -13
  210. package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  211. package/dist/components/time-picker/RuiTimePicker.js.map +1 -1
  212. package/dist/components/time-picker/RuiTimePicker.vue.d.ts +2 -1
  213. package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  214. package/dist/composables/dropdown-menu.js.map +1 -1
  215. package/dist/composables/forms/auto-complete/search.js.map +1 -1
  216. package/dist/composables/forms/auto-complete/value.d.ts +1 -1
  217. package/dist/composables/forms/auto-complete/value.js.map +1 -1
  218. package/dist/composables/prop-model.d.ts +21 -0
  219. package/dist/composables/prop-model.js +33 -0
  220. package/dist/composables/prop-model.js.map +1 -0
  221. package/dist/composables/tables/data-table/columns.d.ts +2 -1
  222. package/dist/composables/tables/data-table/columns.js.map +1 -1
  223. package/dist/composables/tables/data-table/types.d.ts +35 -0
  224. package/dist/composables/tables/data-table/types.js.map +1 -1
  225. package/dist/composables/use-rui-i18n.d.ts +6 -3
  226. package/dist/composables/use-rui-i18n.js +1 -1
  227. package/dist/composables/use-rui-i18n.js.map +1 -1
  228. package/dist/index.d.ts +7 -1
  229. package/dist/index.js +14 -6
  230. package/dist/index.js.map +1 -1
  231. package/dist/types/attributes.d.ts +9 -0
  232. package/dist/utils/blockie.js +10 -9
  233. package/dist/utils/blockie.js.map +1 -1
  234. package/dist/web-types.json +280 -110
  235. package/package.json +3 -3
@@ -1,3 +1,4 @@
1
+ import type { HTMLAttributes } from 'vue';
1
2
  import type { RouteLocationRaw } from 'vue-router';
2
3
  import type { ContextColorsType } from '../../../consts/colors.js';
3
4
  import type { VueClassValue } from '../../../types/class-value.js';
@@ -22,14 +23,15 @@ export interface Props {
22
23
  indicatorPosition?: TabIndicatorPosition;
23
24
  variant?: TabVariant;
24
25
  }
26
+ type __VLS_Props = Props & /* @vue-ignore */ Omit<HTMLAttributes, keyof Props | 'onClick'>;
25
27
  type __VLS_Slots = {
26
28
  default?: (props?: object) => any;
27
29
  prepend?: (props?: object) => any;
28
30
  append?: (props?: object) => any;
29
31
  };
30
- declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
32
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
31
33
  click: (value: string | number) => any;
32
- }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
34
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
33
35
  onClick?: ((value: string | number) => any) | undefined;
34
36
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
35
37
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -1 +1 @@
1
- {"version":3,"file":"RuiTab.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_useSlots","_openBlock","_createBlock","_resolveDynamicComponent","_unref","_mergeProps","_withCtx","_createElementVNode","_normalizeClass","_renderSlot","_createCommentVNode"],"sources":["../../../../src/components/tabs/tab/RuiTab.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { RouteLocationRaw } from 'vue-router';\nimport type { ContextColorsType } from '@/consts/colors';\nimport type { VueClassValue } from '@/types/class-value';\nimport { TabAlignment, TabIndicatorPosition, TabLayout, TabVariant } from '@/components/tabs/tab-props';\nimport { useTabLink } from '@/components/tabs/tab/use-tab-link';\nimport { cn } from '@/utils/tv';\nimport { tabStyles } from './tab-styles';\n\nexport interface RuiTabClassNames {\n root?: VueClassValue;\n active?: VueClassValue;\n}\n\nexport interface Props {\n color?: ContextColorsType;\n disabled?: boolean;\n grow?: boolean;\n value?: number | string;\n active?: boolean;\n classNames?: RuiTabClassNames;\n link?: boolean;\n target?: string;\n to?: RouteLocationRaw;\n exact?: boolean;\n vertical?: boolean;\n align?: TabAlignment;\n indicatorPosition?: TabIndicatorPosition;\n variant?: TabVariant;\n}\n\ndefineOptions({\n name: 'RuiTab',\n inheritAttrs: false,\n});\n\nconst {\n color,\n disabled = false,\n grow = false,\n value = useId(),\n active = false,\n classNames,\n link = false,\n to = '',\n target = '_self',\n exact = false,\n vertical = false,\n align = TabAlignment.center,\n indicatorPosition = TabIndicatorPosition.end,\n variant = TabVariant.underline,\n} = defineProps<Props>();\n\nconst emit = defineEmits<{\n click: [value: string | number];\n}>();\n\nconst slots = defineSlots<{\n default?: (props?: object) => any;\n prepend?: (props?: object) => any;\n append?: (props?: object) => any;\n}>();\n\nconst { isRouteActive, href: linkHref, navigate, isLink } = useTabLink({\n link: () => link,\n to: () => to,\n exact: () => exact,\n});\n\nconst layout = computed<TabLayout>(() => vertical ? TabLayout.vertical : TabLayout.horizontal);\nconst isSelf = computed<boolean>(() => target === '_self');\nconst isEffectivelyActive = computed<boolean>(() => active || get(isRouteActive));\nconst ui = computed<ReturnType<typeof tabStyles>>(() => tabStyles({\n variant,\n layout: get(layout),\n align,\n grow,\n disabled,\n active: get(isEffectivelyActive),\n}));\n\nfunction onClick(event: MouseEvent): void {\n if (disabled) {\n event.preventDefault();\n return;\n }\n\n emit('click', value);\n if (navigate && get(isSelf))\n navigate(event);\n}\n</script>\n\n<template>\n <component\n :is=\"isLink ? 'a' : 'button'\"\n :type=\"isLink ? undefined : 'button'\"\n :class=\"[\n ui.root({ class: cn(classNames?.root) }),\n isEffectivelyActive && classNames?.active,\n ]\"\n :data-active-tab=\"isEffectivelyActive || undefined\"\n :data-align=\"align\"\n :data-indicator-position=\"indicatorPosition\"\n :data-vertical=\"vertical || undefined\"\n :data-variant=\"variant\"\n :data-color=\"isEffectivelyActive ? color : undefined\"\n :disabled=\"isLink ? undefined : disabled\"\n :aria-disabled=\"isLink && disabled ? 'true' : undefined\"\n :href=\"isLink && !isSelf && !disabled ? linkHref : undefined\"\n :target=\"isLink ? target : undefined\"\n role=\"tab\"\n :aria-selected=\"isEffectivelyActive\"\n :tabindex=\"isEffectivelyActive && !disabled ? 0 : -1\"\n v-bind=\"$attrs\"\n @click=\"onClick($event)\"\n >\n <span :class=\"ui.content()\">\n <slot\n v-if=\"slots.prepend\"\n name=\"prepend\"\n />\n <slot />\n <slot\n v-if=\"slots.append\"\n name=\"append\"\n />\n </span>\n </component>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqDA,MAAM,OAAO;EAIb,MAAM,QAAQC,SAAA;EAMd,MAAM,EAAE,eAAe,MAAM,UAAU,UAAU,WAAW,WAAW;GACrE,YAAY,QAAA;GACZ,UAAU,QAAA;GACV,aAAa,QAAA;EACf,CAAC;EAED,MAAM,SAAS,eAA0B,QAAA,WAAW,UAAU,WAAW,UAAU,UAAU;EAC7F,MAAM,SAAS,eAAwB,QAAA,WAAW,OAAO;EACzD,MAAM,sBAAsB,eAAwB,QAAA,UAAU,IAAI,aAAa,CAAC;EAChF,MAAM,KAAK,eAA6C,UAAU;GAChE,SAAM,QAAA;GACN,QAAQ,IAAI,MAAM;GAClB,OAAI,QAAA;GACJ,MAAG,QAAA;GACH,UAAO,QAAA;GACP,QAAQ,IAAI,mBAAmB;EACjC,CAAC,CAAC;EAEF,SAAS,QAAQ,OAAyB;GACxC,IAAI,QAAA,UAAU;IACZ,MAAM,eAAe;IACrB;GACF;GAEA,KAAK,SAAS,QAAA,KAAK;GACnB,IAAI,YAAY,IAAI,MAAM,GACxB,SAAS,KAAK;EAClB;;GAIE,OAAAC,UAAA,GAAAC,YAkCYC,wBAjCLC,MAAA,MAAA,IAAM,MAAA,QAAA,GADbC,WAkCY;IAhCT,MAAMD,MAAA,MAAA,IAAS,KAAA,IAAS;IACxB,OAAK,CAAUA,MAAA,EAAA,CAAE,CAAC,KAAI,EAAA,OAAUA,MAAA,EAAA,CAAE,CAAC,QAAA,YAAY,IAAI,EAAA,CAAA,GAAYA,MAAA,mBAAA,KAAuB,QAAA,YAAY,MAAA;IAIlG,mBAAiBA,MAAA,mBAAA,KAAuB,KAAA;IACxC,cAAY,QAAA;IACZ,2BAAyB,QAAA;IACzB,iBAAe,QAAA,YAAY,KAAA;IAC3B,gBAAc,QAAA;IACd,cAAYA,MAAA,mBAAA,IAAsB,QAAA,QAAQ,KAAA;IAC1C,UAAUA,MAAA,MAAA,IAAS,KAAA,IAAY,QAAA;IAC/B,iBAAeA,MAAA,MAAA,KAAU,QAAA,WAAQ,SAAY,KAAA;IAC7C,MAAMA,MAAA,MAAA,KAAM,CAAKA,MAAA,MAAA,KAAM,CAAK,QAAA,WAAWA,MAAA,QAAA,IAAW,KAAA;IAClD,QAAQA,MAAA,MAAA,IAAS,QAAA,SAAS,KAAA;IAC3B,MAAK;IACJ,iBAAeA,MAAA,mBAAA;IACf,UAAUA,MAAA,mBAAA,KAAmB,CAAK,QAAA,WAAQ,IAAA;GACnCL,GAAAA,KAAAA,QAAM,EACb,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,QAAQ,MAAM,GAAA,CAAA,GAAA;IAEtB,SAAAO,cAUO,CAVPC,mBAUO,QAAA,EAVA,OAAKC,eAAEJ,MAAA,EAAA,CAAE,CAAC,QAAO,CAAA,EAAA,GAAA;KAEd,MAAM,UADdK,WAGE,KAAA,QAAA,WAAA,CAAA,GAAA,KAAA,GAAA,KAAA,GAAA,CAAA,IAAA,mBAAA,IAAA,IAAA;KACFA,WAAQ,KAAA,QAAA,SAAA;KAEA,MAAM,SADdA,WAGE,KAAA,QAAA,UAAA,CAAA,GAAA,KAAA,GAAA,KAAA,GAAA,CAAA,IAAA,mBAAA,IAAA,IAAA"}
1
+ {"version":3,"file":"RuiTab.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_useSlots","_openBlock","_createBlock","_resolveDynamicComponent","_unref","_mergeProps","_withCtx","_createElementVNode","_normalizeClass","_renderSlot","_createCommentVNode"],"sources":["../../../../src/components/tabs/tab/RuiTab.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue';\nimport type { RouteLocationRaw } from 'vue-router';\nimport type { ContextColorsType } from '@/consts/colors';\nimport type { VueClassValue } from '@/types/class-value';\nimport { TabAlignment, TabIndicatorPosition, TabLayout, TabVariant } from '@/components/tabs/tab-props';\nimport { useTabLink } from '@/components/tabs/tab/use-tab-link';\nimport { cn } from '@/utils/tv';\nimport { tabStyles } from './tab-styles';\n\nexport interface RuiTabClassNames {\n root?: VueClassValue;\n active?: VueClassValue;\n}\n\nexport interface Props {\n color?: ContextColorsType;\n disabled?: boolean;\n grow?: boolean;\n value?: number | string;\n active?: boolean;\n classNames?: RuiTabClassNames;\n link?: boolean;\n target?: string;\n to?: RouteLocationRaw;\n exact?: boolean;\n vertical?: boolean;\n align?: TabAlignment;\n indicatorPosition?: TabIndicatorPosition;\n variant?: TabVariant;\n}\n\ndefineOptions({\n name: 'RuiTab',\n inheritAttrs: false,\n});\n\nconst {\n color,\n disabled = false,\n grow = false,\n value = useId(),\n active = false,\n classNames,\n link = false,\n to = '',\n target = '_self',\n exact = false,\n vertical = false,\n align = TabAlignment.center,\n indicatorPosition = TabIndicatorPosition.end,\n variant = TabVariant.underline,\n} = defineProps<Props & /* @vue-ignore */ Omit<HTMLAttributes, keyof Props | 'onClick'>>();\n\nconst emit = defineEmits<{\n click: [value: string | number];\n}>();\n\nconst slots = defineSlots<{\n default?: (props?: object) => any;\n prepend?: (props?: object) => any;\n append?: (props?: object) => any;\n}>();\n\nconst { isRouteActive, href: linkHref, navigate, isLink } = useTabLink({\n link: () => link,\n to: () => to,\n exact: () => exact,\n});\n\nconst layout = computed<TabLayout>(() => vertical ? TabLayout.vertical : TabLayout.horizontal);\nconst isSelf = computed<boolean>(() => target === '_self');\nconst isEffectivelyActive = computed<boolean>(() => active || get(isRouteActive));\nconst ui = computed<ReturnType<typeof tabStyles>>(() => tabStyles({\n variant,\n layout: get(layout),\n align,\n grow,\n disabled,\n active: get(isEffectivelyActive),\n}));\n\nfunction onClick(event: MouseEvent): void {\n if (disabled) {\n event.preventDefault();\n return;\n }\n\n emit('click', value);\n if (navigate && get(isSelf))\n navigate(event);\n}\n</script>\n\n<template>\n <component\n :is=\"isLink ? 'a' : 'button'\"\n :type=\"isLink ? undefined : 'button'\"\n :class=\"[\n ui.root({ class: cn(classNames?.root) }),\n isEffectivelyActive && classNames?.active,\n ]\"\n :data-active-tab=\"isEffectivelyActive || undefined\"\n :data-align=\"align\"\n :data-indicator-position=\"indicatorPosition\"\n :data-vertical=\"vertical || undefined\"\n :data-variant=\"variant\"\n :data-color=\"isEffectivelyActive ? color : undefined\"\n :disabled=\"isLink ? undefined : disabled\"\n :aria-disabled=\"isLink && disabled ? 'true' : undefined\"\n :href=\"isLink && !isSelf && !disabled ? linkHref : undefined\"\n :target=\"isLink ? target : undefined\"\n role=\"tab\"\n :aria-selected=\"isEffectivelyActive\"\n :tabindex=\"isEffectivelyActive && !disabled ? 0 : -1\"\n v-bind=\"$attrs\"\n @click=\"onClick($event)\"\n >\n <span :class=\"ui.content()\">\n <slot\n v-if=\"slots.prepend\"\n name=\"prepend\"\n />\n <slot />\n <slot\n v-if=\"slots.append\"\n name=\"append\"\n />\n </span>\n </component>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsDA,MAAM,OAAO;EAIb,MAAM,QAAQC,SAAA;EAMd,MAAM,EAAE,eAAe,MAAM,UAAU,UAAU,WAAW,WAAW;GACrE,YAAY,QAAA;GACZ,UAAU,QAAA;GACV,aAAa,QAAA;EACf,CAAC;EAED,MAAM,SAAS,eAA0B,QAAA,WAAW,UAAU,WAAW,UAAU,UAAU;EAC7F,MAAM,SAAS,eAAwB,QAAA,WAAW,OAAO;EACzD,MAAM,sBAAsB,eAAwB,QAAA,UAAU,IAAI,aAAa,CAAC;EAChF,MAAM,KAAK,eAA6C,UAAU;GAChE,SAAM,QAAA;GACN,QAAQ,IAAI,MAAM;GAClB,OAAI,QAAA;GACJ,MAAG,QAAA;GACH,UAAO,QAAA;GACP,QAAQ,IAAI,mBAAmB;EACjC,CAAC,CAAC;EAEF,SAAS,QAAQ,OAAyB;GACxC,IAAI,QAAA,UAAU;IACZ,MAAM,eAAe;IACrB;GACF;GAEA,KAAK,SAAS,QAAA,KAAK;GACnB,IAAI,YAAY,IAAI,MAAM,GACxB,SAAS,KAAK;EAClB;;GAIE,OAAAC,UAAA,GAAAC,YAkCYC,wBAjCLC,MAAA,MAAA,IAAM,MAAA,QAAA,GADbC,WAkCY;IAhCT,MAAMD,MAAA,MAAA,IAAS,KAAA,IAAS;IACxB,OAAK,CAAUA,MAAA,EAAA,CAAE,CAAC,KAAI,EAAA,OAAUA,MAAA,EAAA,CAAE,CAAC,QAAA,YAAY,IAAI,EAAA,CAAA,GAAYA,MAAA,mBAAA,KAAuB,QAAA,YAAY,MAAA;IAIlG,mBAAiBA,MAAA,mBAAA,KAAuB,KAAA;IACxC,cAAY,QAAA;IACZ,2BAAyB,QAAA;IACzB,iBAAe,QAAA,YAAY,KAAA;IAC3B,gBAAc,QAAA;IACd,cAAYA,MAAA,mBAAA,IAAsB,QAAA,QAAQ,KAAA;IAC1C,UAAUA,MAAA,MAAA,IAAS,KAAA,IAAY,QAAA;IAC/B,iBAAeA,MAAA,MAAA,KAAU,QAAA,WAAQ,SAAY,KAAA;IAC7C,MAAMA,MAAA,MAAA,KAAM,CAAKA,MAAA,MAAA,KAAM,CAAK,QAAA,WAAWA,MAAA,QAAA,IAAW,KAAA;IAClD,QAAQA,MAAA,MAAA,IAAS,QAAA,SAAS,KAAA;IAC3B,MAAK;IACJ,iBAAeA,MAAA,mBAAA;IACf,UAAUA,MAAA,mBAAA,KAAmB,CAAK,QAAA,WAAQ,IAAA;GACnCL,GAAAA,KAAAA,QAAM,EACb,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,QAAQ,MAAM,GAAA,CAAA,GAAA;IAEtB,SAAAO,cAUO,CAVPC,mBAUO,QAAA,EAVA,OAAKC,eAAEJ,MAAA,EAAA,CAAE,CAAC,QAAO,CAAA,EAAA,GAAA;KAEd,MAAM,UADdK,WAGE,KAAA,QAAA,WAAA,CAAA,GAAA,KAAA,GAAA,KAAA,GAAA,CAAA,IAAA,mBAAA,IAAA,IAAA;KACFA,WAAQ,KAAA,QAAA,SAAA;KAEA,MAAM,SADdA,WAGE,KAAA,QAAA,UAAA,CAAA,GAAA,KAAA,GAAA,KAAA,GAAA,CAAA,IAAA,mBAAA,IAAA,IAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiTabItem.js","names":["_sfc_main"],"sources":["../../../../src/components/tabs/tab-item/RuiTabItem.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nexport interface Props {\n active?: boolean;\n value?: number | string;\n eager?: boolean;\n}\n\ndefineOptions({\n name: 'RuiTabItem',\n});\n\nconst { active = false, value, eager = false } = defineProps<Props>();\n\ndefineSlots<{\n default?: () => any;\n}>();\n</script>\n\n<template>\n <div\n role=\"tabpanel\"\n class=\"w-full\"\n :data-value=\"value\"\n :data-active=\"active || undefined\"\n >\n <!-- the new panel fades in while the old one collapses at once, rather than Material's sideways swipe -->\n <Transition\n enter-from-class=\"opacity-0\"\n enter-active-class=\"w-full transition-opacity duration-150 ease-out motion-reduce:transition-none\"\n enter-to-class=\"opacity-100\"\n leave-active-class=\"w-full h-0! overflow-hidden\"\n >\n <div\n v-if=\"active\"\n class=\"w-full\"\n >\n <slot />\n </div>\n </Transition>\n <div\n v-if=\"eager && !active\"\n class=\"hidden\"\n >\n <slot />\n </div>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiTabItem.js","names":["_sfc_main"],"sources":["../../../../src/components/tabs/tab-item/RuiTabItem.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue';\n\nexport interface Props {\n active?: boolean;\n value?: number | string;\n eager?: boolean;\n}\n\ndefineOptions({\n name: 'RuiTabItem',\n});\n\nconst { active = false, value, eager = false } = defineProps<Props & /* @vue-ignore */ Omit<HTMLAttributes, keyof Props>>();\n\ndefineSlots<{\n default?: () => any;\n}>();\n</script>\n\n<template>\n <div\n role=\"tabpanel\"\n class=\"w-full\"\n :data-value=\"value\"\n :data-active=\"active || undefined\"\n >\n <!-- the new panel fades in while the old one collapses at once, rather than Material's sideways swipe -->\n <Transition\n enter-from-class=\"opacity-0\"\n enter-active-class=\"w-full transition-opacity duration-150 ease-out motion-reduce:transition-none\"\n enter-to-class=\"opacity-100\"\n leave-active-class=\"w-full h-0! overflow-hidden\"\n >\n <div\n v-if=\"active\"\n class=\"w-full\"\n >\n <slot />\n </div>\n </Transition>\n <div\n v-if=\"eager && !active\"\n class=\"hidden\"\n >\n <slot />\n </div>\n </div>\n</template>\n"],"mappings":""}
@@ -1,12 +1,14 @@
1
+ import type { HTMLAttributes } from 'vue';
1
2
  export interface Props {
2
3
  active?: boolean;
3
4
  value?: number | string;
4
5
  eager?: boolean;
5
6
  }
7
+ type __VLS_Props = Props & /* @vue-ignore */ Omit<HTMLAttributes, keyof Props>;
6
8
  type __VLS_Slots = {
7
9
  default?: () => any;
8
10
  };
9
- declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
11
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
10
12
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
11
13
  declare const _default: typeof __VLS_export;
12
14
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"RuiTabItem.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_createVNode","_Transition","_withCtx","_renderSlot","_createCommentVNode"],"sources":["../../../../src/components/tabs/tab-item/RuiTabItem.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nexport interface Props {\n active?: boolean;\n value?: number | string;\n eager?: boolean;\n}\n\ndefineOptions({\n name: 'RuiTabItem',\n});\n\nconst { active = false, value, eager = false } = defineProps<Props>();\n\ndefineSlots<{\n default?: () => any;\n}>();\n</script>\n\n<template>\n <div\n role=\"tabpanel\"\n class=\"w-full\"\n :data-value=\"value\"\n :data-active=\"active || undefined\"\n >\n <!-- the new panel fades in while the old one collapses at once, rather than Material's sideways swipe -->\n <Transition\n enter-from-class=\"opacity-0\"\n enter-active-class=\"w-full transition-opacity duration-150 ease-out motion-reduce:transition-none\"\n enter-to-class=\"opacity-100\"\n leave-active-class=\"w-full h-0! overflow-hidden\"\n >\n <div\n v-if=\"active\"\n class=\"w-full\"\n >\n <slot />\n </div>\n </Transition>\n <div\n v-if=\"eager && !active\"\n class=\"hidden\"\n >\n <slot />\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;GAmBE,OAAAA,UAAA,GAAAC,mBA0BM,OAAA;IAzBJ,MAAK;IACL,OAAM;IACL,cAAY,QAAA;IACZ,eAAa,QAAA,UAAU,KAAA;GAGxBC,GAAAA,CAAAA,YAYaC,YAAA;IAXX,oBAAiB;IACjB,sBAAmB;IACnB,kBAAe;IACf,sBAAmB;;IAEnB,SAAAC,cAKM,CAJE,QAAA,UADRJ,UAAA,GAAAC,mBAKM,OALN,YAKM,CADJI,WAAQ,KAAA,QAAA,SAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,CAAA;;GAIJ,CAAA,GAAA,QAAA,SAAK,CAAK,QAAA,UADlBL,UAAA,GAAAC,mBAKM,OALN,YAKM,CADJI,WAAQ,KAAA,QAAA,SAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,GAAA,UAAA"}
1
+ {"version":3,"file":"RuiTabItem.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_createVNode","_Transition","_withCtx","_renderSlot","_createCommentVNode"],"sources":["../../../../src/components/tabs/tab-item/RuiTabItem.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue';\n\nexport interface Props {\n active?: boolean;\n value?: number | string;\n eager?: boolean;\n}\n\ndefineOptions({\n name: 'RuiTabItem',\n});\n\nconst { active = false, value, eager = false } = defineProps<Props & /* @vue-ignore */ Omit<HTMLAttributes, keyof Props>>();\n\ndefineSlots<{\n default?: () => any;\n}>();\n</script>\n\n<template>\n <div\n role=\"tabpanel\"\n class=\"w-full\"\n :data-value=\"value\"\n :data-active=\"active || undefined\"\n >\n <!-- the new panel fades in while the old one collapses at once, rather than Material's sideways swipe -->\n <Transition\n enter-from-class=\"opacity-0\"\n enter-active-class=\"w-full transition-opacity duration-150 ease-out motion-reduce:transition-none\"\n enter-to-class=\"opacity-100\"\n leave-active-class=\"w-full h-0! overflow-hidden\"\n >\n <div\n v-if=\"active\"\n class=\"w-full\"\n >\n <slot />\n </div>\n </Transition>\n <div\n v-if=\"eager && !active\"\n class=\"hidden\"\n >\n <slot />\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;GAqBE,OAAAA,UAAA,GAAAC,mBA0BM,OAAA;IAzBJ,MAAK;IACL,OAAM;IACL,cAAY,QAAA;IACZ,eAAa,QAAA,UAAU,KAAA;GAGxBC,GAAAA,CAAAA,YAYaC,YAAA;IAXX,oBAAiB;IACjB,sBAAmB;IACnB,kBAAe;IACf,sBAAmB;;IAEnB,SAAAC,cAKM,CAJE,QAAA,UADRJ,UAAA,GAAAC,mBAKM,OALN,YAKM,CADJI,WAAQ,KAAA,QAAA,SAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,CAAA;;GAIJ,CAAA,GAAA,QAAA,SAAK,CAAK,QAAA,UADlBL,UAAA,GAAAC,mBAKM,OALN,YAKM,CADJI,WAAQ,KAAA,QAAA,SAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,GAAA,UAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiTabItems.js","names":["_sfc_main"],"sources":["../../../../src/components/tabs/tab-items/RuiTabItems.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"T extends string | number\">\nimport { Fragment, isVNode } from 'vue';\nimport { useClipWhileResizing } from '@/composables/clip-while-resizing';\n\ndefineOptions({\n name: 'RuiTabItems',\n inheritAttrs: false,\n});\n\n/**\n * The tab whose panel is showing.\n *\n * The default matches RuiTabs. Without one, binding both components to the\n * same ref that starts as `undefined` leaves this component with\n * `modelValue === undefined`, so the `active = modelValue === value` check\n * fails for every tab: the panel renders but stays at height 0, which reads as\n * an element with no content.\n */\nconst modelValue = defineModel<T>({ default: () => 0 as T });\n\nconst slots = useSlots();\n\nconst currIndex = ref<number>(-1);\nconst activeIndex = ref<number>(-1);\nconst inner = useTemplateRef<HTMLDivElement>('inner');\nconst root = useTemplateRef<HTMLDivElement>('root');\n\nconst { height: innerHeight } = useElementSize(inner);\n\n// clip only while the height follows a panel change, so sticky content inside a panel works\nconst clipped = useClipWhileResizing(root, () => get(innerHeight));\n\nconst children = computed<VNode[]>(() => {\n const slotContent = slots.default?.() ?? [];\n\n const tabs = getChildrenTabs(slotContent);\n\n let anyActive = false;\n const children = tabs.map((tab, index) => {\n const value = tab.props?.value ?? index;\n const active = get(modelValue) === value;\n if (active) {\n anyActive = true;\n if (index !== get(currIndex))\n set(currIndex, index);\n }\n\n return {\n ...tab,\n props: {\n value,\n ...tab.props,\n },\n };\n });\n\n if (!anyActive)\n set(currIndex, -1);\n\n return children;\n});\n\n/**\n * Unwraps the fragments a `v-for` in the slot produces, so only tab items come\n * back.\n *\n * @param children - the slot's vnodes\n * @returns the tab items among them\n */\nfunction getChildrenTabs(children: VNode[]): VNode[] {\n return children\n .flatMap((item) => {\n if (item.type === Fragment && Array.isArray(item.children) && item.children.length > 0)\n return getChildrenTabs(item.children.filter(isVNode));\n\n return [item];\n })\n .flat();\n}\n\nwatch(currIndex, (index) => {\n nextTick(() => {\n set(activeIndex, index);\n });\n});\n</script>\n\n<template>\n <div\n ref=\"root\"\n class=\"grow transition-[height] duration-200 ease-out motion-reduce:transition-none\"\n :class=\"{ 'overflow-hidden': clipped }\"\n :data-clipped=\"clipped || undefined\"\n :style=\"{ height: `${innerHeight}px` }\"\n v-bind=\"$attrs\"\n >\n <div ref=\"inner\">\n <Component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n :active=\"i === activeIndex\"\n />\n </div>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiTabItems.js","names":["_sfc_main"],"sources":["../../../../src/components/tabs/tab-items/RuiTabItems.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"T extends string | number\">\nimport type { ModelValueEmits } from '@/composables/prop-model';\nimport { Fragment, type HTMLAttributes, isVNode } from 'vue';\nimport { useClipWhileResizing } from '@/composables/clip-while-resizing';\n\ndefineOptions({\n name: 'RuiTabItems',\n inheritAttrs: false,\n});\n\nconst { modelValue } = defineProps<{\n /** The tab whose panel is showing. */\n modelValue?: T;\n} & /* @vue-ignore */ HTMLAttributes>();\n\n/*\n * Declared so `v-model` binds the same ref RuiTabs updates. The panels only follow the model,\n * so the component never emits it.\n */\ndefineEmits<ModelValueEmits<T>>();\n\n/**\n * The selected tab, the first one while the model is unbound or undefined, as in RuiTabs.\n * Without that fallback, binding both components to a ref that starts as `undefined` fails the\n * `active` check for every tab: the panel renders but stays at height 0, which reads as an\n * element with no content.\n */\nconst selected = computed<string | number>(() => modelValue ?? 0);\n\nconst slots = useSlots();\n\nconst currIndex = ref<number>(-1);\nconst activeIndex = ref<number>(-1);\nconst inner = useTemplateRef<HTMLDivElement>('inner');\nconst root = useTemplateRef<HTMLDivElement>('root');\n\nconst { height: innerHeight } = useElementSize(inner);\n\n// clip only while the height follows a panel change, so sticky content inside a panel works\nconst clipped = useClipWhileResizing(root, () => get(innerHeight));\n\nconst children = computed<VNode[]>(() => {\n const slotContent = slots.default?.() ?? [];\n\n const tabs = getChildrenTabs(slotContent);\n\n let anyActive = false;\n const children = tabs.map((tab, index) => {\n const value = tab.props?.value ?? index;\n const active = get(selected) === value;\n if (active) {\n anyActive = true;\n if (index !== get(currIndex))\n set(currIndex, index);\n }\n\n return {\n ...tab,\n props: {\n value,\n ...tab.props,\n },\n };\n });\n\n if (!anyActive)\n set(currIndex, -1);\n\n return children;\n});\n\n/**\n * Unwraps the fragments a `v-for` in the slot produces, so only tab items come\n * back.\n *\n * @param children - the slot's vnodes\n * @returns the tab items among them\n */\nfunction getChildrenTabs(children: VNode[]): VNode[] {\n return children\n .flatMap((item) => {\n if (item.type === Fragment && Array.isArray(item.children) && item.children.length > 0)\n return getChildrenTabs(item.children.filter(isVNode));\n\n return [item];\n })\n .flat();\n}\n\nwatch(currIndex, (index) => {\n nextTick(() => {\n set(activeIndex, index);\n });\n});\n</script>\n\n<template>\n <div\n ref=\"root\"\n class=\"grow transition-[height] duration-200 ease-out motion-reduce:transition-none\"\n :class=\"{ 'overflow-hidden': clipped }\"\n :data-clipped=\"clipped || undefined\"\n :style=\"{ height: `${innerHeight}px` }\"\n v-bind=\"$attrs\"\n >\n <div ref=\"inner\">\n <component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n :active=\"i === activeIndex\"\n />\n </div>\n </div>\n</template>\n"],"mappings":""}
@@ -1,16 +1,9 @@
1
+ import { type HTMLAttributes } from 'vue';
1
2
  declare const __VLS_export: <T extends string | number>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
2
- props: import("vue").PublicProps & __VLS_PrettifyLocal<{
3
- /**
4
- * The tab whose panel is showing.
5
- *
6
- * The default matches RuiTabs. Without one, binding both components to the
7
- * same ref that starts as `undefined` leaves this component with
8
- * `modelValue === undefined`, so the `active = modelValue === value` check
9
- * fails for every tab: the panel renders but stays at height 0, which reads as
10
- * an element with no content.
11
- */
3
+ props: import("vue").PublicProps & __VLS_PrettifyLocal<({
4
+ /** The tab whose panel is showing. */
12
5
  modelValue?: T;
13
- } & {
6
+ } & HTMLAttributes) & {
14
7
  "onUpdate:modelValue"?: ((value: T) => any) | undefined;
15
8
  }> & (typeof globalThis extends {
16
9
  __VLS_PROPS_FALLBACK: infer P;
@@ -18,7 +11,7 @@ declare const __VLS_export: <T extends string | number>(__VLS_props: NonNullable
18
11
  expose: (exposed: {}) => void;
19
12
  attrs: any;
20
13
  slots: {};
21
- emit: (event: "update:modelValue", value: T) => void;
14
+ emit: (evt: "update:modelValue", value: T) => void;
22
15
  }>) => import("vue").VNode & {
23
16
  __ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
24
17
  };
@@ -1,29 +1,23 @@
1
1
  import { get, set } from "../../../vendor/@vueuse/shared/dist/index.js";
2
2
  import { useElementSize } from "../../../vendor/@vueuse/core/dist/index.js";
3
3
  import { useClipWhileResizing } from "../../../composables/clip-while-resizing.js";
4
- import { Fragment, computed, createBlock, createElementBlock, createElementVNode, defineComponent, isVNode, mergeProps, nextTick, openBlock, ref, renderList, resolveDynamicComponent, unref, useModel, useSlots, useTemplateRef, watch } from "vue";
4
+ import { Fragment, computed, createBlock, createElementBlock, createElementVNode, defineComponent, isVNode, mergeProps, nextTick, openBlock, ref, renderList, resolveDynamicComponent, unref, useSlots, useTemplateRef, watch } from "vue";
5
5
  //#region src/components/tabs/tab-items/RuiTabItems.vue?vue&type=script&setup=true&lang.ts
6
6
  var _hoisted_1 = ["data-clipped"];
7
7
  var RuiTabItems_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
8
8
  name: "RuiTabItems",
9
9
  inheritAttrs: false,
10
10
  __name: "RuiTabItems",
11
- props: {
12
- "modelValue": { default: () => 0 },
13
- "modelModifiers": {}
14
- },
11
+ props: { modelValue: {} },
15
12
  emits: ["update:modelValue"],
16
13
  setup(__props) {
17
14
  /**
18
- * The tab whose panel is showing.
19
- *
20
- * The default matches RuiTabs. Without one, binding both components to the
21
- * same ref that starts as `undefined` leaves this component with
22
- * `modelValue === undefined`, so the `active = modelValue === value` check
23
- * fails for every tab: the panel renders but stays at height 0, which reads as
24
- * an element with no content.
15
+ * The selected tab, the first one while the model is unbound or undefined, as in RuiTabs.
16
+ * Without that fallback, binding both components to a ref that starts as `undefined` fails the
17
+ * `active` check for every tab: the panel renders but stays at height 0, which reads as an
18
+ * element with no content.
25
19
  */
26
- const modelValue = useModel(__props, "modelValue");
20
+ const selected = computed(() => __props.modelValue ?? 0);
27
21
  const slots = useSlots();
28
22
  const currIndex = ref(-1);
29
23
  const activeIndex = ref(-1);
@@ -36,7 +30,7 @@ var RuiTabItems_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defi
36
30
  let anyActive = false;
37
31
  const children = tabs.map((tab, index) => {
38
32
  const value = tab.props?.value ?? index;
39
- if (get(modelValue) === value) {
33
+ if (get(selected) === value) {
40
34
  anyActive = true;
41
35
  if (index !== get(currIndex)) set(currIndex, index);
42
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"RuiTabItems.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_useModel","_openBlock","_createElementBlock","_mergeProps","_unref","_createElementVNode","_Fragment","_renderList","_createBlock","_resolveDynamicComponent"],"sources":["../../../../src/components/tabs/tab-items/RuiTabItems.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"T extends string | number\">\nimport { Fragment, isVNode } from 'vue';\nimport { useClipWhileResizing } from '@/composables/clip-while-resizing';\n\ndefineOptions({\n name: 'RuiTabItems',\n inheritAttrs: false,\n});\n\n/**\n * The tab whose panel is showing.\n *\n * The default matches RuiTabs. Without one, binding both components to the\n * same ref that starts as `undefined` leaves this component with\n * `modelValue === undefined`, so the `active = modelValue === value` check\n * fails for every tab: the panel renders but stays at height 0, which reads as\n * an element with no content.\n */\nconst modelValue = defineModel<T>({ default: () => 0 as T });\n\nconst slots = useSlots();\n\nconst currIndex = ref<number>(-1);\nconst activeIndex = ref<number>(-1);\nconst inner = useTemplateRef<HTMLDivElement>('inner');\nconst root = useTemplateRef<HTMLDivElement>('root');\n\nconst { height: innerHeight } = useElementSize(inner);\n\n// clip only while the height follows a panel change, so sticky content inside a panel works\nconst clipped = useClipWhileResizing(root, () => get(innerHeight));\n\nconst children = computed<VNode[]>(() => {\n const slotContent = slots.default?.() ?? [];\n\n const tabs = getChildrenTabs(slotContent);\n\n let anyActive = false;\n const children = tabs.map((tab, index) => {\n const value = tab.props?.value ?? index;\n const active = get(modelValue) === value;\n if (active) {\n anyActive = true;\n if (index !== get(currIndex))\n set(currIndex, index);\n }\n\n return {\n ...tab,\n props: {\n value,\n ...tab.props,\n },\n };\n });\n\n if (!anyActive)\n set(currIndex, -1);\n\n return children;\n});\n\n/**\n * Unwraps the fragments a `v-for` in the slot produces, so only tab items come\n * back.\n *\n * @param children - the slot's vnodes\n * @returns the tab items among them\n */\nfunction getChildrenTabs(children: VNode[]): VNode[] {\n return children\n .flatMap((item) => {\n if (item.type === Fragment && Array.isArray(item.children) && item.children.length > 0)\n return getChildrenTabs(item.children.filter(isVNode));\n\n return [item];\n })\n .flat();\n}\n\nwatch(currIndex, (index) => {\n nextTick(() => {\n set(activeIndex, index);\n });\n});\n</script>\n\n<template>\n <div\n ref=\"root\"\n class=\"grow transition-[height] duration-200 ease-out motion-reduce:transition-none\"\n :class=\"{ 'overflow-hidden': clipped }\"\n :data-clipped=\"clipped || undefined\"\n :style=\"{ height: `${innerHeight}px` }\"\n v-bind=\"$attrs\"\n >\n <div ref=\"inner\">\n <Component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n :active=\"i === activeIndex\"\n />\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;EAkBA,MAAM,aAAaC,SAAc,SAAA,YAA0B;EAE3D,MAAM,QAAQ,SAAS;EAEvB,MAAM,YAAY,IAAY,EAAE;EAChC,MAAM,cAAc,IAAY,EAAE;EAClC,MAAM,QAAQ,eAA+B,OAAO;EACpD,MAAM,OAAO,eAA+B,MAAM;EAElD,MAAM,EAAE,QAAQ,gBAAgB,eAAe,KAAK;EAGpD,MAAM,UAAU,qBAAqB,YAAY,IAAI,WAAW,CAAC;EAEjE,MAAM,WAAW,eAAwB;GAGvC,MAAM,OAAO,gBAFO,MAAM,UAAU,KAAK,CAAC,CAEF;GAExC,IAAI,YAAY;GAChB,MAAM,WAAW,KAAK,KAAK,KAAK,UAAU;IACxC,MAAM,QAAQ,IAAI,OAAO,SAAS;IAElC,IADe,IAAI,UAAU,MAAM,OACvB;KACV,YAAY;KACZ,IAAI,UAAU,IAAI,SAAS,GACzB,IAAI,WAAW,KAAK;IACxB;IAEA,OAAO;KACL,GAAG;KACH,OAAO;MACL;MACA,GAAG,IAAI;KACT;IACF;GACF,CAAC;GAED,IAAI,CAAC,WACH,IAAI,WAAW,EAAE;GAEnB,OAAO;EACT,CAAC;;;;;;;;EASD,SAAS,gBAAgB,UAA4B;GACnD,OAAO,SACJ,SAAS,SAAS;IACjB,IAAI,KAAK,SAAS,YAAY,MAAM,QAAQ,KAAK,QAAQ,KAAK,KAAK,SAAS,SAAS,GACnF,OAAO,gBAAgB,KAAK,SAAS,OAAO,OAAO,CAAC;IAEtD,OAAO,CAAC,IAAI;GACd,CAAC,CAAA,CACA,KAAK;EACV;EAEA,MAAM,YAAY,UAAU;GAC1B,eAAe;IACb,IAAI,aAAa,KAAK;GACxB,CAAC;EACH,CAAC;;GAIC,OAAAC,UAAA,GAAAC,mBAgBM,OAhBNC,WAgBM;IAfA,SAAA;IAAJ,KAAI;IACJ,OAAK,CAAC,gFAA8E,EAAA,mBACvDC,MAAA,OAAA,EAAO,CAAA;IACnC,gBAAcA,MAAA,OAAA,KAAW,KAAA;IACzB,OAAK,EAAA,QAAA,GAAeA,MAAA,WAAA,EAAW,IAAA;GACxBL,GAAAA,KAAAA,MAAM,GAAA,CAEdM,mBAOM,OAAA;IAPG,SAAA;IAAJ,KAAI;GACPJ,GAAAA,EAAAA,UAAA,IAAA,GAAAC,mBAKEI,UAAA,MAAAC,WAHqBH,MAAA,QAAA,IAAb,OAAO,MAAC;IAFlB,OAAAH,UAAA,GAAAO,YAKEC,wBAJK,KAAK,GAAA;KAET,KAAK;KACL,QAAQ,MAAML,MAAA,WAAA"}
1
+ {"version":3,"file":"RuiTabItems.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_openBlock","_createElementBlock","_mergeProps","_unref","_createElementVNode","_Fragment","_renderList","_createBlock","_resolveDynamicComponent"],"sources":["../../../../src/components/tabs/tab-items/RuiTabItems.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"T extends string | number\">\nimport type { ModelValueEmits } from '@/composables/prop-model';\nimport { Fragment, type HTMLAttributes, isVNode } from 'vue';\nimport { useClipWhileResizing } from '@/composables/clip-while-resizing';\n\ndefineOptions({\n name: 'RuiTabItems',\n inheritAttrs: false,\n});\n\nconst { modelValue } = defineProps<{\n /** The tab whose panel is showing. */\n modelValue?: T;\n} & /* @vue-ignore */ HTMLAttributes>();\n\n/*\n * Declared so `v-model` binds the same ref RuiTabs updates. The panels only follow the model,\n * so the component never emits it.\n */\ndefineEmits<ModelValueEmits<T>>();\n\n/**\n * The selected tab, the first one while the model is unbound or undefined, as in RuiTabs.\n * Without that fallback, binding both components to a ref that starts as `undefined` fails the\n * `active` check for every tab: the panel renders but stays at height 0, which reads as an\n * element with no content.\n */\nconst selected = computed<string | number>(() => modelValue ?? 0);\n\nconst slots = useSlots();\n\nconst currIndex = ref<number>(-1);\nconst activeIndex = ref<number>(-1);\nconst inner = useTemplateRef<HTMLDivElement>('inner');\nconst root = useTemplateRef<HTMLDivElement>('root');\n\nconst { height: innerHeight } = useElementSize(inner);\n\n// clip only while the height follows a panel change, so sticky content inside a panel works\nconst clipped = useClipWhileResizing(root, () => get(innerHeight));\n\nconst children = computed<VNode[]>(() => {\n const slotContent = slots.default?.() ?? [];\n\n const tabs = getChildrenTabs(slotContent);\n\n let anyActive = false;\n const children = tabs.map((tab, index) => {\n const value = tab.props?.value ?? index;\n const active = get(selected) === value;\n if (active) {\n anyActive = true;\n if (index !== get(currIndex))\n set(currIndex, index);\n }\n\n return {\n ...tab,\n props: {\n value,\n ...tab.props,\n },\n };\n });\n\n if (!anyActive)\n set(currIndex, -1);\n\n return children;\n});\n\n/**\n * Unwraps the fragments a `v-for` in the slot produces, so only tab items come\n * back.\n *\n * @param children - the slot's vnodes\n * @returns the tab items among them\n */\nfunction getChildrenTabs(children: VNode[]): VNode[] {\n return children\n .flatMap((item) => {\n if (item.type === Fragment && Array.isArray(item.children) && item.children.length > 0)\n return getChildrenTabs(item.children.filter(isVNode));\n\n return [item];\n })\n .flat();\n}\n\nwatch(currIndex, (index) => {\n nextTick(() => {\n set(activeIndex, index);\n });\n});\n</script>\n\n<template>\n <div\n ref=\"root\"\n class=\"grow transition-[height] duration-200 ease-out motion-reduce:transition-none\"\n :class=\"{ 'overflow-hidden': clipped }\"\n :data-clipped=\"clipped || undefined\"\n :style=\"{ height: `${innerHeight}px` }\"\n v-bind=\"$attrs\"\n >\n <div ref=\"inner\">\n <component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n :active=\"i === activeIndex\"\n />\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;EA2BA,MAAM,WAAW,eAAgC,QAAA,cAAc,CAAC;EAEhE,MAAM,QAAQ,SAAS;EAEvB,MAAM,YAAY,IAAY,EAAE;EAChC,MAAM,cAAc,IAAY,EAAE;EAClC,MAAM,QAAQ,eAA+B,OAAO;EACpD,MAAM,OAAO,eAA+B,MAAM;EAElD,MAAM,EAAE,QAAQ,gBAAgB,eAAe,KAAK;EAGpD,MAAM,UAAU,qBAAqB,YAAY,IAAI,WAAW,CAAC;EAEjE,MAAM,WAAW,eAAwB;GAGvC,MAAM,OAAO,gBAFO,MAAM,UAAU,KAAK,CAAC,CAEF;GAExC,IAAI,YAAY;GAChB,MAAM,WAAW,KAAK,KAAK,KAAK,UAAU;IACxC,MAAM,QAAQ,IAAI,OAAO,SAAS;IAElC,IADe,IAAI,QAAQ,MAAM,OACrB;KACV,YAAY;KACZ,IAAI,UAAU,IAAI,SAAS,GACzB,IAAI,WAAW,KAAK;IACxB;IAEA,OAAO;KACL,GAAG;KACH,OAAO;MACL;MACA,GAAG,IAAI;KACT;IACF;GACF,CAAC;GAED,IAAI,CAAC,WACH,IAAI,WAAW,EAAE;GAEnB,OAAO;EACT,CAAC;;;;;;;;EASD,SAAS,gBAAgB,UAA4B;GACnD,OAAO,SACJ,SAAS,SAAS;IACjB,IAAI,KAAK,SAAS,YAAY,MAAM,QAAQ,KAAK,QAAQ,KAAK,KAAK,SAAS,SAAS,GACnF,OAAO,gBAAgB,KAAK,SAAS,OAAO,OAAO,CAAC;IAEtD,OAAO,CAAC,IAAI;GACd,CAAC,CAAA,CACA,KAAK;EACV;EAEA,MAAM,YAAY,UAAU;GAC1B,eAAe;IACb,IAAI,aAAa,KAAK;GACxB,CAAC;EACH,CAAC;;GAIC,OAAAC,UAAA,GAAAC,mBAgBM,OAhBNC,WAgBM;IAfA,SAAA;IAAJ,KAAI;IACJ,OAAK,CAAC,gFAA8E,EAAA,mBACvDC,MAAA,OAAA,EAAO,CAAA;IACnC,gBAAcA,MAAA,OAAA,KAAW,KAAA;IACzB,OAAK,EAAA,QAAA,GAAeA,MAAA,WAAA,EAAW,IAAA;GACxBJ,GAAAA,KAAAA,MAAM,GAAA,CAEdK,mBAOM,OAAA;IAPG,SAAA;IAAJ,KAAI;GACPJ,GAAAA,EAAAA,UAAA,IAAA,GAAAC,mBAKEI,UAAA,MAAAC,WAHqBH,MAAA,QAAA,IAAb,OAAO,MAAC;IAFlB,OAAAH,UAAA,GAAAO,YAKEC,wBAJK,KAAK,GAAA;KAET,KAAK;KACL,QAAQ,MAAML,MAAA,WAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiTabs.js","names":["_sfc_main"],"sources":["../../../../src/components/tabs/tabs/RuiTabs.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { ContextColorsType } from '@/consts/colors';\nimport { Fragment, isVNode, type VNode } from 'vue';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { type TabAlignment, type TabIndicatorPosition, TabLayout, TabVariant } from '@/components/tabs/tab-props';\nimport { useTabIndicator } from '@/components/tabs/tabs/use-tab-indicator';\nimport { useTabKeyboard } from '@/components/tabs/tabs/use-tab-keyboard';\nimport { useTabRouting } from '@/components/tabs/tabs/use-tab-routing';\nimport { useTabScroll } from '@/components/tabs/tabs/use-tab-scroll';\nimport { useKeyboardScroll } from '@/composables/keyboard-scroll';\nimport { tabsStyles } from './tabs-styles';\n\ntype ChildNode = VNode & { props: Record<string, any> };\n\ninterface ResolvedTabProps {\n value?: string | number;\n to?: unknown;\n link?: boolean;\n exact?: boolean;\n}\n\nexport interface Props {\n color?: ContextColorsType;\n vertical?: boolean;\n disabled?: boolean;\n grow?: boolean;\n align?: TabAlignment;\n indicatorPosition?: TabIndicatorPosition;\n variant?: TabVariant;\n}\n\ndefineOptions({\n name: 'RuiTabs',\n});\n\n/**\n * The selected tab, defaulting to the first one. The default also narrows the\n * `update:modelValue` payload to `number | string`, so a consumer's handler\n * needs no undefined in its signature.\n */\nconst modelValue = defineModel<number | string>({ default: 0 });\n\nconst {\n color,\n vertical = false,\n disabled = false,\n grow = false,\n align = 'center',\n indicatorPosition = 'end',\n variant = TabVariant.underline,\n} = defineProps<Props>();\n\nconst internalModelValue = ref<string | number>();\nconst bar = useTemplateRef<HTMLDivElement>('bar');\nconst wrapper = useTemplateRef<HTMLDivElement>('wrapper');\nconst barTabindex = useKeyboardScroll(bar);\n\nconst slots = useSlots();\n\nconst {\n showArrows,\n prevArrowDisabled,\n nextArrowDisabled,\n onPrevSliderClick,\n onNextSliderClick,\n keepActiveTabVisible,\n} = useTabScroll({ bar, wrapper, vertical: () => vertical });\n\nconst { resolveRoute, isPathMatch } = useTabRouting({\n onRouteChange: () => applyNewValue(true),\n});\n\nconst { onKeydown } = useTabKeyboard({ wrapper, vertical: () => vertical });\n\nconst { style: indicatorStyle, animated, update: updateIndicator } = useTabIndicator({\n bar,\n wrapper,\n vertical: () => vertical,\n variant: () => variant,\n});\n\nconst layout = computed<TabLayout>(() => vertical ? TabLayout.vertical : TabLayout.horizontal);\nconst ui = computed<ReturnType<typeof tabsStyles>>(() => tabsStyles({\n variant,\n layout: get(layout),\n indicatorPosition,\n color,\n wide: vertical || grow,\n animated: get(animated),\n}));\n\nconst children = computed<ChildNode[]>(() => {\n const slotContent = slots.default?.() ?? [];\n\n const tabs = getChildrenTabs(slotContent);\n\n const currentModelValue = get(internalModelValue);\n const inheritedProps = {\n color,\n grow,\n disabled,\n vertical,\n align,\n indicatorPosition,\n variant,\n };\n\n return tabs.map((tab, index) => {\n let tabValue = tab.props?.value ?? index;\n if (tab.props?.link !== false && tab.props?.to)\n tabValue = tab.props.to;\n\n const active = currentModelValue === tabValue;\n return {\n ...tab,\n props: {\n value: tabValue,\n active,\n ...inheritedProps,\n ...tab.props,\n },\n };\n });\n});\n\n/**\n * Unwraps the fragments a `v-for` in the slot produces, so only tabs come\n * back.\n *\n * @param children - the slot's vnodes\n * @returns the tabs among them\n */\nfunction getChildrenTabs(children: VNode[]): VNode[] {\n return children.flatMap((item) => {\n if (item.type === Fragment && Array.isArray(item.children) && item.children.length > 0)\n return getChildrenTabs(item.children.filter(isVNode));\n\n return [item];\n }).flat();\n}\n\nfunction updateModelValue(newModelValue: string | number): void {\n set(modelValue, newModelValue);\n set(internalModelValue, newModelValue);\n}\n\nfunction getTabRouteProps(props: Record<string, unknown>): ResolvedTabProps {\n return {\n value: typeof props.value === 'string' || typeof props.value === 'number' ? props.value : undefined,\n to: props.to ?? undefined,\n link: typeof props.link === 'boolean' ? props.link : undefined,\n exact: typeof props.exact === 'boolean' ? props.exact : undefined,\n };\n}\n\nfunction resolveActiveValue(onlyLink: boolean): string | number | undefined {\n const enabledChildren = get(children).filter(child => !child.props?.disabled);\n if (enabledChildren.length === 0)\n return undefined;\n\n let result: string | number = get(modelValue) || 0;\n enabledChildren.forEach((child, index) => {\n const tabProps = getTabRouteProps(child.props);\n if (!onlyLink && index === 0 && tabProps.value)\n result = tabProps.value;\n\n const fullPath = resolveRoute(tabProps.to);\n\n if (tabProps.link !== false && fullPath && isPathMatch(fullPath, tabProps))\n result = fullPath;\n });\n return result;\n}\n\nfunction applyNewValue(onlyLink = false): void {\n const value = resolveActiveValue(onlyLink);\n if (value !== undefined)\n updateModelValue(value);\n\n keepActiveTabVisible();\n}\n\nwatchImmediate(() => get(modelValue), (modelValue) => {\n set(internalModelValue, modelValue);\n});\n\nwatch(internalModelValue, () => {\n keepActiveTabVisible();\n});\n\nwatch(() => [vertical, variant, grow, align], () => nextTick(updateIndicator), { flush: 'post' });\n\nonMounted(() => {\n if (get(modelValue) !== undefined)\n return;\n\n applyNewValue();\n});\n</script>\n\n<template>\n <div\n :class=\"ui.root()\"\n :data-vertical=\"vertical || undefined\"\n >\n <div\n v-if=\"showArrows\"\n :class=\"ui.arrow()\"\n >\n <RuiButton\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n aria-label=\"Scroll tabs back\"\n :disabled=\"prevArrowDisabled\"\n @click=\"onPrevSliderClick()\"\n >\n <RuiIcon :name=\"vertical ? 'lu-chevron-up' : 'lu-chevron-left'\" />\n </RuiButton>\n </div>\n <div\n ref=\"bar\"\n :class=\"ui.bar()\"\n :tabindex=\"barTabindex\"\n >\n <span\n v-if=\"indicatorStyle\"\n aria-hidden=\"true\"\n data-id=\"tabs-indicator\"\n :class=\"ui.indicator()\"\n :style=\"indicatorStyle\"\n />\n <div\n ref=\"wrapper\"\n role=\"tablist\"\n data-id=\"tabs-wrapper\"\n :aria-orientation=\"vertical ? 'vertical' : undefined\"\n :class=\"ui.wrapper()\"\n @keydown=\"onKeydown($event)\"\n >\n <Component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n @click=\"updateModelValue($event)\"\n />\n </div>\n </div>\n <div\n v-if=\"showArrows\"\n :class=\"ui.arrow()\"\n >\n <RuiButton\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n aria-label=\"Scroll tabs forward\"\n :disabled=\"nextArrowDisabled\"\n @click=\"onNextSliderClick()\"\n >\n <RuiIcon :name=\"vertical ? 'lu-chevron-down' : 'lu-chevron-right'\" />\n </RuiButton>\n </div>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiTabs.js","names":["_sfc_main"],"sources":["../../../../src/components/tabs/tabs/RuiTabs.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"T extends string | number\">\nimport type { ContextColorsType } from '@/consts/colors';\nimport { Fragment, type HTMLAttributes, isVNode, type Ref, type VNode } from 'vue';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { type TabAlignment, type TabIndicatorPosition, TabLayout, TabVariant } from '@/components/tabs/tab-props';\nimport { useTabIndicator } from '@/components/tabs/tabs/use-tab-indicator';\nimport { useTabKeyboard } from '@/components/tabs/tabs/use-tab-keyboard';\nimport { useTabRouting } from '@/components/tabs/tabs/use-tab-routing';\nimport { useTabScroll } from '@/components/tabs/tabs/use-tab-scroll';\nimport { useKeyboardScroll } from '@/composables/keyboard-scroll';\nimport { type ModelValueEmits, usePropModel } from '@/composables/prop-model';\nimport { tabsStyles } from './tabs-styles';\n\n/** Comes first: the component is generic, and only the declarations that open the script are hoisted out of its setup function. */\nexport interface Props {\n color?: ContextColorsType;\n vertical?: boolean;\n disabled?: boolean;\n grow?: boolean;\n align?: TabAlignment;\n indicatorPosition?: TabIndicatorPosition;\n variant?: TabVariant;\n}\n\ntype ChildNode = VNode & { props: Record<string, any> };\n\ninterface ResolvedTabProps {\n value?: string | number;\n to?: unknown;\n link?: boolean;\n exact?: boolean;\n}\n\ndefineOptions({\n name: 'RuiTabs',\n});\n\nconst {\n color,\n vertical = false,\n disabled = false,\n grow = false,\n align = 'center',\n indicatorPosition = 'end',\n variant = TabVariant.underline,\n modelValue: modelValueProp,\n} = defineProps<Props & {\n /**\n * The selected tab's value. `T` is the bound value's type, so a `Ref<'a' | 'b'>` takes the update as is.\n *\n * @defaultValue 0\n */\n modelValue?: T;\n} & /* @vue-ignore */ Omit<HTMLAttributes, keyof Props>>();\n\ndefineEmits<ModelValueEmits<T>>();\n\n/*\n * A prop and an event rather than `defineModel`: the `0` default is no `T`, and without a default\n * the update would be typed with an `undefined` it never carries. The component writes through the\n * wider ref.\n */\nconst model: Ref<string | number | undefined> = usePropModel('modelValue', () => modelValueProp);\n\n// the selected tab, the first one while the model is unbound or undefined\nconst modelValue = computed<string | number>({\n get: () => get(model) ?? 0,\n set: (value: string | number) => set(model, value),\n});\n\nconst internalModelValue = ref<string | number>();\nconst bar = useTemplateRef<HTMLDivElement>('bar');\nconst wrapper = useTemplateRef<HTMLDivElement>('wrapper');\nconst barTabindex = useKeyboardScroll(bar);\n\nconst slots = useSlots();\n\nconst {\n showArrows,\n prevArrowDisabled,\n nextArrowDisabled,\n onPrevSliderClick,\n onNextSliderClick,\n keepActiveTabVisible,\n} = useTabScroll({ bar, wrapper, vertical: () => vertical });\n\nconst { resolveRoute, isPathMatch } = useTabRouting({\n onRouteChange: () => applyNewValue(true),\n});\n\nconst { onKeydown } = useTabKeyboard({ wrapper, vertical: () => vertical });\n\nconst { style: indicatorStyle, animated, update: updateIndicator } = useTabIndicator({\n bar,\n wrapper,\n vertical: () => vertical,\n variant: () => variant,\n});\n\nconst layout = computed<TabLayout>(() => vertical ? TabLayout.vertical : TabLayout.horizontal);\nconst ui = computed<ReturnType<typeof tabsStyles>>(() => tabsStyles({\n variant,\n layout: get(layout),\n indicatorPosition,\n color,\n wide: vertical || grow,\n animated: get(animated),\n}));\n\nconst children = computed<ChildNode[]>(() => {\n const slotContent = slots.default?.() ?? [];\n\n const tabs = getChildrenTabs(slotContent);\n\n const currentModelValue = get(internalModelValue);\n const inheritedProps = {\n color,\n grow,\n disabled,\n vertical,\n align,\n indicatorPosition,\n variant,\n };\n\n return tabs.map((tab, index) => {\n let tabValue = tab.props?.value ?? index;\n if (tab.props?.link !== false && tab.props?.to)\n tabValue = tab.props.to;\n\n const active = currentModelValue === tabValue;\n return {\n ...tab,\n props: {\n value: tabValue,\n active,\n ...inheritedProps,\n ...tab.props,\n },\n };\n });\n});\n\n/**\n * Unwraps the fragments a `v-for` in the slot produces, so only tabs come\n * back.\n *\n * @param children - the slot's vnodes\n * @returns the tabs among them\n */\nfunction getChildrenTabs(children: VNode[]): VNode[] {\n return children.flatMap((item) => {\n if (item.type === Fragment && Array.isArray(item.children) && item.children.length > 0)\n return getChildrenTabs(item.children.filter(isVNode));\n\n return [item];\n }).flat();\n}\n\nfunction updateModelValue(newModelValue: string | number): void {\n set(modelValue, newModelValue);\n set(internalModelValue, newModelValue);\n}\n\nfunction getTabRouteProps(props: Record<string, unknown>): ResolvedTabProps {\n return {\n value: typeof props.value === 'string' || typeof props.value === 'number' ? props.value : undefined,\n to: props.to ?? undefined,\n link: typeof props.link === 'boolean' ? props.link : undefined,\n exact: typeof props.exact === 'boolean' ? props.exact : undefined,\n };\n}\n\nfunction resolveActiveValue(onlyLink: boolean): string | number | undefined {\n const enabledChildren = get(children).filter(child => !child.props?.disabled);\n if (enabledChildren.length === 0)\n return undefined;\n\n let result: string | number = get(modelValue) || 0;\n enabledChildren.forEach((child, index) => {\n const tabProps = getTabRouteProps(child.props);\n if (!onlyLink && index === 0 && tabProps.value)\n result = tabProps.value;\n\n const fullPath = resolveRoute(tabProps.to);\n\n if (tabProps.link !== false && fullPath && isPathMatch(fullPath, tabProps))\n result = fullPath;\n });\n return result;\n}\n\nfunction applyNewValue(onlyLink = false): void {\n const value = resolveActiveValue(onlyLink);\n if (value !== undefined)\n updateModelValue(value);\n\n keepActiveTabVisible();\n}\n\nwatchImmediate(() => get(modelValue), (modelValue) => {\n set(internalModelValue, modelValue);\n});\n\nwatch(internalModelValue, () => {\n keepActiveTabVisible();\n});\n\nwatch(() => [vertical, variant, grow, align], () => nextTick(updateIndicator), { flush: 'post' });\n\nonMounted(() => {\n if (get(modelValue) !== undefined)\n return;\n\n applyNewValue();\n});\n</script>\n\n<template>\n <div\n :class=\"ui.root()\"\n :data-vertical=\"vertical || undefined\"\n >\n <div\n v-if=\"showArrows\"\n :class=\"ui.arrow()\"\n >\n <RuiButton\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n aria-label=\"Scroll tabs back\"\n :disabled=\"prevArrowDisabled\"\n @click=\"onPrevSliderClick()\"\n >\n <RuiIcon :name=\"vertical ? 'lu-chevron-up' : 'lu-chevron-left'\" />\n </RuiButton>\n </div>\n <div\n ref=\"bar\"\n :class=\"ui.bar()\"\n :tabindex=\"barTabindex\"\n >\n <span\n v-if=\"indicatorStyle\"\n aria-hidden=\"true\"\n data-id=\"tabs-indicator\"\n :class=\"ui.indicator()\"\n :style=\"indicatorStyle\"\n />\n <div\n ref=\"wrapper\"\n role=\"tablist\"\n data-id=\"tabs-wrapper\"\n :aria-orientation=\"vertical ? 'vertical' : undefined\"\n :class=\"ui.wrapper()\"\n @keydown=\"onKeydown($event)\"\n >\n <component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n @click=\"updateModelValue($event)\"\n />\n </div>\n </div>\n <div\n v-if=\"showArrows\"\n :class=\"ui.arrow()\"\n >\n <RuiButton\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n aria-label=\"Scroll tabs forward\"\n :disabled=\"nextArrowDisabled\"\n @click=\"onNextSliderClick()\"\n >\n <RuiIcon :name=\"vertical ? 'lu-chevron-down' : 'lu-chevron-right'\" />\n </RuiButton>\n </div>\n </div>\n</template>\n"],"mappings":""}
@@ -1,5 +1,7 @@
1
1
  import type { ContextColorsType } from '../../../consts/colors.js';
2
+ import { type HTMLAttributes } from 'vue';
2
3
  import { type TabAlignment, type TabIndicatorPosition, TabVariant } from '../tab-props.js';
4
+ /** Comes first: the component is generic, and only the declarations that open the script are hoisted out of its setup function. */
3
5
  export interface Props {
4
6
  color?: ContextColorsType;
5
7
  vertical?: boolean;
@@ -9,20 +11,30 @@ export interface Props {
9
11
  indicatorPosition?: TabIndicatorPosition;
10
12
  variant?: TabVariant;
11
13
  }
12
- type __VLS_Props = Props;
13
- type __VLS_ModelProps = {
14
- /**
15
- * The selected tab, defaulting to the first one. The default also narrows the
16
- * `update:modelValue` payload to `number | string`, so a consumer's handler
17
- * needs no undefined in its signature.
18
- */
19
- modelValue?: number | string;
14
+ declare const __VLS_export: <T extends string | number>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
15
+ props: import("vue").PublicProps & __VLS_PrettifyLocal<(Props & {
16
+ /**
17
+ * The selected tab's value. `T` is the bound value's type, so a `Ref<'a' | 'b'>` takes the update as is.
18
+ *
19
+ * @defaultValue 0
20
+ */
21
+ modelValue?: T;
22
+ } & Omit<HTMLAttributes, keyof Props>) & {
23
+ "onUpdate:modelValue"?: ((value: T) => any) | undefined;
24
+ }> & (typeof globalThis extends {
25
+ __VLS_PROPS_FALLBACK: infer P;
26
+ } ? P : {});
27
+ expose: (exposed: {}) => void;
28
+ attrs: any;
29
+ slots: {};
30
+ emit: (evt: "update:modelValue", value: T) => void;
31
+ }>) => import("vue").VNode & {
32
+ __ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
20
33
  };
21
- type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
22
- declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
23
- "update:modelValue": (value: string | number) => any;
24
- }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
25
- "onUpdate:modelValue"?: ((value: string | number) => any) | undefined;
26
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
27
34
  declare const _default: typeof __VLS_export;
28
35
  export default _default;
36
+ type __VLS_PrettifyLocal<T> = (T extends any ? {
37
+ [K in keyof T]: T[K];
38
+ } : {
39
+ [K in keyof T as K]: T[K];
40
+ }) & {};
@@ -1,5 +1,6 @@
1
1
  import { get, set, watchImmediate } from "../../../vendor/@vueuse/shared/dist/index.js";
2
2
  import RuiIcon_default from "../../icons/RuiIcon.js";
3
+ import { usePropModel } from "../../../composables/prop-model.js";
3
4
  import RuiButton_default from "../../buttons/button/RuiButton.js";
4
5
  import { useKeyboardScroll } from "../../../composables/keyboard-scroll.js";
5
6
  import { TabLayout, TabVariant } from "../tab-props.js";
@@ -8,7 +9,7 @@ import { useTabKeyboard } from "./use-tab-keyboard.js";
8
9
  import { useTabRouting } from "./use-tab-routing.js";
9
10
  import { useTabScroll } from "./use-tab-scroll.js";
10
11
  import { tabsStyles } from "./tabs-styles.js";
11
- import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, isVNode, mergeModels, nextTick, normalizeClass, normalizeStyle, onMounted, openBlock, ref, renderList, resolveDynamicComponent, unref, useModel, useSlots, useTemplateRef, watch, withCtx } from "vue";
12
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, isVNode, nextTick, normalizeClass, normalizeStyle, onMounted, openBlock, ref, renderList, resolveDynamicComponent, unref, useSlots, useTemplateRef, watch, withCtx } from "vue";
12
13
  //#region src/components/tabs/tabs/RuiTabs.vue?vue&type=script&setup=true&lang.ts
13
14
  var _hoisted_1 = ["data-vertical"];
14
15
  var _hoisted_2 = ["tabindex"];
@@ -16,7 +17,7 @@ var _hoisted_3 = ["aria-orientation"];
16
17
  var RuiTabs_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
17
18
  name: "RuiTabs",
18
19
  __name: "RuiTabs",
19
- props: /*@__PURE__*/ mergeModels({
20
+ props: {
20
21
  color: {},
21
22
  vertical: {
22
23
  type: Boolean,
@@ -32,19 +33,16 @@ var RuiTabs_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
32
33
  },
33
34
  align: { default: "center" },
34
35
  indicatorPosition: { default: "end" },
35
- variant: { default: () => TabVariant.underline }
36
- }, {
37
- "modelValue": { default: 0 },
38
- "modelModifiers": {}
39
- }),
36
+ variant: { default: () => TabVariant.underline },
37
+ modelValue: {}
38
+ },
40
39
  emits: ["update:modelValue"],
41
40
  setup(__props) {
42
- /**
43
- * The selected tab, defaulting to the first one. The default also narrows the
44
- * `update:modelValue` payload to `number | string`, so a consumer's handler
45
- * needs no undefined in its signature.
46
- */
47
- const modelValue = useModel(__props, "modelValue");
41
+ const model = usePropModel("modelValue", () => __props.modelValue);
42
+ const modelValue = computed({
43
+ get: () => get(model) ?? 0,
44
+ set: (value) => set(model, value)
45
+ });
48
46
  const internalModelValue = ref();
49
47
  const bar = useTemplateRef("bar");
50
48
  const wrapper = useTemplateRef("wrapper");
@@ -1 +1 @@
1
- {"version":3,"file":"RuiTabs.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createElementBlock","_normalizeClass","_unref","_createVNode","RuiButton","_withCtx","RuiIcon","_createCommentVNode","_createElementVNode","_normalizeStyle","_Fragment","_renderList","_createBlock","_resolveDynamicComponent"],"sources":["../../../../src/components/tabs/tabs/RuiTabs.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { ContextColorsType } from '@/consts/colors';\nimport { Fragment, isVNode, type VNode } from 'vue';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { type TabAlignment, type TabIndicatorPosition, TabLayout, TabVariant } from '@/components/tabs/tab-props';\nimport { useTabIndicator } from '@/components/tabs/tabs/use-tab-indicator';\nimport { useTabKeyboard } from '@/components/tabs/tabs/use-tab-keyboard';\nimport { useTabRouting } from '@/components/tabs/tabs/use-tab-routing';\nimport { useTabScroll } from '@/components/tabs/tabs/use-tab-scroll';\nimport { useKeyboardScroll } from '@/composables/keyboard-scroll';\nimport { tabsStyles } from './tabs-styles';\n\ntype ChildNode = VNode & { props: Record<string, any> };\n\ninterface ResolvedTabProps {\n value?: string | number;\n to?: unknown;\n link?: boolean;\n exact?: boolean;\n}\n\nexport interface Props {\n color?: ContextColorsType;\n vertical?: boolean;\n disabled?: boolean;\n grow?: boolean;\n align?: TabAlignment;\n indicatorPosition?: TabIndicatorPosition;\n variant?: TabVariant;\n}\n\ndefineOptions({\n name: 'RuiTabs',\n});\n\n/**\n * The selected tab, defaulting to the first one. The default also narrows the\n * `update:modelValue` payload to `number | string`, so a consumer's handler\n * needs no undefined in its signature.\n */\nconst modelValue = defineModel<number | string>({ default: 0 });\n\nconst {\n color,\n vertical = false,\n disabled = false,\n grow = false,\n align = 'center',\n indicatorPosition = 'end',\n variant = TabVariant.underline,\n} = defineProps<Props>();\n\nconst internalModelValue = ref<string | number>();\nconst bar = useTemplateRef<HTMLDivElement>('bar');\nconst wrapper = useTemplateRef<HTMLDivElement>('wrapper');\nconst barTabindex = useKeyboardScroll(bar);\n\nconst slots = useSlots();\n\nconst {\n showArrows,\n prevArrowDisabled,\n nextArrowDisabled,\n onPrevSliderClick,\n onNextSliderClick,\n keepActiveTabVisible,\n} = useTabScroll({ bar, wrapper, vertical: () => vertical });\n\nconst { resolveRoute, isPathMatch } = useTabRouting({\n onRouteChange: () => applyNewValue(true),\n});\n\nconst { onKeydown } = useTabKeyboard({ wrapper, vertical: () => vertical });\n\nconst { style: indicatorStyle, animated, update: updateIndicator } = useTabIndicator({\n bar,\n wrapper,\n vertical: () => vertical,\n variant: () => variant,\n});\n\nconst layout = computed<TabLayout>(() => vertical ? TabLayout.vertical : TabLayout.horizontal);\nconst ui = computed<ReturnType<typeof tabsStyles>>(() => tabsStyles({\n variant,\n layout: get(layout),\n indicatorPosition,\n color,\n wide: vertical || grow,\n animated: get(animated),\n}));\n\nconst children = computed<ChildNode[]>(() => {\n const slotContent = slots.default?.() ?? [];\n\n const tabs = getChildrenTabs(slotContent);\n\n const currentModelValue = get(internalModelValue);\n const inheritedProps = {\n color,\n grow,\n disabled,\n vertical,\n align,\n indicatorPosition,\n variant,\n };\n\n return tabs.map((tab, index) => {\n let tabValue = tab.props?.value ?? index;\n if (tab.props?.link !== false && tab.props?.to)\n tabValue = tab.props.to;\n\n const active = currentModelValue === tabValue;\n return {\n ...tab,\n props: {\n value: tabValue,\n active,\n ...inheritedProps,\n ...tab.props,\n },\n };\n });\n});\n\n/**\n * Unwraps the fragments a `v-for` in the slot produces, so only tabs come\n * back.\n *\n * @param children - the slot's vnodes\n * @returns the tabs among them\n */\nfunction getChildrenTabs(children: VNode[]): VNode[] {\n return children.flatMap((item) => {\n if (item.type === Fragment && Array.isArray(item.children) && item.children.length > 0)\n return getChildrenTabs(item.children.filter(isVNode));\n\n return [item];\n }).flat();\n}\n\nfunction updateModelValue(newModelValue: string | number): void {\n set(modelValue, newModelValue);\n set(internalModelValue, newModelValue);\n}\n\nfunction getTabRouteProps(props: Record<string, unknown>): ResolvedTabProps {\n return {\n value: typeof props.value === 'string' || typeof props.value === 'number' ? props.value : undefined,\n to: props.to ?? undefined,\n link: typeof props.link === 'boolean' ? props.link : undefined,\n exact: typeof props.exact === 'boolean' ? props.exact : undefined,\n };\n}\n\nfunction resolveActiveValue(onlyLink: boolean): string | number | undefined {\n const enabledChildren = get(children).filter(child => !child.props?.disabled);\n if (enabledChildren.length === 0)\n return undefined;\n\n let result: string | number = get(modelValue) || 0;\n enabledChildren.forEach((child, index) => {\n const tabProps = getTabRouteProps(child.props);\n if (!onlyLink && index === 0 && tabProps.value)\n result = tabProps.value;\n\n const fullPath = resolveRoute(tabProps.to);\n\n if (tabProps.link !== false && fullPath && isPathMatch(fullPath, tabProps))\n result = fullPath;\n });\n return result;\n}\n\nfunction applyNewValue(onlyLink = false): void {\n const value = resolveActiveValue(onlyLink);\n if (value !== undefined)\n updateModelValue(value);\n\n keepActiveTabVisible();\n}\n\nwatchImmediate(() => get(modelValue), (modelValue) => {\n set(internalModelValue, modelValue);\n});\n\nwatch(internalModelValue, () => {\n keepActiveTabVisible();\n});\n\nwatch(() => [vertical, variant, grow, align], () => nextTick(updateIndicator), { flush: 'post' });\n\nonMounted(() => {\n if (get(modelValue) !== undefined)\n return;\n\n applyNewValue();\n});\n</script>\n\n<template>\n <div\n :class=\"ui.root()\"\n :data-vertical=\"vertical || undefined\"\n >\n <div\n v-if=\"showArrows\"\n :class=\"ui.arrow()\"\n >\n <RuiButton\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n aria-label=\"Scroll tabs back\"\n :disabled=\"prevArrowDisabled\"\n @click=\"onPrevSliderClick()\"\n >\n <RuiIcon :name=\"vertical ? 'lu-chevron-up' : 'lu-chevron-left'\" />\n </RuiButton>\n </div>\n <div\n ref=\"bar\"\n :class=\"ui.bar()\"\n :tabindex=\"barTabindex\"\n >\n <span\n v-if=\"indicatorStyle\"\n aria-hidden=\"true\"\n data-id=\"tabs-indicator\"\n :class=\"ui.indicator()\"\n :style=\"indicatorStyle\"\n />\n <div\n ref=\"wrapper\"\n role=\"tablist\"\n data-id=\"tabs-wrapper\"\n :aria-orientation=\"vertical ? 'vertical' : undefined\"\n :class=\"ui.wrapper()\"\n @keydown=\"onKeydown($event)\"\n >\n <Component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n @click=\"updateModelValue($event)\"\n />\n </div>\n </div>\n <div\n v-if=\"showArrows\"\n :class=\"ui.arrow()\"\n >\n <RuiButton\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n aria-label=\"Scroll tabs forward\"\n :disabled=\"nextArrowDisabled\"\n @click=\"onNextSliderClick()\"\n >\n <RuiIcon :name=\"vertical ? 'lu-chevron-down' : 'lu-chevron-right'\" />\n </RuiButton>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"RuiTabs.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_unref","_createVNode","RuiButton","_withCtx","RuiIcon","_createCommentVNode","_createElementVNode","_normalizeStyle","_Fragment","_renderList","_createBlock","_resolveDynamicComponent"],"sources":["../../../../src/components/tabs/tabs/RuiTabs.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"T extends string | number\">\nimport type { ContextColorsType } from '@/consts/colors';\nimport { Fragment, type HTMLAttributes, isVNode, type Ref, type VNode } from 'vue';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { type TabAlignment, type TabIndicatorPosition, TabLayout, TabVariant } from '@/components/tabs/tab-props';\nimport { useTabIndicator } from '@/components/tabs/tabs/use-tab-indicator';\nimport { useTabKeyboard } from '@/components/tabs/tabs/use-tab-keyboard';\nimport { useTabRouting } from '@/components/tabs/tabs/use-tab-routing';\nimport { useTabScroll } from '@/components/tabs/tabs/use-tab-scroll';\nimport { useKeyboardScroll } from '@/composables/keyboard-scroll';\nimport { type ModelValueEmits, usePropModel } from '@/composables/prop-model';\nimport { tabsStyles } from './tabs-styles';\n\n/** Comes first: the component is generic, and only the declarations that open the script are hoisted out of its setup function. */\nexport interface Props {\n color?: ContextColorsType;\n vertical?: boolean;\n disabled?: boolean;\n grow?: boolean;\n align?: TabAlignment;\n indicatorPosition?: TabIndicatorPosition;\n variant?: TabVariant;\n}\n\ntype ChildNode = VNode & { props: Record<string, any> };\n\ninterface ResolvedTabProps {\n value?: string | number;\n to?: unknown;\n link?: boolean;\n exact?: boolean;\n}\n\ndefineOptions({\n name: 'RuiTabs',\n});\n\nconst {\n color,\n vertical = false,\n disabled = false,\n grow = false,\n align = 'center',\n indicatorPosition = 'end',\n variant = TabVariant.underline,\n modelValue: modelValueProp,\n} = defineProps<Props & {\n /**\n * The selected tab's value. `T` is the bound value's type, so a `Ref<'a' | 'b'>` takes the update as is.\n *\n * @defaultValue 0\n */\n modelValue?: T;\n} & /* @vue-ignore */ Omit<HTMLAttributes, keyof Props>>();\n\ndefineEmits<ModelValueEmits<T>>();\n\n/*\n * A prop and an event rather than `defineModel`: the `0` default is no `T`, and without a default\n * the update would be typed with an `undefined` it never carries. The component writes through the\n * wider ref.\n */\nconst model: Ref<string | number | undefined> = usePropModel('modelValue', () => modelValueProp);\n\n// the selected tab, the first one while the model is unbound or undefined\nconst modelValue = computed<string | number>({\n get: () => get(model) ?? 0,\n set: (value: string | number) => set(model, value),\n});\n\nconst internalModelValue = ref<string | number>();\nconst bar = useTemplateRef<HTMLDivElement>('bar');\nconst wrapper = useTemplateRef<HTMLDivElement>('wrapper');\nconst barTabindex = useKeyboardScroll(bar);\n\nconst slots = useSlots();\n\nconst {\n showArrows,\n prevArrowDisabled,\n nextArrowDisabled,\n onPrevSliderClick,\n onNextSliderClick,\n keepActiveTabVisible,\n} = useTabScroll({ bar, wrapper, vertical: () => vertical });\n\nconst { resolveRoute, isPathMatch } = useTabRouting({\n onRouteChange: () => applyNewValue(true),\n});\n\nconst { onKeydown } = useTabKeyboard({ wrapper, vertical: () => vertical });\n\nconst { style: indicatorStyle, animated, update: updateIndicator } = useTabIndicator({\n bar,\n wrapper,\n vertical: () => vertical,\n variant: () => variant,\n});\n\nconst layout = computed<TabLayout>(() => vertical ? TabLayout.vertical : TabLayout.horizontal);\nconst ui = computed<ReturnType<typeof tabsStyles>>(() => tabsStyles({\n variant,\n layout: get(layout),\n indicatorPosition,\n color,\n wide: vertical || grow,\n animated: get(animated),\n}));\n\nconst children = computed<ChildNode[]>(() => {\n const slotContent = slots.default?.() ?? [];\n\n const tabs = getChildrenTabs(slotContent);\n\n const currentModelValue = get(internalModelValue);\n const inheritedProps = {\n color,\n grow,\n disabled,\n vertical,\n align,\n indicatorPosition,\n variant,\n };\n\n return tabs.map((tab, index) => {\n let tabValue = tab.props?.value ?? index;\n if (tab.props?.link !== false && tab.props?.to)\n tabValue = tab.props.to;\n\n const active = currentModelValue === tabValue;\n return {\n ...tab,\n props: {\n value: tabValue,\n active,\n ...inheritedProps,\n ...tab.props,\n },\n };\n });\n});\n\n/**\n * Unwraps the fragments a `v-for` in the slot produces, so only tabs come\n * back.\n *\n * @param children - the slot's vnodes\n * @returns the tabs among them\n */\nfunction getChildrenTabs(children: VNode[]): VNode[] {\n return children.flatMap((item) => {\n if (item.type === Fragment && Array.isArray(item.children) && item.children.length > 0)\n return getChildrenTabs(item.children.filter(isVNode));\n\n return [item];\n }).flat();\n}\n\nfunction updateModelValue(newModelValue: string | number): void {\n set(modelValue, newModelValue);\n set(internalModelValue, newModelValue);\n}\n\nfunction getTabRouteProps(props: Record<string, unknown>): ResolvedTabProps {\n return {\n value: typeof props.value === 'string' || typeof props.value === 'number' ? props.value : undefined,\n to: props.to ?? undefined,\n link: typeof props.link === 'boolean' ? props.link : undefined,\n exact: typeof props.exact === 'boolean' ? props.exact : undefined,\n };\n}\n\nfunction resolveActiveValue(onlyLink: boolean): string | number | undefined {\n const enabledChildren = get(children).filter(child => !child.props?.disabled);\n if (enabledChildren.length === 0)\n return undefined;\n\n let result: string | number = get(modelValue) || 0;\n enabledChildren.forEach((child, index) => {\n const tabProps = getTabRouteProps(child.props);\n if (!onlyLink && index === 0 && tabProps.value)\n result = tabProps.value;\n\n const fullPath = resolveRoute(tabProps.to);\n\n if (tabProps.link !== false && fullPath && isPathMatch(fullPath, tabProps))\n result = fullPath;\n });\n return result;\n}\n\nfunction applyNewValue(onlyLink = false): void {\n const value = resolveActiveValue(onlyLink);\n if (value !== undefined)\n updateModelValue(value);\n\n keepActiveTabVisible();\n}\n\nwatchImmediate(() => get(modelValue), (modelValue) => {\n set(internalModelValue, modelValue);\n});\n\nwatch(internalModelValue, () => {\n keepActiveTabVisible();\n});\n\nwatch(() => [vertical, variant, grow, align], () => nextTick(updateIndicator), { flush: 'post' });\n\nonMounted(() => {\n if (get(modelValue) !== undefined)\n return;\n\n applyNewValue();\n});\n</script>\n\n<template>\n <div\n :class=\"ui.root()\"\n :data-vertical=\"vertical || undefined\"\n >\n <div\n v-if=\"showArrows\"\n :class=\"ui.arrow()\"\n >\n <RuiButton\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n aria-label=\"Scroll tabs back\"\n :disabled=\"prevArrowDisabled\"\n @click=\"onPrevSliderClick()\"\n >\n <RuiIcon :name=\"vertical ? 'lu-chevron-up' : 'lu-chevron-left'\" />\n </RuiButton>\n </div>\n <div\n ref=\"bar\"\n :class=\"ui.bar()\"\n :tabindex=\"barTabindex\"\n >\n <span\n v-if=\"indicatorStyle\"\n aria-hidden=\"true\"\n data-id=\"tabs-indicator\"\n :class=\"ui.indicator()\"\n :style=\"indicatorStyle\"\n />\n <div\n ref=\"wrapper\"\n role=\"tablist\"\n data-id=\"tabs-wrapper\"\n :aria-orientation=\"vertical ? 'vertical' : undefined\"\n :class=\"ui.wrapper()\"\n @keydown=\"onKeydown($event)\"\n >\n <component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n @click=\"updateModelValue($event)\"\n />\n </div>\n </div>\n <div\n v-if=\"showArrows\"\n :class=\"ui.arrow()\"\n >\n <RuiButton\n variant=\"text\"\n icon\n size=\"sm\"\n tabindex=\"-1\"\n aria-label=\"Scroll tabs forward\"\n :disabled=\"nextArrowDisabled\"\n @click=\"onNextSliderClick()\"\n >\n <RuiIcon :name=\"vertical ? 'lu-chevron-down' : 'lu-chevron-right'\" />\n </RuiButton>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiTimePicker.js","names":["_sfc_main"],"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=\"ui.time()\">\n <button\n type=\"button\"\n data-id=\"hour\"\n :aria-label=\"`${formatValue(displayHour)} hours`\"\n :aria-pressed=\"editMode === 'hour'\"\n :class=\"ui.digit({ active: editMode === 'hour' })\"\n @click=\"editMode = 'hour'\"\n >\n {{ formatValue(displayHour) }}\n </button>\n <div :class=\"ui.separator()\">\n :\n </div>\n <button\n type=\"button\"\n data-id=\"minute\"\n :aria-label=\"`${formatValue(selectedMinute)} minutes`\"\n :aria-pressed=\"editMode === 'minute'\"\n :class=\"ui.digit({ active: editMode === 'minute' })\"\n @click=\"editMode = 'minute'\"\n >\n {{ formatValue(selectedMinute) }}\n </button>\n <div\n v-if=\"showSecond\"\n :class=\"ui.separator()\"\n >\n :\n </div>\n <button\n v-if=\"showSecond\"\n type=\"button\"\n data-id=\"second\"\n :aria-label=\"`${formatValue(selectedSecond)} seconds`\"\n :aria-pressed=\"editMode === 'second'\"\n :class=\"ui.digit({ active: editMode === 'second' })\"\n @click=\"editMode = 'second'\"\n >\n {{ formatValue(selectedSecond) }}\n </button>\n\n <div\n v-if=\"showMillisecond\"\n :class=\"ui.separator({ class: 'text-lg' })\"\n >\n .\n </div>\n\n <button\n v-if=\"showMillisecond\"\n type=\"button\"\n data-id=\"millisecond\"\n :aria-label=\"`${formatValue(selectedMillisecond, 3)} milliseconds`\"\n :aria-pressed=\"editMode === 'millisecond'\"\n :class=\"ui.digit({ active: editMode === 'millisecond', class: 'text-lg' })\"\n @click=\"editMode = 'millisecond'\"\n >\n {{ formatValue(selectedMillisecond, 3) }}\n </button>\n </div>\n <button\n type=\"button\"\n aria-label=\"Toggle AM/PM\"\n :class=\"ui.period()\"\n @click=\"toggleAmPm()\"\n >\n {{ period }}\n </button>\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":""}
1
+ {"version":3,"file":"RuiTimePicker.js","names":["_sfc_main"],"sources":["../../../src/components/time-picker/RuiTimePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, type HTMLAttributes, 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 & /* @vue-ignore */ Omit<HTMLAttributes, keyof 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=\"ui.time()\">\n <button\n type=\"button\"\n data-id=\"hour\"\n :aria-label=\"`${formatValue(displayHour)} hours`\"\n :aria-pressed=\"editMode === 'hour'\"\n :class=\"ui.digit({ active: editMode === 'hour' })\"\n @click=\"editMode = 'hour'\"\n >\n {{ formatValue(displayHour) }}\n </button>\n <div :class=\"ui.separator()\">\n :\n </div>\n <button\n type=\"button\"\n data-id=\"minute\"\n :aria-label=\"`${formatValue(selectedMinute)} minutes`\"\n :aria-pressed=\"editMode === 'minute'\"\n :class=\"ui.digit({ active: editMode === 'minute' })\"\n @click=\"editMode = 'minute'\"\n >\n {{ formatValue(selectedMinute) }}\n </button>\n <div\n v-if=\"showSecond\"\n :class=\"ui.separator()\"\n >\n :\n </div>\n <button\n v-if=\"showSecond\"\n type=\"button\"\n data-id=\"second\"\n :aria-label=\"`${formatValue(selectedSecond)} seconds`\"\n :aria-pressed=\"editMode === 'second'\"\n :class=\"ui.digit({ active: editMode === 'second' })\"\n @click=\"editMode = 'second'\"\n >\n {{ formatValue(selectedSecond) }}\n </button>\n\n <div\n v-if=\"showMillisecond\"\n :class=\"ui.separator({ class: 'text-lg' })\"\n >\n .\n </div>\n\n <button\n v-if=\"showMillisecond\"\n type=\"button\"\n data-id=\"millisecond\"\n :aria-label=\"`${formatValue(selectedMillisecond, 3)} milliseconds`\"\n :aria-pressed=\"editMode === 'millisecond'\"\n :class=\"ui.digit({ active: editMode === 'millisecond', class: 'text-lg' })\"\n @click=\"editMode = 'millisecond'\"\n >\n {{ formatValue(selectedMillisecond, 3) }}\n </button>\n </div>\n <button\n type=\"button\"\n aria-label=\"Toggle AM/PM\"\n :class=\"ui.period()\"\n @click=\"toggleAmPm()\"\n >\n {{ period }}\n </button>\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":""}
@@ -1,10 +1,11 @@
1
+ import { type HTMLAttributes } from 'vue';
1
2
  import { TimeAccuracy } from '../../consts/time-accuracy.js';
2
3
  export type TimePickerSelection = 'hour' | 'minute' | 'second' | 'millisecond';
3
4
  export interface RuiTimePickerProps {
4
5
  accuracy?: TimeAccuracy;
5
6
  borderless?: boolean;
6
7
  }
7
- type __VLS_Props = RuiTimePickerProps;
8
+ type __VLS_Props = RuiTimePickerProps & /* @vue-ignore */ Omit<HTMLAttributes, keyof RuiTimePickerProps>;
8
9
  type __VLS_ModelProps = {
9
10
  modelValue: Date | undefined;
10
11
  'hour'?: number | undefined;