@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 +1 @@
1
- {"version":3,"file":"RuiFileUpload.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_useModel","_openBlock","_createElementBlock","_normalizeProps","_guardReactiveProps","_unref","_createElementVNode","_normalizeClass","_renderSlot","_Fragment","_renderList","_createVNode","RuiIcon","_toDisplayString","_createCommentVNode","_mergeProps","RuiProgress","_createBlock","RuiFormTextDetail"],"sources":["../../../../src/components/forms/file-upload/RuiFileUpload.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { RuiIcons } from '@/icons';\nimport RuiFormTextDetail from '@/components/helpers/RuiFormTextDetail.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport RuiProgress from '@/components/progress/RuiProgress.vue';\nimport { useRuiI8n } from '@/composables/use-rui-i18n';\nimport { RUI_I18N_KEYS } from '@/i18n/keys';\nimport { type FormDetails, useFormDetails, useFormTextDetail } from '@/utils/form-text-detail';\nimport { formatFileSize, getNonRootAttrs, getRootAttrs } from '@/utils/helpers';\n\nexport interface FileUploadProps {\n /** File type filter (HTML accept attribute syntax). e.g. '.csv', 'image/*', '.png,.jpg' */\n accept?: string;\n /** Allow multiple file selection. */\n multiple?: boolean;\n disabled?: boolean;\n /** Shows a loading overlay (consumer-driven, e.g. while uploading). */\n loading?: boolean;\n /** Upload progress 0-100. When provided alongside `loading`, the overlay shows a determinate progress bar with percentage. */\n progress?: number;\n /** Renders the success state border/icon. Consumer toggles back to false. */\n uploaded?: boolean;\n /** Optional max size per file in bytes; failures emit `error` and set internal error state. */\n maxSize?: number;\n /** External error messages (e.g. from Vuelidate). Shown via the standard form detail block. */\n errorMessages?: string | string[];\n /** Hint text below the dropzone. */\n hint?: string;\n /** Disable drag-and-drop; the dropzone becomes click-only (matches rotki.com use case). */\n noDrop?: boolean;\n /**\n * Replace the default \"Drag and drop or \\{button\\}\" copy. With `noDrop` the default is empty, so only the button shows.\n * The defaults of this and the other texts, error messages included, come from the `rui.file_upload.*` translation keys.\n */\n uploadText?: string;\n /** Label shown on the inline button when no file is selected. */\n clickToUploadText?: string;\n /** Label shown on the inline button when one or more files are already selected. */\n replaceText?: string;\n /** The line under the dropzone for its hint and errors: `reserve`, `auto` or `hidden`; falls back to the nearest `RuiFieldDefaults`, then the app default, then `reserve`. */\n details?: FormDetails;\n /** @deprecated Use `details=\"hidden\"`. Removed in 4.0. */\n hideDetails?: boolean;\n}\n\ndefineOptions({\n name: 'RuiFileUpload',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<File | File[] | undefined>({ required: true });\n\nconst {\n accept = '*',\n multiple = false,\n disabled = false,\n loading = false,\n progress = undefined,\n uploaded = false,\n maxSize = undefined,\n errorMessages = [],\n hint = '',\n noDrop = false,\n uploadText = undefined,\n clickToUploadText = undefined,\n replaceText = undefined,\n details = undefined,\n hideDetails = false,\n} = defineProps<FileUploadProps>();\n\nconst emit = defineEmits<{\n error: [message: string];\n}>();\n\ndefineSlots<{\n preview?: (props: { files: File[]; remove: () => void }) => any;\n icon?: () => any;\n description?: () => any;\n}>();\n\nconst { t } = useRuiI8n();\n\nconst wrapper = useTemplateRef<HTMLDivElement>('wrapper');\nconst input = useTemplateRef<HTMLInputElement>('input');\nconst internalError = ref<string>('');\n\nconst files = computed<File[]>(() => {\n const value = get(modelValue);\n if (!value)\n return [];\n return Array.isArray(value) ? value : [value];\n});\n\nconst hasFiles = computed<boolean>(() => get(files).length > 0);\n\nconst progressLabel = computed<string | undefined>(() => {\n const value = progress;\n return value === undefined ? undefined : `${Math.round(value)}%`;\n});\n\nconst combinedErrorMessages = computed<string[]>(() => {\n const external = Array.isArray(errorMessages) ? errorMessages : [errorMessages];\n const internal = get(internalError);\n return [...external.filter(Boolean), ...(internal ? [internal] : [])];\n});\n\nconst { hasError } = useFormTextDetail(combinedErrorMessages, () => []);\nconst detailsMode = useFormDetails(() => details, () => hideDetails);\n\n// a click-only dropzone does not offer dragging\nconst resolvedUploadText = computed<string>(() => uploadText ?? (noDrop ? '' : t(RUI_I18N_KEYS.fileUpload.dropPrefix, 'Drag and drop or')));\nconst resolvedClickToUploadText = computed<string>(() => clickToUploadText ?? t(RUI_I18N_KEYS.fileUpload.clickToUpload, 'click to upload'));\nconst resolvedReplaceText = computed<string>(() => replaceText ?? t(RUI_I18N_KEYS.fileUpload.replace, 'replace file'));\n\ntype WellTone = 'primary' | 'error' | 'success';\n\n// the icon well follows the dropzone's state, like its border\nconst wellTone = computed<WellTone>(() => {\n if (get(hasError))\n return 'error';\n if (uploaded)\n return 'success';\n return 'primary';\n});\n\nconst wellIcon = computed<RuiIcons>(() => {\n const tone = get(wellTone);\n if (tone === 'error')\n return 'lu-circle-alert';\n if (tone === 'success')\n return 'lu-circle-check';\n return 'lu-file-up';\n});\n\n// the 10% tint vanishes on a dark page, so dark doubles it\nconst wellClasses: Record<WellTone, string> = {\n primary: 'bg-rui-primary-soft dark:bg-rui-primary/20',\n error: 'bg-rui-error-soft dark:bg-rui-error/20',\n success: 'bg-rui-success-soft dark:bg-rui-success/20',\n};\n\nfunction matchesAccept(file: File, acceptString: string): boolean {\n if (!acceptString || acceptString === '*' || acceptString === '*/*')\n return true;\n\n const fileName = file.name.toLowerCase();\n const fileExtension = fileName.includes('.') ? fileName.slice(fileName.lastIndexOf('.')) : '';\n const fileType = file.type.toLowerCase();\n const acceptTypes = acceptString.split(',').map(value => value.trim().toLowerCase()).filter(Boolean);\n\n return acceptTypes.some((type) => {\n if (type.startsWith('.'))\n return type === fileExtension;\n if (type.endsWith('/*'))\n return fileType.startsWith(type.slice(0, -1));\n return type === fileType;\n });\n}\n\nfunction reportError(message: string): void {\n set(internalError, message);\n emit('error', message);\n}\n\nfunction clearInternalError(): void {\n set(internalError, '');\n}\n\nfunction validate(candidates: File[]): File[] | undefined {\n if (candidates.length === 0)\n return undefined;\n\n if (!multiple && candidates.length > 1) {\n reportError(t(RUI_I18N_KEYS.fileUpload.tooMany, 'Only one file can be uploaded'));\n return undefined;\n }\n\n for (const file of candidates) {\n if (!matchesAccept(file, accept)) {\n reportError(t(RUI_I18N_KEYS.fileUpload.wrongType, { accept }, `Only ${accept} files are allowed`));\n return undefined;\n }\n if (maxSize !== undefined && file.size > maxSize) {\n const size = formatFileSize(maxSize);\n reportError(t(RUI_I18N_KEYS.fileUpload.tooLarge, { name: file.name, size }, `${file.name} exceeds the maximum size of ${size}`));\n return undefined;\n }\n }\n\n return candidates;\n}\n\nfunction setFiles(candidates: File[]): void {\n const validated = validate(candidates);\n if (!validated)\n return;\n clearInternalError();\n set(modelValue, multiple ? validated : validated[0]);\n}\n\nfunction removeFile(target?: File): void {\n clearInternalError();\n const inputEl = get(input);\n if (inputEl)\n inputEl.value = '';\n\n if (!target || !multiple) {\n set(modelValue, multiple ? [] : undefined);\n return;\n }\n\n const remaining = get(files).filter(file => file !== target);\n set(modelValue, remaining);\n}\n\nfunction onSelect(event: Event): void {\n const target = event.target;\n if (!(target instanceof HTMLInputElement) || !target.files)\n return;\n const picked = Array.from(target.files);\n // the model owns the selection; a cleared input fires `change` for the same file again\n target.value = '';\n setFiles(picked);\n}\n\nfunction onDrop(dropped: File[] | null): void {\n if (disabled || noDrop || !dropped || dropped.length === 0)\n return;\n setFiles(dropped);\n}\n\nconst { isOverDropZone } = useDropZone(wrapper, {\n onDrop,\n});\n\nfunction openPicker(): void {\n if (disabled)\n return;\n get(input)?.click();\n}\n\nwatch(() => errorMessages, () => clearInternalError());\n\ndefineExpose({\n removeFile: () => removeFile(),\n openPicker,\n});\n</script>\n\n<template>\n <div v-bind=\"getRootAttrs($attrs)\">\n <div\n ref=\"wrapper\"\n class=\"p-4 border border-rui-outline dark:border-rui-neutral-400 rounded-rui-panel w-full relative border-dashed transition\"\n :class=\"{\n 'border-rui-primary! bg-rui-primary-subtle': isOverDropZone && !disabled && !noDrop,\n 'border-rui-error! border-solid! bg-rui-error-subtle': hasError,\n 'border-rui-success! border-solid! bg-rui-success-subtle': uploaded,\n 'opacity-60 pointer-events-none': disabled,\n }\"\n :data-disabled=\"disabled || undefined\"\n :data-uploaded=\"uploaded || undefined\"\n :data-error=\"hasError ? '' : undefined\"\n :data-drop-active=\"isOverDropZone || undefined\"\n >\n <div\n class=\"flex flex-col items-center justify-center gap-3\"\n :class=\"{ 'opacity-0': loading }\"\n >\n <slot\n name=\"preview\"\n :files=\"files\"\n :remove=\"() => removeFile()\"\n >\n <div\n v-if=\"hasFiles\"\n class=\"flex flex-col gap-1 w-full\"\n data-id=\"file-list\"\n >\n <div\n v-for=\"file in files\"\n :key=\"`${file.name}-${file.lastModified}`\"\n class=\"flex items-center gap-2 bg-rui-primary-soft dark:bg-rui-primary/20 rounded-full pl-3 pr-1 py-1\"\n data-id=\"file-item\"\n >\n <RuiIcon\n name=\"lu-file\"\n color=\"primary\"\n size=\"20\"\n />\n <div class=\"flex-1 overflow-hidden min-w-0\">\n <div\n class=\"text-sm leading-5 truncate\"\n :title=\"file.name\"\n >\n {{ file.name }}\n </div>\n <div class=\"text-rui-text-secondary text-xs leading-3\">\n {{ formatFileSize(file.size) }}\n </div>\n </div>\n <button\n type=\"button\"\n class=\"p-1 rounded-full hover:bg-rui-hover transition focus-visible:focus-ring outline-hidden\"\n :disabled=\"disabled\"\n :aria-label=\"t(RUI_I18N_KEYS.fileUpload.remove, { name: file.name }, `Remove ${file.name}`)\"\n data-id=\"remove-file\"\n @click=\"removeFile(file)\"\n >\n <RuiIcon\n name=\"lu-x\"\n size=\"16\"\n />\n </button>\n </div>\n </div>\n <div\n v-else\n class=\"h-10 w-10 rounded-full flex items-center justify-center\"\n :class=\"wellClasses[wellTone]\"\n data-id=\"icon-well\"\n >\n <slot name=\"icon\">\n <RuiIcon\n :name=\"wellIcon\"\n :color=\"wellTone\"\n :class=\"{ 'dark:text-rui-primary-lighter': wellTone === 'primary' }\"\n />\n </slot>\n </div>\n </slot>\n\n <div class=\"text-center text-sm\">\n <slot name=\"description\">\n <div class=\"flex items-center justify-center gap-1 flex-wrap\">\n <span v-if=\"resolvedUploadText\">{{ resolvedUploadText }}</span>\n <button\n type=\"button\"\n class=\"text-rui-primary dark:text-rui-primary-lighter underline disabled:no-underline disabled:text-rui-text-disabled\"\n :class=\"{ 'first-letter:uppercase': !resolvedUploadText }\"\n :disabled=\"disabled\"\n data-id=\"open-picker\"\n @click=\"openPicker()\"\n >\n {{ hasFiles ? resolvedReplaceText : resolvedClickToUploadText }}\n </button>\n </div>\n </slot>\n </div>\n\n <input\n ref=\"input\"\n type=\"file\"\n :accept=\"accept\"\n :multiple=\"multiple\"\n :disabled=\"disabled\"\n hidden\n data-id=\"file-input\"\n v-bind=\"getNonRootAttrs($attrs, ['class', 'onChange'])\"\n @change=\"onSelect($event)\"\n />\n </div>\n\n <div\n v-if=\"loading\"\n class=\"flex flex-col items-center justify-center absolute h-full w-full top-0 left-0 gap-2\"\n data-id=\"loading\"\n >\n <RuiProgress\n circular\n :variant=\"progress === undefined ? 'indeterminate' : 'determinate'\"\n :value=\"progress\"\n color=\"primary\"\n size=\"40\"\n />\n <div\n v-if=\"progressLabel\"\n class=\"text-xs text-rui-text-secondary\"\n data-id=\"progress-label\"\n v-text=\"progressLabel\"\n />\n </div>\n </div>\n <RuiFormTextDetail\n v-if=\"detailsMode !== 'hidden'\"\n :details=\"detailsMode\"\n :error-messages=\"combinedErrorMessages\"\n :hint=\"hint\"\n />\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"RuiFileUpload.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_useModel","_openBlock","_createElementBlock","_normalizeProps","_guardReactiveProps","_unref","_createElementVNode","_normalizeClass","_renderSlot","_Fragment","_renderList","_createVNode","RuiIcon","_toDisplayString","_createCommentVNode","_mergeProps","RuiProgress","_createBlock","RuiFormTextDetail"],"sources":["../../../../src/components/forms/file-upload/RuiFileUpload.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends File | File[] | undefined\">\nimport type { Ref } from 'vue';\nimport type { RuiIcons } from '@/icons';\nimport type { InputAttributes } from '@/types/attributes';\nimport RuiFormTextDetail from '@/components/helpers/RuiFormTextDetail.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport RuiProgress from '@/components/progress/RuiProgress.vue';\nimport { useRuiI8n } from '@/composables/use-rui-i18n';\nimport { RUI_I18N_KEYS } from '@/i18n/keys';\nimport { type FormDetails, useFormDetails, useFormTextDetail } from '@/utils/form-text-detail';\nimport { formatFileSize, getNonRootAttrs, getRootAttrs } from '@/utils/helpers';\n\nexport interface FileUploadProps {\n /** File type filter (HTML accept attribute syntax). e.g. '.csv', 'image/*', '.png,.jpg' */\n accept?: string;\n /** Allow multiple file selection. */\n multiple?: boolean;\n disabled?: boolean;\n /** Shows a loading overlay (consumer-driven, e.g. while uploading). */\n loading?: boolean;\n /** Upload progress 0-100. When provided alongside `loading`, the overlay shows a determinate progress bar with percentage. */\n progress?: number;\n /** Renders the success state border/icon. Consumer toggles back to false. */\n uploaded?: boolean;\n /** Optional max size per file in bytes; failures emit `error` and set internal error state. */\n maxSize?: number;\n /** External error messages (e.g. from Vuelidate). Shown via the standard form detail block. */\n errorMessages?: string | string[];\n /** Hint text below the dropzone. */\n hint?: string;\n /** Disable drag-and-drop; the dropzone becomes click-only (matches rotki.com use case). */\n noDrop?: boolean;\n /**\n * Replace the default \"Drag and drop or \\{button\\}\" copy. With `noDrop` the default is empty, so only the button shows.\n * The defaults of this and the other texts, error messages included, come from the `rui.file_upload.*` translation keys.\n */\n uploadText?: string;\n /** Label shown on the inline button when no file is selected. */\n clickToUploadText?: string;\n /** Label shown on the inline button when one or more files are already selected. */\n replaceText?: string;\n /** The line under the dropzone for its hint and errors: `reserve`, `auto` or `hidden`; falls back to the nearest `RuiFieldDefaults`, then the app default, then `reserve`. */\n details?: FormDetails;\n /** @deprecated Use `details=\"hidden\"`. Removed in 4.0. */\n hideDetails?: boolean;\n}\n\ndefineOptions({\n name: 'RuiFileUpload',\n inheritAttrs: false,\n});\n\n/**\n * The picked file, or `undefined`; with `multiple`, the picked files in an array. `T` is the bound\n * value's type, so a `Ref<File[]>` takes the update as is. The component writes through the wider\n * ref, in the shape `multiple` asks for.\n */\nconst modelValue: Ref<File | File[] | undefined> = defineModel<T>({ required: true });\n\nconst {\n accept = '*',\n multiple = false,\n disabled = false,\n loading = false,\n progress = undefined,\n uploaded = false,\n maxSize = undefined,\n errorMessages = [],\n hint = '',\n noDrop = false,\n uploadText = undefined,\n clickToUploadText = undefined,\n replaceText = undefined,\n details = undefined,\n hideDetails = false,\n} = defineProps<FileUploadProps & /* @vue-ignore */ Omit<InputAttributes, keyof FileUploadProps | 'onError'>>();\n\nconst emit = defineEmits<{\n error: [message: string];\n}>();\n\ndefineSlots<{\n preview?: (props: { files: File[]; remove: () => void }) => any;\n icon?: () => any;\n description?: () => any;\n}>();\n\nconst { t } = useRuiI8n();\n\nconst wrapper = useTemplateRef<HTMLDivElement>('wrapper');\nconst input = useTemplateRef<HTMLInputElement>('input');\nconst internalError = ref<string>('');\n\nconst files = computed<File[]>(() => {\n const value = get(modelValue);\n if (!value)\n return [];\n return Array.isArray(value) ? value : [value];\n});\n\nconst hasFiles = computed<boolean>(() => get(files).length > 0);\n\nconst progressLabel = computed<string | undefined>(() => {\n const value = progress;\n return value === undefined ? undefined : `${Math.round(value)}%`;\n});\n\nconst combinedErrorMessages = computed<string[]>(() => {\n const external = Array.isArray(errorMessages) ? errorMessages : [errorMessages];\n const internal = get(internalError);\n return [...external.filter(Boolean), ...(internal ? [internal] : [])];\n});\n\nconst { hasError } = useFormTextDetail(combinedErrorMessages, () => []);\nconst detailsMode = useFormDetails(() => details, () => hideDetails);\n\n// a click-only dropzone does not offer dragging\nconst resolvedUploadText = computed<string>(() => uploadText ?? (noDrop ? '' : t(RUI_I18N_KEYS.fileUpload.dropPrefix, 'Drag and drop or')));\nconst resolvedClickToUploadText = computed<string>(() => clickToUploadText ?? t(RUI_I18N_KEYS.fileUpload.clickToUpload, 'click to upload'));\nconst resolvedReplaceText = computed<string>(() => replaceText ?? t(RUI_I18N_KEYS.fileUpload.replace, 'replace file'));\n\ntype WellTone = 'primary' | 'error' | 'success';\n\n// the icon well follows the dropzone's state, like its border\nconst wellTone = computed<WellTone>(() => {\n if (get(hasError))\n return 'error';\n if (uploaded)\n return 'success';\n return 'primary';\n});\n\nconst wellIcon = computed<RuiIcons>(() => {\n const tone = get(wellTone);\n if (tone === 'error')\n return 'lu-circle-alert';\n if (tone === 'success')\n return 'lu-circle-check';\n return 'lu-file-up';\n});\n\n// the 10% tint vanishes on a dark page, so dark doubles it\nconst wellClasses: Record<WellTone, string> = {\n primary: 'bg-rui-primary-soft dark:bg-rui-primary/20',\n error: 'bg-rui-error-soft dark:bg-rui-error/20',\n success: 'bg-rui-success-soft dark:bg-rui-success/20',\n};\n\nfunction matchesAccept(file: File, acceptString: string): boolean {\n if (!acceptString || acceptString === '*' || acceptString === '*/*')\n return true;\n\n const fileName = file.name.toLowerCase();\n const fileExtension = fileName.includes('.') ? fileName.slice(fileName.lastIndexOf('.')) : '';\n const fileType = file.type.toLowerCase();\n const acceptTypes = acceptString.split(',').map(value => value.trim().toLowerCase()).filter(Boolean);\n\n return acceptTypes.some((type) => {\n if (type.startsWith('.'))\n return type === fileExtension;\n if (type.endsWith('/*'))\n return fileType.startsWith(type.slice(0, -1));\n return type === fileType;\n });\n}\n\nfunction reportError(message: string): void {\n set(internalError, message);\n emit('error', message);\n}\n\nfunction clearInternalError(): void {\n set(internalError, '');\n}\n\nfunction validate(candidates: File[]): File[] | undefined {\n if (candidates.length === 0)\n return undefined;\n\n if (!multiple && candidates.length > 1) {\n reportError(t(RUI_I18N_KEYS.fileUpload.tooMany, 'Only one file can be uploaded'));\n return undefined;\n }\n\n for (const file of candidates) {\n if (!matchesAccept(file, accept)) {\n reportError(t(RUI_I18N_KEYS.fileUpload.wrongType, { accept }, `Only ${accept} files are allowed`));\n return undefined;\n }\n if (maxSize !== undefined && file.size > maxSize) {\n const size = formatFileSize(maxSize);\n reportError(t(RUI_I18N_KEYS.fileUpload.tooLarge, { name: file.name, size }, `${file.name} exceeds the maximum size of ${size}`));\n return undefined;\n }\n }\n\n return candidates;\n}\n\nfunction setFiles(candidates: File[]): void {\n const validated = validate(candidates);\n if (!validated)\n return;\n clearInternalError();\n set(modelValue, multiple ? validated : validated[0]);\n}\n\nfunction removeFile(target?: File): void {\n clearInternalError();\n const inputEl = get(input);\n if (inputEl)\n inputEl.value = '';\n\n if (!target || !multiple) {\n set(modelValue, multiple ? [] : undefined);\n return;\n }\n\n const remaining = get(files).filter(file => file !== target);\n set(modelValue, remaining);\n}\n\nfunction onSelect(event: Event): void {\n const target = event.target;\n if (!(target instanceof HTMLInputElement) || !target.files)\n return;\n const picked = Array.from(target.files);\n // the model owns the selection; a cleared input fires `change` for the same file again\n target.value = '';\n setFiles(picked);\n}\n\nfunction onDrop(dropped: File[] | null): void {\n if (disabled || noDrop || !dropped || dropped.length === 0)\n return;\n setFiles(dropped);\n}\n\nconst { isOverDropZone } = useDropZone(wrapper, {\n onDrop,\n});\n\nfunction openPicker(): void {\n if (disabled)\n return;\n get(input)?.click();\n}\n\nwatch(() => errorMessages, () => clearInternalError());\n\ndefineExpose({\n removeFile: () => removeFile(),\n openPicker,\n});\n</script>\n\n<template>\n <div v-bind=\"getRootAttrs($attrs)\">\n <div\n ref=\"wrapper\"\n class=\"p-4 border border-rui-outline dark:border-rui-neutral-400 rounded-rui-panel w-full relative border-dashed transition\"\n :class=\"{\n 'border-rui-primary! bg-rui-primary-subtle': isOverDropZone && !disabled && !noDrop,\n 'border-rui-error! border-solid! bg-rui-error-subtle': hasError,\n 'border-rui-success! border-solid! bg-rui-success-subtle': uploaded,\n 'opacity-60 pointer-events-none': disabled,\n }\"\n :data-disabled=\"disabled || undefined\"\n :data-uploaded=\"uploaded || undefined\"\n :data-error=\"hasError ? '' : undefined\"\n :data-drop-active=\"isOverDropZone || undefined\"\n >\n <div\n class=\"flex flex-col items-center justify-center gap-3\"\n :class=\"{ 'opacity-0': loading }\"\n >\n <slot\n name=\"preview\"\n :files=\"files\"\n :remove=\"() => removeFile()\"\n >\n <div\n v-if=\"hasFiles\"\n class=\"flex flex-col gap-1 w-full\"\n data-id=\"file-list\"\n >\n <div\n v-for=\"file in files\"\n :key=\"`${file.name}-${file.lastModified}`\"\n class=\"flex items-center gap-2 bg-rui-primary-soft dark:bg-rui-primary/20 rounded-full pl-3 pr-1 py-1\"\n data-id=\"file-item\"\n >\n <RuiIcon\n name=\"lu-file\"\n color=\"primary\"\n size=\"20\"\n />\n <div class=\"flex-1 overflow-hidden min-w-0\">\n <div\n class=\"text-sm leading-5 truncate\"\n :title=\"file.name\"\n >\n {{ file.name }}\n </div>\n <div class=\"text-rui-text-secondary text-xs leading-3\">\n {{ formatFileSize(file.size) }}\n </div>\n </div>\n <button\n type=\"button\"\n class=\"p-1 rounded-full hover:bg-rui-hover transition focus-visible:focus-ring outline-hidden\"\n :disabled=\"disabled\"\n :aria-label=\"t(RUI_I18N_KEYS.fileUpload.remove, { name: file.name }, `Remove ${file.name}`)\"\n data-id=\"remove-file\"\n @click=\"removeFile(file)\"\n >\n <RuiIcon\n name=\"lu-x\"\n size=\"16\"\n />\n </button>\n </div>\n </div>\n <div\n v-else\n class=\"h-10 w-10 rounded-full flex items-center justify-center\"\n :class=\"wellClasses[wellTone]\"\n data-id=\"icon-well\"\n >\n <slot name=\"icon\">\n <RuiIcon\n :name=\"wellIcon\"\n :color=\"wellTone\"\n :class=\"{ 'dark:text-rui-primary-lighter': wellTone === 'primary' }\"\n />\n </slot>\n </div>\n </slot>\n\n <div class=\"text-center text-sm\">\n <slot name=\"description\">\n <div class=\"flex items-center justify-center gap-1 flex-wrap\">\n <span v-if=\"resolvedUploadText\">{{ resolvedUploadText }}</span>\n <button\n type=\"button\"\n class=\"text-rui-primary dark:text-rui-primary-lighter underline disabled:no-underline disabled:text-rui-text-disabled\"\n :class=\"{ 'first-letter:uppercase': !resolvedUploadText }\"\n :disabled=\"disabled\"\n data-id=\"open-picker\"\n @click=\"openPicker()\"\n >\n {{ hasFiles ? resolvedReplaceText : resolvedClickToUploadText }}\n </button>\n </div>\n </slot>\n </div>\n\n <input\n ref=\"input\"\n type=\"file\"\n :accept=\"accept\"\n :multiple=\"multiple\"\n :disabled=\"disabled\"\n hidden\n data-id=\"file-input\"\n v-bind=\"getNonRootAttrs($attrs, ['class', 'onChange'])\"\n @change=\"onSelect($event)\"\n />\n </div>\n\n <div\n v-if=\"loading\"\n class=\"flex flex-col items-center justify-center absolute h-full w-full top-0 left-0 gap-2\"\n data-id=\"loading\"\n >\n <RuiProgress\n circular\n :variant=\"progress === undefined ? 'indeterminate' : 'determinate'\"\n :value=\"progress\"\n color=\"primary\"\n size=\"40\"\n />\n <div\n v-if=\"progressLabel\"\n class=\"text-xs text-rui-text-secondary\"\n data-id=\"progress-label\"\n v-text=\"progressLabel\"\n />\n </div>\n </div>\n <RuiFormTextDetail\n v-if=\"detailsMode !== 'hidden'\"\n :details=\"detailsMode\"\n :error-messages=\"combinedErrorMessages\"\n :hint=\"hint\"\n />\n </div>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiRadio.js","names":["_sfc_main"],"sources":["../../../../../src/components/forms/radio-button/radio/RuiRadio.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"TValue\">\nimport type { ContextColorsType } from '@/consts/colors';\nimport { checkControlStyles } from '@/components/forms/check-control-styles';\nimport RuiFormTextDetail from '@/components/helpers/RuiFormTextDetail.vue';\nimport { type FormDetails, useFormDetails, useFormTextDetail } from '@/utils/form-text-detail';\nimport { getNonRootAttrs, getRootAttrs } from '@/utils/helpers';\n\nexport interface RadioProps<TValue> {\n value: TValue;\n disabled?: boolean;\n color?: ContextColorsType;\n size?: 'sm' | 'lg';\n label?: string;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n /** The line under the control for its hint and messages: `reserve`, `auto` or `hidden`; falls back to the nearest `RuiFieldDefaults`, then the app default, then `reserve`. */\n details?: FormDetails;\n /** @deprecated Use `details=\"hidden\"`. Removed in 4.0. */\n hideDetails?: boolean;\n /** Puts the hint or message under the label text instead of under the radio, so a list of radios keeps one text column. */\n detailsUnderLabel?: boolean;\n required?: boolean;\n}\n\ndefineOptions({\n name: 'RuiRadio',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<TValue>({ required: false });\n\nconst {\n value,\n disabled = false,\n color,\n size,\n label = '',\n hint = '',\n errorMessages = [],\n successMessages = [],\n details = undefined,\n hideDetails = false,\n detailsUnderLabel = false,\n required = false,\n} = defineProps<RadioProps<TValue>>();\n\ndefineSlots<{\n default?: () => any;\n}>();\n\nconst { hasError, validation } = useFormTextDetail(\n () => errorMessages,\n () => successMessages,\n);\nconst detailsMode = useFormDetails(() => details, () => hideDetails);\n\nconst selected = computed<boolean>(() => get(modelValue) === value);\n\nconst ui = computed<ReturnType<typeof checkControlStyles>>(() => checkControlStyles({\n size,\n shape: 'round',\n disabled,\n checked: get(selected),\n validation: get(validation),\n color: color ?? 'grey',\n underLabel: detailsUnderLabel,\n}));\n\nfunction input(event: Event): void {\n const target = event.target;\n if (target instanceof HTMLInputElement && target.checked)\n set(modelValue, value);\n}\n</script>\n\n<template>\n <div v-bind=\"getRootAttrs($attrs)\">\n <label\n :class=\"ui.wrapper()\"\n :data-disabled=\"disabled || undefined\"\n :data-checked=\"selected || undefined\"\n :data-error=\"hasError ? '' : undefined\"\n >\n <input\n :checked=\"selected\"\n type=\"radio\"\n :class=\"ui.input()\"\n :disabled=\"disabled\"\n :aria-invalid=\"hasError\"\n v-bind=\"getNonRootAttrs($attrs)\"\n :value=\"value\"\n @input=\"input($event)\"\n />\n <div :class=\"ui.control()\">\n <span\n :class=\"ui.mark()\"\n data-mark\n :data-state=\"selected ? 'checked' : 'unchecked'\"\n >\n <span\n v-if=\"selected\"\n :class=\"ui.dot()\"\n />\n </span>\n </div>\n <div\n v-if=\"label || $slots.default\"\n :class=\"ui.label()\"\n >\n <slot>{{ label }}</slot>\n <span\n v-if=\"required\"\n class=\"text-rui-error\"\n >\n *\n </span>\n </div>\n </label>\n <RuiFormTextDetail\n v-if=\"detailsMode !== 'hidden'\"\n :class=\"ui.details()\"\n :details=\"detailsMode\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n />\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiRadio.js","names":["_sfc_main"],"sources":["../../../../../src/components/forms/radio-button/radio/RuiRadio.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"TValue\">\nimport type { ContextColorsType } from '@/consts/colors';\nimport type { InputAttributes } from '@/types/attributes';\nimport { checkControlStyles } from '@/components/forms/check-control-styles';\nimport RuiFormTextDetail from '@/components/helpers/RuiFormTextDetail.vue';\nimport { type ModelValueEmits, usePropModel } from '@/composables/prop-model';\nimport { type FormDetails, useFormDetails, useFormTextDetail } from '@/utils/form-text-detail';\nimport { getNonRootAttrs, getRootAttrs } from '@/utils/helpers';\n\nexport interface RadioProps<TValue> {\n value: TValue;\n disabled?: boolean;\n color?: ContextColorsType;\n size?: 'sm' | 'lg';\n label?: string;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n /** The line under the control for its hint and messages: `reserve`, `auto` or `hidden`; falls back to the nearest `RuiFieldDefaults`, then the app default, then `reserve`. */\n details?: FormDetails;\n /** @deprecated Use `details=\"hidden\"`. Removed in 4.0. */\n hideDetails?: boolean;\n /** Puts the hint or message under the label text instead of under the radio, so a list of radios keeps one text column. */\n detailsUnderLabel?: boolean;\n required?: boolean;\n}\n\ndefineOptions({\n name: 'RuiRadio',\n inheritAttrs: false,\n});\n\nconst {\n value,\n disabled = false,\n color,\n size,\n label = '',\n hint = '',\n errorMessages = [],\n successMessages = [],\n details = undefined,\n hideDetails = false,\n detailsUnderLabel = false,\n required = false,\n modelValue: modelValueProp,\n} = defineProps<RadioProps<TValue> & {\n /** The checked radio's value. Optional, and only ever updated to this radio's `value`. */\n modelValue?: TValue;\n} & /* @vue-ignore */ Omit<InputAttributes, keyof RadioProps<TValue>>>();\n\ndefineEmits<ModelValueEmits<TValue>>();\n\ndefineSlots<{\n default?: () => any;\n}>();\n\n// a prop and an event rather than `defineModel`, so the update is typed without `undefined`\nconst modelValue = usePropModel('modelValue', () => modelValueProp);\n\nconst { hasError, validation } = useFormTextDetail(\n () => errorMessages,\n () => successMessages,\n);\nconst detailsMode = useFormDetails(() => details, () => hideDetails);\n\nconst selected = computed<boolean>(() => get(modelValue) === value);\n\nconst ui = computed<ReturnType<typeof checkControlStyles>>(() => checkControlStyles({\n size,\n shape: 'round',\n disabled,\n checked: get(selected),\n validation: get(validation),\n color: color ?? 'grey',\n underLabel: detailsUnderLabel,\n}));\n\nfunction input(event: Event): void {\n const target = event.target;\n if (target instanceof HTMLInputElement && target.checked)\n set(modelValue, value);\n}\n</script>\n\n<template>\n <div v-bind=\"getRootAttrs($attrs)\">\n <label\n :class=\"ui.wrapper()\"\n :data-disabled=\"disabled || undefined\"\n :data-checked=\"selected || undefined\"\n :data-error=\"hasError ? '' : undefined\"\n >\n <input\n :checked=\"selected\"\n type=\"radio\"\n :class=\"ui.input()\"\n :disabled=\"disabled\"\n :aria-invalid=\"hasError\"\n v-bind=\"getNonRootAttrs($attrs)\"\n :value=\"value\"\n @input=\"input($event)\"\n />\n <div :class=\"ui.control()\">\n <span\n :class=\"ui.mark()\"\n data-mark\n :data-state=\"selected ? 'checked' : 'unchecked'\"\n >\n <span\n v-if=\"selected\"\n :class=\"ui.dot()\"\n />\n </span>\n </div>\n <div\n v-if=\"label || $slots.default\"\n :class=\"ui.label()\"\n >\n <slot>{{ label }}</slot>\n <span\n v-if=\"required\"\n class=\"text-rui-error\"\n >\n *\n </span>\n </div>\n </label>\n <RuiFormTextDetail\n v-if=\"detailsMode !== 'hidden'\"\n :class=\"ui.details()\"\n :details=\"detailsMode\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n />\n </div>\n</template>\n"],"mappings":""}
@@ -1,4 +1,5 @@
1
1
  import type { ContextColorsType } from '../../../../consts/colors.js';
2
+ import type { InputAttributes } from '../../../../types/attributes.js';
2
3
  import { type FormDetails } from '../../../../utils/form-text-detail.js';
3
4
  export interface RadioProps<TValue> {
4
5
  value: TValue;
@@ -19,9 +20,10 @@ export interface RadioProps<TValue> {
19
20
  }
20
21
  declare const __VLS_export: <TValue>(__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<{
21
22
  props: import("vue").PublicProps & __VLS_PrettifyLocal<(RadioProps<TValue> & {
23
+ /** The checked radio's value. Optional, and only ever updated to this radio's `value`. */
22
24
  modelValue?: TValue;
23
- }) & {
24
- "onUpdate:modelValue"?: ((value: TValue | undefined) => any) | undefined;
25
+ } & Omit<InputAttributes, keyof RadioProps<TValue>>) & {
26
+ "onUpdate:modelValue"?: ((value: TValue) => any) | undefined;
25
27
  }> & (typeof globalThis extends {
26
28
  __VLS_PROPS_FALLBACK: infer P;
27
29
  } ? P : {});
@@ -30,7 +32,7 @@ declare const __VLS_export: <TValue>(__VLS_props: NonNullable<Awaited<typeof __V
30
32
  slots: {
31
33
  default?: () => any;
32
34
  };
33
- emit: (event: "update:modelValue", value: TValue | undefined) => void;
35
+ emit: (evt: "update:modelValue", value: TValue) => void;
34
36
  }>) => import("vue").VNode & {
35
37
  __ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
36
38
  };
@@ -1,9 +1,10 @@
1
1
  import { get, set } from "../../../../vendor/@vueuse/shared/dist/index.js";
2
+ import { usePropModel } from "../../../../composables/prop-model.js";
2
3
  import { useFormDetails, useFormTextDetail } from "../../../../utils/form-text-detail.js";
3
4
  import RuiFormTextDetail_default from "../../../helpers/RuiFormTextDetail.js";
4
5
  import { getNonRootAttrs, getRootAttrs } from "../../../../utils/helpers.js";
5
6
  import { checkControlStyles } from "../../check-control-styles.js";
6
- import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, defineComponent, guardReactiveProps, mergeModels, mergeProps, normalizeClass, normalizeProps, openBlock, renderSlot, toDisplayString, unref, useModel } from "vue";
7
+ import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, defineComponent, guardReactiveProps, mergeProps, normalizeClass, normalizeProps, openBlock, renderSlot, toDisplayString, unref } from "vue";
7
8
  //#region src/components/forms/radio-button/radio/RuiRadio.vue?vue&type=script&setup=true&lang.ts
8
9
  var _hoisted_1 = [
9
10
  "data-disabled",
@@ -25,7 +26,7 @@ var RuiRadio_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
25
26
  name: "RuiRadio",
26
27
  inheritAttrs: false,
27
28
  __name: "RuiRadio",
28
- props: /*@__PURE__*/ mergeModels({
29
+ props: {
29
30
  value: {},
30
31
  disabled: {
31
32
  type: Boolean,
@@ -49,14 +50,12 @@ var RuiRadio_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
49
50
  required: {
50
51
  type: Boolean,
51
52
  default: false
52
- }
53
- }, {
54
- "modelValue": { required: false },
55
- "modelModifiers": {}
56
- }),
53
+ },
54
+ modelValue: {}
55
+ },
57
56
  emits: ["update:modelValue"],
58
57
  setup(__props) {
59
- const modelValue = useModel(__props, "modelValue");
58
+ const modelValue = usePropModel("modelValue", () => __props.modelValue);
60
59
  const { hasError, validation } = useFormTextDetail(() => __props.errorMessages, () => __props.successMessages);
61
60
  const detailsMode = useFormDetails(() => __props.details, () => __props.hideDetails);
62
61
  const selected = computed(() => get(modelValue) === __props.value);
@@ -1 +1 @@
1
- {"version":3,"file":"RuiRadio.vue_vue_type_script_setup_true_lang.js","names":["$attrs","$slots","_useModel","_openBlock","_createElementBlock","_normalizeProps","_guardReactiveProps","_unref","_createElementVNode","_normalizeClass","_mergeProps","_createCommentVNode","_renderSlot","_createTextVNode","_toDisplayString","_createBlock","RuiFormTextDetail"],"sources":["../../../../../src/components/forms/radio-button/radio/RuiRadio.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"TValue\">\nimport type { ContextColorsType } from '@/consts/colors';\nimport { checkControlStyles } from '@/components/forms/check-control-styles';\nimport RuiFormTextDetail from '@/components/helpers/RuiFormTextDetail.vue';\nimport { type FormDetails, useFormDetails, useFormTextDetail } from '@/utils/form-text-detail';\nimport { getNonRootAttrs, getRootAttrs } from '@/utils/helpers';\n\nexport interface RadioProps<TValue> {\n value: TValue;\n disabled?: boolean;\n color?: ContextColorsType;\n size?: 'sm' | 'lg';\n label?: string;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n /** The line under the control for its hint and messages: `reserve`, `auto` or `hidden`; falls back to the nearest `RuiFieldDefaults`, then the app default, then `reserve`. */\n details?: FormDetails;\n /** @deprecated Use `details=\"hidden\"`. Removed in 4.0. */\n hideDetails?: boolean;\n /** Puts the hint or message under the label text instead of under the radio, so a list of radios keeps one text column. */\n detailsUnderLabel?: boolean;\n required?: boolean;\n}\n\ndefineOptions({\n name: 'RuiRadio',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<TValue>({ required: false });\n\nconst {\n value,\n disabled = false,\n color,\n size,\n label = '',\n hint = '',\n errorMessages = [],\n successMessages = [],\n details = undefined,\n hideDetails = false,\n detailsUnderLabel = false,\n required = false,\n} = defineProps<RadioProps<TValue>>();\n\ndefineSlots<{\n default?: () => any;\n}>();\n\nconst { hasError, validation } = useFormTextDetail(\n () => errorMessages,\n () => successMessages,\n);\nconst detailsMode = useFormDetails(() => details, () => hideDetails);\n\nconst selected = computed<boolean>(() => get(modelValue) === value);\n\nconst ui = computed<ReturnType<typeof checkControlStyles>>(() => checkControlStyles({\n size,\n shape: 'round',\n disabled,\n checked: get(selected),\n validation: get(validation),\n color: color ?? 'grey',\n underLabel: detailsUnderLabel,\n}));\n\nfunction input(event: Event): void {\n const target = event.target;\n if (target instanceof HTMLInputElement && target.checked)\n set(modelValue, value);\n}\n</script>\n\n<template>\n <div v-bind=\"getRootAttrs($attrs)\">\n <label\n :class=\"ui.wrapper()\"\n :data-disabled=\"disabled || undefined\"\n :data-checked=\"selected || undefined\"\n :data-error=\"hasError ? '' : undefined\"\n >\n <input\n :checked=\"selected\"\n type=\"radio\"\n :class=\"ui.input()\"\n :disabled=\"disabled\"\n :aria-invalid=\"hasError\"\n v-bind=\"getNonRootAttrs($attrs)\"\n :value=\"value\"\n @input=\"input($event)\"\n />\n <div :class=\"ui.control()\">\n <span\n :class=\"ui.mark()\"\n data-mark\n :data-state=\"selected ? 'checked' : 'unchecked'\"\n >\n <span\n v-if=\"selected\"\n :class=\"ui.dot()\"\n />\n </span>\n </div>\n <div\n v-if=\"label || $slots.default\"\n :class=\"ui.label()\"\n >\n <slot>{{ label }}</slot>\n <span\n v-if=\"required\"\n class=\"text-rui-error\"\n >\n *\n </span>\n </div>\n </label>\n <RuiFormTextDetail\n v-if=\"detailsMode !== 'hidden'\"\n :class=\"ui.details()\"\n :details=\"detailsMode\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n />\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BA,MAAM,aAAaE,SAAmB,SAAA,YAAoB;EAqB1D,MAAM,EAAE,UAAU,eAAe,wBACzB,QAAA,qBACA,QAAA,eACR;EACA,MAAM,cAAc,qBAAqB,QAAA,eAAe,QAAA,WAAW;EAEnE,MAAM,WAAW,eAAwB,IAAI,UAAU,MAAM,QAAA,KAAK;EAElE,MAAM,KAAK,eAAsD,mBAAmB;GAClF,MAAG,QAAA;GACH,OAAO;GACP,UAAO,QAAA;GACP,SAAS,IAAI,QAAQ;GACrB,YAAY,IAAI,UAAU;GAC1B,OAAO,QAAA,SAAS;GAChB,YAAY,QAAA;EACd,CAAC,CAAC;EAEF,SAAS,MAAM,OAAoB;GACjC,MAAM,SAAS,MAAM;GACrB,IAAI,kBAAkB,oBAAoB,OAAO,SAC/C,IAAI,YAAY,QAAA,KAAK;EACzB;;GAIE,OAAAC,UAAA,GAAAC,mBAkDM,OAAAC,eAAAC,mBAlDOC,MAAA,YAAA,CAAY,CAACP,KAAAA,MAAM,CAAA,CAAA,GAAA,CAC9BQ,mBAwCQ,SAAA;IAvCL,OAAKC,eAAEF,MAAA,EAAA,CAAE,CAAC,QAAO,CAAA;IACjB,iBAAe,QAAA,YAAY,KAAA;IAC3B,gBAAcA,MAAA,QAAA,KAAY,KAAA;IAC1B,cAAYA,MAAA,QAAA,IAAQ,KAAQ,KAAA;;IAE7BC,mBASE,SATFE,WASE;KARC,SAASH,MAAA,QAAA;KACV,MAAK;KACJ,OAAOA,MAAA,EAAA,CAAE,CAAC,MAAK;KACf,UAAU,QAAA;KACV,gBAAcA,MAAA,QAAA;IACP,GAAAA,MAAA,eAAA,CAAe,CAACP,KAAAA,MAAM,GAAA;KAC7B,OAAO,QAAA;KACP,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,MAAM,MAAM;;IAEtBQ,mBAWM,OAAA,EAXA,OAAKC,eAAEF,MAAA,EAAA,CAAE,CAAC,QAAO,CAAA,EAAA,GAAA,CACrBC,mBASO,QAAA;KARJ,OAAKC,eAAEF,MAAA,EAAA,CAAE,CAAC,KAAI,CAAA;KACf,aAAA;KACC,cAAYA,MAAA,QAAA,IAAQ,YAAA;IAGbA,GAAAA,CAAAA,MAAA,QAAA,KADRJ,UAAA,GAAAC,mBAGE,QAAA;;KADC,OAAKK,eAAEF,MAAA,EAAA,CAAE,CAAC,IAAG,CAAA;;IAKZ,QAAA,SAASN,KAAAA,OAAO,WADxBE,UAAA,GAAAC,mBAWM,OAAA;;KATH,OAAKK,eAAEF,MAAA,EAAA,CAAE,CAAC,MAAK,CAAA;IAEhBK,GAAAA,CAAAA,WAAwB,KAAA,QAAA,WAAA,CAAA,SAAA,CAAfC,gBAAAC,gBAAA,QAAA,KAAK,GAAA,CAAA,CAAA,CAAA,GAEN,QAAA,YADRX,UAAA,GAAAC,mBAKO,QALP,YAGC,KAED,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;GAIIG,GAAAA,IAAAA,UAAAA,GAAAA,MAAA,WAAA,MAAW,YADnBJ,UAAA,GAAAY,YAOEC,2BAAA;;IALC,OAAKP,eAAEF,MAAA,EAAA,CAAE,CAAC,QAAO,CAAA;IACjB,SAASA,MAAA,WAAA;IACT,kBAAgB,QAAA;IAChB,oBAAkB,QAAA;IAClB,MAAM,QAAA"}
1
+ {"version":3,"file":"RuiRadio.vue_vue_type_script_setup_true_lang.js","names":["$attrs","$slots","_openBlock","_createElementBlock","_normalizeProps","_guardReactiveProps","_unref","_createElementVNode","_normalizeClass","_mergeProps","_createCommentVNode","_renderSlot","_createTextVNode","_toDisplayString","_createBlock","RuiFormTextDetail"],"sources":["../../../../../src/components/forms/radio-button/radio/RuiRadio.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"TValue\">\nimport type { ContextColorsType } from '@/consts/colors';\nimport type { InputAttributes } from '@/types/attributes';\nimport { checkControlStyles } from '@/components/forms/check-control-styles';\nimport RuiFormTextDetail from '@/components/helpers/RuiFormTextDetail.vue';\nimport { type ModelValueEmits, usePropModel } from '@/composables/prop-model';\nimport { type FormDetails, useFormDetails, useFormTextDetail } from '@/utils/form-text-detail';\nimport { getNonRootAttrs, getRootAttrs } from '@/utils/helpers';\n\nexport interface RadioProps<TValue> {\n value: TValue;\n disabled?: boolean;\n color?: ContextColorsType;\n size?: 'sm' | 'lg';\n label?: string;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n /** The line under the control for its hint and messages: `reserve`, `auto` or `hidden`; falls back to the nearest `RuiFieldDefaults`, then the app default, then `reserve`. */\n details?: FormDetails;\n /** @deprecated Use `details=\"hidden\"`. Removed in 4.0. */\n hideDetails?: boolean;\n /** Puts the hint or message under the label text instead of under the radio, so a list of radios keeps one text column. */\n detailsUnderLabel?: boolean;\n required?: boolean;\n}\n\ndefineOptions({\n name: 'RuiRadio',\n inheritAttrs: false,\n});\n\nconst {\n value,\n disabled = false,\n color,\n size,\n label = '',\n hint = '',\n errorMessages = [],\n successMessages = [],\n details = undefined,\n hideDetails = false,\n detailsUnderLabel = false,\n required = false,\n modelValue: modelValueProp,\n} = defineProps<RadioProps<TValue> & {\n /** The checked radio's value. Optional, and only ever updated to this radio's `value`. */\n modelValue?: TValue;\n} & /* @vue-ignore */ Omit<InputAttributes, keyof RadioProps<TValue>>>();\n\ndefineEmits<ModelValueEmits<TValue>>();\n\ndefineSlots<{\n default?: () => any;\n}>();\n\n// a prop and an event rather than `defineModel`, so the update is typed without `undefined`\nconst modelValue = usePropModel('modelValue', () => modelValueProp);\n\nconst { hasError, validation } = useFormTextDetail(\n () => errorMessages,\n () => successMessages,\n);\nconst detailsMode = useFormDetails(() => details, () => hideDetails);\n\nconst selected = computed<boolean>(() => get(modelValue) === value);\n\nconst ui = computed<ReturnType<typeof checkControlStyles>>(() => checkControlStyles({\n size,\n shape: 'round',\n disabled,\n checked: get(selected),\n validation: get(validation),\n color: color ?? 'grey',\n underLabel: detailsUnderLabel,\n}));\n\nfunction input(event: Event): void {\n const target = event.target;\n if (target instanceof HTMLInputElement && target.checked)\n set(modelValue, value);\n}\n</script>\n\n<template>\n <div v-bind=\"getRootAttrs($attrs)\">\n <label\n :class=\"ui.wrapper()\"\n :data-disabled=\"disabled || undefined\"\n :data-checked=\"selected || undefined\"\n :data-error=\"hasError ? '' : undefined\"\n >\n <input\n :checked=\"selected\"\n type=\"radio\"\n :class=\"ui.input()\"\n :disabled=\"disabled\"\n :aria-invalid=\"hasError\"\n v-bind=\"getNonRootAttrs($attrs)\"\n :value=\"value\"\n @input=\"input($event)\"\n />\n <div :class=\"ui.control()\">\n <span\n :class=\"ui.mark()\"\n data-mark\n :data-state=\"selected ? 'checked' : 'unchecked'\"\n >\n <span\n v-if=\"selected\"\n :class=\"ui.dot()\"\n />\n </span>\n </div>\n <div\n v-if=\"label || $slots.default\"\n :class=\"ui.label()\"\n >\n <slot>{{ label }}</slot>\n <span\n v-if=\"required\"\n class=\"text-rui-error\"\n >\n *\n </span>\n </div>\n </label>\n <RuiFormTextDetail\n v-if=\"detailsMode !== 'hidden'\"\n :class=\"ui.details()\"\n :details=\"detailsMode\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n />\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0DA,MAAM,aAAa,aAAa,oBAAoB,QAAA,UAAc;EAElE,MAAM,EAAE,UAAU,eAAe,wBACzB,QAAA,qBACA,QAAA,eACR;EACA,MAAM,cAAc,qBAAqB,QAAA,eAAe,QAAA,WAAW;EAEnE,MAAM,WAAW,eAAwB,IAAI,UAAU,MAAM,QAAA,KAAK;EAElE,MAAM,KAAK,eAAsD,mBAAmB;GAClF,MAAG,QAAA;GACH,OAAO;GACP,UAAO,QAAA;GACP,SAAS,IAAI,QAAQ;GACrB,YAAY,IAAI,UAAU;GAC1B,OAAO,QAAA,SAAS;GAChB,YAAY,QAAA;EACd,CAAC,CAAC;EAEF,SAAS,MAAM,OAAoB;GACjC,MAAM,SAAS,MAAM;GACrB,IAAI,kBAAkB,oBAAoB,OAAO,SAC/C,IAAI,YAAY,QAAA,KAAK;EACzB;;GAIE,OAAAE,UAAA,GAAAC,mBAkDM,OAAAC,eAAAC,mBAlDOC,MAAA,YAAA,CAAY,CAACN,KAAAA,MAAM,CAAA,CAAA,GAAA,CAC9BO,mBAwCQ,SAAA;IAvCL,OAAKC,eAAEF,MAAA,EAAA,CAAE,CAAC,QAAO,CAAA;IACjB,iBAAe,QAAA,YAAY,KAAA;IAC3B,gBAAcA,MAAA,QAAA,KAAY,KAAA;IAC1B,cAAYA,MAAA,QAAA,IAAQ,KAAQ,KAAA;;IAE7BC,mBASE,SATFE,WASE;KARC,SAASH,MAAA,QAAA;KACV,MAAK;KACJ,OAAOA,MAAA,EAAA,CAAE,CAAC,MAAK;KACf,UAAU,QAAA;KACV,gBAAcA,MAAA,QAAA;IACP,GAAAA,MAAA,eAAA,CAAe,CAACN,KAAAA,MAAM,GAAA;KAC7B,OAAO,QAAA;KACP,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,MAAM,MAAM;;IAEtBO,mBAWM,OAAA,EAXA,OAAKC,eAAEF,MAAA,EAAA,CAAE,CAAC,QAAO,CAAA,EAAA,GAAA,CACrBC,mBASO,QAAA;KARJ,OAAKC,eAAEF,MAAA,EAAA,CAAE,CAAC,KAAI,CAAA;KACf,aAAA;KACC,cAAYA,MAAA,QAAA,IAAQ,YAAA;IAGbA,GAAAA,CAAAA,MAAA,QAAA,KADRJ,UAAA,GAAAC,mBAGE,QAAA;;KADC,OAAKK,eAAEF,MAAA,EAAA,CAAE,CAAC,IAAG,CAAA;;IAKZ,QAAA,SAASL,KAAAA,OAAO,WADxBC,UAAA,GAAAC,mBAWM,OAAA;;KATH,OAAKK,eAAEF,MAAA,EAAA,CAAE,CAAC,MAAK,CAAA;IAEhBK,GAAAA,CAAAA,WAAwB,KAAA,QAAA,WAAA,CAAA,SAAA,CAAfC,gBAAAC,gBAAA,QAAA,KAAK,GAAA,CAAA,CAAA,CAAA,GAEN,QAAA,YADRX,UAAA,GAAAC,mBAKO,QALP,YAGC,KAED,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;GAIIG,GAAAA,IAAAA,UAAAA,GAAAA,MAAA,WAAA,MAAW,YADnBJ,UAAA,GAAAY,YAOEC,2BAAA;;IALC,OAAKP,eAAEF,MAAA,EAAA,CAAE,CAAC,QAAO,CAAA;IACjB,SAASA,MAAA,WAAA;IACT,kBAAgB,QAAA;IAChB,oBAAkB,QAAA;IAClB,MAAM,QAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiRadioGroup.js","names":["_sfc_main"],"sources":["../../../../../src/components/forms/radio-button/radio-group/RuiRadioGroup.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"TValue\">\nimport type { ContextColorsType } from '@/consts/colors';\nimport { Fragment, isVNode } from 'vue';\nimport RuiFormTextDetail from '@/components/helpers/RuiFormTextDetail.vue';\nimport { assert } from '@/utils/assert';\nimport { type FormDetails, useFormDetails } from '@/utils/form-text-detail';\n\nexport interface Props {\n inline?: boolean;\n label?: string;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n /** The line under the group for its hint and messages: `reserve`, `auto` or `hidden`; falls back to the nearest `RuiFieldDefaults`, then the app default, then `reserve`. */\n details?: FormDetails;\n /** @deprecated Use `details=\"hidden\"`. Removed in 4.0. */\n hideDetails?: boolean;\n disabled?: boolean;\n color?: ContextColorsType;\n size?: 'sm' | 'lg';\n required?: boolean;\n}\n\ndefineOptions({\n name: 'RuiRadioGroup',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<TValue>({ required: false });\n\nconst {\n inline = false,\n label = '',\n hint = '',\n errorMessages = [],\n successMessages = [],\n details = undefined,\n hideDetails = false,\n disabled = false,\n color,\n size,\n required = false,\n} = defineProps<Props>();\n\nconst slots = defineSlots<{\n default?: () => any;\n}>();\n\nconst radioGroupName = useId();\nconst detailsMode = useFormDetails(() => details, () => hideDetails);\n\nconst children = computed<VNode[]>(() => {\n const slotContent = slots.default?.() ?? [];\n\n // A `v-for` in the slot arrives as a single fragment holding the children\n if (slotContent.length === 1) {\n const firstChild = slotContent[0];\n assert(firstChild);\n if (firstChild.type === Fragment) {\n return Array.isArray(firstChild.children) ? firstChild.children.filter(isVNode) : [];\n }\n }\n return slotContent;\n});\n</script>\n\n<template>\n <div\n role=\"radiogroup\"\n v-bind=\"$attrs\"\n >\n <div\n v-if=\"label\"\n class=\"text-rui-text text-sm/5 font-medium\"\n >\n {{ label }}\n <span\n v-if=\"required\"\n class=\"text-rui-error\"\n >\n *\n </span>\n </div>\n <div :class=\"{ 'flex between:ml-6 between:mr-0': inline }\">\n <Component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n v-model=\"modelValue\"\n :disabled=\"disabled\"\n :color=\"color\"\n :size=\"size\"\n details=\"hidden\"\n :name=\"radioGroupName\"\n />\n </div>\n <RuiFormTextDetail\n v-if=\"detailsMode !== 'hidden'\"\n :details=\"detailsMode\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n />\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiRadioGroup.js","names":["_sfc_main"],"sources":["../../../../../src/components/forms/radio-button/radio-group/RuiRadioGroup.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"TValue\">\nimport type { ContextColorsType } from '@/consts/colors';\nimport { Fragment, type HTMLAttributes, isVNode } from 'vue';\nimport RuiFormTextDetail from '@/components/helpers/RuiFormTextDetail.vue';\nimport { type ModelValueEmits, usePropModel } from '@/composables/prop-model';\nimport { assert } from '@/utils/assert';\nimport { type FormDetails, useFormDetails } from '@/utils/form-text-detail';\n\nexport interface Props {\n inline?: boolean;\n label?: string;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n /** The line under the group for its hint and messages: `reserve`, `auto` or `hidden`; falls back to the nearest `RuiFieldDefaults`, then the app default, then `reserve`. */\n details?: FormDetails;\n /** @deprecated Use `details=\"hidden\"`. Removed in 4.0. */\n hideDetails?: boolean;\n disabled?: boolean;\n color?: ContextColorsType;\n size?: 'sm' | 'lg';\n required?: boolean;\n}\n\ndefineOptions({\n name: 'RuiRadioGroup',\n inheritAttrs: false,\n});\n\nconst {\n inline = false,\n label = '',\n hint = '',\n errorMessages = [],\n successMessages = [],\n details = undefined,\n hideDetails = false,\n disabled = false,\n color,\n size,\n required = false,\n modelValue: modelValueProp,\n} = defineProps<Props & {\n /** The checked radio's value. Optional, and only ever updated to a radio's value. */\n modelValue?: TValue;\n} & /* @vue-ignore */ Omit<HTMLAttributes, keyof Props>>();\n\ndefineEmits<ModelValueEmits<TValue>>();\n\nconst slots = defineSlots<{\n default?: () => any;\n}>();\n\n// a prop and an event rather than `defineModel`, so the update is typed without `undefined`\nconst modelValue = usePropModel('modelValue', () => modelValueProp);\n\nconst radioGroupName = useId();\nconst detailsMode = useFormDetails(() => details, () => hideDetails);\n\nconst children = computed<VNode[]>(() => {\n const slotContent = slots.default?.() ?? [];\n\n // A `v-for` in the slot arrives as a single fragment holding the children\n if (slotContent.length === 1) {\n const firstChild = slotContent[0];\n assert(firstChild);\n if (firstChild.type === Fragment) {\n return Array.isArray(firstChild.children) ? firstChild.children.filter(isVNode) : [];\n }\n }\n return slotContent;\n});\n</script>\n\n<template>\n <div\n role=\"radiogroup\"\n v-bind=\"$attrs\"\n >\n <div\n v-if=\"label\"\n class=\"text-rui-text text-sm/5 font-medium\"\n >\n {{ label }}\n <span\n v-if=\"required\"\n class=\"text-rui-error\"\n >\n *\n </span>\n </div>\n <div :class=\"{ 'flex between:ml-6 between:mr-0': inline }\">\n <component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n v-model=\"modelValue\"\n :disabled=\"disabled\"\n :color=\"color\"\n :size=\"size\"\n details=\"hidden\"\n :name=\"radioGroupName\"\n />\n </div>\n <RuiFormTextDetail\n v-if=\"detailsMode !== 'hidden'\"\n :details=\"detailsMode\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n />\n </div>\n</template>\n"],"mappings":""}
@@ -1,4 +1,5 @@
1
1
  import type { ContextColorsType } from '../../../../consts/colors.js';
2
+ import { type HTMLAttributes } from 'vue';
2
3
  import { type FormDetails } from '../../../../utils/form-text-detail.js';
3
4
  export interface Props {
4
5
  inline?: boolean;
@@ -17,9 +18,10 @@ export interface Props {
17
18
  }
18
19
  declare const __VLS_export: <TValue>(__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<{
19
20
  props: import("vue").PublicProps & __VLS_PrettifyLocal<(Props & {
21
+ /** The checked radio's value. Optional, and only ever updated to a radio's value. */
20
22
  modelValue?: TValue;
21
- }) & {
22
- "onUpdate:modelValue"?: ((value: TValue | undefined) => any) | undefined;
23
+ } & Omit<HTMLAttributes, keyof Props>) & {
24
+ "onUpdate:modelValue"?: ((value: TValue) => any) | undefined;
23
25
  }> & (typeof globalThis extends {
24
26
  __VLS_PROPS_FALLBACK: infer P;
25
27
  } ? P : {});
@@ -28,7 +30,7 @@ declare const __VLS_export: <TValue>(__VLS_props: NonNullable<Awaited<typeof __V
28
30
  slots: {
29
31
  default?: () => any;
30
32
  };
31
- emit: (event: "update:modelValue", value: TValue | undefined) => void;
33
+ emit: (evt: "update:modelValue", value: TValue) => void;
32
34
  }>) => import("vue").VNode & {
33
35
  __ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
34
36
  };
@@ -1,7 +1,8 @@
1
1
  import { assert } from "../../../../utils/assert.js";
2
+ import { usePropModel } from "../../../../composables/prop-model.js";
2
3
  import { useFormDetails } from "../../../../utils/form-text-detail.js";
3
4
  import RuiFormTextDetail_default from "../../../helpers/RuiFormTextDetail.js";
4
- import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, defineComponent, isVNode, mergeModels, mergeProps, normalizeClass, openBlock, renderList, resolveDynamicComponent, toDisplayString, unref, useId, useModel, useSlots } from "vue";
5
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, defineComponent, isRef, isVNode, mergeProps, normalizeClass, openBlock, renderList, resolveDynamicComponent, toDisplayString, unref, useId, useSlots } from "vue";
5
6
  //#region src/components/forms/radio-button/radio-group/RuiRadioGroup.vue?vue&type=script&setup=true&lang.ts
6
7
  var _hoisted_1 = {
7
8
  key: 0,
@@ -15,7 +16,7 @@ var RuiRadioGroup_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
15
16
  name: "RuiRadioGroup",
16
17
  inheritAttrs: false,
17
18
  __name: "RuiRadioGroup",
18
- props: /*@__PURE__*/ mergeModels({
19
+ props: {
19
20
  inline: {
20
21
  type: Boolean,
21
22
  default: false
@@ -38,15 +39,13 @@ var RuiRadioGroup_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
38
39
  required: {
39
40
  type: Boolean,
40
41
  default: false
41
- }
42
- }, {
43
- "modelValue": { required: false },
44
- "modelModifiers": {}
45
- }),
42
+ },
43
+ modelValue: {}
44
+ },
46
45
  emits: ["update:modelValue"],
47
46
  setup(__props) {
48
- const modelValue = useModel(__props, "modelValue");
49
47
  const slots = useSlots();
48
+ const modelValue = usePropModel("modelValue", () => __props.modelValue);
50
49
  const radioGroupName = useId();
51
50
  const detailsMode = useFormDetails(() => __props.details, () => __props.hideDetails);
52
51
  const children = computed(() => {
@@ -64,8 +63,8 @@ var RuiRadioGroup_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
64
63
  createElementVNode("div", { class: normalizeClass({ "flex between:ml-6 between:mr-0": __props.inline }) }, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(children), (child, i) => {
65
64
  return openBlock(), createBlock(resolveDynamicComponent(child), {
66
65
  key: i,
67
- modelValue: modelValue.value,
68
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => modelValue.value = $event),
66
+ modelValue: unref(modelValue),
67
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isRef(modelValue) ? modelValue.value = $event : null),
69
68
  disabled: __props.disabled,
70
69
  color: __props.color,
71
70
  size: __props.size,
@@ -1 +1 @@
1
- {"version":3,"file":"RuiRadioGroup.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_useModel","_useSlots","_openBlock","_createElementBlock","_mergeProps","_createTextVNode","_toDisplayString","_createCommentVNode","_createElementVNode","_normalizeClass","_Fragment","_renderList","_unref","_createBlock","_resolveDynamicComponent","RuiFormTextDetail"],"sources":["../../../../../src/components/forms/radio-button/radio-group/RuiRadioGroup.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"TValue\">\nimport type { ContextColorsType } from '@/consts/colors';\nimport { Fragment, isVNode } from 'vue';\nimport RuiFormTextDetail from '@/components/helpers/RuiFormTextDetail.vue';\nimport { assert } from '@/utils/assert';\nimport { type FormDetails, useFormDetails } from '@/utils/form-text-detail';\n\nexport interface Props {\n inline?: boolean;\n label?: string;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n /** The line under the group for its hint and messages: `reserve`, `auto` or `hidden`; falls back to the nearest `RuiFieldDefaults`, then the app default, then `reserve`. */\n details?: FormDetails;\n /** @deprecated Use `details=\"hidden\"`. Removed in 4.0. */\n hideDetails?: boolean;\n disabled?: boolean;\n color?: ContextColorsType;\n size?: 'sm' | 'lg';\n required?: boolean;\n}\n\ndefineOptions({\n name: 'RuiRadioGroup',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<TValue>({ required: false });\n\nconst {\n inline = false,\n label = '',\n hint = '',\n errorMessages = [],\n successMessages = [],\n details = undefined,\n hideDetails = false,\n disabled = false,\n color,\n size,\n required = false,\n} = defineProps<Props>();\n\nconst slots = defineSlots<{\n default?: () => any;\n}>();\n\nconst radioGroupName = useId();\nconst detailsMode = useFormDetails(() => details, () => hideDetails);\n\nconst children = computed<VNode[]>(() => {\n const slotContent = slots.default?.() ?? [];\n\n // A `v-for` in the slot arrives as a single fragment holding the children\n if (slotContent.length === 1) {\n const firstChild = slotContent[0];\n assert(firstChild);\n if (firstChild.type === Fragment) {\n return Array.isArray(firstChild.children) ? firstChild.children.filter(isVNode) : [];\n }\n }\n return slotContent;\n});\n</script>\n\n<template>\n <div\n role=\"radiogroup\"\n v-bind=\"$attrs\"\n >\n <div\n v-if=\"label\"\n class=\"text-rui-text text-sm/5 font-medium\"\n >\n {{ label }}\n <span\n v-if=\"required\"\n class=\"text-rui-error\"\n >\n *\n </span>\n </div>\n <div :class=\"{ 'flex between:ml-6 between:mr-0': inline }\">\n <Component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n v-model=\"modelValue\"\n :disabled=\"disabled\"\n :color=\"color\"\n :size=\"size\"\n details=\"hidden\"\n :name=\"radioGroupName\"\n />\n </div>\n <RuiFormTextDetail\n v-if=\"detailsMode !== 'hidden'\"\n :details=\"detailsMode\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n />\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BA,MAAM,aAAaC,SAAmB,SAAA,YAAoB;EAgB1D,MAAM,QAAQC,SAAA;EAId,MAAM,iBAAiB,MAAM;EAC7B,MAAM,cAAc,qBAAqB,QAAA,eAAe,QAAA,WAAW;EAEnE,MAAM,WAAW,eAAwB;GACvC,MAAM,cAAc,MAAM,UAAU,KAAK,CAAC;GAG1C,IAAI,YAAY,WAAW,GAAG;IAC5B,MAAM,aAAa,YAAY;IAC/B,OAAO,UAAU;IACjB,IAAI,WAAW,SAAS,UACtB,OAAO,MAAM,QAAQ,WAAW,QAAQ,IAAI,WAAW,SAAS,OAAO,OAAO,IAAI,CAAC;GAEvF;GACA,OAAO;EACT,CAAC;;GAIC,OAAAC,UAAA,GAAAC,mBAoCM,OApCNC,WAoCM,EAnCJ,MAAK,aAAY,GACTL,KAAAA,MAAM,GAAA;IAGN,QAAA,SADRG,UAAA,GAAAC,mBAWM,OAXN,YAWM,CAPDE,gBAAAC,gBAAA,QAAA,KAAK,IAAG,KACX,CAAA,GACQ,QAAA,YADRJ,UAAA,GAAAC,mBAKO,QALP,YAGC,KAED,KAAA,mBAAA,IAAA,IAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;IAEFK,mBAYM,OAAA,EAZA,OAAKC,eAAA,EAAA,kCAAsC,QAAA,OAAM,CAAA,EAAA,GAAA,EACrDP,UAAA,IAAA,GAAAC,mBAUEO,UAAA,MAAAC,WARqBC,MAAA,QAAA,IAAb,OAAO,MAAC;KAFlB,OAAAV,UAAA,GAAAW,YAUEC,wBATK,KAAK,GAAA;MAET,KAAK;MACG,YAAA,WAAA;MAAA,uBAAA,OAAA,OAAA,OAAA,MAAA,WAAA,WAAU,QAAA;MAClB,UAAU,QAAA;MACV,OAAO,QAAA;MACP,MAAM,QAAA;MACP,SAAQ;MACP,MAAMF,MAAA,cAAA;;;;;;;;;IAIHA,MAAA,WAAA,MAAW,YADnBV,UAAA,GAAAW,YAMEE,2BAAA;;KAJC,SAASH,MAAA,WAAA;KACT,kBAAgB,QAAA;KAChB,oBAAkB,QAAA;KAClB,MAAM,QAAA"}
1
+ {"version":3,"file":"RuiRadioGroup.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_useSlots","_openBlock","_createElementBlock","_mergeProps","_createTextVNode","_toDisplayString","_createCommentVNode","_createElementVNode","_normalizeClass","_Fragment","_renderList","_unref","_createBlock","_resolveDynamicComponent","_isRef","RuiFormTextDetail"],"sources":["../../../../../src/components/forms/radio-button/radio-group/RuiRadioGroup.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"TValue\">\nimport type { ContextColorsType } from '@/consts/colors';\nimport { Fragment, type HTMLAttributes, isVNode } from 'vue';\nimport RuiFormTextDetail from '@/components/helpers/RuiFormTextDetail.vue';\nimport { type ModelValueEmits, usePropModel } from '@/composables/prop-model';\nimport { assert } from '@/utils/assert';\nimport { type FormDetails, useFormDetails } from '@/utils/form-text-detail';\n\nexport interface Props {\n inline?: boolean;\n label?: string;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n /** The line under the group for its hint and messages: `reserve`, `auto` or `hidden`; falls back to the nearest `RuiFieldDefaults`, then the app default, then `reserve`. */\n details?: FormDetails;\n /** @deprecated Use `details=\"hidden\"`. Removed in 4.0. */\n hideDetails?: boolean;\n disabled?: boolean;\n color?: ContextColorsType;\n size?: 'sm' | 'lg';\n required?: boolean;\n}\n\ndefineOptions({\n name: 'RuiRadioGroup',\n inheritAttrs: false,\n});\n\nconst {\n inline = false,\n label = '',\n hint = '',\n errorMessages = [],\n successMessages = [],\n details = undefined,\n hideDetails = false,\n disabled = false,\n color,\n size,\n required = false,\n modelValue: modelValueProp,\n} = defineProps<Props & {\n /** The checked radio's value. Optional, and only ever updated to a radio's value. */\n modelValue?: TValue;\n} & /* @vue-ignore */ Omit<HTMLAttributes, keyof Props>>();\n\ndefineEmits<ModelValueEmits<TValue>>();\n\nconst slots = defineSlots<{\n default?: () => any;\n}>();\n\n// a prop and an event rather than `defineModel`, so the update is typed without `undefined`\nconst modelValue = usePropModel('modelValue', () => modelValueProp);\n\nconst radioGroupName = useId();\nconst detailsMode = useFormDetails(() => details, () => hideDetails);\n\nconst children = computed<VNode[]>(() => {\n const slotContent = slots.default?.() ?? [];\n\n // A `v-for` in the slot arrives as a single fragment holding the children\n if (slotContent.length === 1) {\n const firstChild = slotContent[0];\n assert(firstChild);\n if (firstChild.type === Fragment) {\n return Array.isArray(firstChild.children) ? firstChild.children.filter(isVNode) : [];\n }\n }\n return slotContent;\n});\n</script>\n\n<template>\n <div\n role=\"radiogroup\"\n v-bind=\"$attrs\"\n >\n <div\n v-if=\"label\"\n class=\"text-rui-text text-sm/5 font-medium\"\n >\n {{ label }}\n <span\n v-if=\"required\"\n class=\"text-rui-error\"\n >\n *\n </span>\n </div>\n <div :class=\"{ 'flex between:ml-6 between:mr-0': inline }\">\n <component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n v-model=\"modelValue\"\n :disabled=\"disabled\"\n :color=\"color\"\n :size=\"size\"\n details=\"hidden\"\n :name=\"radioGroupName\"\n />\n </div>\n <RuiFormTextDetail\n v-if=\"detailsMode !== 'hidden'\"\n :details=\"detailsMode\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n />\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiDA,MAAM,QAAQC,SAAA;EAKd,MAAM,aAAa,aAAa,oBAAoB,QAAA,UAAc;EAElE,MAAM,iBAAiB,MAAM;EAC7B,MAAM,cAAc,qBAAqB,QAAA,eAAe,QAAA,WAAW;EAEnE,MAAM,WAAW,eAAwB;GACvC,MAAM,cAAc,MAAM,UAAU,KAAK,CAAC;GAG1C,IAAI,YAAY,WAAW,GAAG;IAC5B,MAAM,aAAa,YAAY;IAC/B,OAAO,UAAU;IACjB,IAAI,WAAW,SAAS,UACtB,OAAO,MAAM,QAAQ,WAAW,QAAQ,IAAI,WAAW,SAAS,OAAO,OAAO,IAAI,CAAC;GAEvF;GACA,OAAO;EACT,CAAC;;GAIC,OAAAC,UAAA,GAAAC,mBAoCM,OApCNC,WAoCM,EAnCJ,MAAK,aAAY,GACTJ,KAAAA,MAAM,GAAA;IAGN,QAAA,SADRE,UAAA,GAAAC,mBAWM,OAXN,YAWM,CAPDE,gBAAAC,gBAAA,QAAA,KAAK,IAAG,KACX,CAAA,GACQ,QAAA,YADRJ,UAAA,GAAAC,mBAKO,QALP,YAGC,KAED,KAAA,mBAAA,IAAA,IAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;IAEFK,mBAYM,OAAA,EAZA,OAAKC,eAAA,EAAA,kCAAsC,QAAA,OAAM,CAAA,EAAA,GAAA,EACrDP,UAAA,IAAA,GAAAC,mBAUEO,UAAA,MAAAC,WARqBC,MAAA,QAAA,IAAb,OAAO,MAAC;KAFlB,OAAAV,UAAA,GAAAW,YAUEC,wBATK,KAAK,GAAA;MAET,KAAK;MACG,YAAAF,MAAA,UAAA;MAAA,uBAAA,OAAA,OAAA,OAAA,MAAA,WAAAG,MAAA,UAAA,IAAA,WAAU,QAAA,SAAA;MAClB,UAAU,QAAA;MACV,OAAO,QAAA;MACP,MAAM,QAAA;MACP,SAAQ;MACP,MAAMH,MAAA,cAAA;;;;;;;;;IAIHA,MAAA,WAAA,MAAW,YADnBV,UAAA,GAAAW,YAMEG,2BAAA;;KAJC,SAASJ,MAAA,WAAA;KACT,kBAAgB,QAAA;KAChB,oBAAkB,QAAA;KAClB,MAAM,QAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiRevealableTextField.js","names":["_sfc_main"],"sources":["../../../../src/components/forms/revealable-text-field/RuiRevealableTextField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiTextField, { type TextFieldProps } from '@/components/forms/text-field/RuiTextField.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\n\nexport interface Props extends TextFieldProps {}\n\ndefineOptions({\n name: 'RuiRevealableTextField',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<string>({ required: true });\n\nconst {\n label = '',\n placeholder = '',\n disabled = false,\n labelPlacement = undefined,\n dense = false,\n hint = '',\n errorMessages = [],\n successMessages = [],\n details = undefined,\n hideDetails = false,\n readonly = false,\n clearable = false,\n required = false,\n} = defineProps<Props>();\n\ndefineSlots<{\n prepend?: () => any;\n append?: () => any;\n}>();\n\nconst hidden = ref<boolean>(true);\n</script>\n\n<template>\n <RuiTextField\n v-bind=\"$attrs\"\n v-model=\"modelValue\"\n :label=\"label\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :label-placement=\"labelPlacement\"\n :dense=\"dense\"\n :hint=\"hint\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :details=\"hideDetails ? 'hidden' : details\"\n :readonly=\"readonly\"\n :clearable=\"clearable\"\n :required=\"required\"\n :type=\"hidden ? 'password' : 'text'\"\n >\n <template\n v-if=\"$slots.prepend\"\n #prepend\n >\n <slot name=\"prepend\" />\n </template>\n <template #append>\n <div class=\"flex items-center\">\n <RuiButton\n :disabled=\"disabled\"\n :aria-label=\"hidden ? 'Show password' : 'Hide password'\"\n tabindex=\"-1\"\n variant=\"text\"\n type=\"button\"\n icon\n data-id=\"toggle-visibility\"\n class=\"-mr-1 p-1!\"\n @click=\"hidden = !hidden\"\n >\n <!--\n 24px round the field's 16px glyph, so the focus ring and its offset stay inside even the 32px\n dense field; the muted tone of the other field icons\n -->\n <RuiIcon\n class=\"text-rui-neutral-500 dark:text-rui-neutral-400\"\n size=\"16\"\n :name=\"hidden ? 'lu-eye-off' : 'lu-eye'\"\n />\n </RuiButton>\n\n <slot name=\"append\" />\n </div>\n </template>\n </RuiTextField>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiRevealableTextField.js","names":["_sfc_main"],"sources":["../../../../src/components/forms/revealable-text-field/RuiRevealableTextField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiTextField, { type TextFieldProps } from '@/components/forms/text-field/RuiTextField.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\n\nexport interface Props extends TextFieldProps {}\n\n/**\n * What the field forwards to its RuiTextField through `$attrs`: the input's attributes and the text\n * field's events (`blur`, `clear`, `focus-input`, `remove`). The field sets `type` itself. A template\n * listener `@focus-input` is checked as `onFocusInput`, which Vue also matches at runtime.\n */\ntype TextFieldAttributes = Omit<InstanceType<typeof RuiTextField>['$props'], keyof Props | 'modelValue' | 'onUpdate:modelValue' | 'modelModifiers' | 'type'>\n & Partial<Record<'onFocusInput', (event: Event) => void>>;\n\ndefineOptions({\n name: 'RuiRevealableTextField',\n inheritAttrs: false,\n});\n\n// `v-model.trim` trims the update, which Vue applies to any model event\nconst modelValue = defineModel<string, 'trim'>({ required: true });\n\nconst {\n label = '',\n placeholder = '',\n disabled = false,\n labelPlacement = undefined,\n dense = false,\n hint = '',\n errorMessages = [],\n successMessages = [],\n details = undefined,\n hideDetails = false,\n readonly = false,\n clearable = false,\n required = false,\n} = defineProps<Props & /* @vue-ignore */ TextFieldAttributes>();\n\ndefineSlots<{\n prepend?: () => any;\n append?: () => any;\n}>();\n\nconst hidden = ref<boolean>(true);\n</script>\n\n<template>\n <RuiTextField\n v-bind=\"$attrs\"\n v-model=\"modelValue\"\n :label=\"label\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :label-placement=\"labelPlacement\"\n :dense=\"dense\"\n :hint=\"hint\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :details=\"hideDetails ? 'hidden' : details\"\n :readonly=\"readonly\"\n :clearable=\"clearable\"\n :required=\"required\"\n :type=\"hidden ? 'password' : 'text'\"\n >\n <template\n v-if=\"$slots.prepend\"\n #prepend\n >\n <slot name=\"prepend\" />\n </template>\n <template #append>\n <div class=\"flex items-center\">\n <RuiButton\n :disabled=\"disabled\"\n :aria-label=\"hidden ? 'Show password' : 'Hide password'\"\n tabindex=\"-1\"\n variant=\"text\"\n type=\"button\"\n icon\n data-id=\"toggle-visibility\"\n class=\"-mr-1 p-1!\"\n @click=\"hidden = !hidden\"\n >\n <!--\n 24px round the field's 16px glyph, so the focus ring and its offset stay inside even the 32px\n dense field; the muted tone of the other field icons\n -->\n <RuiIcon\n class=\"text-rui-neutral-500 dark:text-rui-neutral-400\"\n size=\"16\"\n :name=\"hidden ? 'lu-eye-off' : 'lu-eye'\"\n />\n </RuiButton>\n\n <slot name=\"append\" />\n </div>\n </template>\n </RuiTextField>\n</template>\n"],"mappings":""}
@@ -1,13 +1,20 @@
1
- import { type TextFieldProps } from '../text-field/RuiTextField.vue.js';
1
+ import RuiTextField, { type TextFieldProps } from '../text-field/RuiTextField.vue.js';
2
2
  export interface Props extends TextFieldProps {
3
3
  }
4
- type __VLS_Props = Props;
4
+ /**
5
+ * What the field forwards to its RuiTextField through `$attrs`: the input's attributes and the text
6
+ * field's events (`blur`, `clear`, `focus-input`, `remove`). The field sets `type` itself. A template
7
+ * listener `@focus-input` is checked as `onFocusInput`, which Vue also matches at runtime.
8
+ */
9
+ type TextFieldAttributes = Omit<InstanceType<typeof RuiTextField>['$props'], keyof Props | 'modelValue' | 'onUpdate:modelValue' | 'modelModifiers' | 'type'> & Partial<Record<'onFocusInput', (event: Event) => void>>;
10
+ type __VLS_Props = Props & /* @vue-ignore */ TextFieldAttributes;
5
11
  type __VLS_Slots = {
6
12
  prepend?: () => any;
7
13
  append?: () => any;
8
14
  };
9
15
  type __VLS_ModelProps = {
10
16
  modelValue: string;
17
+ 'modelModifiers'?: Partial<Record<'trim', true>>;
11
18
  };
12
19
  type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
13
20
  declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
@@ -1 +1 @@
1
- {"version":3,"file":"RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js","names":["$attrs","$slots","_useModel","_openBlock","_createBlock","RuiTextField","_mergeProps","_unref","_createSlots","_withCtx","_createElementVNode","_createVNode","RuiButton","RuiIcon","_renderSlot"],"sources":["../../../../src/components/forms/revealable-text-field/RuiRevealableTextField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiTextField, { type TextFieldProps } from '@/components/forms/text-field/RuiTextField.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\n\nexport interface Props extends TextFieldProps {}\n\ndefineOptions({\n name: 'RuiRevealableTextField',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<string>({ required: true });\n\nconst {\n label = '',\n placeholder = '',\n disabled = false,\n labelPlacement = undefined,\n dense = false,\n hint = '',\n errorMessages = [],\n successMessages = [],\n details = undefined,\n hideDetails = false,\n readonly = false,\n clearable = false,\n required = false,\n} = defineProps<Props>();\n\ndefineSlots<{\n prepend?: () => any;\n append?: () => any;\n}>();\n\nconst hidden = ref<boolean>(true);\n</script>\n\n<template>\n <RuiTextField\n v-bind=\"$attrs\"\n v-model=\"modelValue\"\n :label=\"label\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :label-placement=\"labelPlacement\"\n :dense=\"dense\"\n :hint=\"hint\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :details=\"hideDetails ? 'hidden' : details\"\n :readonly=\"readonly\"\n :clearable=\"clearable\"\n :required=\"required\"\n :type=\"hidden ? 'password' : 'text'\"\n >\n <template\n v-if=\"$slots.prepend\"\n #prepend\n >\n <slot name=\"prepend\" />\n </template>\n <template #append>\n <div class=\"flex items-center\">\n <RuiButton\n :disabled=\"disabled\"\n :aria-label=\"hidden ? 'Show password' : 'Hide password'\"\n tabindex=\"-1\"\n variant=\"text\"\n type=\"button\"\n icon\n data-id=\"toggle-visibility\"\n class=\"-mr-1 p-1!\"\n @click=\"hidden = !hidden\"\n >\n <!--\n 24px round the field's 16px glyph, so the focus ring and its offset stay inside even the 32px\n dense field; the muted tone of the other field icons\n -->\n <RuiIcon\n class=\"text-rui-neutral-500 dark:text-rui-neutral-400\"\n size=\"16\"\n :name=\"hidden ? 'lu-eye-off' : 'lu-eye'\"\n />\n </RuiButton>\n\n <slot name=\"append\" />\n </div>\n </template>\n </RuiTextField>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYA,MAAM,aAAaE,SAAmB,SAAA,YAAmB;EAuBzD,MAAM,SAAS,IAAa,IAAI;;GAI9B,OAAAC,UAAA,GAAAC,YAkDeC,sBAlDfC,WACUN,KAiDK,QAjDC;IACL,YAAA,WAAA;IAAA,uBAAA,OAAA,OAAA,OAAA,MAAA,WAAA,WAAU,QAAA;IAClB,OAAO,QAAA;IACP,aAAa,QAAA;IACb,UAAU,QAAA;IACV,mBAAiB,QAAA;IACjB,OAAO,QAAA;IACP,MAAM,QAAA;IACN,kBAAgB,QAAA;IAChB,oBAAkB,QAAA;IAClB,SAAS,QAAA,cAAW,WAAc,QAAA;IAClC,UAAU,QAAA;IACV,WAAW,QAAA;IACX,UAAU,QAAA;IACV,MAAMO,MAAA,MAAA,IAAM,aAAA;;IAQF,QAAME,cAyBT,CAxBNC,mBAwBM,OAxBN,YAwBM,CAvBJC,YAoBYC,mBAAA;KAnBT,UAAU,QAAA;KACV,cAAYL,MAAA,MAAA,IAAM,kBAAA;KACnB,UAAS;KACT,SAAQ;KACR,MAAK;KACL,MAAA;KACA,WAAQ;KACR,OAAM;KACL,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,OAAA,QAAM,CAAIA,MAAA,MAAA;;KAMlB,SAAAE,cAIE,CAJFE,YAIEE,iBAAA;MAHA,OAAM;MACN,MAAK;MACJ,MAAMN,MAAA,MAAA,IAAM,eAAA;;;IAIjBO,GAAAA,GAAAA,CAAAA,YAAAA,YAAAA,CAAAA,GAAAA,WAAsB,KAAA,QAAA,QAAA,CAAA,CAAA,CAAA,CAAA;;GA7BlBb,GAAAA,CAAAA,KAAAA,OAAO,UAAA;IACZ,MAAA;IAED,IAAAQ,cAAuB,CAAvBK,WAAuB,KAAA,QAAA,SAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js","names":["$attrs","$slots","_useModel","_openBlock","_createBlock","RuiTextField","_mergeProps","_unref","_createSlots","_withCtx","_createElementVNode","_createVNode","RuiButton","RuiIcon","_renderSlot"],"sources":["../../../../src/components/forms/revealable-text-field/RuiRevealableTextField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiTextField, { type TextFieldProps } from '@/components/forms/text-field/RuiTextField.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\n\nexport interface Props extends TextFieldProps {}\n\n/**\n * What the field forwards to its RuiTextField through `$attrs`: the input's attributes and the text\n * field's events (`blur`, `clear`, `focus-input`, `remove`). The field sets `type` itself. A template\n * listener `@focus-input` is checked as `onFocusInput`, which Vue also matches at runtime.\n */\ntype TextFieldAttributes = Omit<InstanceType<typeof RuiTextField>['$props'], keyof Props | 'modelValue' | 'onUpdate:modelValue' | 'modelModifiers' | 'type'>\n & Partial<Record<'onFocusInput', (event: Event) => void>>;\n\ndefineOptions({\n name: 'RuiRevealableTextField',\n inheritAttrs: false,\n});\n\n// `v-model.trim` trims the update, which Vue applies to any model event\nconst modelValue = defineModel<string, 'trim'>({ required: true });\n\nconst {\n label = '',\n placeholder = '',\n disabled = false,\n labelPlacement = undefined,\n dense = false,\n hint = '',\n errorMessages = [],\n successMessages = [],\n details = undefined,\n hideDetails = false,\n readonly = false,\n clearable = false,\n required = false,\n} = defineProps<Props & /* @vue-ignore */ TextFieldAttributes>();\n\ndefineSlots<{\n prepend?: () => any;\n append?: () => any;\n}>();\n\nconst hidden = ref<boolean>(true);\n</script>\n\n<template>\n <RuiTextField\n v-bind=\"$attrs\"\n v-model=\"modelValue\"\n :label=\"label\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :label-placement=\"labelPlacement\"\n :dense=\"dense\"\n :hint=\"hint\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :details=\"hideDetails ? 'hidden' : details\"\n :readonly=\"readonly\"\n :clearable=\"clearable\"\n :required=\"required\"\n :type=\"hidden ? 'password' : 'text'\"\n >\n <template\n v-if=\"$slots.prepend\"\n #prepend\n >\n <slot name=\"prepend\" />\n </template>\n <template #append>\n <div class=\"flex items-center\">\n <RuiButton\n :disabled=\"disabled\"\n :aria-label=\"hidden ? 'Show password' : 'Hide password'\"\n tabindex=\"-1\"\n variant=\"text\"\n type=\"button\"\n icon\n data-id=\"toggle-visibility\"\n class=\"-mr-1 p-1!\"\n @click=\"hidden = !hidden\"\n >\n <!--\n 24px round the field's 16px glyph, so the focus ring and its offset stay inside even the 32px\n dense field; the muted tone of the other field icons\n -->\n <RuiIcon\n class=\"text-rui-neutral-500 dark:text-rui-neutral-400\"\n size=\"16\"\n :name=\"hidden ? 'lu-eye-off' : 'lu-eye'\"\n />\n </RuiButton>\n\n <slot name=\"append\" />\n </div>\n </template>\n </RuiTextField>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqBA,MAAM,aAAaE,SAA2B,SAAA,YAAmB;EAuBjE,MAAM,SAAS,IAAa,IAAI;;GAI9B,OAAAC,UAAA,GAAAC,YAkDeC,sBAlDfC,WACUN,KAiDK,QAjDC;IACL,YAAA,WAAA;IAAA,uBAAA,OAAA,OAAA,OAAA,MAAA,WAAA,WAAU,QAAA;IAClB,OAAO,QAAA;IACP,aAAa,QAAA;IACb,UAAU,QAAA;IACV,mBAAiB,QAAA;IACjB,OAAO,QAAA;IACP,MAAM,QAAA;IACN,kBAAgB,QAAA;IAChB,oBAAkB,QAAA;IAClB,SAAS,QAAA,cAAW,WAAc,QAAA;IAClC,UAAU,QAAA;IACV,WAAW,QAAA;IACX,UAAU,QAAA;IACV,MAAMO,MAAA,MAAA,IAAM,aAAA;;IAQF,QAAME,cAyBT,CAxBNC,mBAwBM,OAxBN,YAwBM,CAvBJC,YAoBYC,mBAAA;KAnBT,UAAU,QAAA;KACV,cAAYL,MAAA,MAAA,IAAM,kBAAA;KACnB,UAAS;KACT,SAAQ;KACR,MAAK;KACL,MAAA;KACA,WAAQ;KACR,OAAM;KACL,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,OAAA,QAAM,CAAIA,MAAA,MAAA;;KAMlB,SAAAE,cAIE,CAJFE,YAIEE,iBAAA;MAHA,OAAM;MACN,MAAK;MACJ,MAAMN,MAAA,MAAA,IAAM,eAAA;;;IAIjBO,GAAAA,GAAAA,CAAAA,YAAAA,YAAAA,CAAAA,GAAAA,WAAsB,KAAA,QAAA,QAAA,CAAA,CAAA,CAAA,CAAA;;GA7BlBb,GAAAA,CAAAA,KAAAA,OAAO,UAAA;IACZ,MAAA;IAED,IAAAQ,cAAuB,CAAvBK,WAAuB,KAAA,QAAA,SAAA,CAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiMenuSelect.js","names":["_sfc_main"],"sources":["../../../../src/components/forms/select/RuiMenuSelect.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"TValue, TItem\">\nimport type { VueClassValue } from '@/types/class-value';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiFieldLabel from '@/components/forms/field-label/RuiFieldLabel.vue';\nimport { menuSelectStyles } from '@/components/forms/select/menu-select-styles';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport RuiMenu, { type MenuProps } from '@/components/overlays/menu/RuiMenu.vue';\nimport RuiProgress from '@/components/progress/RuiProgress.vue';\nimport { type LabelPlacement, useLabelPlacement } from '@/composables/defaults/field';\nimport { getOptionHeight, type KeyOfType, useDropdownMenu } from '@/composables/dropdown-menu';\nimport { type FloatingOptions, Placement } from '@/composables/floating';\nimport { type FormDetails, useFormDetails, useFormTextDetail } from '@/utils/form-text-detail';\nimport { getNonRootAttrs, getRootAttrs } from '@/utils/helpers';\nimport { cn } from '@/utils/tv';\n\nexport interface RuiMenuSelectClassNames {\n root?: VueClassValue;\n label?: VueClassValue;\n menu?: VueClassValue;\n option?: VueClassValue;\n}\n\nexport interface MenuSelectProps<TValue, TItem> {\n options: TItem[];\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem;\n disabled?: boolean;\n loading?: boolean;\n readOnly?: boolean;\n dense?: boolean;\n clearable?: boolean;\n label?: string;\n /** Where the label shows; falls back to the nearest `RuiFieldDefaults`, then the app default, then `top`. */\n labelPlacement?: LabelPlacement;\n menuOptions?: MenuProps;\n classNames?: RuiMenuSelectClassNames;\n prependWidth?: number;\n appendWidth?: number;\n itemHeight?: number;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n /** The line under the field for its hint and messages: `reserve`, `auto` or `hidden`; falls back to the nearest `RuiFieldDefaults`, then the app default, then `reserve`. */\n details?: FormDetails;\n /** @deprecated Use `details=\"hidden\"`. Removed in 4.0. */\n hideDetails?: boolean;\n autoSelectFirst?: boolean;\n hideNoData?: boolean;\n noDataText?: string;\n required?: boolean;\n}\n\ndefineOptions({\n name: 'RuiMenuSelect',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<TValue | undefined>({ required: true });\n\nconst {\n options,\n disabled = false,\n loading = false,\n readOnly = false,\n dense = false,\n clearable = false,\n details = undefined,\n hideDetails = false,\n label = 'Select',\n labelPlacement = undefined,\n menuOptions,\n classNames,\n hint,\n keyAttr,\n textAttr,\n itemHeight,\n prependWidth,\n appendWidth,\n errorMessages = [],\n successMessages = [],\n autoSelectFirst = false,\n hideNoData = false,\n noDataText = 'No data available',\n required = false,\n} = defineProps<MenuSelectProps<TValue, TItem>>();\n\ndefineSlots<{\n 'activator'?: (props: {\n disabled: boolean;\n value: TItem | undefined;\n readOnly: boolean;\n attrs: Record<string, unknown>;\n open: boolean;\n hasError: boolean;\n hasSuccess: boolean;\n }) => any;\n 'selection.prepend'?: (props: { item: TItem }) => any;\n 'selection'?: (props: { item: TItem }) => any;\n 'item.prepend'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'item'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'item.append'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'no-data'?: () => any;\n}>();\n\nconst menuRef = useTemplateRef<HTMLDivElement>('menuRef');\nconst activator = useTemplateRef<HTMLDivElement>('activator');\nconst { focused } = useFocus(activator);\nconst isHovered = ref<boolean>(false);\nconst labelId = useId();\n\nconst placement = useLabelPlacement(() => labelPlacement);\n\nconst { hasError, hasSuccess } = useFormTextDetail(\n () => errorMessages,\n () => successMessages,\n);\nconst detailsMode = useFormDetails(() => details, () => hideDetails);\n\nconst value = computed<TItem | undefined>({\n get: () => {\n const value = get(modelValue);\n if (keyAttr)\n return options.find(option => option[keyAttr] === value);\n // eslint-disable-next-line slop/no-chained-type-assertions -- without keyAttr the model holds the item itself, which the two generics cannot express\n return value as unknown as TItem;\n },\n set: (selected?: TItem) => {\n const selection = keyAttr && selected ? selected[keyAttr] : selected;\n set(modelValue, selection as TValue);\n },\n});\n\nfunction setValue(val: TItem): void {\n set(value, val);\n set(focused, true);\n}\n\nconst {\n containerProps,\n wrapperProps,\n renderedData,\n isOpen,\n menuWidth,\n getText,\n getIdentifier,\n isActiveItem,\n modelHighlightedIndex,\n moveHighlight,\n applyHighlighted,\n valueKey,\n} = useDropdownMenu<TValue, TItem>({\n itemHeight: itemHeight ?? getOptionHeight(dense),\n keyAttr,\n textAttr,\n options: () => options,\n dense: () => dense,\n value,\n menuRef,\n disabled: () => disabled,\n autoSelectFirst,\n setValue,\n prependWidth,\n appendWidth,\n});\n\nconst ui = computed<ReturnType<typeof menuSelectStyles>>(() => menuSelectStyles({\n opened: get(isOpen),\n hovered: get(isHovered),\n dense,\n disabled,\n readonly: readOnly,\n hasError: get(hasError),\n hasSuccess: get(hasSuccess) && !get(hasError),\n}));\n\nconst highlightedClass = menuSelectStyles({}).highlighted();\n\nfunction clear(): void {\n set(modelValue, undefined);\n}\n\nconst menuFloatingOptions = computed<FloatingOptions>(() => ({\n placement: Placement.bottomStart,\n ...menuOptions?.options,\n}));\n</script>\n\n<template>\n <RuiMenu\n v-model=\"isOpen\"\n v-bind=\"{ ...getRootAttrs($attrs, []), ...menuOptions }\"\n :class=\"ui.wrapper({ class: cn($attrs.class) })\"\n :class-names=\"{ ...menuOptions?.classNames, details: ['px-0', cn(menuOptions?.classNames?.details) ?? ''] }\"\n :options=\"menuFloatingOptions\"\n close-on-content-click\n full-width\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n :dense=\"dense\"\n :show-details=\"detailsMode !== 'hidden'\"\n :details=\"detailsMode === 'auto' ? 'auto' : 'reserve'\"\n :disabled=\"disabled\"\n disable-auto-focus\n role=\"listbox\"\n >\n <template\n v-if=\"label\"\n #label\n >\n <RuiFieldLabel\n :id=\"labelId\"\n :text=\"label\"\n :hidden=\"placement === 'hidden'\"\n :required=\"required\"\n :disabled=\"disabled\"\n />\n </template>\n <template #activator=\"{ attrs, open, hasError: slotHasError, hasSuccess: slotHasSuccess }\">\n <slot\n name=\"activator\"\n v-bind=\"{ disabled, value, readOnly, attrs, open, hasError: slotHasError, hasSuccess: slotHasSuccess }\"\n >\n <!-- a select-only combobox: the button opens a listbox of options, and carries the field's state -->\n <button\n ref=\"activator\"\n role=\"combobox\"\n :disabled=\"disabled\"\n :aria-disabled=\"disabled\"\n :aria-expanded=\"isOpen\"\n :aria-readonly=\"readOnly || undefined\"\n :aria-required=\"required || undefined\"\n :aria-busy=\"loading || undefined\"\n :aria-labelledby=\"label ? labelId : undefined\"\n type=\"button\"\n :tabindex=\"disabled || readOnly ? -1 : 0\"\n :class=\"ui.activator({ class: cn(classNames?.label) })\"\n v-bind=\"{\n ...getNonRootAttrs($attrs),\n ...(readOnly ? {} : attrs),\n }\"\n data-id=\"activator\"\n :aria-invalid=\"hasError\"\n @mouseenter=\"isHovered = true\"\n @mouseleave=\"isHovered = false\"\n @keydown.up.prevent=\"moveHighlight(true)\"\n @keydown.down.prevent=\"moveHighlight(false)\"\n @keydown.enter.prevent=\"applyHighlighted()\"\n @keydown.space.prevent=\"applyHighlighted()\"\n @keydown.home.prevent=\"modelHighlightedIndex = 0\"\n @keydown.end.prevent=\"modelHighlightedIndex = options.length - 1\"\n >\n <span\n v-if=\"value\"\n :class=\"ui.value()\"\n >\n <slot\n name=\"selection.prepend\"\n v-bind=\"{ item: value }\"\n />\n <slot\n name=\"selection\"\n v-bind=\"{ item: value }\"\n >\n {{ getText(value) }}\n </slot>\n </span>\n\n <span\n v-if=\"clearable && value && !disabled && !readOnly\"\n data-id=\"clear\"\n :class=\"[ui.clear(), focused && 'visible!', { 'mr-2': !dense }]\"\n @click.stop.prevent=\"clear()\"\n >\n <RuiIcon\n name=\"lu-x\"\n size=\"16\"\n />\n </span>\n\n <span :class=\"ui.iconWrapper()\">\n <RuiIcon\n :class=\"ui.icon()\"\n :size=\"dense ? 16 : 20\"\n name=\"lu-chevron-down\"\n />\n </span>\n\n <RuiProgress\n v-if=\"loading\"\n :class=\"ui.progress()\"\n color=\"primary\"\n thickness=\"2\"\n variant=\"indeterminate\"\n />\n </button>\n <fieldset :class=\"ui.fieldset()\" />\n </slot>\n <input\n :value=\"valueKey\"\n class=\"hidden\"\n type=\"hidden\"\n />\n </template>\n <template #default=\"{ width }\">\n <div\n v-if=\"options.length > 0\"\n :ref=\"containerProps.ref\"\n :class=\"ui.menu({ class: cn(classNames?.menu) })\"\n :style=\"[containerProps.style, { width: `${width}px`, minWidth: menuWidth }]\"\n @scroll=\"containerProps.onScroll\"\n @keydown.up.prevent=\"moveHighlight(true)\"\n @keydown.down.prevent=\"moveHighlight(false)\"\n >\n <div\n v-bind=\"wrapperProps\"\n ref=\"menuRef\"\n >\n <RuiButton\n v-for=\"{ item, _index } in renderedData\"\n :key=\"getIdentifier(item)\"\n :active=\"isActiveItem(item)\"\n role=\"option\"\n :aria-selected=\"isActiveItem(item)\"\n :size=\"dense ? 'sm' : undefined\"\n variant=\"list\"\n :data-highlighted=\"modelHighlightedIndex === _index\"\n :class=\"{\n [highlightedClass]: !isActiveItem(item) && modelHighlightedIndex === _index,\n }\"\n @click=\"setValue(item)\"\n >\n <template #prepend>\n <slot\n name=\"item.prepend\"\n v-bind=\"{ disabled, item, active: isActiveItem(item) }\"\n />\n </template>\n <slot\n name=\"item\"\n v-bind=\"{ disabled, item, active: isActiveItem(item) }\"\n >\n {{ getText(item) }}\n </slot>\n <template #append>\n <slot\n name=\"item.append\"\n v-bind=\"{ disabled, item, active: isActiveItem(item) }\"\n />\n </template>\n </RuiButton>\n </div>\n </div>\n\n <div\n v-else-if=\"!hideNoData\"\n data-id=\"no-data\"\n :style=\"{ width: `${width}px`, minWidth: menuWidth }\"\n :class=\"classNames?.menu\"\n >\n <slot name=\"no-data\">\n <div class=\"p-4\">\n {{ noDataText }}\n </div>\n </slot>\n </div>\n </template>\n </RuiMenu>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiMenuSelect.js","names":["_sfc_main"],"sources":["../../../../src/components/forms/select/RuiMenuSelect.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"TValue, TItem\">\nimport type { ButtonHTMLAttributes, Ref } from 'vue';\nimport type { VueClassValue } from '@/types/class-value';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiFieldLabel from '@/components/forms/field-label/RuiFieldLabel.vue';\nimport { menuSelectStyles } from '@/components/forms/select/menu-select-styles';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport RuiMenu, { type MenuProps } from '@/components/overlays/menu/RuiMenu.vue';\nimport RuiProgress from '@/components/progress/RuiProgress.vue';\nimport { type LabelPlacement, useLabelPlacement } from '@/composables/defaults/field';\nimport { getOptionHeight, type KeyOfType, useDropdownMenu } from '@/composables/dropdown-menu';\nimport { type FloatingOptions, Placement } from '@/composables/floating';\nimport { type FormDetails, useFormDetails, useFormTextDetail } from '@/utils/form-text-detail';\nimport { getNonRootAttrs, getRootAttrs } from '@/utils/helpers';\nimport { cn } from '@/utils/tv';\n\nexport interface RuiMenuSelectClassNames {\n root?: VueClassValue;\n label?: VueClassValue;\n menu?: VueClassValue;\n option?: VueClassValue;\n}\n\nexport interface MenuSelectProps<TValue, TItem> {\n options: TItem[];\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem;\n disabled?: boolean;\n loading?: boolean;\n readOnly?: boolean;\n dense?: boolean;\n clearable?: boolean;\n label?: string;\n /** Where the label shows; falls back to the nearest `RuiFieldDefaults`, then the app default, then `top`. */\n labelPlacement?: LabelPlacement;\n menuOptions?: MenuProps;\n classNames?: RuiMenuSelectClassNames;\n prependWidth?: number;\n appendWidth?: number;\n itemHeight?: number;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n /** The line under the field for its hint and messages: `reserve`, `auto` or `hidden`; falls back to the nearest `RuiFieldDefaults`, then the app default, then `reserve`. */\n details?: FormDetails;\n /** @deprecated Use `details=\"hidden\"`. Removed in 4.0. */\n hideDetails?: boolean;\n autoSelectFirst?: boolean;\n hideNoData?: boolean;\n noDataText?: string;\n required?: boolean;\n}\n\ndefineOptions({\n name: 'RuiMenuSelect',\n inheritAttrs: false,\n});\n\n/**\n * The selected key, or the item itself without `keyAttr`. Its type is the bound value's, so a\n * `Ref<number>` takes the update as is. `clearable` sets it to `undefined`: bind a type that allows\n * it. The component writes through the wider ref.\n */\nconst modelValue: Ref<TValue | undefined> = defineModel<TValue>({ required: true });\n\nconst {\n options,\n disabled = false,\n loading = false,\n readOnly = false,\n dense = false,\n clearable = false,\n details = undefined,\n hideDetails = false,\n label = 'Select',\n labelPlacement = undefined,\n menuOptions,\n classNames,\n hint,\n keyAttr,\n textAttr,\n itemHeight,\n prependWidth,\n appendWidth,\n errorMessages = [],\n successMessages = [],\n autoSelectFirst = false,\n hideNoData = false,\n noDataText = 'No data available',\n required = false,\n} = defineProps<MenuSelectProps<TValue, TItem> & /* @vue-ignore */ Omit<ButtonHTMLAttributes, keyof MenuSelectProps<TValue, TItem>>>();\n\ndefineSlots<{\n 'activator'?: (props: {\n disabled: boolean;\n value: TItem | undefined;\n readOnly: boolean;\n attrs: Record<string, unknown>;\n open: boolean;\n hasError: boolean;\n hasSuccess: boolean;\n }) => any;\n 'selection.prepend'?: (props: { item: TItem }) => any;\n 'selection'?: (props: { item: TItem }) => any;\n 'item.prepend'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'item'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'item.append'?: (props: { disabled: boolean; item: TItem; active: boolean }) => any;\n 'no-data'?: () => any;\n}>();\n\nconst menuRef = useTemplateRef<HTMLDivElement>('menuRef');\nconst activator = useTemplateRef<HTMLDivElement>('activator');\nconst { focused } = useFocus(activator);\nconst isHovered = ref<boolean>(false);\nconst labelId = useId();\n\nconst placement = useLabelPlacement(() => labelPlacement);\n\nconst { hasError, hasSuccess } = useFormTextDetail(\n () => errorMessages,\n () => successMessages,\n);\nconst detailsMode = useFormDetails(() => details, () => hideDetails);\n\nconst value = computed<TItem | undefined>({\n get: () => {\n const value = get(modelValue);\n if (keyAttr)\n return options.find(option => option[keyAttr] === value);\n // eslint-disable-next-line slop/no-chained-type-assertions -- without keyAttr the model holds the item itself, which the two generics cannot express\n return value as unknown as TItem;\n },\n set: (selected?: TItem) => {\n const selection = keyAttr && selected ? selected[keyAttr] : selected;\n set(modelValue, selection as TValue);\n },\n});\n\nfunction setValue(val: TItem): void {\n set(value, val);\n set(focused, true);\n}\n\nconst {\n containerProps,\n wrapperProps,\n renderedData,\n isOpen,\n menuWidth,\n getText,\n getIdentifier,\n isActiveItem,\n modelHighlightedIndex,\n moveHighlight,\n applyHighlighted,\n valueKey,\n} = useDropdownMenu<TValue, TItem>({\n itemHeight: itemHeight ?? getOptionHeight(dense),\n keyAttr,\n textAttr,\n options: () => options,\n dense: () => dense,\n value,\n menuRef,\n disabled: () => disabled,\n autoSelectFirst,\n setValue,\n prependWidth,\n appendWidth,\n});\n\nconst ui = computed<ReturnType<typeof menuSelectStyles>>(() => menuSelectStyles({\n opened: get(isOpen),\n hovered: get(isHovered),\n dense,\n disabled,\n readonly: readOnly,\n hasError: get(hasError),\n hasSuccess: get(hasSuccess) && !get(hasError),\n}));\n\nconst highlightedClass = menuSelectStyles({}).highlighted();\n\nfunction clear(): void {\n set(modelValue, undefined);\n}\n\nconst menuFloatingOptions = computed<FloatingOptions>(() => ({\n placement: Placement.bottomStart,\n ...menuOptions?.options,\n}));\n</script>\n\n<template>\n <RuiMenu\n v-model=\"isOpen\"\n v-bind=\"{ ...getRootAttrs($attrs, []), ...menuOptions }\"\n :class=\"ui.wrapper({ class: cn($attrs.class) })\"\n :class-names=\"{ ...menuOptions?.classNames, details: ['px-0', cn(menuOptions?.classNames?.details) ?? ''] }\"\n :options=\"menuFloatingOptions\"\n close-on-content-click\n full-width\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n :dense=\"dense\"\n :show-details=\"detailsMode !== 'hidden'\"\n :details=\"detailsMode === 'auto' ? 'auto' : 'reserve'\"\n :disabled=\"disabled\"\n disable-auto-focus\n role=\"listbox\"\n >\n <template\n v-if=\"label\"\n #label\n >\n <RuiFieldLabel\n :id=\"labelId\"\n :text=\"label\"\n :hidden=\"placement === 'hidden'\"\n :required=\"required\"\n :disabled=\"disabled\"\n />\n </template>\n <template #activator=\"{ attrs, open, hasError: slotHasError, hasSuccess: slotHasSuccess }\">\n <slot\n name=\"activator\"\n v-bind=\"{ disabled, value, readOnly, attrs, open, hasError: slotHasError, hasSuccess: slotHasSuccess }\"\n >\n <!-- a select-only combobox: the button opens a listbox of options, and carries the field's state -->\n <button\n ref=\"activator\"\n role=\"combobox\"\n :disabled=\"disabled\"\n :aria-disabled=\"disabled\"\n :aria-expanded=\"isOpen\"\n :aria-readonly=\"readOnly || undefined\"\n :aria-required=\"required || undefined\"\n :aria-busy=\"loading || undefined\"\n :aria-labelledby=\"label ? labelId : undefined\"\n type=\"button\"\n :tabindex=\"disabled || readOnly ? -1 : 0\"\n :class=\"ui.activator({ class: cn(classNames?.label) })\"\n v-bind=\"{\n ...getNonRootAttrs($attrs),\n ...(readOnly ? {} : attrs),\n }\"\n data-id=\"activator\"\n :aria-invalid=\"hasError\"\n @mouseenter=\"isHovered = true\"\n @mouseleave=\"isHovered = false\"\n @keydown.up.prevent=\"moveHighlight(true)\"\n @keydown.down.prevent=\"moveHighlight(false)\"\n @keydown.enter.prevent=\"applyHighlighted()\"\n @keydown.space.prevent=\"applyHighlighted()\"\n @keydown.home.prevent=\"modelHighlightedIndex = 0\"\n @keydown.end.prevent=\"modelHighlightedIndex = options.length - 1\"\n >\n <span\n v-if=\"value\"\n :class=\"ui.value()\"\n >\n <slot\n name=\"selection.prepend\"\n v-bind=\"{ item: value }\"\n />\n <slot\n name=\"selection\"\n v-bind=\"{ item: value }\"\n >\n {{ getText(value) }}\n </slot>\n </span>\n\n <span\n v-if=\"clearable && value && !disabled && !readOnly\"\n data-id=\"clear\"\n :class=\"[ui.clear(), focused && 'visible!', { 'mr-2': !dense }]\"\n @click.stop.prevent=\"clear()\"\n >\n <RuiIcon\n name=\"lu-x\"\n size=\"16\"\n />\n </span>\n\n <span :class=\"ui.iconWrapper()\">\n <RuiIcon\n :class=\"ui.icon()\"\n :size=\"dense ? 16 : 20\"\n name=\"lu-chevron-down\"\n />\n </span>\n\n <RuiProgress\n v-if=\"loading\"\n :class=\"ui.progress()\"\n color=\"primary\"\n thickness=\"2\"\n variant=\"indeterminate\"\n />\n </button>\n <fieldset :class=\"ui.fieldset()\" />\n </slot>\n <input\n :value=\"valueKey\"\n class=\"hidden\"\n type=\"hidden\"\n />\n </template>\n <template #default=\"{ width }\">\n <div\n v-if=\"options.length > 0\"\n :ref=\"containerProps.ref\"\n :class=\"ui.menu({ class: cn(classNames?.menu) })\"\n :style=\"[containerProps.style, { width: `${width}px`, minWidth: menuWidth }]\"\n @scroll=\"containerProps.onScroll\"\n @keydown.up.prevent=\"moveHighlight(true)\"\n @keydown.down.prevent=\"moveHighlight(false)\"\n >\n <div\n v-bind=\"wrapperProps\"\n ref=\"menuRef\"\n >\n <RuiButton\n v-for=\"{ item, _index } in renderedData\"\n :key=\"getIdentifier(item)\"\n :active=\"isActiveItem(item)\"\n role=\"option\"\n :aria-selected=\"isActiveItem(item)\"\n :size=\"dense ? 'sm' : undefined\"\n variant=\"list\"\n :data-highlighted=\"modelHighlightedIndex === _index\"\n :class=\"{\n [highlightedClass]: !isActiveItem(item) && modelHighlightedIndex === _index,\n }\"\n @click=\"setValue(item)\"\n >\n <template #prepend>\n <slot\n name=\"item.prepend\"\n v-bind=\"{ disabled, item, active: isActiveItem(item) }\"\n />\n </template>\n <slot\n name=\"item\"\n v-bind=\"{ disabled, item, active: isActiveItem(item) }\"\n >\n {{ getText(item) }}\n </slot>\n <template #append>\n <slot\n name=\"item.append\"\n v-bind=\"{ disabled, item, active: isActiveItem(item) }\"\n />\n </template>\n </RuiButton>\n </div>\n </div>\n\n <div\n v-else-if=\"!hideNoData\"\n data-id=\"no-data\"\n :style=\"{ width: `${width}px`, minWidth: menuWidth }\"\n :class=\"classNames?.menu\"\n >\n <slot name=\"no-data\">\n <div class=\"p-4\">\n {{ noDataText }}\n </div>\n </slot>\n </div>\n </template>\n </RuiMenu>\n</template>\n"],"mappings":""}
@@ -1,3 +1,4 @@
1
+ import type { ButtonHTMLAttributes } from 'vue';
1
2
  import type { VueClassValue } from '../../../types/class-value.js';
2
3
  import { type MenuProps } from '../../overlays/menu/RuiMenu.vue.js';
3
4
  import { type LabelPlacement } from '../../../composables/defaults/field.js';
@@ -39,10 +40,15 @@ export interface MenuSelectProps<TValue, TItem> {
39
40
  required?: boolean;
40
41
  }
41
42
  declare const __VLS_export: <TValue, TItem>(__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<{
42
- props: import("vue").PublicProps & __VLS_PrettifyLocal<(MenuSelectProps<TValue, TItem> & {
43
- modelValue: TValue | undefined;
43
+ props: import("vue").PublicProps & __VLS_PrettifyLocal<(MenuSelectProps<TValue, TItem> & Omit<ButtonHTMLAttributes, keyof MenuSelectProps<TValue, TItem>> & {
44
+ /**
45
+ * The selected key, or the item itself without `keyAttr`. Its type is the bound value's, so a
46
+ * `Ref<number>` takes the update as is. `clearable` sets it to `undefined`: bind a type that allows
47
+ * it. The component writes through the wider ref.
48
+ */
49
+ modelValue: TValue;
44
50
  }) & {
45
- "onUpdate:modelValue"?: ((value: TValue | undefined) => any) | undefined;
51
+ "onUpdate:modelValue"?: ((value: TValue) => any) | undefined;
46
52
  }> & (typeof globalThis extends {
47
53
  __VLS_PROPS_FALLBACK: infer P;
48
54
  } ? P : {});
@@ -81,7 +87,7 @@ declare const __VLS_export: <TValue, TItem>(__VLS_props: NonNullable<Awaited<typ
81
87
  }) => any;
82
88
  'no-data'?: () => any;
83
89
  };
84
- emit: (event: "update:modelValue", value: TValue | undefined) => void;
90
+ emit: (event: "update:modelValue", value: TValue) => void;
85
91
  }>) => import("vue").VNode & {
86
92
  __ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
87
93
  };
@@ -89,6 +89,11 @@ var RuiMenuSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
89
89
  }),
90
90
  emits: ["update:modelValue"],
91
91
  setup(__props) {
92
+ /**
93
+ * The selected key, or the item itself without `keyAttr`. Its type is the bound value's, so a
94
+ * `Ref<number>` takes the update as is. `clearable` sets it to `undefined`: bind a type that allows
95
+ * it. The component writes through the wider ref.
96
+ */
92
97
  const modelValue = useModel(__props, "modelValue");
93
98
  const menuRef = useTemplateRef("menuRef");
94
99
  const activator = useTemplateRef("activator");