@rotki/ui-library 3.0.0-beta.2 → 3.0.0-beta.4

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 (254) hide show
  1. package/README.md +27 -14
  2. package/dist/components/accordions/accordion/RuiAccordion.js.map +1 -1
  3. package/dist/components/accordions/accordion/RuiAccordion.vue.d.ts +1 -1
  4. package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
  5. package/dist/components/accordions/accordions/RuiAccordions.js.map +1 -1
  6. package/dist/components/accordions/accordions/RuiAccordions.vue_vue_type_script_setup_true_lang.js.map +1 -1
  7. package/dist/components/alerts/RuiAlert.js.map +1 -1
  8. package/dist/components/alerts/RuiAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
  9. package/dist/components/avatars/RuiAvatar.js.map +1 -1
  10. package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  11. package/dist/components/avatars/RuiAvatarGroup.js.map +1 -1
  12. package/dist/components/avatars/RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  13. package/dist/components/buttons/button/RuiButton.js.map +1 -1
  14. package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  15. package/dist/components/buttons/button-group/RuiButtonGroup.js.map +1 -1
  16. package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  17. package/dist/components/calendar/RuiCalendar.js.map +1 -1
  18. package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  19. package/dist/components/calendar/RuiCalendarGrid.js.map +1 -1
  20. package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
  21. package/dist/components/calendar/RuiCalendarHeader.js.map +1 -1
  22. package/dist/components/calendar/RuiCalendarHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  23. package/dist/components/calendar/RuiCalendarMenu.js.map +1 -1
  24. package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  25. package/dist/components/cards/RuiCard.js.map +1 -1
  26. package/dist/components/cards/RuiCard.vue.d.ts +1 -1
  27. package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  28. package/dist/components/cards/RuiCardHeader.js.map +1 -1
  29. package/dist/components/cards/RuiCardHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  30. package/dist/components/chips/RuiChip.js.map +1 -1
  31. package/dist/components/chips/RuiChip.vue.d.ts +1 -1
  32. package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  33. package/dist/components/color-picker/RuiColorBoard.js.map +1 -1
  34. package/dist/components/color-picker/RuiColorBoard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  35. package/dist/components/color-picker/RuiColorDisplay.js.map +1 -1
  36. package/dist/components/color-picker/RuiColorDisplay.vue_vue_type_script_setup_true_lang.js.map +1 -1
  37. package/dist/components/color-picker/RuiColorHue.js.map +1 -1
  38. package/dist/components/color-picker/RuiColorHue.vue_vue_type_script_setup_true_lang.js.map +1 -1
  39. package/dist/components/color-picker/RuiColorInput.js.map +1 -1
  40. package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  41. package/dist/components/color-picker/RuiColorPicker.js.map +1 -1
  42. package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  43. package/dist/components/date-time-picker/RuiDateTimePicker.js.map +1 -1
  44. package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  45. package/dist/components/date-time-picker/RuiDateTimePickerMenu.js.map +1 -1
  46. package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue.d.ts +1 -1
  47. package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  48. package/dist/components/date-time-picker/RuiTimezoneSelect.js.map +1 -1
  49. package/dist/components/date-time-picker/RuiTimezoneSelect.vue.d.ts +2 -2
  50. package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  51. package/dist/components/divider/RuiDivider.js.map +1 -1
  52. package/dist/components/divider/RuiDivider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  53. package/dist/components/forms/auto-complete/RuiAutoComplete.js.map +1 -1
  54. package/dist/components/forms/auto-complete/RuiAutoComplete.vue.d.ts +1 -1
  55. package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js +1 -0
  56. package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  57. package/dist/components/forms/auto-complete/RuiAutoCompleteOption.js.map +1 -1
  58. package/dist/components/forms/auto-complete/RuiAutoCompleteOption.vue_vue_type_script_setup_true_lang.js.map +1 -1
  59. package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.js.map +1 -1
  60. package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.vue.d.ts +1 -1
  61. package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.vue_vue_type_script_setup_true_lang.js.map +1 -1
  62. package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.js.map +1 -1
  63. package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.vue_vue_type_script_setup_true_lang.js.map +1 -1
  64. package/dist/components/forms/auto-complete/auto-complete-props.d.ts +2 -2
  65. package/dist/components/forms/auto-complete/auto-complete-styles.d.ts +3 -53
  66. package/dist/components/forms/auto-complete/auto-complete-styles.js +2 -1
  67. package/dist/components/forms/auto-complete/auto-complete-styles.js.map +1 -1
  68. package/dist/components/forms/category-picker/RuiCategoryPicker.js.map +1 -1
  69. package/dist/components/forms/category-picker/RuiCategoryPicker.vue.d.ts +2 -2
  70. package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js +6 -2
  71. package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  72. package/dist/components/forms/checkbox/RuiCheckbox.js.map +1 -1
  73. package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  74. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.js.map +1 -1
  75. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  76. package/dist/components/forms/field-defaults/RuiFieldDefaults.js.map +1 -1
  77. package/dist/components/forms/field-defaults/RuiFieldDefaults.vue_vue_type_script_setup_true_lang.js.map +1 -1
  78. package/dist/components/forms/field-label/RuiFieldLabel.js.map +1 -1
  79. package/dist/components/forms/field-label/RuiFieldLabel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  80. package/dist/components/forms/file-upload/RuiFileUpload.js.map +1 -1
  81. package/dist/components/forms/file-upload/RuiFileUpload.vue.d.ts +4 -1
  82. package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js +17 -8
  83. package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
  84. package/dist/components/forms/radio-button/radio/RuiRadio.js.map +1 -1
  85. package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
  86. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.js.map +1 -1
  87. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  88. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.js.map +1 -1
  89. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue.d.ts +1 -1
  90. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  91. package/dist/components/forms/select/RuiMenuSelect.js.map +1 -1
  92. package/dist/components/forms/select/RuiMenuSelect.vue.d.ts +2 -2
  93. package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  94. package/dist/components/forms/select/RuiSimpleSelect.js.map +1 -1
  95. package/dist/components/forms/select/RuiSimpleSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  96. package/dist/components/forms/slider/RuiSlider.js.map +1 -1
  97. package/dist/components/forms/slider/RuiSlider.vue.d.ts +1 -1
  98. package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  99. package/dist/components/forms/slider/RuiSliderTicks.js.map +1 -1
  100. package/dist/components/forms/slider/RuiSliderTicks.vue_vue_type_script_setup_true_lang.js.map +1 -1
  101. package/dist/components/forms/switch/RuiSwitch.js.map +1 -1
  102. package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  103. package/dist/components/forms/text-area/RuiTextArea.js.map +1 -1
  104. package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  105. package/dist/components/forms/text-field/RuiTextField.js.map +1 -1
  106. package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  107. package/dist/components/forms/text-input-styles.js +1 -1
  108. package/dist/components/forms/text-input-styles.js.map +1 -1
  109. package/dist/components/helpers/RuiFormTextDetail.js.map +1 -1
  110. package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js +1 -2
  111. package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js.map +1 -1
  112. package/dist/components/icons/RuiIcon.js.map +1 -1
  113. package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js +11 -10
  114. package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  115. package/dist/components/index.d.ts +57 -57
  116. package/dist/components/loaders/RuiSkeletonBase.js.map +1 -1
  117. package/dist/components/loaders/RuiSkeletonBase.vue_vue_type_script_setup_true_lang.js.map +1 -1
  118. package/dist/components/loaders/RuiSkeletonLoader.js.map +1 -1
  119. package/dist/components/loaders/RuiSkeletonLoader.vue.d.ts +1 -1
  120. package/dist/components/loaders/RuiSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  121. package/dist/components/logos/RuiLogo.js.map +1 -1
  122. package/dist/components/logos/RuiLogo.vue_vue_type_script_setup_true_lang.js.map +1 -1
  123. package/dist/components/overlays/badge/RuiBadge.js.map +1 -1
  124. package/dist/components/overlays/badge/RuiBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
  125. package/dist/components/overlays/bottom-sheet/RuiBottomSheet.js.map +1 -1
  126. package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue_vue_type_script_setup_true_lang.js.map +1 -1
  127. package/dist/components/overlays/dialog/RuiDialog.js.map +1 -1
  128. package/dist/components/overlays/dialog/RuiDialog.vue.d.ts +1 -1
  129. package/dist/components/overlays/dialog/RuiDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  130. package/dist/components/overlays/menu/RuiMenu.js.map +1 -1
  131. package/dist/components/overlays/menu/RuiMenu.vue.d.ts +1 -1
  132. package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  133. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.js.map +1 -1
  134. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue.d.ts +1 -1
  135. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  136. package/dist/components/overlays/notification/RuiNotification.js.map +1 -1
  137. package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js.map +1 -1
  138. package/dist/components/overlays/tooltip/RuiTooltip.js.map +1 -1
  139. package/dist/components/overlays/tooltip/RuiTooltip.vue.d.ts +1 -1
  140. package/dist/components/overlays/tooltip/RuiTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  141. package/dist/components/progress/RuiProgress.js.map +1 -1
  142. package/dist/components/progress/RuiProgress.vue_vue_type_script_setup_true_lang.js.map +1 -1
  143. package/dist/components/steppers/RuiFooterStepper.js.map +1 -1
  144. package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js +6 -2
  145. package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  146. package/dist/components/steppers/RuiStepper.js.map +1 -1
  147. package/dist/components/steppers/RuiStepper.vue.d.ts +1 -1
  148. package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  149. package/dist/components/steppers/RuiStepperIcon.js.map +1 -1
  150. package/dist/components/steppers/RuiStepperIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  151. package/dist/components/tables/RuiDataTable.js.map +1 -1
  152. package/dist/components/tables/RuiDataTable.vue.d.ts +11 -2
  153. package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js +8 -3
  154. package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  155. package/dist/components/tables/RuiExpandButton.js.map +1 -1
  156. package/dist/components/tables/RuiExpandButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  157. package/dist/components/tables/RuiTable.js.map +1 -1
  158. package/dist/components/tables/RuiTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  159. package/dist/components/tables/RuiTableEmptyState.js.map +1 -1
  160. package/dist/components/tables/RuiTableEmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
  161. package/dist/components/tables/RuiTableErrorState.js.map +1 -1
  162. package/dist/components/tables/RuiTableErrorState.vue_vue_type_script_setup_true_lang.js.map +1 -1
  163. package/dist/components/tables/RuiTableHead.js.map +1 -1
  164. package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js.map +1 -1
  165. package/dist/components/tables/RuiTableLoadingState.js.map +1 -1
  166. package/dist/components/tables/RuiTableLoadingState.vue_vue_type_script_setup_true_lang.js.map +1 -1
  167. package/dist/components/tables/RuiTablePagination.js.map +1 -1
  168. package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  169. package/dist/components/tables/data-table/RuiDataTableAppendRow.js +7 -0
  170. package/dist/components/tables/data-table/RuiDataTableAppendRow.js.map +1 -0
  171. package/dist/components/tables/data-table/RuiDataTableAppendRow.vue.d.ts +26 -0
  172. package/dist/components/tables/data-table/RuiDataTableAppendRow.vue_vue_type_script_setup_true_lang.js +39 -0
  173. package/dist/components/tables/data-table/RuiDataTableAppendRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
  174. package/dist/components/tables/data-table/RuiDataTableBody.js.map +1 -1
  175. package/dist/components/tables/data-table/RuiDataTableBody.vue.d.ts +5 -1
  176. package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js +18 -10
  177. package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js.map +1 -1
  178. package/dist/components/tables/data-table/RuiDataTableCell.js.map +1 -1
  179. package/dist/components/tables/data-table/RuiDataTableCell.vue.d.ts +1 -1
  180. package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  181. package/dist/components/tables/data-table/RuiDataTableEmptyRow.js.map +1 -1
  182. package/dist/components/tables/data-table/RuiDataTableEmptyRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  183. package/dist/components/tables/data-table/RuiDataTableErrorRow.js.map +1 -1
  184. package/dist/components/tables/data-table/RuiDataTableErrorRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  185. package/dist/components/tables/data-table/RuiDataTableExpandedRow.js.map +1 -1
  186. package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  187. package/dist/components/tables/data-table/RuiDataTableGroupRow.js.map +1 -1
  188. package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  189. package/dist/components/tables/data-table/RuiDataTableLoadingRow.js.map +1 -1
  190. package/dist/components/tables/data-table/RuiDataTableLoadingRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  191. package/dist/components/tables/data-table/RuiDataTableMobileSort.js.map +1 -1
  192. package/dist/components/tables/data-table/RuiDataTableMobileSort.vue.d.ts +1 -1
  193. package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js.map +1 -1
  194. package/dist/components/tables/data-table/RuiDataTableRow.js.map +1 -1
  195. package/dist/components/tables/data-table/RuiDataTableRow.vue.d.ts +5 -1
  196. package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js +144 -88
  197. package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  198. package/dist/components/tables/data-table/context.d.ts +1 -1
  199. package/dist/components/tables/data-table-styles.js +1 -1
  200. package/dist/components/tables/data-table-styles.js.map +1 -1
  201. package/dist/components/tabs/tab/RuiTab.js.map +1 -1
  202. package/dist/components/tabs/tab/RuiTab.vue.d.ts +1 -1
  203. package/dist/components/tabs/tab/RuiTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
  204. package/dist/components/tabs/tab-item/RuiTabItem.js.map +1 -1
  205. package/dist/components/tabs/tab-item/RuiTabItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  206. package/dist/components/tabs/tab-items/RuiTabItems.js.map +1 -1
  207. package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js.map +1 -1
  208. package/dist/components/tabs/tabs/RuiTabs.js.map +1 -1
  209. package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  210. package/dist/components/time-picker/RuiTimePicker.js.map +1 -1
  211. package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js +12 -8
  212. package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  213. package/dist/composables/floating.d.ts +1 -1
  214. package/dist/composables/icons.d.ts +1 -1
  215. package/dist/composables/icons.js +1 -7
  216. package/dist/composables/icons.js.map +1 -1
  217. package/dist/composables/tables/data-table/columns.d.ts +1 -1
  218. package/dist/composables/tables/data-table/grouping.d.ts +1 -1
  219. package/dist/composables/tables/data-table/page-scroll.d.ts +1 -1
  220. package/dist/composables/tables/data-table/pagination.d.ts +2 -2
  221. package/dist/composables/tables/data-table/sort.d.ts +2 -2
  222. package/dist/composables/tables/data-table/types.d.ts +2 -2
  223. package/dist/i18n/keys.d.ts +9 -0
  224. package/dist/i18n/keys.js +9 -0
  225. package/dist/i18n/keys.js.map +1 -1
  226. package/dist/icons/icons_1.d.ts +26 -26
  227. package/dist/icons/icons_1.js +348 -365
  228. package/dist/icons/icons_1.js.map +1 -1
  229. package/dist/icons/icons_2.d.ts +28 -28
  230. package/dist/icons/icons_2.js +434 -323
  231. package/dist/icons/icons_2.js.map +1 -1
  232. package/dist/icons/icons_3.d.ts +32 -32
  233. package/dist/icons/icons_3.js +334 -364
  234. package/dist/icons/icons_3.js.map +1 -1
  235. package/dist/icons/icons_4.d.ts +64 -64
  236. package/dist/icons/icons_4.js +769 -669
  237. package/dist/icons/icons_4.js.map +1 -1
  238. package/dist/icons/icons_5.d.ts +66 -9
  239. package/dist/icons/icons_5.js +693 -83
  240. package/dist/icons/icons_5.js.map +1 -1
  241. package/dist/icons/index.d.ts +1 -1
  242. package/dist/icons/index.js +108 -51
  243. package/dist/icons/index.js.map +1 -1
  244. package/dist/index.d.ts +1 -1
  245. package/dist/index.js +6 -6
  246. package/dist/style.css +26 -4
  247. package/dist/types/theme.d.ts +1 -1
  248. package/dist/utils/tv.d.ts +1 -1
  249. package/dist/vendor/@vueuse/core/dist/index.js +63 -55
  250. package/dist/vendor/@vueuse/core/dist/index.js.map +1 -1
  251. package/dist/vendor/@vueuse/shared/dist/index.js +4 -4
  252. package/dist/vendor/@vueuse/shared/dist/index.js.map +1 -1
  253. package/dist/web-types.json +88 -4
  254. package/package.json +26 -26
package/README.md CHANGED
@@ -242,19 +242,30 @@ app.mount('#app');
242
242
 
243
243
  #### Available translation keys
244
244
 
245
- The UI library uses the following translation keys:
246
-
247
- ```typescript
248
- // These are defined in src/i18n/keys.ts
249
- export const RUI_I18N_KEYS = {
250
- dateTimePicker: {
251
- dateAfterMax: 'rui.date_time_picker.date_after_max',
252
- dateBeforeMin: 'rui.date_time_picker.date_before_min',
253
- dateInFuture: 'rui.date_time_picker.date_in_future',
254
- pasteUnreadable: 'rui.date_time_picker.paste_unreadable',
255
- },
256
- } as const;
257
- ```
245
+ The UI library reads these keys, defined in `src/i18n/keys.ts`. A key your messages leave out shows
246
+ its English default, and `translationKeys()` returns the full list.
247
+
248
+ | Key | English default |
249
+ | --------------------------------------- | --------------------------------------------- |
250
+ | `rui.date_time_picker.clear` | Clear |
251
+ | `rui.date_time_picker.clear_value` | Clear the date |
252
+ | `rui.date_time_picker.close_calendar` | Close the calendar |
253
+ | `rui.date_time_picker.date_after_max` | Date cannot be after `{date}` |
254
+ | `rui.date_time_picker.date_before_min` | Date cannot be before `{date}` |
255
+ | `rui.date_time_picker.date_in_future` | The selected date cannot be in the future |
256
+ | `rui.date_time_picker.label` | Pick a date |
257
+ | `rui.date_time_picker.now` | Now |
258
+ | `rui.date_time_picker.open_calendar` | Open the calendar |
259
+ | `rui.date_time_picker.paste_unreadable` | Could not read a date from the pasted text |
260
+ | `rui.date_time_picker.today` | Today |
261
+ | `rui.file_upload.click_to_upload` | click to upload |
262
+ | `rui.file_upload.drop_prefix` | Drag and drop or |
263
+ | `rui.file_upload.remove` | Remove `{name}` |
264
+ | `rui.file_upload.replace` | replace file |
265
+ | `rui.file_upload.too_large` | `{name}` exceeds the maximum size of `{size}` |
266
+ | `rui.file_upload.too_many` | Only one file can be uploaded |
267
+ | `rui.file_upload.wrong_type` | Only `{accept}` files are allowed |
268
+ | `rui.timezone_select.label` | Timezone |
258
269
 
259
270
  ### Use the @rotki/ui-library Tailwind CSS theme
260
271
 
@@ -366,7 +377,9 @@ When the dependency installed on the main project, it will run the `prepare` scr
366
377
 
367
378
  ### Generating the library icons
368
379
 
369
- We use [Lucide](https://lucide.dev/) icons as the base icon set. Brand icons (Discord, Reddit, X/Twitter, etc.) in the `src/custom-icons/` directory are sourced from [Simple Icons](https://simpleicons.org/).
380
+ We use [Lucide](https://lucide.dev/) icons as the base icon set. `src/custom-icons/` holds the rotki-specific icons Lucide lacks, drawn on Lucide's 24×24 grid with round caps and joins. The library ships no brand logos; apps register their own.
381
+
382
+ A custom SVG must use `viewBox="0 0 24 24"` and put everything on its primitives (`path`, `rect`, `circle`, ...): the generator rejects a `transform`, attributes on a `<g>`, and paint on the `<svg>` other than `fill="none"` / `stroke="currentColor"`. It drops `stroke-width`, `stroke-linecap` and `stroke-linejoin`, which `RuiIcon` sets, and turns any colour into `currentColor`. Icons are outlined by default; give a solid shape `fill="currentColor" stroke="none"`. The `CustomIcons` story in Storybook shows every custom icon beside its Lucide neighbour.
370
383
 
371
384
  The generator (`scripts/generate-icons.ts`) reads each Lucide icon's pre-parsed component data and the parsed XML of every SVG in `src/custom-icons/`, and emits one `[tag, attrs]` tuple per renderable primitive into `src/icons/icons_*.ts`. Multi-path icons stay as multiple entries — they are not collapsed into a single concatenated path. The generated files are gitignored and rebuilt by the `build` script; run the command below if you need to regenerate them by hand.
372
385
 
@@ -1 +1 @@
1
- {"version":3,"file":"RuiAccordion.js","names":[],"sources":["../../../../src/components/accordions/accordion/RuiAccordion.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { VueClassValue } from '@/types/class-value';\nimport Icon from '@/components/icons/RuiIcon.vue';\nimport { cn, tv } from '@/utils/tv';\n\nexport interface RuiAccordionClassNames {\n root?: VueClassValue;\n header?: VueClassValue;\n content?: VueClassValue;\n}\n\nexport interface AccordionProps {\n open?: boolean;\n eager?: boolean;\n headerGrow?: boolean;\n classNames?: RuiAccordionClassNames;\n}\n\ndefineOptions({\n name: 'RuiAccordion',\n inheritAttrs: false,\n});\n\nconst {\n open = false,\n eager = false,\n headerGrow = false,\n classNames,\n} = defineProps<AccordionProps>();\n\nconst emit = defineEmits<{\n click: [];\n}>();\n\ndefineSlots<{\n header?: (props: { open: boolean }) => any;\n default?: () => any;\n}>();\n\nconst inner = useTemplateRef<HTMLDivElement>('inner');\n\nconst triggerId = useId();\nconst contentId = useId();\nconst { height: innerHeight } = useElementSize(inner);\n\nconst contentHeight = computed<string>(() => (open ? `${get(innerHeight)}px` : '0px'));\n\nfunction toggle(): void {\n emit('click');\n}\n\nfunction onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n toggle();\n }\n}\n\nconst rootStyle = tv({ base: 'flex flex-col items-start' });\n</script>\n\n<template>\n <div\n :class=\"rootStyle({ class: cn(classNames?.root ?? $attrs.class) })\"\n :data-state=\"open ? 'open' : 'closed'\"\n data-accordion\n v-bind=\"{ ...$attrs, class: undefined }\"\n >\n <!-- rounded only while focused: a permanent radius bent any border an app draws on the header -->\n <div\n v-if=\"$slots.header\"\n :id=\"triggerId\"\n class=\"group flex gap-2 items-center cursor-pointer outline-hidden focus-visible:focus-ring focus-visible:rounded-rui-control\"\n :class=\"[classNames?.header, { 'w-full': headerGrow }]\"\n role=\"button\"\n tabindex=\"0\"\n :aria-expanded=\"open\"\n :aria-controls=\"contentId\"\n data-accordion-trigger\n @click=\"toggle()\"\n @keydown=\"onKeydown($event)\"\n >\n <div :class=\"{ grow: headerGrow }\">\n <slot\n name=\"header\"\n :open=\"open\"\n />\n </div>\n <Icon\n class=\"shrink-0 text-rui-text-secondary transition-[rotate,color] duration-200 ease-out group-hover:text-rui-text motion-reduce:transition-none\"\n :class=\"{ '-rotate-180': open }\"\n name=\"lu-chevron-down\"\n :size=\"16\"\n />\n </div>\n <div\n v-if=\"open || eager\"\n :id=\"contentId\"\n class=\"grow transition-[height] duration-200 ease-out overflow-hidden w-full motion-reduce:transition-none\"\n :class=\"classNames?.content\"\n :style=\"{ height: contentHeight }\"\n role=\"region\"\n :aria-labelledby=\"triggerId\"\n data-accordion-content\n >\n <div ref=\"inner\">\n <slot name=\"default\" />\n </div>\n </div>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiAccordion.js","names":["_sfc_main"],"sources":["../../../../src/components/accordions/accordion/RuiAccordion.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { VueClassValue } from '@/types/class-value';\nimport Icon from '@/components/icons/RuiIcon.vue';\nimport { cn, tv } from '@/utils/tv';\n\nexport interface RuiAccordionClassNames {\n root?: VueClassValue;\n header?: VueClassValue;\n content?: VueClassValue;\n}\n\nexport interface AccordionProps {\n open?: boolean;\n eager?: boolean;\n headerGrow?: boolean;\n classNames?: RuiAccordionClassNames;\n}\n\ndefineOptions({\n name: 'RuiAccordion',\n inheritAttrs: false,\n});\n\nconst {\n open = false,\n eager = false,\n headerGrow = false,\n classNames,\n} = defineProps<AccordionProps>();\n\nconst emit = defineEmits<{\n click: [];\n}>();\n\ndefineSlots<{\n header?: (props: { open: boolean }) => any;\n default?: () => any;\n}>();\n\nconst inner = useTemplateRef<HTMLDivElement>('inner');\n\nconst triggerId = useId();\nconst contentId = useId();\nconst { height: innerHeight } = useElementSize(inner);\n\nconst contentHeight = computed<string>(() => (open ? `${get(innerHeight)}px` : '0px'));\n\nfunction toggle(): void {\n emit('click');\n}\n\nfunction onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n toggle();\n }\n}\n\nconst rootStyle = tv({ base: 'flex flex-col items-start' });\n</script>\n\n<template>\n <div\n :class=\"rootStyle({ class: cn(classNames?.root ?? $attrs.class) })\"\n :data-state=\"open ? 'open' : 'closed'\"\n data-accordion\n v-bind=\"{ ...$attrs, class: undefined }\"\n >\n <!-- rounded only while focused: a permanent radius bent any border an app draws on the header -->\n <div\n v-if=\"$slots.header\"\n :id=\"triggerId\"\n class=\"group flex gap-2 items-center cursor-pointer outline-hidden focus-visible:focus-ring focus-visible:rounded-rui-control\"\n :class=\"[classNames?.header, { 'w-full': headerGrow }]\"\n role=\"button\"\n tabindex=\"0\"\n :aria-expanded=\"open\"\n :aria-controls=\"contentId\"\n data-accordion-trigger\n @click=\"toggle()\"\n @keydown=\"onKeydown($event)\"\n >\n <div :class=\"{ grow: headerGrow }\">\n <slot\n name=\"header\"\n :open=\"open\"\n />\n </div>\n <Icon\n class=\"shrink-0 text-rui-text-secondary transition-[rotate,color] duration-200 ease-out group-hover:text-rui-text motion-reduce:transition-none\"\n :class=\"{ '-rotate-180': open }\"\n name=\"lu-chevron-down\"\n :size=\"16\"\n />\n </div>\n <div\n v-if=\"open || eager\"\n :id=\"contentId\"\n class=\"grow transition-[height] duration-200 ease-out overflow-hidden w-full motion-reduce:transition-none\"\n :class=\"classNames?.content\"\n :style=\"{ height: contentHeight }\"\n role=\"region\"\n :aria-labelledby=\"triggerId\"\n data-accordion-content\n >\n <div ref=\"inner\">\n <slot name=\"default\" />\n </div>\n </div>\n </div>\n</template>\n"],"mappings":""}
@@ -1,4 +1,4 @@
1
- import type { VueClassValue } from '../../../types/class-value';
1
+ import type { VueClassValue } from '../../../types/class-value.js';
2
2
  export interface RuiAccordionClassNames {
3
3
  root?: VueClassValue;
4
4
  header?: VueClassValue;
@@ -1 +1 @@
1
- {"version":3,"file":"RuiAccordion.vue_vue_type_script_setup_true_lang.js","names":["$attrs","$slots"],"sources":["../../../../src/components/accordions/accordion/RuiAccordion.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { VueClassValue } from '@/types/class-value';\nimport Icon from '@/components/icons/RuiIcon.vue';\nimport { cn, tv } from '@/utils/tv';\n\nexport interface RuiAccordionClassNames {\n root?: VueClassValue;\n header?: VueClassValue;\n content?: VueClassValue;\n}\n\nexport interface AccordionProps {\n open?: boolean;\n eager?: boolean;\n headerGrow?: boolean;\n classNames?: RuiAccordionClassNames;\n}\n\ndefineOptions({\n name: 'RuiAccordion',\n inheritAttrs: false,\n});\n\nconst {\n open = false,\n eager = false,\n headerGrow = false,\n classNames,\n} = defineProps<AccordionProps>();\n\nconst emit = defineEmits<{\n click: [];\n}>();\n\ndefineSlots<{\n header?: (props: { open: boolean }) => any;\n default?: () => any;\n}>();\n\nconst inner = useTemplateRef<HTMLDivElement>('inner');\n\nconst triggerId = useId();\nconst contentId = useId();\nconst { height: innerHeight } = useElementSize(inner);\n\nconst contentHeight = computed<string>(() => (open ? `${get(innerHeight)}px` : '0px'));\n\nfunction toggle(): void {\n emit('click');\n}\n\nfunction onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n toggle();\n }\n}\n\nconst rootStyle = tv({ base: 'flex flex-col items-start' });\n</script>\n\n<template>\n <div\n :class=\"rootStyle({ class: cn(classNames?.root ?? $attrs.class) })\"\n :data-state=\"open ? 'open' : 'closed'\"\n data-accordion\n v-bind=\"{ ...$attrs, class: undefined }\"\n >\n <!-- rounded only while focused: a permanent radius bent any border an app draws on the header -->\n <div\n v-if=\"$slots.header\"\n :id=\"triggerId\"\n class=\"group flex gap-2 items-center cursor-pointer outline-hidden focus-visible:focus-ring focus-visible:rounded-rui-control\"\n :class=\"[classNames?.header, { 'w-full': headerGrow }]\"\n role=\"button\"\n tabindex=\"0\"\n :aria-expanded=\"open\"\n :aria-controls=\"contentId\"\n data-accordion-trigger\n @click=\"toggle()\"\n @keydown=\"onKeydown($event)\"\n >\n <div :class=\"{ grow: headerGrow }\">\n <slot\n name=\"header\"\n :open=\"open\"\n />\n </div>\n <Icon\n class=\"shrink-0 text-rui-text-secondary transition-[rotate,color] duration-200 ease-out group-hover:text-rui-text motion-reduce:transition-none\"\n :class=\"{ '-rotate-180': open }\"\n name=\"lu-chevron-down\"\n :size=\"16\"\n />\n </div>\n <div\n v-if=\"open || eager\"\n :id=\"contentId\"\n class=\"grow transition-[height] duration-200 ease-out overflow-hidden w-full motion-reduce:transition-none\"\n :class=\"classNames?.content\"\n :style=\"{ height: contentHeight }\"\n role=\"region\"\n :aria-labelledby=\"triggerId\"\n data-accordion-content\n >\n <div ref=\"inner\">\n <slot name=\"default\" />\n </div>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BA,MAAM,OAAO;EASb,MAAM,QAAQ,eAA+B,OAAO;EAEpD,MAAM,YAAY,MAAM;EACxB,MAAM,YAAY,MAAM;EACxB,MAAM,EAAE,QAAQ,gBAAgB,eAAe,KAAK;EAEpD,MAAM,gBAAgB,eAAwB,QAAA,OAAO,GAAG,IAAI,WAAW,EAAE,MAAM,KAAM;EAErF,SAAS,SAAe;GACtB,KAAK,OAAO;EACd;EAEA,SAAS,UAAU,OAA4B;GAC7C,IAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;IAC9C,MAAM,eAAe;IACrB,OAAO;GACT;EACF;EAEA,MAAM,YAAY,GAAG,EAAE,MAAM,4BAA4B,CAAC;;GAIxD,OAAA,UAAA,GAAA,mBA+CM,OA/CN,WA+CM;IA9CH,OAAO,MAAA,SAAA,CAAS,CAAA,EAAA,OAAU,MAAA,EAAA,CAAE,CAAC,QAAA,YAAY,QAAQA,KAAAA,OAAO,KAAK,EAAA,CAAA;IAC7D,cAAY,QAAA,OAAI,SAAA;IACjB,kBAAA;GACaA,GAAAA;IAAAA,GAAAA,KAAAA;IAAM,OAAS,KAAA;GAAS,CAAA,GAAA,CAI7BC,KAAAA,OAAO,UADf,UAAA,GAAA,mBAyBM,OAAA;;IAvBH,IAAI,MAAA,SAAA;IACL,OAAK,eAAA,CAAC,0HAAwH,CACrH,QAAA,YAAY,QAAM,EAAA,UAAc,QAAA,WAAU,CAAA,CAAA,CAAA;IACnD,MAAK;IACL,UAAS;IACR,iBAAe,QAAA;IACf,iBAAe,MAAA,SAAA;IAChB,0BAAA;IACC,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,OAAM;IACb,WAAO,OAAA,OAAA,OAAA,MAAA,WAAE,UAAU,MAAM;GAE1B,GAAA,CAAA,mBAKM,OAAA,EALA,OAAK,eAAA,EAAA,MAAU,QAAA,WAAU,CAAA,EAAA,GAAA,CAC7B,WAGE,KAAA,QAAA,UAAA,EADC,MAAM,QAAA,KAAI,CAAA,CAAA,GAAA,CAAA,GAGf,YAKE,iBAAA;IAJA,OAAK,eAAA,CAAC,4IAA0I,EAAA,eACvH,QAAA,KAAI,CAAA,CAAA;IAC7B,MAAK;IACJ,MAAM;GAIH,GAAA,MAAA,GAAA,CAAA,OAAA,CAAA,CAAA,GAAA,IAAA,UAAA,KAAA,mBAAA,IAAA,IAAA,GAAA,QAAA,QAAQ,QAAA,SADhB,UAAA,GAAA,mBAaM,OAAA;;IAXH,IAAI,MAAA,SAAA;IACL,OAAK,eAAA,CAAC,uGACE,QAAA,YAAY,OAAO,CAAA;IAC1B,OAAK,eAAA,EAAA,QAAY,MAAA,aAAA,EAAa,CAAA;IAC/B,MAAK;IACJ,mBAAiB,MAAA,SAAA;IAClB,0BAAA;GAEA,GAAA,CAAA,mBAEM,OAAA;IAFG,SAAA;IAAJ,KAAI;GACP,GAAA,CAAA,WAAuB,KAAA,QAAA,SAAA,CAAA,GAAA,GAAA,CAAA,GAAA,IAAA,UAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,IAAA,UAAA"}
1
+ {"version":3,"file":"RuiAccordion.vue_vue_type_script_setup_true_lang.js","names":["$attrs","$slots","_openBlock","_createElementBlock","_mergeProps","_unref","_normalizeClass","_createElementVNode","_renderSlot","_createVNode","Icon","_createCommentVNode","_normalizeStyle"],"sources":["../../../../src/components/accordions/accordion/RuiAccordion.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { VueClassValue } from '@/types/class-value';\nimport Icon from '@/components/icons/RuiIcon.vue';\nimport { cn, tv } from '@/utils/tv';\n\nexport interface RuiAccordionClassNames {\n root?: VueClassValue;\n header?: VueClassValue;\n content?: VueClassValue;\n}\n\nexport interface AccordionProps {\n open?: boolean;\n eager?: boolean;\n headerGrow?: boolean;\n classNames?: RuiAccordionClassNames;\n}\n\ndefineOptions({\n name: 'RuiAccordion',\n inheritAttrs: false,\n});\n\nconst {\n open = false,\n eager = false,\n headerGrow = false,\n classNames,\n} = defineProps<AccordionProps>();\n\nconst emit = defineEmits<{\n click: [];\n}>();\n\ndefineSlots<{\n header?: (props: { open: boolean }) => any;\n default?: () => any;\n}>();\n\nconst inner = useTemplateRef<HTMLDivElement>('inner');\n\nconst triggerId = useId();\nconst contentId = useId();\nconst { height: innerHeight } = useElementSize(inner);\n\nconst contentHeight = computed<string>(() => (open ? `${get(innerHeight)}px` : '0px'));\n\nfunction toggle(): void {\n emit('click');\n}\n\nfunction onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n toggle();\n }\n}\n\nconst rootStyle = tv({ base: 'flex flex-col items-start' });\n</script>\n\n<template>\n <div\n :class=\"rootStyle({ class: cn(classNames?.root ?? $attrs.class) })\"\n :data-state=\"open ? 'open' : 'closed'\"\n data-accordion\n v-bind=\"{ ...$attrs, class: undefined }\"\n >\n <!-- rounded only while focused: a permanent radius bent any border an app draws on the header -->\n <div\n v-if=\"$slots.header\"\n :id=\"triggerId\"\n class=\"group flex gap-2 items-center cursor-pointer outline-hidden focus-visible:focus-ring focus-visible:rounded-rui-control\"\n :class=\"[classNames?.header, { 'w-full': headerGrow }]\"\n role=\"button\"\n tabindex=\"0\"\n :aria-expanded=\"open\"\n :aria-controls=\"contentId\"\n data-accordion-trigger\n @click=\"toggle()\"\n @keydown=\"onKeydown($event)\"\n >\n <div :class=\"{ grow: headerGrow }\">\n <slot\n name=\"header\"\n :open=\"open\"\n />\n </div>\n <Icon\n class=\"shrink-0 text-rui-text-secondary transition-[rotate,color] duration-200 ease-out group-hover:text-rui-text motion-reduce:transition-none\"\n :class=\"{ '-rotate-180': open }\"\n name=\"lu-chevron-down\"\n :size=\"16\"\n />\n </div>\n <div\n v-if=\"open || eager\"\n :id=\"contentId\"\n class=\"grow transition-[height] duration-200 ease-out overflow-hidden w-full motion-reduce:transition-none\"\n :class=\"classNames?.content\"\n :style=\"{ height: contentHeight }\"\n role=\"region\"\n :aria-labelledby=\"triggerId\"\n data-accordion-content\n >\n <div ref=\"inner\">\n <slot name=\"default\" />\n </div>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BA,MAAM,OAAO;EASb,MAAM,QAAQ,eAA+B,OAAO;EAEpD,MAAM,YAAY,MAAM;EACxB,MAAM,YAAY,MAAM;EACxB,MAAM,EAAE,QAAQ,gBAAgB,eAAe,KAAK;EAEpD,MAAM,gBAAgB,eAAwB,QAAA,OAAO,GAAG,IAAI,WAAW,EAAE,MAAM,KAAM;EAErF,SAAS,SAAe;GACtB,KAAK,OAAO;EACd;EAEA,SAAS,UAAU,OAA4B;GAC7C,IAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;IAC9C,MAAM,eAAe;IACrB,OAAO;GACT;EACF;EAEA,MAAM,YAAY,GAAG,EAAE,MAAM,4BAA4B,CAAC;;GAIxD,OAAAE,UAAA,GAAAC,mBA+CM,OA/CNC,WA+CM;IA9CH,OAAOC,MAAA,SAAA,CAAS,CAAA,EAAA,OAAUA,MAAA,EAAA,CAAE,CAAC,QAAA,YAAY,QAAQL,KAAAA,OAAO,KAAK,EAAA,CAAA;IAC7D,cAAY,QAAA,OAAI,SAAA;IACjB,kBAAA;GACaA,GAAAA;IAAAA,GAAAA,KAAAA;IAAM,OAAS,KAAA;GAAS,CAAA,GAAA,CAI7BC,KAAAA,OAAO,UADfC,UAAA,GAAAC,mBAyBM,OAAA;;IAvBH,IAAIE,MAAA,SAAA;IACL,OAAKC,eAAA,CAAC,0HAAwH,CACrH,QAAA,YAAY,QAAM,EAAA,UAAc,QAAA,WAAU,CAAA,CAAA,CAAA;IACnD,MAAK;IACL,UAAS;IACR,iBAAe,QAAA;IACf,iBAAeD,MAAA,SAAA;IAChB,0BAAA;IACC,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,OAAM;IACb,WAAO,OAAA,OAAA,OAAA,MAAA,WAAE,UAAU,MAAM;GAE1BE,GAAAA,CAAAA,mBAKM,OAAA,EALA,OAAKD,eAAA,EAAA,MAAU,QAAA,WAAU,CAAA,EAAA,GAAA,CAC7BE,WAGE,KAAA,QAAA,UAAA,EADC,MAAM,QAAA,KAAI,CAAA,CAAA,GAAA,CAAA,GAGfC,YAKEC,iBAAA;IAJA,OAAKJ,eAAA,CAAC,4IAA0I,EAAA,eACvH,QAAA,KAAI,CAAA,CAAA;IAC7B,MAAK;IACJ,MAAM;GAIH,GAAA,MAAA,GAAA,CAAA,OAAA,CAAA,CAAA,GAAA,IAAA,UAAA,KAAA,mBAAA,IAAA,IAAA,GAAA,QAAA,QAAQ,QAAA,SADhBJ,UAAA,GAAAC,mBAaM,OAAA;;IAXH,IAAIE,MAAA,SAAA;IACL,OAAKC,eAAA,CAAC,uGACE,QAAA,YAAY,OAAO,CAAA;IAC1B,OAAKM,eAAA,EAAA,QAAYP,MAAA,aAAA,EAAa,CAAA;IAC/B,MAAK;IACJ,mBAAiBA,MAAA,SAAA;IAClB,0BAAA;GAEAE,GAAAA,CAAAA,mBAEM,OAAA;IAFG,SAAA;IAAJ,KAAI;GACPC,GAAAA,CAAAA,WAAuB,KAAA,QAAA,SAAA,CAAA,GAAA,GAAA,CAAA,GAAA,IAAA,UAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,IAAA,UAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiAccordions.js","names":[],"sources":["../../../../src/components/accordions/accordions/RuiAccordions.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { Fragment, isVNode } from 'vue';\n\nexport interface Props {\n multiple?: boolean;\n}\n\ndefineOptions({\n name: 'RuiAccordions',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<number[] | number>({ default: -1 });\n\nconst { multiple = false } = defineProps<Props>();\n\nconst internalValue = ref<number[] | number>();\n\nconst slots = useSlots();\n\n/**\n * Unwraps the Fragments a `v-for` or `<template>` makes, so each accordion gets its own index.\n * The placeholder a false `v-if` leaves keeps its index, so hiding one does not renumber the rest.\n *\n * @param nodes - the slot's top-level vnodes\n * @returns the accordions in order\n */\nfunction flattenSlotContent(nodes: VNode[]): VNode[] {\n return nodes.flatMap((node) => {\n if (node.type === Fragment && Array.isArray(node.children))\n return flattenSlotContent(node.children.filter(isVNode));\n\n return [node];\n });\n}\n\nconst children = computed<VNode[]>(() => {\n const accordions = flattenSlotContent(slots.default?.() ?? []);\n const currentValue = get(internalValue);\n\n return accordions.map((accordion, index) => {\n const open =\n multiple && Array.isArray(currentValue)\n ? currentValue.includes(index)\n : currentValue === index;\n\n return {\n ...accordion,\n props: {\n open,\n ...accordion.props,\n },\n };\n });\n});\n\nfunction updateValue(newModelValue: number): void {\n let newValue: number[] | number;\n const internal = get(internalValue);\n if (multiple && Array.isArray(internal)) {\n const temp = [...internal];\n const index = temp.indexOf(newModelValue);\n if (index === -1)\n temp.push(newModelValue);\n else temp.splice(index, 1);\n newValue = temp;\n }\n else {\n if (internal === newModelValue)\n newValue = -1;\n else newValue = newModelValue;\n }\n set(modelValue, newValue);\n set(internalValue, newValue);\n}\n\nwatch(\n [modelValue, () => multiple],\n ([value, isMultiple]) => {\n let internal: number | number[] = value;\n if (isMultiple && !Array.isArray(internal))\n internal = internal === -1 ? [] : [internal];\n else if (!isMultiple && Array.isArray(internal))\n internal = internal[0] ?? -1;\n\n set(internalValue, internal);\n },\n { immediate: true },\n);\n</script>\n\n<template>\n <div v-bind=\"$attrs\">\n <Component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n @click=\"updateValue(i)\"\n />\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiAccordions.js","names":["_sfc_main"],"sources":["../../../../src/components/accordions/accordions/RuiAccordions.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { Fragment, isVNode } from 'vue';\n\nexport interface Props {\n multiple?: boolean;\n}\n\ndefineOptions({\n name: 'RuiAccordions',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<number[] | number>({ default: -1 });\n\nconst { multiple = false } = defineProps<Props>();\n\nconst internalValue = ref<number[] | number>();\n\nconst slots = useSlots();\n\n/**\n * Unwraps the Fragments a `v-for` or `<template>` makes, so each accordion gets its own index.\n * The placeholder a false `v-if` leaves keeps its index, so hiding one does not renumber the rest.\n *\n * @param nodes - the slot's top-level vnodes\n * @returns the accordions in order\n */\nfunction flattenSlotContent(nodes: VNode[]): VNode[] {\n return nodes.flatMap((node) => {\n if (node.type === Fragment && Array.isArray(node.children))\n return flattenSlotContent(node.children.filter(isVNode));\n\n return [node];\n });\n}\n\nconst children = computed<VNode[]>(() => {\n const accordions = flattenSlotContent(slots.default?.() ?? []);\n const currentValue = get(internalValue);\n\n return accordions.map((accordion, index) => {\n const open =\n multiple && Array.isArray(currentValue)\n ? currentValue.includes(index)\n : currentValue === index;\n\n return {\n ...accordion,\n props: {\n open,\n ...accordion.props,\n },\n };\n });\n});\n\nfunction updateValue(newModelValue: number): void {\n let newValue: number[] | number;\n const internal = get(internalValue);\n if (multiple && Array.isArray(internal)) {\n const temp = [...internal];\n const index = temp.indexOf(newModelValue);\n if (index === -1)\n temp.push(newModelValue);\n else temp.splice(index, 1);\n newValue = temp;\n }\n else {\n if (internal === newModelValue)\n newValue = -1;\n else newValue = newModelValue;\n }\n set(modelValue, newValue);\n set(internalValue, newValue);\n}\n\nwatch(\n [modelValue, () => multiple],\n ([value, isMultiple]) => {\n let internal: number | number[] = value;\n if (isMultiple && !Array.isArray(internal))\n internal = internal === -1 ? [] : [internal];\n else if (!isMultiple && Array.isArray(internal))\n internal = internal[0] ?? -1;\n\n set(internalValue, internal);\n },\n { immediate: true },\n);\n</script>\n\n<template>\n <div v-bind=\"$attrs\">\n <Component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n @click=\"updateValue(i)\"\n />\n </div>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiAccordions.vue_vue_type_script_setup_true_lang.js","names":["$attrs"],"sources":["../../../../src/components/accordions/accordions/RuiAccordions.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { Fragment, isVNode } from 'vue';\n\nexport interface Props {\n multiple?: boolean;\n}\n\ndefineOptions({\n name: 'RuiAccordions',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<number[] | number>({ default: -1 });\n\nconst { multiple = false } = defineProps<Props>();\n\nconst internalValue = ref<number[] | number>();\n\nconst slots = useSlots();\n\n/**\n * Unwraps the Fragments a `v-for` or `<template>` makes, so each accordion gets its own index.\n * The placeholder a false `v-if` leaves keeps its index, so hiding one does not renumber the rest.\n *\n * @param nodes - the slot's top-level vnodes\n * @returns the accordions in order\n */\nfunction flattenSlotContent(nodes: VNode[]): VNode[] {\n return nodes.flatMap((node) => {\n if (node.type === Fragment && Array.isArray(node.children))\n return flattenSlotContent(node.children.filter(isVNode));\n\n return [node];\n });\n}\n\nconst children = computed<VNode[]>(() => {\n const accordions = flattenSlotContent(slots.default?.() ?? []);\n const currentValue = get(internalValue);\n\n return accordions.map((accordion, index) => {\n const open =\n multiple && Array.isArray(currentValue)\n ? currentValue.includes(index)\n : currentValue === index;\n\n return {\n ...accordion,\n props: {\n open,\n ...accordion.props,\n },\n };\n });\n});\n\nfunction updateValue(newModelValue: number): void {\n let newValue: number[] | number;\n const internal = get(internalValue);\n if (multiple && Array.isArray(internal)) {\n const temp = [...internal];\n const index = temp.indexOf(newModelValue);\n if (index === -1)\n temp.push(newModelValue);\n else temp.splice(index, 1);\n newValue = temp;\n }\n else {\n if (internal === newModelValue)\n newValue = -1;\n else newValue = newModelValue;\n }\n set(modelValue, newValue);\n set(internalValue, newValue);\n}\n\nwatch(\n [modelValue, () => multiple],\n ([value, isMultiple]) => {\n let internal: number | number[] = value;\n if (isMultiple && !Array.isArray(internal))\n internal = internal === -1 ? [] : [internal];\n else if (!isMultiple && Array.isArray(internal))\n internal = internal[0] ?? -1;\n\n set(internalValue, internal);\n },\n { immediate: true },\n);\n</script>\n\n<template>\n <div v-bind=\"$attrs\">\n <Component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n @click=\"updateValue(i)\"\n />\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;EAYA,MAAM,aAAa,SAA8B,SAAA,YAAgB;EAIjE,MAAM,gBAAgB,IAAuB;EAE7C,MAAM,QAAQ,SAAS;;;;;;;;EASvB,SAAS,mBAAmB,OAAyB;GACnD,OAAO,MAAM,SAAS,SAAS;IAC7B,IAAI,KAAK,SAAS,YAAY,MAAM,QAAQ,KAAK,QAAQ,GACvD,OAAO,mBAAmB,KAAK,SAAS,OAAO,OAAO,CAAC;IAEzD,OAAO,CAAC,IAAI;GACd,CAAC;EACH;EAEA,MAAM,WAAW,eAAwB;GACvC,MAAM,aAAa,mBAAmB,MAAM,UAAU,KAAK,CAAC,CAAC;GAC7D,MAAM,eAAe,IAAI,aAAa;GAEtC,OAAO,WAAW,KAAK,WAAW,UAAU;IAC1C,MAAM,OACJ,QAAA,YAAY,MAAM,QAAQ,YAAY,IAClC,aAAa,SAAS,KAAK,IAC3B,iBAAiB;IAEvB,OAAO;KACL,GAAG;KACH,OAAO;MACL;MACA,GAAG,UAAU;KACf;IACF;GACF,CAAC;EACH,CAAC;EAED,SAAS,YAAY,eAA6B;GAChD,IAAI;GACJ,MAAM,WAAW,IAAI,aAAa;GAClC,IAAI,QAAA,YAAY,MAAM,QAAQ,QAAQ,GAAG;IACvC,MAAM,OAAO,CAAC,GAAG,QAAQ;IACzB,MAAM,QAAQ,KAAK,QAAQ,aAAa;IACxC,IAAI,UAAU,IACZ,KAAK,KAAK,aAAa;SACpB,KAAK,OAAO,OAAO,CAAC;IACzB,WAAW;GACb,OAEE,IAAI,aAAa,eACf,WAAW;QACR,WAAW;GAElB,IAAI,YAAY,QAAQ;GACxB,IAAI,eAAe,QAAQ;EAC7B;EAEA,MACE,CAAC,kBAAkB,QAAA,QAAQ,IAC1B,CAAC,OAAO,gBAAgB;GACvB,IAAI,WAA8B;GAClC,IAAI,cAAc,CAAC,MAAM,QAAQ,QAAQ,GACvC,WAAW,aAAa,KAAK,CAAC,IAAI,CAAC,QAAQ;QACxC,IAAI,CAAC,cAAc,MAAM,QAAQ,QAAQ,GAC5C,WAAW,SAAS,MAAM;GAE5B,IAAI,eAAe,QAAQ;EAC7B,GACA,EAAE,WAAW,KAAK,CACpB;;GAIE,OAAA,UAAA,GAAA,mBAOM,OAAA,eAAA,mBAPOA,KAAAA,MAAM,CAAA,GAAA,EACjB,UAAA,IAAA,GAAA,mBAKE,UAAA,MAAA,WAHqB,MAAA,QAAA,IAAb,OAAO,MAAC;IAFlB,OAAA,UAAA,GAAA,YAKE,wBAJK,KAAK,GAAA;KAET,KAAK;KACL,UAAK,WAAE,YAAY,CAAC"}
1
+ {"version":3,"file":"RuiAccordions.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_useModel","_openBlock","_createElementBlock","_normalizeProps","_guardReactiveProps","_Fragment","_renderList","_unref","_createBlock","_resolveDynamicComponent"],"sources":["../../../../src/components/accordions/accordions/RuiAccordions.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { Fragment, isVNode } from 'vue';\n\nexport interface Props {\n multiple?: boolean;\n}\n\ndefineOptions({\n name: 'RuiAccordions',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<number[] | number>({ default: -1 });\n\nconst { multiple = false } = defineProps<Props>();\n\nconst internalValue = ref<number[] | number>();\n\nconst slots = useSlots();\n\n/**\n * Unwraps the Fragments a `v-for` or `<template>` makes, so each accordion gets its own index.\n * The placeholder a false `v-if` leaves keeps its index, so hiding one does not renumber the rest.\n *\n * @param nodes - the slot's top-level vnodes\n * @returns the accordions in order\n */\nfunction flattenSlotContent(nodes: VNode[]): VNode[] {\n return nodes.flatMap((node) => {\n if (node.type === Fragment && Array.isArray(node.children))\n return flattenSlotContent(node.children.filter(isVNode));\n\n return [node];\n });\n}\n\nconst children = computed<VNode[]>(() => {\n const accordions = flattenSlotContent(slots.default?.() ?? []);\n const currentValue = get(internalValue);\n\n return accordions.map((accordion, index) => {\n const open =\n multiple && Array.isArray(currentValue)\n ? currentValue.includes(index)\n : currentValue === index;\n\n return {\n ...accordion,\n props: {\n open,\n ...accordion.props,\n },\n };\n });\n});\n\nfunction updateValue(newModelValue: number): void {\n let newValue: number[] | number;\n const internal = get(internalValue);\n if (multiple && Array.isArray(internal)) {\n const temp = [...internal];\n const index = temp.indexOf(newModelValue);\n if (index === -1)\n temp.push(newModelValue);\n else temp.splice(index, 1);\n newValue = temp;\n }\n else {\n if (internal === newModelValue)\n newValue = -1;\n else newValue = newModelValue;\n }\n set(modelValue, newValue);\n set(internalValue, newValue);\n}\n\nwatch(\n [modelValue, () => multiple],\n ([value, isMultiple]) => {\n let internal: number | number[] = value;\n if (isMultiple && !Array.isArray(internal))\n internal = internal === -1 ? [] : [internal];\n else if (!isMultiple && Array.isArray(internal))\n internal = internal[0] ?? -1;\n\n set(internalValue, internal);\n },\n { immediate: true },\n);\n</script>\n\n<template>\n <div v-bind=\"$attrs\">\n <Component\n :is=\"child\"\n v-for=\"(child, i) in children\"\n :key=\"i\"\n @click=\"updateValue(i)\"\n />\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;EAYA,MAAM,aAAaC,SAA8B,SAAA,YAAgB;EAIjE,MAAM,gBAAgB,IAAuB;EAE7C,MAAM,QAAQ,SAAS;;;;;;;;EASvB,SAAS,mBAAmB,OAAyB;GACnD,OAAO,MAAM,SAAS,SAAS;IAC7B,IAAI,KAAK,SAAS,YAAY,MAAM,QAAQ,KAAK,QAAQ,GACvD,OAAO,mBAAmB,KAAK,SAAS,OAAO,OAAO,CAAC;IAEzD,OAAO,CAAC,IAAI;GACd,CAAC;EACH;EAEA,MAAM,WAAW,eAAwB;GACvC,MAAM,aAAa,mBAAmB,MAAM,UAAU,KAAK,CAAC,CAAC;GAC7D,MAAM,eAAe,IAAI,aAAa;GAEtC,OAAO,WAAW,KAAK,WAAW,UAAU;IAC1C,MAAM,OACJ,QAAA,YAAY,MAAM,QAAQ,YAAY,IAClC,aAAa,SAAS,KAAK,IAC3B,iBAAiB;IAEvB,OAAO;KACL,GAAG;KACH,OAAO;MACL;MACA,GAAG,UAAU;KACf;IACF;GACF,CAAC;EACH,CAAC;EAED,SAAS,YAAY,eAA6B;GAChD,IAAI;GACJ,MAAM,WAAW,IAAI,aAAa;GAClC,IAAI,QAAA,YAAY,MAAM,QAAQ,QAAQ,GAAG;IACvC,MAAM,OAAO,CAAC,GAAG,QAAQ;IACzB,MAAM,QAAQ,KAAK,QAAQ,aAAa;IACxC,IAAI,UAAU,IACZ,KAAK,KAAK,aAAa;SACpB,KAAK,OAAO,OAAO,CAAC;IACzB,WAAW;GACb,OAEE,IAAI,aAAa,eACf,WAAW;QACR,WAAW;GAElB,IAAI,YAAY,QAAQ;GACxB,IAAI,eAAe,QAAQ;EAC7B;EAEA,MACE,CAAC,kBAAkB,QAAA,QAAQ,IAC1B,CAAC,OAAO,gBAAgB;GACvB,IAAI,WAA8B;GAClC,IAAI,cAAc,CAAC,MAAM,QAAQ,QAAQ,GACvC,WAAW,aAAa,KAAK,CAAC,IAAI,CAAC,QAAQ;QACxC,IAAI,CAAC,cAAc,MAAM,QAAQ,QAAQ,GAC5C,WAAW,SAAS,MAAM;GAE5B,IAAI,eAAe,QAAQ;EAC7B,GACA,EAAE,WAAW,KAAK,CACpB;;GAIE,OAAAC,UAAA,GAAAC,mBAOM,OAAAC,eAAAC,mBAPOL,KAAAA,MAAM,CAAA,GAAA,EACjBE,UAAA,IAAA,GAAAC,mBAKEG,UAAA,MAAAC,WAHqBC,MAAA,QAAA,IAAb,OAAO,MAAC;IAFlB,OAAAN,UAAA,GAAAO,YAKEC,wBAJK,KAAK,GAAA;KAET,KAAK;KACL,UAAK,WAAE,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiAlert.js","names":[],"sources":["../../../src/components/alerts/RuiAlert.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ContextColorsType } from '@/consts/colors';\nimport type { RuiIcons } from '@/icons';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { tv } from '@/utils/tv';\n\nexport interface Props {\n title?: string;\n description?: string;\n type?: ContextColorsType;\n icon?: RuiIcons;\n variant?: 'default' | 'filled' | 'outlined';\n actionText?: string;\n closeable?: boolean;\n}\n\ndefineOptions({\n name: 'RuiAlert',\n inheritAttrs: false,\n});\n\nconst {\n title = '',\n description = '',\n type = 'primary',\n icon = undefined,\n variant = 'default',\n actionText = '',\n closeable = false,\n} = defineProps<Props>();\n\nconst emit = defineEmits<{\n action: [];\n close: [];\n}>();\n\nconst slots = defineSlots<{\n title?: () => any;\n default?: () => any;\n}>();\n\nconst alertStyles = tv({\n slots: {\n root: 'px-4 py-2.5 rounded-rui-panel flex between:ml-4 between:mr-0',\n content: 'flex between:ml-3 between:mr-0 py-1 grow',\n // as tall as the first line of text and centered in it, so the icon lines up however the text wraps\n icon: 'flex shrink-0 items-center',\n texts: 'between:mt-1 between:mb-0 grow',\n action: '',\n close: '',\n },\n variants: {\n // the first line is the title's (24px) when there is one, else the description's (text-sm, 20px)\n titled: {\n true: { icon: 'h-6' },\n false: { icon: 'h-5' },\n },\n variant: {\n default: {},\n filled: {\n icon: 'text-rui-dark-text!',\n texts: 'text-rui-dark-text!',\n action: 'text-rui-dark-text!',\n close: 'text-rui-dark-text!',\n },\n outlined: { root: 'border -m-px bg-transparent' },\n },\n /*\n * Each type names its color once, as `--rui-alert`, and the variants mix from it. The tints\n * and shades used to be paused CSS animations behind an `@supports (color-mix())` check that\n * never matched (it is not a valid condition), so every browser took the animation; mixing\n * directly gives the same colors without it.\n */\n type: {\n primary: { root: '[--rui-alert:var(--rui-primary-main)]' },\n secondary: { root: '[--rui-alert:var(--rui-secondary-main)]' },\n // a status color's dark `main` is a text tone, so a filled alert takes the deep `darker` there\n error: { root: '[--rui-alert:var(--rui-error-main)] [--rui-alert-fill:var(--rui-error-darker)]' },\n warning: { root: '[--rui-alert:var(--rui-warning-main)] [--rui-alert-fill:var(--rui-warning-darker)]' },\n info: { root: '[--rui-alert:var(--rui-info-main)] [--rui-alert-fill:var(--rui-info-darker)]' },\n success: { root: '[--rui-alert:var(--rui-success-main)] [--rui-alert-fill:var(--rui-success-darker)]' },\n },\n },\n compoundVariants: [\n // A tint of the type's color with a hairline of it, which reads on any surface in either theme\n {\n variant: 'default',\n class: { root: 'border -m-px bg-[color-mix(in_srgb,rgb(var(--rui-alert))_8%,transparent)] dark:bg-[color-mix(in_srgb,rgb(var(--rui-alert))_12%,transparent)] border-[color-mix(in_srgb,rgb(var(--rui-alert))_25%,transparent)]' },\n },\n { variant: 'filled', class: { root: 'bg-[rgb(var(--rui-alert))] dark:bg-[rgb(var(--rui-alert-fill,var(--rui-alert)))]' } },\n // without a tint behind it, the outlined alert carries its type in the icon too\n { variant: 'outlined', class: { root: 'border-[rgb(var(--rui-alert))]', icon: 'text-[rgb(var(--rui-alert))]' } },\n ],\n compoundSlots: [\n {\n slots: ['texts', 'action', 'close'],\n variant: ['default', 'outlined'],\n class: 'text-[color-mix(in_srgb,black_60%,rgb(var(--rui-alert)))] dark:text-[color-mix(in_srgb,white_60%,rgb(var(--rui-alert)))]',\n },\n {\n slots: ['icon'],\n variant: 'default',\n class: 'text-[color-mix(in_srgb,black_60%,rgb(var(--rui-alert)))] dark:text-[color-mix(in_srgb,white_60%,rgb(var(--rui-alert)))]',\n },\n ],\n});\n\nconst ui = computed<ReturnType<typeof alertStyles>>(() => alertStyles({ variant, type, titled: !!slots.title || !!title }));\n\nconst usedIcon = computed<RuiIcons | undefined>(() => {\n if (icon)\n return icon;\n\n const iconMap: Record<ContextColorsType, RuiIcons | undefined> = {\n primary: undefined,\n secondary: undefined,\n warning: 'lu-triangle-alert',\n info: 'lu-info',\n error: 'lu-circle-alert',\n success: 'lu-circle-check',\n };\n\n return iconMap[type];\n});\n</script>\n\n<template>\n <div\n :class=\"ui.root()\"\n v-bind=\"$attrs\"\n :data-variant=\"variant\"\n :data-type=\"type\"\n >\n <div :class=\"ui.content()\">\n <div\n v-if=\"usedIcon\"\n :class=\"ui.icon()\"\n >\n <RuiIcon\n :name=\"usedIcon\"\n size=\"20\"\n />\n </div>\n <div :class=\"ui.texts()\">\n <div\n v-if=\"$slots.title || title\"\n :class=\"{\n 'font-medium': !!title,\n }\"\n >\n <slot name=\"title\">\n {{ title }}\n </slot>\n </div>\n\n <div\n v-if=\"$slots.default || description\"\n class=\"text-body-2\"\n >\n <slot>\n {{ description }}\n </slot>\n </div>\n </div>\n </div>\n <div v-if=\"actionText\">\n <RuiButton\n variant=\"text\"\n size=\"sm\"\n :color=\"variant === 'filled' ? undefined : type\"\n :class=\"ui.action()\"\n data-id=\"alert-action\"\n @click=\"emit('action')\"\n >\n {{ actionText }}\n </RuiButton>\n </div>\n <div v-if=\"closeable\">\n <RuiButton\n :color=\"variant === 'filled' ? undefined : type\"\n size=\"sm\"\n icon\n variant=\"text\"\n :class=\"ui.close()\"\n data-id=\"alert-close\"\n @click=\"emit('close')\"\n >\n <RuiIcon\n name=\"lu-x\"\n size=\"20\"\n />\n </RuiButton>\n </div>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiAlert.js","names":["_sfc_main"],"sources":["../../../src/components/alerts/RuiAlert.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ContextColorsType } from '@/consts/colors';\nimport type { RuiIcons } from '@/icons';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { tv } from '@/utils/tv';\n\nexport interface Props {\n title?: string;\n description?: string;\n type?: ContextColorsType;\n icon?: RuiIcons;\n variant?: 'default' | 'filled' | 'outlined';\n actionText?: string;\n closeable?: boolean;\n}\n\ndefineOptions({\n name: 'RuiAlert',\n inheritAttrs: false,\n});\n\nconst {\n title = '',\n description = '',\n type = 'primary',\n icon = undefined,\n variant = 'default',\n actionText = '',\n closeable = false,\n} = defineProps<Props>();\n\nconst emit = defineEmits<{\n action: [];\n close: [];\n}>();\n\nconst slots = defineSlots<{\n title?: () => any;\n default?: () => any;\n}>();\n\nconst alertStyles = tv({\n slots: {\n root: 'px-4 py-2.5 rounded-rui-panel flex between:ml-4 between:mr-0',\n content: 'flex between:ml-3 between:mr-0 py-1 grow',\n // as tall as the first line of text and centered in it, so the icon lines up however the text wraps\n icon: 'flex shrink-0 items-center',\n texts: 'between:mt-1 between:mb-0 grow',\n action: '',\n close: '',\n },\n variants: {\n // the first line is the title's (24px) when there is one, else the description's (text-sm, 20px)\n titled: {\n true: { icon: 'h-6' },\n false: { icon: 'h-5' },\n },\n variant: {\n default: {},\n filled: {\n icon: 'text-rui-dark-text!',\n texts: 'text-rui-dark-text!',\n action: 'text-rui-dark-text!',\n close: 'text-rui-dark-text!',\n },\n outlined: { root: 'border -m-px bg-transparent' },\n },\n /*\n * Each type names its color once, as `--rui-alert`, and the variants mix from it. The tints\n * and shades used to be paused CSS animations behind an `@supports (color-mix())` check that\n * never matched (it is not a valid condition), so every browser took the animation; mixing\n * directly gives the same colors without it.\n */\n type: {\n primary: { root: '[--rui-alert:var(--rui-primary-main)]' },\n secondary: { root: '[--rui-alert:var(--rui-secondary-main)]' },\n // a status color's dark `main` is a text tone, so a filled alert takes the deep `darker` there\n error: { root: '[--rui-alert:var(--rui-error-main)] [--rui-alert-fill:var(--rui-error-darker)]' },\n warning: { root: '[--rui-alert:var(--rui-warning-main)] [--rui-alert-fill:var(--rui-warning-darker)]' },\n info: { root: '[--rui-alert:var(--rui-info-main)] [--rui-alert-fill:var(--rui-info-darker)]' },\n success: { root: '[--rui-alert:var(--rui-success-main)] [--rui-alert-fill:var(--rui-success-darker)]' },\n },\n },\n compoundVariants: [\n // A tint of the type's color with a hairline of it, which reads on any surface in either theme\n {\n variant: 'default',\n class: { root: 'border -m-px bg-[color-mix(in_srgb,rgb(var(--rui-alert))_8%,transparent)] dark:bg-[color-mix(in_srgb,rgb(var(--rui-alert))_12%,transparent)] border-[color-mix(in_srgb,rgb(var(--rui-alert))_25%,transparent)]' },\n },\n { variant: 'filled', class: { root: 'bg-[rgb(var(--rui-alert))] dark:bg-[rgb(var(--rui-alert-fill,var(--rui-alert)))]' } },\n // without a tint behind it, the outlined alert carries its type in the icon too\n { variant: 'outlined', class: { root: 'border-[rgb(var(--rui-alert))]', icon: 'text-[rgb(var(--rui-alert))]' } },\n ],\n compoundSlots: [\n {\n slots: ['texts', 'action', 'close'],\n variant: ['default', 'outlined'],\n class: 'text-[color-mix(in_srgb,black_60%,rgb(var(--rui-alert)))] dark:text-[color-mix(in_srgb,white_60%,rgb(var(--rui-alert)))]',\n },\n {\n slots: ['icon'],\n variant: 'default',\n class: 'text-[color-mix(in_srgb,black_60%,rgb(var(--rui-alert)))] dark:text-[color-mix(in_srgb,white_60%,rgb(var(--rui-alert)))]',\n },\n ],\n});\n\nconst ui = computed<ReturnType<typeof alertStyles>>(() => alertStyles({ variant, type, titled: !!slots.title || !!title }));\n\nconst usedIcon = computed<RuiIcons | undefined>(() => {\n if (icon)\n return icon;\n\n const iconMap: Record<ContextColorsType, RuiIcons | undefined> = {\n primary: undefined,\n secondary: undefined,\n warning: 'lu-triangle-alert',\n info: 'lu-info',\n error: 'lu-circle-alert',\n success: 'lu-circle-check',\n };\n\n return iconMap[type];\n});\n</script>\n\n<template>\n <div\n :class=\"ui.root()\"\n v-bind=\"$attrs\"\n :data-variant=\"variant\"\n :data-type=\"type\"\n >\n <div :class=\"ui.content()\">\n <div\n v-if=\"usedIcon\"\n :class=\"ui.icon()\"\n >\n <RuiIcon\n :name=\"usedIcon\"\n size=\"20\"\n />\n </div>\n <div :class=\"ui.texts()\">\n <div\n v-if=\"$slots.title || title\"\n :class=\"{\n 'font-medium': !!title,\n }\"\n >\n <slot name=\"title\">\n {{ title }}\n </slot>\n </div>\n\n <div\n v-if=\"$slots.default || description\"\n class=\"text-body-2\"\n >\n <slot>\n {{ description }}\n </slot>\n </div>\n </div>\n </div>\n <div v-if=\"actionText\">\n <RuiButton\n variant=\"text\"\n size=\"sm\"\n :color=\"variant === 'filled' ? undefined : type\"\n :class=\"ui.action()\"\n data-id=\"alert-action\"\n @click=\"emit('action')\"\n >\n {{ actionText }}\n </RuiButton>\n </div>\n <div v-if=\"closeable\">\n <RuiButton\n :color=\"variant === 'filled' ? undefined : type\"\n size=\"sm\"\n icon\n variant=\"text\"\n :class=\"ui.close()\"\n data-id=\"alert-close\"\n @click=\"emit('close')\"\n >\n <RuiIcon\n name=\"lu-x\"\n size=\"20\"\n />\n </RuiButton>\n </div>\n </div>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiAlert.vue_vue_type_script_setup_true_lang.js","names":["$attrs","$slots"],"sources":["../../../src/components/alerts/RuiAlert.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ContextColorsType } from '@/consts/colors';\nimport type { RuiIcons } from '@/icons';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { tv } from '@/utils/tv';\n\nexport interface Props {\n title?: string;\n description?: string;\n type?: ContextColorsType;\n icon?: RuiIcons;\n variant?: 'default' | 'filled' | 'outlined';\n actionText?: string;\n closeable?: boolean;\n}\n\ndefineOptions({\n name: 'RuiAlert',\n inheritAttrs: false,\n});\n\nconst {\n title = '',\n description = '',\n type = 'primary',\n icon = undefined,\n variant = 'default',\n actionText = '',\n closeable = false,\n} = defineProps<Props>();\n\nconst emit = defineEmits<{\n action: [];\n close: [];\n}>();\n\nconst slots = defineSlots<{\n title?: () => any;\n default?: () => any;\n}>();\n\nconst alertStyles = tv({\n slots: {\n root: 'px-4 py-2.5 rounded-rui-panel flex between:ml-4 between:mr-0',\n content: 'flex between:ml-3 between:mr-0 py-1 grow',\n // as tall as the first line of text and centered in it, so the icon lines up however the text wraps\n icon: 'flex shrink-0 items-center',\n texts: 'between:mt-1 between:mb-0 grow',\n action: '',\n close: '',\n },\n variants: {\n // the first line is the title's (24px) when there is one, else the description's (text-sm, 20px)\n titled: {\n true: { icon: 'h-6' },\n false: { icon: 'h-5' },\n },\n variant: {\n default: {},\n filled: {\n icon: 'text-rui-dark-text!',\n texts: 'text-rui-dark-text!',\n action: 'text-rui-dark-text!',\n close: 'text-rui-dark-text!',\n },\n outlined: { root: 'border -m-px bg-transparent' },\n },\n /*\n * Each type names its color once, as `--rui-alert`, and the variants mix from it. The tints\n * and shades used to be paused CSS animations behind an `@supports (color-mix())` check that\n * never matched (it is not a valid condition), so every browser took the animation; mixing\n * directly gives the same colors without it.\n */\n type: {\n primary: { root: '[--rui-alert:var(--rui-primary-main)]' },\n secondary: { root: '[--rui-alert:var(--rui-secondary-main)]' },\n // a status color's dark `main` is a text tone, so a filled alert takes the deep `darker` there\n error: { root: '[--rui-alert:var(--rui-error-main)] [--rui-alert-fill:var(--rui-error-darker)]' },\n warning: { root: '[--rui-alert:var(--rui-warning-main)] [--rui-alert-fill:var(--rui-warning-darker)]' },\n info: { root: '[--rui-alert:var(--rui-info-main)] [--rui-alert-fill:var(--rui-info-darker)]' },\n success: { root: '[--rui-alert:var(--rui-success-main)] [--rui-alert-fill:var(--rui-success-darker)]' },\n },\n },\n compoundVariants: [\n // A tint of the type's color with a hairline of it, which reads on any surface in either theme\n {\n variant: 'default',\n class: { root: 'border -m-px bg-[color-mix(in_srgb,rgb(var(--rui-alert))_8%,transparent)] dark:bg-[color-mix(in_srgb,rgb(var(--rui-alert))_12%,transparent)] border-[color-mix(in_srgb,rgb(var(--rui-alert))_25%,transparent)]' },\n },\n { variant: 'filled', class: { root: 'bg-[rgb(var(--rui-alert))] dark:bg-[rgb(var(--rui-alert-fill,var(--rui-alert)))]' } },\n // without a tint behind it, the outlined alert carries its type in the icon too\n { variant: 'outlined', class: { root: 'border-[rgb(var(--rui-alert))]', icon: 'text-[rgb(var(--rui-alert))]' } },\n ],\n compoundSlots: [\n {\n slots: ['texts', 'action', 'close'],\n variant: ['default', 'outlined'],\n class: 'text-[color-mix(in_srgb,black_60%,rgb(var(--rui-alert)))] dark:text-[color-mix(in_srgb,white_60%,rgb(var(--rui-alert)))]',\n },\n {\n slots: ['icon'],\n variant: 'default',\n class: 'text-[color-mix(in_srgb,black_60%,rgb(var(--rui-alert)))] dark:text-[color-mix(in_srgb,white_60%,rgb(var(--rui-alert)))]',\n },\n ],\n});\n\nconst ui = computed<ReturnType<typeof alertStyles>>(() => alertStyles({ variant, type, titled: !!slots.title || !!title }));\n\nconst usedIcon = computed<RuiIcons | undefined>(() => {\n if (icon)\n return icon;\n\n const iconMap: Record<ContextColorsType, RuiIcons | undefined> = {\n primary: undefined,\n secondary: undefined,\n warning: 'lu-triangle-alert',\n info: 'lu-info',\n error: 'lu-circle-alert',\n success: 'lu-circle-check',\n };\n\n return iconMap[type];\n});\n</script>\n\n<template>\n <div\n :class=\"ui.root()\"\n v-bind=\"$attrs\"\n :data-variant=\"variant\"\n :data-type=\"type\"\n >\n <div :class=\"ui.content()\">\n <div\n v-if=\"usedIcon\"\n :class=\"ui.icon()\"\n >\n <RuiIcon\n :name=\"usedIcon\"\n size=\"20\"\n />\n </div>\n <div :class=\"ui.texts()\">\n <div\n v-if=\"$slots.title || title\"\n :class=\"{\n 'font-medium': !!title,\n }\"\n >\n <slot name=\"title\">\n {{ title }}\n </slot>\n </div>\n\n <div\n v-if=\"$slots.default || description\"\n class=\"text-body-2\"\n >\n <slot>\n {{ description }}\n </slot>\n </div>\n </div>\n </div>\n <div v-if=\"actionText\">\n <RuiButton\n variant=\"text\"\n size=\"sm\"\n :color=\"variant === 'filled' ? undefined : type\"\n :class=\"ui.action()\"\n data-id=\"alert-action\"\n @click=\"emit('action')\"\n >\n {{ actionText }}\n </RuiButton>\n </div>\n <div v-if=\"closeable\">\n <RuiButton\n :color=\"variant === 'filled' ? undefined : type\"\n size=\"sm\"\n icon\n variant=\"text\"\n :class=\"ui.close()\"\n data-id=\"alert-close\"\n @click=\"emit('close')\"\n >\n <RuiIcon\n name=\"lu-x\"\n size=\"20\"\n />\n </RuiButton>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"RuiAlert.vue_vue_type_script_setup_true_lang.js","names":["$attrs","$slots","_useSlots","_openBlock","_createElementBlock","_mergeProps","_unref","_createElementVNode","_normalizeClass","_createVNode","RuiIcon","_createCommentVNode","_renderSlot","_createTextVNode","_toDisplayString","RuiButton","_withCtx"],"sources":["../../../src/components/alerts/RuiAlert.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { ContextColorsType } from '@/consts/colors';\nimport type { RuiIcons } from '@/icons';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { tv } from '@/utils/tv';\n\nexport interface Props {\n title?: string;\n description?: string;\n type?: ContextColorsType;\n icon?: RuiIcons;\n variant?: 'default' | 'filled' | 'outlined';\n actionText?: string;\n closeable?: boolean;\n}\n\ndefineOptions({\n name: 'RuiAlert',\n inheritAttrs: false,\n});\n\nconst {\n title = '',\n description = '',\n type = 'primary',\n icon = undefined,\n variant = 'default',\n actionText = '',\n closeable = false,\n} = defineProps<Props>();\n\nconst emit = defineEmits<{\n action: [];\n close: [];\n}>();\n\nconst slots = defineSlots<{\n title?: () => any;\n default?: () => any;\n}>();\n\nconst alertStyles = tv({\n slots: {\n root: 'px-4 py-2.5 rounded-rui-panel flex between:ml-4 between:mr-0',\n content: 'flex between:ml-3 between:mr-0 py-1 grow',\n // as tall as the first line of text and centered in it, so the icon lines up however the text wraps\n icon: 'flex shrink-0 items-center',\n texts: 'between:mt-1 between:mb-0 grow',\n action: '',\n close: '',\n },\n variants: {\n // the first line is the title's (24px) when there is one, else the description's (text-sm, 20px)\n titled: {\n true: { icon: 'h-6' },\n false: { icon: 'h-5' },\n },\n variant: {\n default: {},\n filled: {\n icon: 'text-rui-dark-text!',\n texts: 'text-rui-dark-text!',\n action: 'text-rui-dark-text!',\n close: 'text-rui-dark-text!',\n },\n outlined: { root: 'border -m-px bg-transparent' },\n },\n /*\n * Each type names its color once, as `--rui-alert`, and the variants mix from it. The tints\n * and shades used to be paused CSS animations behind an `@supports (color-mix())` check that\n * never matched (it is not a valid condition), so every browser took the animation; mixing\n * directly gives the same colors without it.\n */\n type: {\n primary: { root: '[--rui-alert:var(--rui-primary-main)]' },\n secondary: { root: '[--rui-alert:var(--rui-secondary-main)]' },\n // a status color's dark `main` is a text tone, so a filled alert takes the deep `darker` there\n error: { root: '[--rui-alert:var(--rui-error-main)] [--rui-alert-fill:var(--rui-error-darker)]' },\n warning: { root: '[--rui-alert:var(--rui-warning-main)] [--rui-alert-fill:var(--rui-warning-darker)]' },\n info: { root: '[--rui-alert:var(--rui-info-main)] [--rui-alert-fill:var(--rui-info-darker)]' },\n success: { root: '[--rui-alert:var(--rui-success-main)] [--rui-alert-fill:var(--rui-success-darker)]' },\n },\n },\n compoundVariants: [\n // A tint of the type's color with a hairline of it, which reads on any surface in either theme\n {\n variant: 'default',\n class: { root: 'border -m-px bg-[color-mix(in_srgb,rgb(var(--rui-alert))_8%,transparent)] dark:bg-[color-mix(in_srgb,rgb(var(--rui-alert))_12%,transparent)] border-[color-mix(in_srgb,rgb(var(--rui-alert))_25%,transparent)]' },\n },\n { variant: 'filled', class: { root: 'bg-[rgb(var(--rui-alert))] dark:bg-[rgb(var(--rui-alert-fill,var(--rui-alert)))]' } },\n // without a tint behind it, the outlined alert carries its type in the icon too\n { variant: 'outlined', class: { root: 'border-[rgb(var(--rui-alert))]', icon: 'text-[rgb(var(--rui-alert))]' } },\n ],\n compoundSlots: [\n {\n slots: ['texts', 'action', 'close'],\n variant: ['default', 'outlined'],\n class: 'text-[color-mix(in_srgb,black_60%,rgb(var(--rui-alert)))] dark:text-[color-mix(in_srgb,white_60%,rgb(var(--rui-alert)))]',\n },\n {\n slots: ['icon'],\n variant: 'default',\n class: 'text-[color-mix(in_srgb,black_60%,rgb(var(--rui-alert)))] dark:text-[color-mix(in_srgb,white_60%,rgb(var(--rui-alert)))]',\n },\n ],\n});\n\nconst ui = computed<ReturnType<typeof alertStyles>>(() => alertStyles({ variant, type, titled: !!slots.title || !!title }));\n\nconst usedIcon = computed<RuiIcons | undefined>(() => {\n if (icon)\n return icon;\n\n const iconMap: Record<ContextColorsType, RuiIcons | undefined> = {\n primary: undefined,\n secondary: undefined,\n warning: 'lu-triangle-alert',\n info: 'lu-info',\n error: 'lu-circle-alert',\n success: 'lu-circle-check',\n };\n\n return iconMap[type];\n});\n</script>\n\n<template>\n <div\n :class=\"ui.root()\"\n v-bind=\"$attrs\"\n :data-variant=\"variant\"\n :data-type=\"type\"\n >\n <div :class=\"ui.content()\">\n <div\n v-if=\"usedIcon\"\n :class=\"ui.icon()\"\n >\n <RuiIcon\n :name=\"usedIcon\"\n size=\"20\"\n />\n </div>\n <div :class=\"ui.texts()\">\n <div\n v-if=\"$slots.title || title\"\n :class=\"{\n 'font-medium': !!title,\n }\"\n >\n <slot name=\"title\">\n {{ title }}\n </slot>\n </div>\n\n <div\n v-if=\"$slots.default || description\"\n class=\"text-body-2\"\n >\n <slot>\n {{ description }}\n </slot>\n </div>\n </div>\n </div>\n <div v-if=\"actionText\">\n <RuiButton\n variant=\"text\"\n size=\"sm\"\n :color=\"variant === 'filled' ? undefined : type\"\n :class=\"ui.action()\"\n data-id=\"alert-action\"\n @click=\"emit('action')\"\n >\n {{ actionText }}\n </RuiButton>\n </div>\n <div v-if=\"closeable\">\n <RuiButton\n :color=\"variant === 'filled' ? undefined : type\"\n size=\"sm\"\n icon\n variant=\"text\"\n :class=\"ui.close()\"\n data-id=\"alert-close\"\n @click=\"emit('close')\"\n >\n <RuiIcon\n name=\"lu-x\"\n size=\"20\"\n />\n </RuiButton>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiAvatar.js","names":[],"sources":["../../../src/components/avatars/RuiAvatar.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { ContextColorsType } from '@/consts/colors';\nimport type { RuiIcons } from '@/icons';\nimport { get, set } from '@vueuse/shared';\nimport {\n type AvatarSize,\n type AvatarVariant,\n computeAvatarText,\n computeInitials,\n resolveAvatarIconPx,\n resolveAvatarSizePx,\n resolveAvatarTextSize,\n} from '@/components/avatars/avatar-props';\nimport { useAvatarGroup } from '@/components/avatars/use-avatar-group';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { tv } from '@/utils/tv';\n\nexport interface Props {\n src?: string | null;\n alt?: string;\n text?: string | null;\n icon?: RuiIcons | null;\n size?: AvatarSize | number;\n variant?: AvatarVariant;\n color?: 'default' | ContextColorsType;\n loading?: 'lazy' | 'eager';\n}\n\ndefineOptions({\n name: 'RuiAvatar',\n});\n\nconst {\n src = null,\n alt = '',\n text = null,\n icon = null,\n size,\n variant,\n color = 'default',\n loading = 'lazy',\n} = defineProps<Props>();\n\nconst emit = defineEmits<{\n load: [event: Event];\n error: [event: Event];\n}>();\n\nconst slots = defineSlots<{\n default?: () => any;\n}>();\n\nconst group = useAvatarGroup();\n\nconst resolvedSize = computed<AvatarSize | number>(() => {\n if (size !== undefined)\n return size;\n if (group)\n return get(group).size;\n return 'md';\n});\n\nconst resolvedVariant = computed<AvatarVariant>(() => {\n if (variant !== undefined)\n return variant;\n if (group)\n return get(group).variant;\n return 'circular';\n});\n\n// A numeric size borrows the text scale of the nearest token below it\nconst textSize = computed<AvatarSize>(() => resolveAvatarTextSize(get(resolvedSize)));\n\nconst sizePx = computed<number>(() => resolveAvatarSizePx(get(resolvedSize)));\nconst iconPx = computed<number>(() => resolveAvatarIconPx(get(resolvedSize)));\n\nconst errored = ref<boolean>(false);\n\nwatch(() => src, () => {\n set(errored, false);\n});\n\nconst initials = computed<string>(() => {\n const explicit = computeAvatarText(text);\n if (explicit)\n return explicit;\n return computeInitials(alt);\n});\n\ntype DisplayMode = 'image' | 'slot' | 'initials' | 'icon' | 'empty';\n\nconst displayMode = computed<DisplayMode>(() => {\n if (src && !get(errored))\n return 'image';\n if (slots.default)\n return 'slot';\n if (icon)\n return 'icon';\n if (get(initials))\n return 'initials';\n return 'empty';\n});\n\nconst decorative = computed<boolean>(() => alt === '' && !text);\n\nconst ariaLabel = computed<string | undefined>(() => {\n if (get(displayMode) === 'image')\n return undefined;\n if (get(decorative))\n return undefined;\n return text ?? alt ?? undefined;\n});\n\nconst rootStyle = computed<Record<string, string>>(() => {\n const px = `${get(sizePx)}px`;\n return { width: px, height: px };\n});\n\nconst avatarStyles = tv({\n slots: {\n root: 'relative inline-flex items-center justify-center shrink-0 overflow-hidden select-none font-medium align-middle',\n image: 'w-full h-full object-cover',\n fallback: 'w-full h-full flex items-center justify-center',\n initials: 'uppercase leading-none',\n },\n variants: {\n variant: {\n circular: { root: 'rounded-full' },\n rounded: { root: 'rounded-rui-control' },\n square: { root: 'rounded-none' },\n },\n // `-fill` is `main` in light and, for a status color, the deep `darker` in dark\n color: {\n default: { root: 'bg-rui-neutral-200 text-rui-text dark:bg-rui-neutral-700' },\n primary: { root: 'bg-rui-primary-fill text-rui-primary-foreground' },\n secondary: { root: 'bg-rui-secondary-fill text-rui-secondary-foreground' },\n error: { root: 'bg-rui-error-fill text-rui-error-foreground' },\n warning: { root: 'bg-rui-warning-fill text-rui-warning-foreground' },\n info: { root: 'bg-rui-info-fill text-rui-info-foreground' },\n success: { root: 'bg-rui-success-fill text-rui-success-foreground' },\n },\n // On the root so slot content (such as a group's `+N`) scales too\n size: {\n 'xs': { root: 'text-[0.625rem]' },\n 'sm': { root: 'text-[0.6875rem]' },\n 'md': { root: 'text-sm' },\n 'lg': { root: 'text-base' },\n 'xl': { root: 'text-lg' },\n '2xl': { root: 'text-xl' },\n },\n },\n defaultVariants: {\n variant: 'circular',\n color: 'default',\n size: 'md',\n },\n});\n\nconst ui = computed<ReturnType<typeof avatarStyles>>(() => avatarStyles({\n variant: get(resolvedVariant),\n color,\n size: get(textSize),\n}));\n\nfunction onLoad(event: Event): void {\n set(errored, false);\n emit('load', event);\n}\n\nfunction onError(event: Event): void {\n set(errored, true);\n emit('error', event);\n}\n</script>\n\n<template>\n <span\n :class=\"ui.root()\"\n :style=\"rootStyle\"\n :role=\"ariaLabel ? 'img' : undefined\"\n :aria-label=\"ariaLabel\"\n :aria-hidden=\"displayMode !== 'image' && decorative ? 'true' : undefined\"\n :data-id=\"$attrs['data-id'] ?? 'avatar-root'\"\n :data-size=\"typeof resolvedSize === 'string' ? resolvedSize : undefined\"\n :data-variant=\"resolvedVariant\"\n :data-color=\"color\"\n >\n <img\n v-if=\"displayMode === 'image' && src\"\n :class=\"ui.image()\"\n :src=\"src\"\n :alt=\"alt\"\n :loading=\"loading\"\n :width=\"sizePx\"\n :height=\"sizePx\"\n data-id=\"avatar-image\"\n @load=\"onLoad($event)\"\n @error=\"onError($event)\"\n />\n <span\n v-else\n :class=\"ui.fallback()\"\n data-id=\"avatar-fallback\"\n aria-hidden=\"true\"\n >\n <slot v-if=\"displayMode === 'slot'\" />\n <span\n v-else-if=\"displayMode === 'initials'\"\n :class=\"ui.initials()\"\n data-id=\"avatar-initials\"\n >\n {{ initials }}\n </span>\n <RuiIcon\n v-else-if=\"displayMode === 'icon' && icon\"\n :name=\"icon\"\n :size=\"iconPx\"\n data-id=\"avatar-icon\"\n />\n <span v-else>&nbsp;</span>\n </span>\n </span>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiAvatar.js","names":["_sfc_main"],"sources":["../../../src/components/avatars/RuiAvatar.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { ContextColorsType } from '@/consts/colors';\nimport type { RuiIcons } from '@/icons';\nimport { get, set } from '@vueuse/shared';\nimport {\n type AvatarSize,\n type AvatarVariant,\n computeAvatarText,\n computeInitials,\n resolveAvatarIconPx,\n resolveAvatarSizePx,\n resolveAvatarTextSize,\n} from '@/components/avatars/avatar-props';\nimport { useAvatarGroup } from '@/components/avatars/use-avatar-group';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { tv } from '@/utils/tv';\n\nexport interface Props {\n src?: string | null;\n alt?: string;\n text?: string | null;\n icon?: RuiIcons | null;\n size?: AvatarSize | number;\n variant?: AvatarVariant;\n color?: 'default' | ContextColorsType;\n loading?: 'lazy' | 'eager';\n}\n\ndefineOptions({\n name: 'RuiAvatar',\n});\n\nconst {\n src = null,\n alt = '',\n text = null,\n icon = null,\n size,\n variant,\n color = 'default',\n loading = 'lazy',\n} = defineProps<Props>();\n\nconst emit = defineEmits<{\n load: [event: Event];\n error: [event: Event];\n}>();\n\nconst slots = defineSlots<{\n default?: () => any;\n}>();\n\nconst group = useAvatarGroup();\n\nconst resolvedSize = computed<AvatarSize | number>(() => {\n if (size !== undefined)\n return size;\n if (group)\n return get(group).size;\n return 'md';\n});\n\nconst resolvedVariant = computed<AvatarVariant>(() => {\n if (variant !== undefined)\n return variant;\n if (group)\n return get(group).variant;\n return 'circular';\n});\n\n// A numeric size borrows the text scale of the nearest token below it\nconst textSize = computed<AvatarSize>(() => resolveAvatarTextSize(get(resolvedSize)));\n\nconst sizePx = computed<number>(() => resolveAvatarSizePx(get(resolvedSize)));\nconst iconPx = computed<number>(() => resolveAvatarIconPx(get(resolvedSize)));\n\nconst errored = ref<boolean>(false);\n\nwatch(() => src, () => {\n set(errored, false);\n});\n\nconst initials = computed<string>(() => {\n const explicit = computeAvatarText(text);\n if (explicit)\n return explicit;\n return computeInitials(alt);\n});\n\ntype DisplayMode = 'image' | 'slot' | 'initials' | 'icon' | 'empty';\n\nconst displayMode = computed<DisplayMode>(() => {\n if (src && !get(errored))\n return 'image';\n if (slots.default)\n return 'slot';\n if (icon)\n return 'icon';\n if (get(initials))\n return 'initials';\n return 'empty';\n});\n\nconst decorative = computed<boolean>(() => alt === '' && !text);\n\nconst ariaLabel = computed<string | undefined>(() => {\n if (get(displayMode) === 'image')\n return undefined;\n if (get(decorative))\n return undefined;\n return text ?? alt ?? undefined;\n});\n\nconst rootStyle = computed<Record<string, string>>(() => {\n const px = `${get(sizePx)}px`;\n return { width: px, height: px };\n});\n\nconst avatarStyles = tv({\n slots: {\n root: 'relative inline-flex items-center justify-center shrink-0 overflow-hidden select-none font-medium align-middle',\n image: 'w-full h-full object-cover',\n fallback: 'w-full h-full flex items-center justify-center',\n initials: 'uppercase leading-none',\n },\n variants: {\n variant: {\n circular: { root: 'rounded-full' },\n rounded: { root: 'rounded-rui-control' },\n square: { root: 'rounded-none' },\n },\n // `-fill` is `main` in light and, for a status color, the deep `darker` in dark\n color: {\n default: { root: 'bg-rui-neutral-200 text-rui-text dark:bg-rui-neutral-700' },\n primary: { root: 'bg-rui-primary-fill text-rui-primary-foreground' },\n secondary: { root: 'bg-rui-secondary-fill text-rui-secondary-foreground' },\n error: { root: 'bg-rui-error-fill text-rui-error-foreground' },\n warning: { root: 'bg-rui-warning-fill text-rui-warning-foreground' },\n info: { root: 'bg-rui-info-fill text-rui-info-foreground' },\n success: { root: 'bg-rui-success-fill text-rui-success-foreground' },\n },\n // On the root so slot content (such as a group's `+N`) scales too\n size: {\n 'xs': { root: 'text-[0.625rem]' },\n 'sm': { root: 'text-[0.6875rem]' },\n 'md': { root: 'text-sm' },\n 'lg': { root: 'text-base' },\n 'xl': { root: 'text-lg' },\n '2xl': { root: 'text-xl' },\n },\n },\n defaultVariants: {\n variant: 'circular',\n color: 'default',\n size: 'md',\n },\n});\n\nconst ui = computed<ReturnType<typeof avatarStyles>>(() => avatarStyles({\n variant: get(resolvedVariant),\n color,\n size: get(textSize),\n}));\n\nfunction onLoad(event: Event): void {\n set(errored, false);\n emit('load', event);\n}\n\nfunction onError(event: Event): void {\n set(errored, true);\n emit('error', event);\n}\n</script>\n\n<template>\n <span\n :class=\"ui.root()\"\n :style=\"rootStyle\"\n :role=\"ariaLabel ? 'img' : undefined\"\n :aria-label=\"ariaLabel\"\n :aria-hidden=\"displayMode !== 'image' && decorative ? 'true' : undefined\"\n :data-id=\"$attrs['data-id'] ?? 'avatar-root'\"\n :data-size=\"typeof resolvedSize === 'string' ? resolvedSize : undefined\"\n :data-variant=\"resolvedVariant\"\n :data-color=\"color\"\n >\n <img\n v-if=\"displayMode === 'image' && src\"\n :class=\"ui.image()\"\n :src=\"src\"\n :alt=\"alt\"\n :loading=\"loading\"\n :width=\"sizePx\"\n :height=\"sizePx\"\n data-id=\"avatar-image\"\n @load=\"onLoad($event)\"\n @error=\"onError($event)\"\n />\n <span\n v-else\n :class=\"ui.fallback()\"\n data-id=\"avatar-fallback\"\n aria-hidden=\"true\"\n >\n <slot v-if=\"displayMode === 'slot'\" />\n <span\n v-else-if=\"displayMode === 'initials'\"\n :class=\"ui.initials()\"\n data-id=\"avatar-initials\"\n >\n {{ initials }}\n </span>\n <RuiIcon\n v-else-if=\"displayMode === 'icon' && icon\"\n :name=\"icon\"\n :size=\"iconPx\"\n data-id=\"avatar-icon\"\n />\n <span v-else>&nbsp;</span>\n </span>\n </span>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiAvatar.vue_vue_type_script_setup_true_lang.js","names":["$attrs"],"sources":["../../../src/components/avatars/RuiAvatar.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { ContextColorsType } from '@/consts/colors';\nimport type { RuiIcons } from '@/icons';\nimport { get, set } from '@vueuse/shared';\nimport {\n type AvatarSize,\n type AvatarVariant,\n computeAvatarText,\n computeInitials,\n resolveAvatarIconPx,\n resolveAvatarSizePx,\n resolveAvatarTextSize,\n} from '@/components/avatars/avatar-props';\nimport { useAvatarGroup } from '@/components/avatars/use-avatar-group';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { tv } from '@/utils/tv';\n\nexport interface Props {\n src?: string | null;\n alt?: string;\n text?: string | null;\n icon?: RuiIcons | null;\n size?: AvatarSize | number;\n variant?: AvatarVariant;\n color?: 'default' | ContextColorsType;\n loading?: 'lazy' | 'eager';\n}\n\ndefineOptions({\n name: 'RuiAvatar',\n});\n\nconst {\n src = null,\n alt = '',\n text = null,\n icon = null,\n size,\n variant,\n color = 'default',\n loading = 'lazy',\n} = defineProps<Props>();\n\nconst emit = defineEmits<{\n load: [event: Event];\n error: [event: Event];\n}>();\n\nconst slots = defineSlots<{\n default?: () => any;\n}>();\n\nconst group = useAvatarGroup();\n\nconst resolvedSize = computed<AvatarSize | number>(() => {\n if (size !== undefined)\n return size;\n if (group)\n return get(group).size;\n return 'md';\n});\n\nconst resolvedVariant = computed<AvatarVariant>(() => {\n if (variant !== undefined)\n return variant;\n if (group)\n return get(group).variant;\n return 'circular';\n});\n\n// A numeric size borrows the text scale of the nearest token below it\nconst textSize = computed<AvatarSize>(() => resolveAvatarTextSize(get(resolvedSize)));\n\nconst sizePx = computed<number>(() => resolveAvatarSizePx(get(resolvedSize)));\nconst iconPx = computed<number>(() => resolveAvatarIconPx(get(resolvedSize)));\n\nconst errored = ref<boolean>(false);\n\nwatch(() => src, () => {\n set(errored, false);\n});\n\nconst initials = computed<string>(() => {\n const explicit = computeAvatarText(text);\n if (explicit)\n return explicit;\n return computeInitials(alt);\n});\n\ntype DisplayMode = 'image' | 'slot' | 'initials' | 'icon' | 'empty';\n\nconst displayMode = computed<DisplayMode>(() => {\n if (src && !get(errored))\n return 'image';\n if (slots.default)\n return 'slot';\n if (icon)\n return 'icon';\n if (get(initials))\n return 'initials';\n return 'empty';\n});\n\nconst decorative = computed<boolean>(() => alt === '' && !text);\n\nconst ariaLabel = computed<string | undefined>(() => {\n if (get(displayMode) === 'image')\n return undefined;\n if (get(decorative))\n return undefined;\n return text ?? alt ?? undefined;\n});\n\nconst rootStyle = computed<Record<string, string>>(() => {\n const px = `${get(sizePx)}px`;\n return { width: px, height: px };\n});\n\nconst avatarStyles = tv({\n slots: {\n root: 'relative inline-flex items-center justify-center shrink-0 overflow-hidden select-none font-medium align-middle',\n image: 'w-full h-full object-cover',\n fallback: 'w-full h-full flex items-center justify-center',\n initials: 'uppercase leading-none',\n },\n variants: {\n variant: {\n circular: { root: 'rounded-full' },\n rounded: { root: 'rounded-rui-control' },\n square: { root: 'rounded-none' },\n },\n // `-fill` is `main` in light and, for a status color, the deep `darker` in dark\n color: {\n default: { root: 'bg-rui-neutral-200 text-rui-text dark:bg-rui-neutral-700' },\n primary: { root: 'bg-rui-primary-fill text-rui-primary-foreground' },\n secondary: { root: 'bg-rui-secondary-fill text-rui-secondary-foreground' },\n error: { root: 'bg-rui-error-fill text-rui-error-foreground' },\n warning: { root: 'bg-rui-warning-fill text-rui-warning-foreground' },\n info: { root: 'bg-rui-info-fill text-rui-info-foreground' },\n success: { root: 'bg-rui-success-fill text-rui-success-foreground' },\n },\n // On the root so slot content (such as a group's `+N`) scales too\n size: {\n 'xs': { root: 'text-[0.625rem]' },\n 'sm': { root: 'text-[0.6875rem]' },\n 'md': { root: 'text-sm' },\n 'lg': { root: 'text-base' },\n 'xl': { root: 'text-lg' },\n '2xl': { root: 'text-xl' },\n },\n },\n defaultVariants: {\n variant: 'circular',\n color: 'default',\n size: 'md',\n },\n});\n\nconst ui = computed<ReturnType<typeof avatarStyles>>(() => avatarStyles({\n variant: get(resolvedVariant),\n color,\n size: get(textSize),\n}));\n\nfunction onLoad(event: Event): void {\n set(errored, false);\n emit('load', event);\n}\n\nfunction onError(event: Event): void {\n set(errored, true);\n emit('error', event);\n}\n</script>\n\n<template>\n <span\n :class=\"ui.root()\"\n :style=\"rootStyle\"\n :role=\"ariaLabel ? 'img' : undefined\"\n :aria-label=\"ariaLabel\"\n :aria-hidden=\"displayMode !== 'image' && decorative ? 'true' : undefined\"\n :data-id=\"$attrs['data-id'] ?? 'avatar-root'\"\n :data-size=\"typeof resolvedSize === 'string' ? resolvedSize : undefined\"\n :data-variant=\"resolvedVariant\"\n :data-color=\"color\"\n >\n <img\n v-if=\"displayMode === 'image' && src\"\n :class=\"ui.image()\"\n :src=\"src\"\n :alt=\"alt\"\n :loading=\"loading\"\n :width=\"sizePx\"\n :height=\"sizePx\"\n data-id=\"avatar-image\"\n @load=\"onLoad($event)\"\n @error=\"onError($event)\"\n />\n <span\n v-else\n :class=\"ui.fallback()\"\n data-id=\"avatar-fallback\"\n aria-hidden=\"true\"\n >\n <slot v-if=\"displayMode === 'slot'\" />\n <span\n v-else-if=\"displayMode === 'initials'\"\n :class=\"ui.initials()\"\n data-id=\"avatar-initials\"\n >\n {{ initials }}\n </span>\n <RuiIcon\n v-else-if=\"displayMode === 'icon' && icon\"\n :name=\"icon\"\n :size=\"iconPx\"\n data-id=\"avatar-icon\"\n />\n <span v-else>&nbsp;</span>\n </span>\n </span>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"RuiAvatar.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_useSlots","_openBlock","_createElementBlock","_normalizeClass","_unref","_normalizeStyle","_renderSlot","_toDisplayString","_createBlock","RuiIcon"],"sources":["../../../src/components/avatars/RuiAvatar.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { ContextColorsType } from '@/consts/colors';\nimport type { RuiIcons } from '@/icons';\nimport { get, set } from '@vueuse/shared';\nimport {\n type AvatarSize,\n type AvatarVariant,\n computeAvatarText,\n computeInitials,\n resolveAvatarIconPx,\n resolveAvatarSizePx,\n resolveAvatarTextSize,\n} from '@/components/avatars/avatar-props';\nimport { useAvatarGroup } from '@/components/avatars/use-avatar-group';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { tv } from '@/utils/tv';\n\nexport interface Props {\n src?: string | null;\n alt?: string;\n text?: string | null;\n icon?: RuiIcons | null;\n size?: AvatarSize | number;\n variant?: AvatarVariant;\n color?: 'default' | ContextColorsType;\n loading?: 'lazy' | 'eager';\n}\n\ndefineOptions({\n name: 'RuiAvatar',\n});\n\nconst {\n src = null,\n alt = '',\n text = null,\n icon = null,\n size,\n variant,\n color = 'default',\n loading = 'lazy',\n} = defineProps<Props>();\n\nconst emit = defineEmits<{\n load: [event: Event];\n error: [event: Event];\n}>();\n\nconst slots = defineSlots<{\n default?: () => any;\n}>();\n\nconst group = useAvatarGroup();\n\nconst resolvedSize = computed<AvatarSize | number>(() => {\n if (size !== undefined)\n return size;\n if (group)\n return get(group).size;\n return 'md';\n});\n\nconst resolvedVariant = computed<AvatarVariant>(() => {\n if (variant !== undefined)\n return variant;\n if (group)\n return get(group).variant;\n return 'circular';\n});\n\n// A numeric size borrows the text scale of the nearest token below it\nconst textSize = computed<AvatarSize>(() => resolveAvatarTextSize(get(resolvedSize)));\n\nconst sizePx = computed<number>(() => resolveAvatarSizePx(get(resolvedSize)));\nconst iconPx = computed<number>(() => resolveAvatarIconPx(get(resolvedSize)));\n\nconst errored = ref<boolean>(false);\n\nwatch(() => src, () => {\n set(errored, false);\n});\n\nconst initials = computed<string>(() => {\n const explicit = computeAvatarText(text);\n if (explicit)\n return explicit;\n return computeInitials(alt);\n});\n\ntype DisplayMode = 'image' | 'slot' | 'initials' | 'icon' | 'empty';\n\nconst displayMode = computed<DisplayMode>(() => {\n if (src && !get(errored))\n return 'image';\n if (slots.default)\n return 'slot';\n if (icon)\n return 'icon';\n if (get(initials))\n return 'initials';\n return 'empty';\n});\n\nconst decorative = computed<boolean>(() => alt === '' && !text);\n\nconst ariaLabel = computed<string | undefined>(() => {\n if (get(displayMode) === 'image')\n return undefined;\n if (get(decorative))\n return undefined;\n return text ?? alt ?? undefined;\n});\n\nconst rootStyle = computed<Record<string, string>>(() => {\n const px = `${get(sizePx)}px`;\n return { width: px, height: px };\n});\n\nconst avatarStyles = tv({\n slots: {\n root: 'relative inline-flex items-center justify-center shrink-0 overflow-hidden select-none font-medium align-middle',\n image: 'w-full h-full object-cover',\n fallback: 'w-full h-full flex items-center justify-center',\n initials: 'uppercase leading-none',\n },\n variants: {\n variant: {\n circular: { root: 'rounded-full' },\n rounded: { root: 'rounded-rui-control' },\n square: { root: 'rounded-none' },\n },\n // `-fill` is `main` in light and, for a status color, the deep `darker` in dark\n color: {\n default: { root: 'bg-rui-neutral-200 text-rui-text dark:bg-rui-neutral-700' },\n primary: { root: 'bg-rui-primary-fill text-rui-primary-foreground' },\n secondary: { root: 'bg-rui-secondary-fill text-rui-secondary-foreground' },\n error: { root: 'bg-rui-error-fill text-rui-error-foreground' },\n warning: { root: 'bg-rui-warning-fill text-rui-warning-foreground' },\n info: { root: 'bg-rui-info-fill text-rui-info-foreground' },\n success: { root: 'bg-rui-success-fill text-rui-success-foreground' },\n },\n // On the root so slot content (such as a group's `+N`) scales too\n size: {\n 'xs': { root: 'text-[0.625rem]' },\n 'sm': { root: 'text-[0.6875rem]' },\n 'md': { root: 'text-sm' },\n 'lg': { root: 'text-base' },\n 'xl': { root: 'text-lg' },\n '2xl': { root: 'text-xl' },\n },\n },\n defaultVariants: {\n variant: 'circular',\n color: 'default',\n size: 'md',\n },\n});\n\nconst ui = computed<ReturnType<typeof avatarStyles>>(() => avatarStyles({\n variant: get(resolvedVariant),\n color,\n size: get(textSize),\n}));\n\nfunction onLoad(event: Event): void {\n set(errored, false);\n emit('load', event);\n}\n\nfunction onError(event: Event): void {\n set(errored, true);\n emit('error', event);\n}\n</script>\n\n<template>\n <span\n :class=\"ui.root()\"\n :style=\"rootStyle\"\n :role=\"ariaLabel ? 'img' : undefined\"\n :aria-label=\"ariaLabel\"\n :aria-hidden=\"displayMode !== 'image' && decorative ? 'true' : undefined\"\n :data-id=\"$attrs['data-id'] ?? 'avatar-root'\"\n :data-size=\"typeof resolvedSize === 'string' ? resolvedSize : undefined\"\n :data-variant=\"resolvedVariant\"\n :data-color=\"color\"\n >\n <img\n v-if=\"displayMode === 'image' && src\"\n :class=\"ui.image()\"\n :src=\"src\"\n :alt=\"alt\"\n :loading=\"loading\"\n :width=\"sizePx\"\n :height=\"sizePx\"\n data-id=\"avatar-image\"\n @load=\"onLoad($event)\"\n @error=\"onError($event)\"\n />\n <span\n v-else\n :class=\"ui.fallback()\"\n data-id=\"avatar-fallback\"\n aria-hidden=\"true\"\n >\n <slot v-if=\"displayMode === 'slot'\" />\n <span\n v-else-if=\"displayMode === 'initials'\"\n :class=\"ui.initials()\"\n data-id=\"avatar-initials\"\n >\n {{ initials }}\n </span>\n <RuiIcon\n v-else-if=\"displayMode === 'icon' && icon\"\n :name=\"icon\"\n :size=\"iconPx\"\n data-id=\"avatar-icon\"\n />\n <span v-else>&nbsp;</span>\n </span>\n </span>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiAvatarGroup.js","names":[],"sources":["../../../src/components/avatars/RuiAvatarGroup.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { get } from '@vueuse/shared';\nimport { Comment, defineComponent, Fragment, Text, type VNode } from 'vue';\nimport {\n avatarGroupInjectionKey,\n AvatarGroupSpacing,\n type AvatarSize,\n type AvatarVariant,\n resolveAvatarGroupSpacingPx,\n resolveAvatarSizePx,\n} from '@/components/avatars/avatar-props';\nimport RuiAvatar from '@/components/avatars/RuiAvatar.vue';\nimport { tv } from '@/utils/tv';\n\nexport interface Props {\n size?: AvatarSize | number;\n variant?: AvatarVariant;\n max?: number;\n total?: number;\n /**\n * How much each avatar overlaps the previous one. The tokens name the\n * amount of overlap, so `lg` overlaps the most and `sm` the least; they\n * scale with the avatar size. A number is the inline margin in pixels and\n * should be negative to overlap.\n */\n spacing?: AvatarGroupSpacing | number;\n}\n\ndefineOptions({\n name: 'RuiAvatarGroup',\n});\n\nconst {\n size,\n variant = 'circular',\n max,\n total,\n spacing = AvatarGroupSpacing.md,\n} = defineProps<Props>();\n\nconst slots = defineSlots<{\n default?: () => VNode[];\n surplus?: (props: { count: number }) => any;\n}>();\n\nconst resolvedSize = computed<AvatarSize | number>(() => size ?? 'md');\n\nconst VNodeRenderer = defineComponent<{ vnode: VNode }>({\n props: ['vnode'],\n setup(props) {\n return (): VNode => props.vnode;\n },\n});\n\nprovide(avatarGroupInjectionKey, computed(() => ({ size: get(resolvedSize), variant })));\n\nconst groupStyles = tv({\n slots: {\n root: 'inline-flex items-center isolate',\n item: 'relative ring-2 ring-rui-surface',\n surplus: 'leading-none text-[0.85em] tracking-tight',\n },\n // The ring follows the avatar outline\n variants: {\n variant: {\n circular: { item: 'rounded-full' },\n rounded: { item: 'rounded-rui-control' },\n square: { item: 'rounded-none' },\n },\n },\n});\n\nfunction flattenChildren(nodes: VNode[] | undefined): VNode[] {\n if (!nodes)\n return [];\n const out: VNode[] = [];\n for (const node of nodes) {\n if (node.type === Comment)\n continue;\n if (node.type === Text && typeof node.children === 'string' && node.children.trim() === '')\n continue;\n if (node.type === Fragment && Array.isArray(node.children)) {\n const inner = node.children.filter((c): c is VNode => typeof c === 'object' && c !== null && 'type' in c);\n out.push(...flattenChildren(inner));\n continue;\n }\n out.push(node);\n }\n return out;\n}\n\nconst children = computed<VNode[]>(() => flattenChildren(slots.default?.()));\n\nconst visible = computed<VNode[]>(() => {\n if (max === undefined)\n return get(children);\n return get(children).slice(0, max);\n});\n\nconst surplusCount = computed<number>(() => {\n const totalCount = total ?? get(children).length;\n const shown = get(visible).length;\n return Math.max(0, totalCount - shown);\n});\n\nconst spacingPx = computed<number>(() => resolveAvatarGroupSpacingPx(spacing, get(resolvedSize)));\n\n// The configured spacing, which is already negative, so the items overlap\nconst ringOffsetPx = computed<number>(() => get(spacingPx));\n\nconst itemStyle = computed<Record<string, string>>(() => ({\n marginInlineStart: `${get(ringOffsetPx)}px`,\n}));\n\nconst firstItemStyle = computed<Record<string, string>>(() => ({\n marginInlineStart: '0',\n}));\n\nconst avatarPx = computed<number>(() => resolveAvatarSizePx(get(resolvedSize)));\n\nconst ui = computed<ReturnType<typeof groupStyles>>(() => groupStyles({ variant }));\n</script>\n\n<template>\n <div\n :class=\"ui.root()\"\n data-id=\"avatar-group\"\n :data-size=\"typeof resolvedSize === 'string' ? resolvedSize : undefined\"\n :data-variant=\"variant\"\n >\n <span\n v-for=\"(child, index) in visible\"\n :key=\"child.key ?? index\"\n :class=\"ui.item()\"\n :style=\"index === 0 ? firstItemStyle : itemStyle\"\n >\n <VNodeRenderer :vnode=\"child\" />\n </span>\n <span\n v-if=\"surplusCount > 0\"\n :class=\"ui.item()\"\n :style=\"visible.length === 0 ? firstItemStyle : itemStyle\"\n data-id=\"avatar-group-surplus\"\n >\n <slot\n name=\"surplus\"\n :count=\"surplusCount\"\n >\n <RuiAvatar\n :size=\"resolvedSize\"\n :variant=\"variant\"\n :alt=\"`+${surplusCount} more`\"\n :style=\"{ width: `${avatarPx}px`, height: `${avatarPx}px` }\"\n >\n <span :class=\"ui.surplus()\">+{{ surplusCount }}</span>\n </RuiAvatar>\n </slot>\n </span>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiAvatarGroup.js","names":["_sfc_main"],"sources":["../../../src/components/avatars/RuiAvatarGroup.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { get } from '@vueuse/shared';\nimport { Comment, defineComponent, Fragment, Text, type VNode } from 'vue';\nimport {\n avatarGroupInjectionKey,\n AvatarGroupSpacing,\n type AvatarSize,\n type AvatarVariant,\n resolveAvatarGroupSpacingPx,\n resolveAvatarSizePx,\n} from '@/components/avatars/avatar-props';\nimport RuiAvatar from '@/components/avatars/RuiAvatar.vue';\nimport { tv } from '@/utils/tv';\n\nexport interface Props {\n size?: AvatarSize | number;\n variant?: AvatarVariant;\n max?: number;\n total?: number;\n /**\n * How much each avatar overlaps the previous one. The tokens name the\n * amount of overlap, so `lg` overlaps the most and `sm` the least; they\n * scale with the avatar size. A number is the inline margin in pixels and\n * should be negative to overlap.\n */\n spacing?: AvatarGroupSpacing | number;\n}\n\ndefineOptions({\n name: 'RuiAvatarGroup',\n});\n\nconst {\n size,\n variant = 'circular',\n max,\n total,\n spacing = AvatarGroupSpacing.md,\n} = defineProps<Props>();\n\nconst slots = defineSlots<{\n default?: () => VNode[];\n surplus?: (props: { count: number }) => any;\n}>();\n\nconst resolvedSize = computed<AvatarSize | number>(() => size ?? 'md');\n\nconst VNodeRenderer = defineComponent<{ vnode: VNode }>({\n props: ['vnode'],\n setup(props) {\n return (): VNode => props.vnode;\n },\n});\n\nprovide(avatarGroupInjectionKey, computed(() => ({ size: get(resolvedSize), variant })));\n\nconst groupStyles = tv({\n slots: {\n root: 'inline-flex items-center isolate',\n item: 'relative ring-2 ring-rui-surface',\n surplus: 'leading-none text-[0.85em] tracking-tight',\n },\n // The ring follows the avatar outline\n variants: {\n variant: {\n circular: { item: 'rounded-full' },\n rounded: { item: 'rounded-rui-control' },\n square: { item: 'rounded-none' },\n },\n },\n});\n\nfunction flattenChildren(nodes: VNode[] | undefined): VNode[] {\n if (!nodes)\n return [];\n const out: VNode[] = [];\n for (const node of nodes) {\n if (node.type === Comment)\n continue;\n if (node.type === Text && typeof node.children === 'string' && node.children.trim() === '')\n continue;\n if (node.type === Fragment && Array.isArray(node.children)) {\n const inner = node.children.filter((c): c is VNode => typeof c === 'object' && c !== null && 'type' in c);\n out.push(...flattenChildren(inner));\n continue;\n }\n out.push(node);\n }\n return out;\n}\n\nconst children = computed<VNode[]>(() => flattenChildren(slots.default?.()));\n\nconst visible = computed<VNode[]>(() => {\n if (max === undefined)\n return get(children);\n return get(children).slice(0, max);\n});\n\nconst surplusCount = computed<number>(() => {\n const totalCount = total ?? get(children).length;\n const shown = get(visible).length;\n return Math.max(0, totalCount - shown);\n});\n\nconst spacingPx = computed<number>(() => resolveAvatarGroupSpacingPx(spacing, get(resolvedSize)));\n\n// The configured spacing, which is already negative, so the items overlap\nconst ringOffsetPx = computed<number>(() => get(spacingPx));\n\nconst itemStyle = computed<Record<string, string>>(() => ({\n marginInlineStart: `${get(ringOffsetPx)}px`,\n}));\n\nconst firstItemStyle = computed<Record<string, string>>(() => ({\n marginInlineStart: '0',\n}));\n\nconst avatarPx = computed<number>(() => resolveAvatarSizePx(get(resolvedSize)));\n\nconst ui = computed<ReturnType<typeof groupStyles>>(() => groupStyles({ variant }));\n</script>\n\n<template>\n <div\n :class=\"ui.root()\"\n data-id=\"avatar-group\"\n :data-size=\"typeof resolvedSize === 'string' ? resolvedSize : undefined\"\n :data-variant=\"variant\"\n >\n <span\n v-for=\"(child, index) in visible\"\n :key=\"child.key ?? index\"\n :class=\"ui.item()\"\n :style=\"index === 0 ? firstItemStyle : itemStyle\"\n >\n <VNodeRenderer :vnode=\"child\" />\n </span>\n <span\n v-if=\"surplusCount > 0\"\n :class=\"ui.item()\"\n :style=\"visible.length === 0 ? firstItemStyle : itemStyle\"\n data-id=\"avatar-group-surplus\"\n >\n <slot\n name=\"surplus\"\n :count=\"surplusCount\"\n >\n <RuiAvatar\n :size=\"resolvedSize\"\n :variant=\"variant\"\n :alt=\"`+${surplusCount} more`\"\n :style=\"{ width: `${avatarPx}px`, height: `${avatarPx}px` }\"\n >\n <span :class=\"ui.surplus()\">+{{ surplusCount }}</span>\n </RuiAvatar>\n </slot>\n </span>\n </div>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/avatars/RuiAvatarGroup.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { get } from '@vueuse/shared';\nimport { Comment, defineComponent, Fragment, Text, type VNode } from 'vue';\nimport {\n avatarGroupInjectionKey,\n AvatarGroupSpacing,\n type AvatarSize,\n type AvatarVariant,\n resolveAvatarGroupSpacingPx,\n resolveAvatarSizePx,\n} from '@/components/avatars/avatar-props';\nimport RuiAvatar from '@/components/avatars/RuiAvatar.vue';\nimport { tv } from '@/utils/tv';\n\nexport interface Props {\n size?: AvatarSize | number;\n variant?: AvatarVariant;\n max?: number;\n total?: number;\n /**\n * How much each avatar overlaps the previous one. The tokens name the\n * amount of overlap, so `lg` overlaps the most and `sm` the least; they\n * scale with the avatar size. A number is the inline margin in pixels and\n * should be negative to overlap.\n */\n spacing?: AvatarGroupSpacing | number;\n}\n\ndefineOptions({\n name: 'RuiAvatarGroup',\n});\n\nconst {\n size,\n variant = 'circular',\n max,\n total,\n spacing = AvatarGroupSpacing.md,\n} = defineProps<Props>();\n\nconst slots = defineSlots<{\n default?: () => VNode[];\n surplus?: (props: { count: number }) => any;\n}>();\n\nconst resolvedSize = computed<AvatarSize | number>(() => size ?? 'md');\n\nconst VNodeRenderer = defineComponent<{ vnode: VNode }>({\n props: ['vnode'],\n setup(props) {\n return (): VNode => props.vnode;\n },\n});\n\nprovide(avatarGroupInjectionKey, computed(() => ({ size: get(resolvedSize), variant })));\n\nconst groupStyles = tv({\n slots: {\n root: 'inline-flex items-center isolate',\n item: 'relative ring-2 ring-rui-surface',\n surplus: 'leading-none text-[0.85em] tracking-tight',\n },\n // The ring follows the avatar outline\n variants: {\n variant: {\n circular: { item: 'rounded-full' },\n rounded: { item: 'rounded-rui-control' },\n square: { item: 'rounded-none' },\n },\n },\n});\n\nfunction flattenChildren(nodes: VNode[] | undefined): VNode[] {\n if (!nodes)\n return [];\n const out: VNode[] = [];\n for (const node of nodes) {\n if (node.type === Comment)\n continue;\n if (node.type === Text && typeof node.children === 'string' && node.children.trim() === '')\n continue;\n if (node.type === Fragment && Array.isArray(node.children)) {\n const inner = node.children.filter((c): c is VNode => typeof c === 'object' && c !== null && 'type' in c);\n out.push(...flattenChildren(inner));\n continue;\n }\n out.push(node);\n }\n return out;\n}\n\nconst children = computed<VNode[]>(() => flattenChildren(slots.default?.()));\n\nconst visible = computed<VNode[]>(() => {\n if (max === undefined)\n return get(children);\n return get(children).slice(0, max);\n});\n\nconst surplusCount = computed<number>(() => {\n const totalCount = total ?? get(children).length;\n const shown = get(visible).length;\n return Math.max(0, totalCount - shown);\n});\n\nconst spacingPx = computed<number>(() => resolveAvatarGroupSpacingPx(spacing, get(resolvedSize)));\n\n// The configured spacing, which is already negative, so the items overlap\nconst ringOffsetPx = computed<number>(() => get(spacingPx));\n\nconst itemStyle = computed<Record<string, string>>(() => ({\n marginInlineStart: `${get(ringOffsetPx)}px`,\n}));\n\nconst firstItemStyle = computed<Record<string, string>>(() => ({\n marginInlineStart: '0',\n}));\n\nconst avatarPx = computed<number>(() => resolveAvatarSizePx(get(resolvedSize)));\n\nconst ui = computed<ReturnType<typeof groupStyles>>(() => groupStyles({ variant }));\n</script>\n\n<template>\n <div\n :class=\"ui.root()\"\n data-id=\"avatar-group\"\n :data-size=\"typeof resolvedSize === 'string' ? resolvedSize : undefined\"\n :data-variant=\"variant\"\n >\n <span\n v-for=\"(child, index) in visible\"\n :key=\"child.key ?? index\"\n :class=\"ui.item()\"\n :style=\"index === 0 ? firstItemStyle : itemStyle\"\n >\n <VNodeRenderer :vnode=\"child\" />\n </span>\n <span\n v-if=\"surplusCount > 0\"\n :class=\"ui.item()\"\n :style=\"visible.length === 0 ? firstItemStyle : itemStyle\"\n data-id=\"avatar-group-surplus\"\n >\n <slot\n name=\"surplus\"\n :count=\"surplusCount\"\n >\n <RuiAvatar\n :size=\"resolvedSize\"\n :variant=\"variant\"\n :alt=\"`+${surplusCount} more`\"\n :style=\"{ width: `${avatarPx}px`, height: `${avatarPx}px` }\"\n >\n <span :class=\"ui.surplus()\">+{{ surplusCount }}</span>\n </RuiAvatar>\n </slot>\n </span>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;EAwCA,MAAM,QAAQ,SAAA;EAKd,MAAM,eAAe,eAAoC,QAAA,QAAQ,IAAI;EAErE,MAAM,gBAAgB,gBAAkC;GACtD,OAAO,CAAC,OAAO;GACf,MAAM,OAAO;IACX,aAAoB,MAAM;GAC5B;EACF,CAAC;EAED,QAAQ,yBAAyB,gBAAgB;GAAE,MAAM,IAAI,YAAY;GAAG,SAAM,QAAA;EAAE,EAAE,CAAC;EAEvF,MAAM,cAAc,GAAG;GACrB,OAAO;IACL,MAAM;IACN,MAAM;IACN,SAAS;GACX;GAEA,UAAU,EACR,SAAS;IACP,UAAU,EAAE,MAAM,eAAe;IACjC,SAAS,EAAE,MAAM,sBAAsB;IACvC,QAAQ,EAAE,MAAM,eAAe;GACjC,EACF;EACF,CAAC;EAED,SAAS,gBAAgB,OAAqC;GAC5D,IAAI,CAAC,OACH,OAAO,CAAC;GACV,MAAM,MAAe,CAAC;GACtB,KAAK,MAAM,QAAQ,OAAO;IACxB,IAAI,KAAK,SAAS,SAChB;IACF,IAAI,KAAK,SAAS,QAAQ,OAAO,KAAK,aAAa,YAAY,KAAK,SAAS,KAAK,MAAM,IACtF;IACF,IAAI,KAAK,SAAS,YAAY,MAAM,QAAQ,KAAK,QAAQ,GAAG;KAC1D,MAAM,QAAQ,KAAK,SAAS,QAAQ,MAAkB,OAAO,MAAM,YAAY,MAAM,QAAQ,UAAU,CAAC;KACxG,IAAI,KAAK,GAAG,gBAAgB,KAAK,CAAC;KAClC;IACF;IACA,IAAI,KAAK,IAAI;GACf;GACA,OAAO;EACT;EAEA,MAAM,WAAW,eAAwB,gBAAgB,MAAM,UAAU,CAAC,CAAC;EAE3E,MAAM,UAAU,eAAwB;GACtC,IAAI,QAAA,QAAQ,KAAA,GACV,OAAO,IAAI,QAAQ;GACrB,OAAO,IAAI,QAAQ,CAAC,CAAC,MAAM,GAAG,QAAA,GAAG;EACnC,CAAC;EAED,MAAM,eAAe,eAAuB;GAC1C,MAAM,aAAa,QAAA,SAAS,IAAI,QAAQ,CAAC,CAAC;GAC1C,MAAM,QAAQ,IAAI,OAAO,CAAC,CAAC;GAC3B,OAAO,KAAK,IAAI,GAAG,aAAa,KAAK;EACvC,CAAC;EAED,MAAM,YAAY,eAAuB,4BAA4B,QAAA,SAAS,IAAI,YAAY,CAAC,CAAC;EAGhG,MAAM,eAAe,eAAuB,IAAI,SAAS,CAAC;EAE1D,MAAM,YAAY,gBAAwC,EACxD,mBAAmB,GAAG,IAAI,YAAY,EAAE,IAC1C,EAAE;EAEF,MAAM,iBAAiB,gBAAwC,EAC7D,mBAAmB,IACrB,EAAE;EAEF,MAAM,WAAW,eAAuB,oBAAoB,IAAI,YAAY,CAAC,CAAC;EAE9E,MAAM,KAAK,eAA+C,YAAY,EAAE,SAAM,QAAA,QAAE,CAAC,CAAC;;GAIhF,OAAA,UAAA,GAAA,mBAkCM,OAAA;IAjCH,OAAK,eAAE,MAAA,EAAA,CAAE,CAAC,KAAI,CAAA;IACf,WAAQ;IACP,aAAS,OAAS,MAAA,YAAA,MAAY,WAAgB,MAAA,YAAA,IAAe,KAAA;IAC7D,gBAAc,QAAA;GAEf,GAAA,EAAA,UAAA,IAAA,GAAA,mBAOO,UAAA,MAAA,WANoB,MAAA,OAAA,IAAjB,OAAO,UAAK;IADtB,OAAA,UAAA,GAAA,mBAOO,QAAA;KALJ,KAAK,MAAM,OAAO;KAClB,OAAK,eAAE,MAAA,EAAA,CAAE,CAAC,KAAI,CAAA;KACd,OAAK,eAAE,UAAK,IAAS,MAAA,cAAA,IAAiB,MAAA,SAAA,CAAS;IAEhD,GAAA,CAAA,YAAgC,MAAA,aAAA,GAAA,EAAhB,OAAO,MAAK,GAAA,MAAA,GAAA,CAAA,OAAA,CAAA,CAAA,GAAA,CAAA;GAGtB,CAAA,GAAA,GAAA,IAAA,MAAA,YAAA,IAAY,KADpB,UAAA,GAAA,mBAmBO,QAAA;;IAjBJ,OAAK,eAAE,MAAA,EAAA,CAAE,CAAC,KAAI,CAAA;IACd,OAAK,eAAE,MAAA,OAAA,CAAO,CAAC,WAAM,IAAS,MAAA,cAAA,IAAiB,MAAA,SAAA,CAAS;IACzD,WAAQ;GAER,GAAA,CAAA,WAYO,KAAA,QAAA,WAAA,EAVJ,OAAO,MAAA,YAAA,EAAY,SAUf,CARL,YAOY,mBAAA;IANT,MAAM,MAAA,YAAA;IACN,SAAS,QAAA;IACT,KAAG,IAAM,MAAA,YAAA,EAAY;IACrB,OAAK,eAAA;KAAA,OAAA,GAAc,MAAA,QAAA,EAAQ;KAAA,QAAA,GAAiB,MAAA,QAAA,EAAQ;IAAA,CAAA;;IAErD,SAAA,cAAsD,CAAtD,mBAAsD,QAAA,EAA/C,OAAK,eAAE,MAAA,EAAA,CAAE,CAAC,QAAO,CAAA,EAAI,GAAA,MAAC,gBAAG,MAAA,YAAA,CAAY,GAAA,CAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js","names":["_useSlots","_openBlock","_createElementBlock","_normalizeClass","_unref","_Fragment","_renderList","_normalizeStyle","_createVNode","_renderSlot","RuiAvatar","_withCtx","_createElementVNode","_toDisplayString","_createCommentVNode"],"sources":["../../../src/components/avatars/RuiAvatarGroup.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport { get } from '@vueuse/shared';\nimport { Comment, defineComponent, Fragment, Text, type VNode } from 'vue';\nimport {\n avatarGroupInjectionKey,\n AvatarGroupSpacing,\n type AvatarSize,\n type AvatarVariant,\n resolveAvatarGroupSpacingPx,\n resolveAvatarSizePx,\n} from '@/components/avatars/avatar-props';\nimport RuiAvatar from '@/components/avatars/RuiAvatar.vue';\nimport { tv } from '@/utils/tv';\n\nexport interface Props {\n size?: AvatarSize | number;\n variant?: AvatarVariant;\n max?: number;\n total?: number;\n /**\n * How much each avatar overlaps the previous one. The tokens name the\n * amount of overlap, so `lg` overlaps the most and `sm` the least; they\n * scale with the avatar size. A number is the inline margin in pixels and\n * should be negative to overlap.\n */\n spacing?: AvatarGroupSpacing | number;\n}\n\ndefineOptions({\n name: 'RuiAvatarGroup',\n});\n\nconst {\n size,\n variant = 'circular',\n max,\n total,\n spacing = AvatarGroupSpacing.md,\n} = defineProps<Props>();\n\nconst slots = defineSlots<{\n default?: () => VNode[];\n surplus?: (props: { count: number }) => any;\n}>();\n\nconst resolvedSize = computed<AvatarSize | number>(() => size ?? 'md');\n\nconst VNodeRenderer = defineComponent<{ vnode: VNode }>({\n props: ['vnode'],\n setup(props) {\n return (): VNode => props.vnode;\n },\n});\n\nprovide(avatarGroupInjectionKey, computed(() => ({ size: get(resolvedSize), variant })));\n\nconst groupStyles = tv({\n slots: {\n root: 'inline-flex items-center isolate',\n item: 'relative ring-2 ring-rui-surface',\n surplus: 'leading-none text-[0.85em] tracking-tight',\n },\n // The ring follows the avatar outline\n variants: {\n variant: {\n circular: { item: 'rounded-full' },\n rounded: { item: 'rounded-rui-control' },\n square: { item: 'rounded-none' },\n },\n },\n});\n\nfunction flattenChildren(nodes: VNode[] | undefined): VNode[] {\n if (!nodes)\n return [];\n const out: VNode[] = [];\n for (const node of nodes) {\n if (node.type === Comment)\n continue;\n if (node.type === Text && typeof node.children === 'string' && node.children.trim() === '')\n continue;\n if (node.type === Fragment && Array.isArray(node.children)) {\n const inner = node.children.filter((c): c is VNode => typeof c === 'object' && c !== null && 'type' in c);\n out.push(...flattenChildren(inner));\n continue;\n }\n out.push(node);\n }\n return out;\n}\n\nconst children = computed<VNode[]>(() => flattenChildren(slots.default?.()));\n\nconst visible = computed<VNode[]>(() => {\n if (max === undefined)\n return get(children);\n return get(children).slice(0, max);\n});\n\nconst surplusCount = computed<number>(() => {\n const totalCount = total ?? get(children).length;\n const shown = get(visible).length;\n return Math.max(0, totalCount - shown);\n});\n\nconst spacingPx = computed<number>(() => resolveAvatarGroupSpacingPx(spacing, get(resolvedSize)));\n\n// The configured spacing, which is already negative, so the items overlap\nconst ringOffsetPx = computed<number>(() => get(spacingPx));\n\nconst itemStyle = computed<Record<string, string>>(() => ({\n marginInlineStart: `${get(ringOffsetPx)}px`,\n}));\n\nconst firstItemStyle = computed<Record<string, string>>(() => ({\n marginInlineStart: '0',\n}));\n\nconst avatarPx = computed<number>(() => resolveAvatarSizePx(get(resolvedSize)));\n\nconst ui = computed<ReturnType<typeof groupStyles>>(() => groupStyles({ variant }));\n</script>\n\n<template>\n <div\n :class=\"ui.root()\"\n data-id=\"avatar-group\"\n :data-size=\"typeof resolvedSize === 'string' ? resolvedSize : undefined\"\n :data-variant=\"variant\"\n >\n <span\n v-for=\"(child, index) in visible\"\n :key=\"child.key ?? index\"\n :class=\"ui.item()\"\n :style=\"index === 0 ? firstItemStyle : itemStyle\"\n >\n <VNodeRenderer :vnode=\"child\" />\n </span>\n <span\n v-if=\"surplusCount > 0\"\n :class=\"ui.item()\"\n :style=\"visible.length === 0 ? firstItemStyle : itemStyle\"\n data-id=\"avatar-group-surplus\"\n >\n <slot\n name=\"surplus\"\n :count=\"surplusCount\"\n >\n <RuiAvatar\n :size=\"resolvedSize\"\n :variant=\"variant\"\n :alt=\"`+${surplusCount} more`\"\n :style=\"{ width: `${avatarPx}px`, height: `${avatarPx}px` }\"\n >\n <span :class=\"ui.surplus()\">+{{ surplusCount }}</span>\n </RuiAvatar>\n </slot>\n </span>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiButton.js","names":[],"sources":["../../../../src/components/buttons/button/RuiButton.vue"],"sourcesContent":["<script lang=\"ts\" generic=\"T = undefined\" setup>\nimport type { ContextColorsType } from '@/consts/colors';\nimport { ButtonGroupKey } from '@/components/buttons/button-group/button-group-context';\nimport { type ButtonSize, ButtonVariant, getButtonSpinnerSize } from '@/components/buttons/button/button-props';\nimport { buttonStyles } from '@/components/buttons/button/button-styles';\nimport RuiProgress from '@/components/progress/RuiProgress.vue';\nimport { cn } from '@/utils/tv';\n\nexport interface Props<T = undefined> {\n disabled?: boolean;\n loading?: boolean;\n color?: ContextColorsType;\n rounded?: boolean;\n variant?: ButtonVariant;\n icon?: boolean;\n active?: boolean;\n size?: ButtonSize;\n tag?: 'button' | 'a';\n type?: 'button' | 'submit';\n modelValue?: T;\n hideFocusIndicator?: boolean;\n}\n\ndefineOptions({\n name: 'RuiButton',\n inheritAttrs: false,\n});\n\nconst {\n disabled = false,\n loading = false,\n color = undefined,\n rounded = false,\n variant = ButtonVariant.default,\n icon = false,\n active = false,\n size = undefined,\n tag = 'button',\n type = 'button',\n modelValue = undefined,\n hideFocusIndicator = false,\n} = defineProps<Props<T>>();\n\nconst emit = defineEmits<{\n 'update:model-value': [value?: T];\n}>();\n\nconst slots = defineSlots<{\n prepend?: () => any;\n append?: () => any;\n default?: () => any;\n}>();\n\n// a RuiButtonGroup anywhere above, unless an overlay's content sits in between\nconst group = inject(ButtonGroupKey, undefined);\n\nconst btnValue = computed<T | undefined>(() => modelValue);\n\nconst resolvedVariant = computed<ButtonVariant>(() => group?.variant() ?? variant);\n\nconst resolvedSize = computed<ButtonSize | undefined>(() => size ?? group?.size());\n\nconst resolvedDisabled = computed<boolean>(() => disabled || (group?.disabled() ?? false));\n\n// a grouped button is pressed when the group's model holds its value; it needs one to take part\nconst resolvedActive = computed<boolean>(() => active || (!!group && modelValue !== undefined && group.isActive(modelValue)));\n\nconst resolvedColor = computed<ContextColorsType | undefined>(() => group?.color(get(resolvedActive)) ?? color);\n\nconst spinnerSize = computed<number>(() => getButtonSpinnerSize(get(resolvedSize)));\n\nconst ui = computed<ReturnType<typeof buttonStyles>>(() => buttonStyles({\n variant: get(resolvedVariant),\n color: get(resolvedColor) ?? 'grey',\n size: get(resolvedSize),\n rounded,\n icon,\n active: get(resolvedActive),\n loading,\n hideFocusIndicator,\n}));\n\nfunction onClick(): void {\n emit('update:model-value', get(btnValue));\n if (group && modelValue !== undefined)\n group.toggle(modelValue);\n}\n</script>\n\n<template>\n <Component\n :is=\"tag\"\n :class=\"ui.root({ class: cn([group?.itemClass(), $attrs.class]) })\"\n :disabled=\"resolvedDisabled || loading\"\n :type=\"tag === 'button' ? type : undefined\"\n :data-variant=\"resolvedVariant\"\n :data-size=\"resolvedSize ?? 'md'\"\n :data-color=\"resolvedColor\"\n :data-active=\"resolvedActive || undefined\"\n :aria-busy=\"loading || undefined\"\n v-bind=\"{ ...$attrs, class: undefined }\"\n @click=\"onClick()\"\n >\n <!-- the button's aria-busy announces the wait, so the spinner stays out of the accessibility tree -->\n <RuiProgress\n v-if=\"loading\"\n circular\n data-spinner\n aria-hidden=\"true\"\n :class=\"ui.spinner()\"\n variant=\"indeterminate\"\n thickness=\"2\"\n :size=\"spinnerSize\"\n />\n <!-- while loading, the spinner stands in for the prepend icon; the label stays -->\n <slot\n v-if=\"!loading || icon\"\n name=\"prepend\"\n />\n <span\n v-if=\"slots.default\"\n :class=\"ui.label()\"\n data-id=\"btn-label\"\n >\n <slot />\n </span>\n <slot name=\"append\" />\n </Component>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiButton.js","names":["_sfc_main"],"sources":["../../../../src/components/buttons/button/RuiButton.vue"],"sourcesContent":["<script lang=\"ts\" generic=\"T = undefined\" setup>\nimport type { ContextColorsType } from '@/consts/colors';\nimport { ButtonGroupKey } from '@/components/buttons/button-group/button-group-context';\nimport { type ButtonSize, ButtonVariant, getButtonSpinnerSize } from '@/components/buttons/button/button-props';\nimport { buttonStyles } from '@/components/buttons/button/button-styles';\nimport RuiProgress from '@/components/progress/RuiProgress.vue';\nimport { cn } from '@/utils/tv';\n\nexport interface Props<T = undefined> {\n disabled?: boolean;\n loading?: boolean;\n color?: ContextColorsType;\n rounded?: boolean;\n variant?: ButtonVariant;\n icon?: boolean;\n active?: boolean;\n size?: ButtonSize;\n tag?: 'button' | 'a';\n type?: 'button' | 'submit';\n modelValue?: T;\n hideFocusIndicator?: boolean;\n}\n\ndefineOptions({\n name: 'RuiButton',\n inheritAttrs: false,\n});\n\nconst {\n disabled = false,\n loading = false,\n color = undefined,\n rounded = false,\n variant = ButtonVariant.default,\n icon = false,\n active = false,\n size = undefined,\n tag = 'button',\n type = 'button',\n modelValue = undefined,\n hideFocusIndicator = false,\n} = defineProps<Props<T>>();\n\nconst emit = defineEmits<{\n 'update:model-value': [value?: T];\n}>();\n\nconst slots = defineSlots<{\n prepend?: () => any;\n append?: () => any;\n default?: () => any;\n}>();\n\n// a RuiButtonGroup anywhere above, unless an overlay's content sits in between\nconst group = inject(ButtonGroupKey, undefined);\n\nconst btnValue = computed<T | undefined>(() => modelValue);\n\nconst resolvedVariant = computed<ButtonVariant>(() => group?.variant() ?? variant);\n\nconst resolvedSize = computed<ButtonSize | undefined>(() => size ?? group?.size());\n\nconst resolvedDisabled = computed<boolean>(() => disabled || (group?.disabled() ?? false));\n\n// a grouped button is pressed when the group's model holds its value; it needs one to take part\nconst resolvedActive = computed<boolean>(() => active || (!!group && modelValue !== undefined && group.isActive(modelValue)));\n\nconst resolvedColor = computed<ContextColorsType | undefined>(() => group?.color(get(resolvedActive)) ?? color);\n\nconst spinnerSize = computed<number>(() => getButtonSpinnerSize(get(resolvedSize)));\n\nconst ui = computed<ReturnType<typeof buttonStyles>>(() => buttonStyles({\n variant: get(resolvedVariant),\n color: get(resolvedColor) ?? 'grey',\n size: get(resolvedSize),\n rounded,\n icon,\n active: get(resolvedActive),\n loading,\n hideFocusIndicator,\n}));\n\nfunction onClick(): void {\n emit('update:model-value', get(btnValue));\n if (group && modelValue !== undefined)\n group.toggle(modelValue);\n}\n</script>\n\n<template>\n <Component\n :is=\"tag\"\n :class=\"ui.root({ class: cn([group?.itemClass(), $attrs.class]) })\"\n :disabled=\"resolvedDisabled || loading\"\n :type=\"tag === 'button' ? type : undefined\"\n :data-variant=\"resolvedVariant\"\n :data-size=\"resolvedSize ?? 'md'\"\n :data-color=\"resolvedColor\"\n :data-active=\"resolvedActive || undefined\"\n :aria-busy=\"loading || undefined\"\n v-bind=\"{ ...$attrs, class: undefined }\"\n @click=\"onClick()\"\n >\n <!-- the button's aria-busy announces the wait, so the spinner stays out of the accessibility tree -->\n <RuiProgress\n v-if=\"loading\"\n circular\n data-spinner\n aria-hidden=\"true\"\n :class=\"ui.spinner()\"\n variant=\"indeterminate\"\n thickness=\"2\"\n :size=\"spinnerSize\"\n />\n <!-- while loading, the spinner stands in for the prepend icon; the label stays -->\n <slot\n v-if=\"!loading || icon\"\n name=\"prepend\"\n />\n <span\n v-if=\"slots.default\"\n :class=\"ui.label()\"\n data-id=\"btn-label\"\n >\n <slot />\n </span>\n <slot name=\"append\" />\n </Component>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiButton.vue_vue_type_script_setup_true_lang.js","names":["$attrs"],"sources":["../../../../src/components/buttons/button/RuiButton.vue"],"sourcesContent":["<script lang=\"ts\" generic=\"T = undefined\" setup>\nimport type { ContextColorsType } from '@/consts/colors';\nimport { ButtonGroupKey } from '@/components/buttons/button-group/button-group-context';\nimport { type ButtonSize, ButtonVariant, getButtonSpinnerSize } from '@/components/buttons/button/button-props';\nimport { buttonStyles } from '@/components/buttons/button/button-styles';\nimport RuiProgress from '@/components/progress/RuiProgress.vue';\nimport { cn } from '@/utils/tv';\n\nexport interface Props<T = undefined> {\n disabled?: boolean;\n loading?: boolean;\n color?: ContextColorsType;\n rounded?: boolean;\n variant?: ButtonVariant;\n icon?: boolean;\n active?: boolean;\n size?: ButtonSize;\n tag?: 'button' | 'a';\n type?: 'button' | 'submit';\n modelValue?: T;\n hideFocusIndicator?: boolean;\n}\n\ndefineOptions({\n name: 'RuiButton',\n inheritAttrs: false,\n});\n\nconst {\n disabled = false,\n loading = false,\n color = undefined,\n rounded = false,\n variant = ButtonVariant.default,\n icon = false,\n active = false,\n size = undefined,\n tag = 'button',\n type = 'button',\n modelValue = undefined,\n hideFocusIndicator = false,\n} = defineProps<Props<T>>();\n\nconst emit = defineEmits<{\n 'update:model-value': [value?: T];\n}>();\n\nconst slots = defineSlots<{\n prepend?: () => any;\n append?: () => any;\n default?: () => any;\n}>();\n\n// a RuiButtonGroup anywhere above, unless an overlay's content sits in between\nconst group = inject(ButtonGroupKey, undefined);\n\nconst btnValue = computed<T | undefined>(() => modelValue);\n\nconst resolvedVariant = computed<ButtonVariant>(() => group?.variant() ?? variant);\n\nconst resolvedSize = computed<ButtonSize | undefined>(() => size ?? group?.size());\n\nconst resolvedDisabled = computed<boolean>(() => disabled || (group?.disabled() ?? false));\n\n// a grouped button is pressed when the group's model holds its value; it needs one to take part\nconst resolvedActive = computed<boolean>(() => active || (!!group && modelValue !== undefined && group.isActive(modelValue)));\n\nconst resolvedColor = computed<ContextColorsType | undefined>(() => group?.color(get(resolvedActive)) ?? color);\n\nconst spinnerSize = computed<number>(() => getButtonSpinnerSize(get(resolvedSize)));\n\nconst ui = computed<ReturnType<typeof buttonStyles>>(() => buttonStyles({\n variant: get(resolvedVariant),\n color: get(resolvedColor) ?? 'grey',\n size: get(resolvedSize),\n rounded,\n icon,\n active: get(resolvedActive),\n loading,\n hideFocusIndicator,\n}));\n\nfunction onClick(): void {\n emit('update:model-value', get(btnValue));\n if (group && modelValue !== undefined)\n group.toggle(modelValue);\n}\n</script>\n\n<template>\n <Component\n :is=\"tag\"\n :class=\"ui.root({ class: cn([group?.itemClass(), $attrs.class]) })\"\n :disabled=\"resolvedDisabled || loading\"\n :type=\"tag === 'button' ? type : undefined\"\n :data-variant=\"resolvedVariant\"\n :data-size=\"resolvedSize ?? 'md'\"\n :data-color=\"resolvedColor\"\n :data-active=\"resolvedActive || undefined\"\n :aria-busy=\"loading || undefined\"\n v-bind=\"{ ...$attrs, class: undefined }\"\n @click=\"onClick()\"\n >\n <!-- the button's aria-busy announces the wait, so the spinner stays out of the accessibility tree -->\n <RuiProgress\n v-if=\"loading\"\n circular\n data-spinner\n aria-hidden=\"true\"\n :class=\"ui.spinner()\"\n variant=\"indeterminate\"\n thickness=\"2\"\n :size=\"spinnerSize\"\n />\n <!-- while loading, the spinner stands in for the prepend icon; the label stays -->\n <slot\n v-if=\"!loading || icon\"\n name=\"prepend\"\n />\n <span\n v-if=\"slots.default\"\n :class=\"ui.label()\"\n data-id=\"btn-label\"\n >\n <slot />\n </span>\n <slot name=\"append\" />\n </Component>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2CA,MAAM,OAAO;EAIb,MAAM,QAAQ,SAAA;EAOd,MAAM,QAAQ,OAAO,gBAAgB,KAAA,CAAS;EAE9C,MAAM,WAAW,eAA8B,QAAA,UAAU;EAEzD,MAAM,kBAAkB,eAA8B,OAAO,QAAQ,KAAK,QAAA,OAAO;EAEjF,MAAM,eAAe,eAAuC,QAAA,QAAQ,OAAO,KAAK,CAAC;EAEjF,MAAM,mBAAmB,eAAwB,QAAA,aAAa,OAAO,SAAS,KAAK,MAAM;EAGzF,MAAM,iBAAiB,eAAwB,QAAA,UAAW,CAAC,CAAC,SAAS,QAAA,eAAe,KAAA,KAAa,MAAM,SAAS,QAAA,UAAU,CAAE;EAE5H,MAAM,gBAAgB,eAA8C,OAAO,MAAM,IAAI,cAAc,CAAC,KAAK,QAAA,KAAK;EAE9G,MAAM,cAAc,eAAuB,qBAAqB,IAAI,YAAY,CAAC,CAAC;EAElF,MAAM,KAAK,eAAgD,aAAa;GACtE,SAAS,IAAI,eAAe;GAC5B,OAAO,IAAI,aAAa,KAAK;GAC7B,MAAM,IAAI,YAAY;GACtB,SAAM,QAAA;GACN,MAAG,QAAA;GACH,QAAQ,IAAI,cAAc;GAC1B,SAAM,QAAA;GACN,oBAAiB,QAAA;EACnB,CAAC,CAAC;EAEF,SAAS,UAAgB;GACvB,KAAK,sBAAsB,IAAI,QAAQ,CAAC;GACxC,IAAI,SAAS,QAAA,eAAe,KAAA,GAC1B,MAAM,OAAO,QAAA,UAAU;EAC3B;;GAIE,OAAA,UAAA,GAAA,YAqCY,wBApCL,QAAA,GAAG,GADV,WAqCY;IAnCT,OAAO,MAAA,EAAA,CAAE,CAAC,KAAI,EAAA,OAAU,MAAA,EAAA,CAAE,CAAA,CAAE,MAAA,KAAA,CAAK,EAAE,UAAS,GAAIA,KAAAA,OAAO,KAAK,CAAA,EAAA,CAAA;IAC5D,UAAU,MAAA,gBAAA,KAAoB,QAAA;IAC9B,MAAM,QAAA,QAAG,WAAgB,QAAA,OAAO,KAAA;IAChC,gBAAc,MAAA,eAAA;IACd,aAAW,MAAA,YAAA,KAAY;IACvB,cAAY,MAAA,aAAA;IACZ,eAAa,MAAA,cAAA,KAAkB,KAAA;IAC/B,aAAW,QAAA,WAAW,KAAA;GACVA,GAAAA;IAAAA,GAAAA,KAAAA;IAAM,OAAS,KAAA;GAAS,GAAA,EACpC,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,QAAO,GAAA,CAAA,GAAA;IAGf,SAAA,cASE;KARM,QAAA,WADR,UAAA,GAAA,YASE,qBAAA;;MAPA,UAAA;MACA,gBAAA;MACA,eAAY;MACX,OAAK,eAAE,MAAA,EAAA,CAAE,CAAC,QAAO,CAAA;MAClB,SAAQ;MACR,WAAU;MACT,MAAM,MAAA,WAAA;;KAIA,CAAA,QAAA,WAAW,QAAA,OADpB,WAGE,KAAA,QAAA,WAAA,CAAA,GAAA,KAAA,GAAA,KAAA,GAAA,CAAA,IAAA,mBAAA,IAAA,IAAA;KAEM,MAAM,WADd,UAAA,GAAA,mBAMO,QAAA;;MAJJ,OAAK,eAAE,MAAA,EAAA,CAAE,CAAC,MAAK,CAAA;MAChB,WAAQ;KAER,GAAA,CAAA,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;KAEV,WAAsB,KAAA,QAAA,QAAA"}
1
+ {"version":3,"file":"RuiButton.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_useSlots","_openBlock","_createBlock","_resolveDynamicComponent","_mergeProps","_unref","_withCtx","RuiProgress","_normalizeClass","_createCommentVNode","_renderSlot","_createElementBlock"],"sources":["../../../../src/components/buttons/button/RuiButton.vue"],"sourcesContent":["<script lang=\"ts\" generic=\"T = undefined\" setup>\nimport type { ContextColorsType } from '@/consts/colors';\nimport { ButtonGroupKey } from '@/components/buttons/button-group/button-group-context';\nimport { type ButtonSize, ButtonVariant, getButtonSpinnerSize } from '@/components/buttons/button/button-props';\nimport { buttonStyles } from '@/components/buttons/button/button-styles';\nimport RuiProgress from '@/components/progress/RuiProgress.vue';\nimport { cn } from '@/utils/tv';\n\nexport interface Props<T = undefined> {\n disabled?: boolean;\n loading?: boolean;\n color?: ContextColorsType;\n rounded?: boolean;\n variant?: ButtonVariant;\n icon?: boolean;\n active?: boolean;\n size?: ButtonSize;\n tag?: 'button' | 'a';\n type?: 'button' | 'submit';\n modelValue?: T;\n hideFocusIndicator?: boolean;\n}\n\ndefineOptions({\n name: 'RuiButton',\n inheritAttrs: false,\n});\n\nconst {\n disabled = false,\n loading = false,\n color = undefined,\n rounded = false,\n variant = ButtonVariant.default,\n icon = false,\n active = false,\n size = undefined,\n tag = 'button',\n type = 'button',\n modelValue = undefined,\n hideFocusIndicator = false,\n} = defineProps<Props<T>>();\n\nconst emit = defineEmits<{\n 'update:model-value': [value?: T];\n}>();\n\nconst slots = defineSlots<{\n prepend?: () => any;\n append?: () => any;\n default?: () => any;\n}>();\n\n// a RuiButtonGroup anywhere above, unless an overlay's content sits in between\nconst group = inject(ButtonGroupKey, undefined);\n\nconst btnValue = computed<T | undefined>(() => modelValue);\n\nconst resolvedVariant = computed<ButtonVariant>(() => group?.variant() ?? variant);\n\nconst resolvedSize = computed<ButtonSize | undefined>(() => size ?? group?.size());\n\nconst resolvedDisabled = computed<boolean>(() => disabled || (group?.disabled() ?? false));\n\n// a grouped button is pressed when the group's model holds its value; it needs one to take part\nconst resolvedActive = computed<boolean>(() => active || (!!group && modelValue !== undefined && group.isActive(modelValue)));\n\nconst resolvedColor = computed<ContextColorsType | undefined>(() => group?.color(get(resolvedActive)) ?? color);\n\nconst spinnerSize = computed<number>(() => getButtonSpinnerSize(get(resolvedSize)));\n\nconst ui = computed<ReturnType<typeof buttonStyles>>(() => buttonStyles({\n variant: get(resolvedVariant),\n color: get(resolvedColor) ?? 'grey',\n size: get(resolvedSize),\n rounded,\n icon,\n active: get(resolvedActive),\n loading,\n hideFocusIndicator,\n}));\n\nfunction onClick(): void {\n emit('update:model-value', get(btnValue));\n if (group && modelValue !== undefined)\n group.toggle(modelValue);\n}\n</script>\n\n<template>\n <Component\n :is=\"tag\"\n :class=\"ui.root({ class: cn([group?.itemClass(), $attrs.class]) })\"\n :disabled=\"resolvedDisabled || loading\"\n :type=\"tag === 'button' ? type : undefined\"\n :data-variant=\"resolvedVariant\"\n :data-size=\"resolvedSize ?? 'md'\"\n :data-color=\"resolvedColor\"\n :data-active=\"resolvedActive || undefined\"\n :aria-busy=\"loading || undefined\"\n v-bind=\"{ ...$attrs, class: undefined }\"\n @click=\"onClick()\"\n >\n <!-- the button's aria-busy announces the wait, so the spinner stays out of the accessibility tree -->\n <RuiProgress\n v-if=\"loading\"\n circular\n data-spinner\n aria-hidden=\"true\"\n :class=\"ui.spinner()\"\n variant=\"indeterminate\"\n thickness=\"2\"\n :size=\"spinnerSize\"\n />\n <!-- while loading, the spinner stands in for the prepend icon; the label stays -->\n <slot\n v-if=\"!loading || icon\"\n name=\"prepend\"\n />\n <span\n v-if=\"slots.default\"\n :class=\"ui.label()\"\n data-id=\"btn-label\"\n >\n <slot />\n </span>\n <slot name=\"append\" />\n </Component>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2CA,MAAM,OAAO;EAIb,MAAM,QAAQC,SAAA;EAOd,MAAM,QAAQ,OAAO,gBAAgB,KAAA,CAAS;EAE9C,MAAM,WAAW,eAA8B,QAAA,UAAU;EAEzD,MAAM,kBAAkB,eAA8B,OAAO,QAAQ,KAAK,QAAA,OAAO;EAEjF,MAAM,eAAe,eAAuC,QAAA,QAAQ,OAAO,KAAK,CAAC;EAEjF,MAAM,mBAAmB,eAAwB,QAAA,aAAa,OAAO,SAAS,KAAK,MAAM;EAGzF,MAAM,iBAAiB,eAAwB,QAAA,UAAW,CAAC,CAAC,SAAS,QAAA,eAAe,KAAA,KAAa,MAAM,SAAS,QAAA,UAAU,CAAE;EAE5H,MAAM,gBAAgB,eAA8C,OAAO,MAAM,IAAI,cAAc,CAAC,KAAK,QAAA,KAAK;EAE9G,MAAM,cAAc,eAAuB,qBAAqB,IAAI,YAAY,CAAC,CAAC;EAElF,MAAM,KAAK,eAAgD,aAAa;GACtE,SAAS,IAAI,eAAe;GAC5B,OAAO,IAAI,aAAa,KAAK;GAC7B,MAAM,IAAI,YAAY;GACtB,SAAM,QAAA;GACN,MAAG,QAAA;GACH,QAAQ,IAAI,cAAc;GAC1B,SAAM,QAAA;GACN,oBAAiB,QAAA;EACnB,CAAC,CAAC;EAEF,SAAS,UAAgB;GACvB,KAAK,sBAAsB,IAAI,QAAQ,CAAC;GACxC,IAAI,SAAS,QAAA,eAAe,KAAA,GAC1B,MAAM,OAAO,QAAA,UAAU;EAC3B;;GAIE,OAAAC,UAAA,GAAAC,YAqCYC,wBApCL,QAAA,GAAG,GADVC,WAqCY;IAnCT,OAAOC,MAAA,EAAA,CAAE,CAAC,KAAI,EAAA,OAAUA,MAAA,EAAA,CAAE,CAAA,CAAEA,MAAA,KAAA,CAAK,EAAE,UAAS,GAAIN,KAAAA,OAAO,KAAK,CAAA,EAAA,CAAA;IAC5D,UAAUM,MAAA,gBAAA,KAAoB,QAAA;IAC9B,MAAM,QAAA,QAAG,WAAgB,QAAA,OAAO,KAAA;IAChC,gBAAcA,MAAA,eAAA;IACd,aAAWA,MAAA,YAAA,KAAY;IACvB,cAAYA,MAAA,aAAA;IACZ,eAAaA,MAAA,cAAA,KAAkB,KAAA;IAC/B,aAAW,QAAA,WAAW,KAAA;GACVN,GAAAA;IAAAA,GAAAA,KAAAA;IAAM,OAAS,KAAA;GAAS,GAAA,EACpC,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,QAAO,GAAA,CAAA,GAAA;IAGf,SAAAO,cASE;KARM,QAAA,WADRL,UAAA,GAAAC,YASEK,qBAAA;;MAPA,UAAA;MACA,gBAAA;MACA,eAAY;MACX,OAAKC,eAAEH,MAAA,EAAA,CAAE,CAAC,QAAO,CAAA;MAClB,SAAQ;MACR,WAAU;MACT,MAAMA,MAAA,WAAA;;KAIA,CAAA,QAAA,WAAW,QAAA,OADpBK,WAGE,KAAA,QAAA,WAAA,CAAA,GAAA,KAAA,GAAA,KAAA,GAAA,CAAA,IAAA,mBAAA,IAAA,IAAA;KAEM,MAAM,WADdT,UAAA,GAAAU,mBAMO,QAAA;;MAJJ,OAAKH,eAAEH,MAAA,EAAA,CAAE,CAAC,MAAK,CAAA;MAChB,WAAQ;KAERK,GAAAA,CAAAA,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;KAEVA,WAAsB,KAAA,QAAA,QAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiButtonGroup.js","names":[],"sources":["../../../../src/components/buttons/button-group/RuiButtonGroup.vue"],"sourcesContent":["<script lang=\"ts\" generic=\"T = undefined\" setup>\nimport type { ButtonSize } from '@/components/buttons/button/button-props';\nimport type { ContextColorsType } from '@/consts/colors';\nimport { type ButtonGroupContext, ButtonGroupKey } from '@/components/buttons/button-group/button-group-context';\nimport { cn, tv } from '@/utils/tv';\n\nexport interface Props {\n vertical?: boolean;\n color?: ContextColorsType;\n activeColor?: ContextColorsType;\n /**\n * `segmented` draws the options as `RuiTabs variant=\"segmented\"` does: a neutral track whose active\n * option is a raised surface. It is neutral, so it ignores `color` and `activeColor`.\n */\n variant?: 'default' | 'outlined' | 'text' | 'segmented';\n size?: ButtonSize;\n gap?: 'sm' | 'md' | 'lg';\n required?: boolean;\n disabled?: boolean;\n}\n\ndefineOptions({\n name: 'RuiButtonGroup',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<T | T[]>();\n\nconst {\n vertical = false,\n color,\n activeColor,\n variant = 'default',\n size,\n gap,\n required = false,\n disabled = false,\n} = defineProps<Props>();\n\ndefineSlots<{\n default?: () => any;\n}>();\n\nconst buttonGroupStyles = tv({\n slots: {\n /*\n * `w-fit`: a flex column stretches its children, inline-flex or not, which drew an outlined\n * group's frame across the whole row. A consumer's own width still wins through the class merge.\n * Between filled buttons a separator only needs to part the fills, so it takes the light divider.\n */\n root: 'inline-flex w-fit max-w-full rounded-rui-control between:border-l between:border-r-0 between:border-rui-divider outline-solid outline-1 outline-transparent -outline-offset-1',\n button: 'border-0 inset-ring-0 focus:z-1',\n },\n variants: {\n vertical: {\n true: {\n root: 'flex-col items-start between:border-l-0 between:border-t between:border-b-0 *:w-full',\n button: 'w-full',\n },\n false: {},\n },\n gap: {\n none: {\n button: 'rounded-none!',\n },\n sm: {\n root: 'between:border-0 outline-0 gap-2',\n button: 'inset-ring',\n },\n md: {\n root: 'between:border-0 outline-0 gap-4',\n button: 'inset-ring',\n },\n lg: {\n root: 'between:border-0 outline-0 gap-6',\n button: 'inset-ring',\n },\n },\n variant: {\n default: {},\n outlined: {\n // the control edge, matching RuiButton's colourless outlined treatment\n root: 'outline-rui-outline between:border-rui-outline',\n },\n text: {},\n // the segmented tabs' track and pill; the 32px options make a 36px control, a field's height\n segmented: {\n root: 'rounded-rui-panel bg-rui-neutral-200 p-0.5 gap-0.5 outline-0 between:border-0 dark:bg-rui-neutral-800',\n button: [\n 'h-8 px-3 text-rui-text-secondary transition-colors hover:text-rui-text focus-visible:-outline-offset-2',\n 'data-[active]:bg-rui-surface data-[active]:text-rui-text data-[active]:shadow-rui-control dark:data-[active]:bg-rui-neutral-700',\n ].join(' '),\n },\n },\n color: {\n primary: {},\n secondary: {},\n error: {},\n warning: {},\n info: {},\n success: {},\n },\n },\n compoundVariants: [\n /*\n * The outer corners go to the button that is, or sits inside, the group's first or last item, so a\n * button wrapped in a tooltip or a menu activator rounds like a direct child.\n */\n { gap: 'none', vertical: false, class: { button: '[&:is([data-button-group]>:first-child,[data-button-group]>:first-child_*)]:rounded-l-rui-control! [&:is([data-button-group]>:last-child,[data-button-group]>:last-child_*)]:rounded-r-rui-control!' } },\n { gap: 'none', vertical: true, class: { button: '[&:is([data-button-group]>:first-child,[data-button-group]>:first-child_*)]:rounded-t-rui-control! [&:is([data-button-group]>:last-child,[data-button-group]>:last-child_*)]:rounded-b-rui-control!' } },\n /*\n * In a joined group the focus outline's sides fall on the neighbours, and on a primary neighbour a\n * primary outline vanishes. A surface ring fills the outline's offset, so the raised segment's\n * ring is parted from its neighbours on every side.\n */\n { gap: 'none', variant: ['default', 'outlined', 'text'], class: { button: 'focus-visible:ring-2 focus-visible:ring-rui-surface' } },\n // each segment is its own rounded pill inside the track, not a slice of one joined bar\n { variant: 'segmented', class: { button: 'rounded-rui-control!' } },\n\n // Color dividers for outlined/text (overrides darker dividers above)\n { color: 'primary', variant: ['outlined', 'text'], class: { root: 'between:border-rui-primary/50' } },\n { color: 'secondary', variant: ['outlined', 'text'], class: { root: 'between:border-rui-secondary/50' } },\n { color: 'error', variant: ['outlined', 'text'], class: { root: 'between:border-rui-error/50' } },\n { color: 'warning', variant: ['outlined', 'text'], class: { root: 'between:border-rui-warning/50' } },\n { color: 'info', variant: ['outlined', 'text'], class: { root: 'between:border-rui-info/50' } },\n { color: 'success', variant: ['outlined', 'text'], class: { root: 'between:border-rui-success/50' } },\n\n // Color outline for outlined variant\n { color: 'primary', variant: 'outlined', class: { root: 'outline-rui-primary/50' } },\n { color: 'secondary', variant: 'outlined', class: { root: 'outline-rui-secondary/50' } },\n { color: 'error', variant: 'outlined', class: { root: 'outline-rui-error/50' } },\n { color: 'warning', variant: 'outlined', class: { root: 'outline-rui-warning/50' } },\n { color: 'info', variant: 'outlined', class: { root: 'outline-rui-info/50' } },\n { color: 'success', variant: 'outlined', class: { root: 'outline-rui-success/50' } },\n ],\n defaultVariants: {\n vertical: false,\n gap: 'none',\n variant: 'default',\n },\n});\n\nconst ui = computed<ReturnType<typeof buttonGroupStyles>>(() => buttonGroupStyles({\n vertical,\n gap: gap ?? 'none',\n variant,\n color,\n}));\n\n/**\n * The color a button takes: the pressed one's `activeColor` when set, otherwise the group's. The\n * segmented variant is neutral, like the segmented tabs, so its buttons take none.\n *\n * @param active - whether the button is the pressed one\n * @returns the color to set, or undefined to leave the button grey\n */\nfunction buttonColor(active: boolean): ContextColorsType | undefined {\n if (variant === 'segmented')\n return undefined;\n return active && activeColor ? activeColor : color;\n}\n\nfunction isActive(id: T, selected?: T | T[]): boolean {\n if (Array.isArray(selected))\n return selected.includes(id);\n\n return selected === id;\n}\n\nfunction onClick(id: T): void {\n const selected = get(modelValue);\n\n if (Array.isArray(selected)) {\n const index = selected.indexOf(id);\n if (index >= 0) {\n if (required && selected.length === 1)\n return;\n\n set(modelValue, selected.filter((_, i) => i !== index));\n }\n else {\n set(modelValue, [...selected, id]);\n }\n }\n else if (required) {\n set(modelValue, id);\n }\n else {\n set(modelValue, isActive(id, selected) ? undefined : id);\n }\n}\n\n// a button that sets its own size keeps it; the rest take the group's\nprovide(ButtonGroupKey, {\n variant: () => variant === 'segmented' ? 'text' : variant,\n size: () => size,\n disabled: () => disabled,\n color: buttonColor,\n itemClass: () => get(ui).button(),\n isActive: (value: T) => isActive(value, get(modelValue)),\n toggle: onClick,\n} satisfies ButtonGroupContext<T>);\n</script>\n\n<template>\n <div\n :class=\"ui.root({ class: cn($attrs.class) })\"\n data-button-group\n v-bind=\"{ ...$attrs, class: undefined }\"\n >\n <slot />\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiButtonGroup.js","names":["_sfc_main"],"sources":["../../../../src/components/buttons/button-group/RuiButtonGroup.vue"],"sourcesContent":["<script lang=\"ts\" generic=\"T = undefined\" setup>\nimport type { ButtonSize } from '@/components/buttons/button/button-props';\nimport type { ContextColorsType } from '@/consts/colors';\nimport { type ButtonGroupContext, ButtonGroupKey } from '@/components/buttons/button-group/button-group-context';\nimport { cn, tv } from '@/utils/tv';\n\nexport interface Props {\n vertical?: boolean;\n color?: ContextColorsType;\n activeColor?: ContextColorsType;\n /**\n * `segmented` draws the options as `RuiTabs variant=\"segmented\"` does: a neutral track whose active\n * option is a raised surface. It is neutral, so it ignores `color` and `activeColor`.\n */\n variant?: 'default' | 'outlined' | 'text' | 'segmented';\n size?: ButtonSize;\n gap?: 'sm' | 'md' | 'lg';\n required?: boolean;\n disabled?: boolean;\n}\n\ndefineOptions({\n name: 'RuiButtonGroup',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<T | T[]>();\n\nconst {\n vertical = false,\n color,\n activeColor,\n variant = 'default',\n size,\n gap,\n required = false,\n disabled = false,\n} = defineProps<Props>();\n\ndefineSlots<{\n default?: () => any;\n}>();\n\nconst buttonGroupStyles = tv({\n slots: {\n /*\n * `w-fit`: a flex column stretches its children, inline-flex or not, which drew an outlined\n * group's frame across the whole row. A consumer's own width still wins through the class merge.\n * Between filled buttons a separator only needs to part the fills, so it takes the light divider.\n */\n root: 'inline-flex w-fit max-w-full rounded-rui-control between:border-l between:border-r-0 between:border-rui-divider outline-solid outline-1 outline-transparent -outline-offset-1',\n button: 'border-0 inset-ring-0 focus:z-1',\n },\n variants: {\n vertical: {\n true: {\n root: 'flex-col items-start between:border-l-0 between:border-t between:border-b-0 *:w-full',\n button: 'w-full',\n },\n false: {},\n },\n gap: {\n none: {\n button: 'rounded-none!',\n },\n sm: {\n root: 'between:border-0 outline-0 gap-2',\n button: 'inset-ring',\n },\n md: {\n root: 'between:border-0 outline-0 gap-4',\n button: 'inset-ring',\n },\n lg: {\n root: 'between:border-0 outline-0 gap-6',\n button: 'inset-ring',\n },\n },\n variant: {\n default: {},\n outlined: {\n // the control edge, matching RuiButton's colourless outlined treatment\n root: 'outline-rui-outline between:border-rui-outline',\n },\n text: {},\n // the segmented tabs' track and pill; the 32px options make a 36px control, a field's height\n segmented: {\n root: 'rounded-rui-panel bg-rui-neutral-200 p-0.5 gap-0.5 outline-0 between:border-0 dark:bg-rui-neutral-800',\n button: [\n 'h-8 px-3 text-rui-text-secondary transition-colors hover:text-rui-text focus-visible:-outline-offset-2',\n 'data-[active]:bg-rui-surface data-[active]:text-rui-text data-[active]:shadow-rui-control dark:data-[active]:bg-rui-neutral-700',\n ].join(' '),\n },\n },\n color: {\n primary: {},\n secondary: {},\n error: {},\n warning: {},\n info: {},\n success: {},\n },\n },\n compoundVariants: [\n /*\n * The outer corners go to the button that is, or sits inside, the group's first or last item, so a\n * button wrapped in a tooltip or a menu activator rounds like a direct child.\n */\n { gap: 'none', vertical: false, class: { button: '[&:is([data-button-group]>:first-child,[data-button-group]>:first-child_*)]:rounded-l-rui-control! [&:is([data-button-group]>:last-child,[data-button-group]>:last-child_*)]:rounded-r-rui-control!' } },\n { gap: 'none', vertical: true, class: { button: '[&:is([data-button-group]>:first-child,[data-button-group]>:first-child_*)]:rounded-t-rui-control! [&:is([data-button-group]>:last-child,[data-button-group]>:last-child_*)]:rounded-b-rui-control!' } },\n /*\n * In a joined group the focus outline's sides fall on the neighbours, and on a primary neighbour a\n * primary outline vanishes. A surface ring fills the outline's offset, so the raised segment's\n * ring is parted from its neighbours on every side.\n */\n { gap: 'none', variant: ['default', 'outlined', 'text'], class: { button: 'focus-visible:ring-2 focus-visible:ring-rui-surface' } },\n // each segment is its own rounded pill inside the track, not a slice of one joined bar\n { variant: 'segmented', class: { button: 'rounded-rui-control!' } },\n\n // Color dividers for outlined/text (overrides darker dividers above)\n { color: 'primary', variant: ['outlined', 'text'], class: { root: 'between:border-rui-primary/50' } },\n { color: 'secondary', variant: ['outlined', 'text'], class: { root: 'between:border-rui-secondary/50' } },\n { color: 'error', variant: ['outlined', 'text'], class: { root: 'between:border-rui-error/50' } },\n { color: 'warning', variant: ['outlined', 'text'], class: { root: 'between:border-rui-warning/50' } },\n { color: 'info', variant: ['outlined', 'text'], class: { root: 'between:border-rui-info/50' } },\n { color: 'success', variant: ['outlined', 'text'], class: { root: 'between:border-rui-success/50' } },\n\n // Color outline for outlined variant\n { color: 'primary', variant: 'outlined', class: { root: 'outline-rui-primary/50' } },\n { color: 'secondary', variant: 'outlined', class: { root: 'outline-rui-secondary/50' } },\n { color: 'error', variant: 'outlined', class: { root: 'outline-rui-error/50' } },\n { color: 'warning', variant: 'outlined', class: { root: 'outline-rui-warning/50' } },\n { color: 'info', variant: 'outlined', class: { root: 'outline-rui-info/50' } },\n { color: 'success', variant: 'outlined', class: { root: 'outline-rui-success/50' } },\n ],\n defaultVariants: {\n vertical: false,\n gap: 'none',\n variant: 'default',\n },\n});\n\nconst ui = computed<ReturnType<typeof buttonGroupStyles>>(() => buttonGroupStyles({\n vertical,\n gap: gap ?? 'none',\n variant,\n color,\n}));\n\n/**\n * The color a button takes: the pressed one's `activeColor` when set, otherwise the group's. The\n * segmented variant is neutral, like the segmented tabs, so its buttons take none.\n *\n * @param active - whether the button is the pressed one\n * @returns the color to set, or undefined to leave the button grey\n */\nfunction buttonColor(active: boolean): ContextColorsType | undefined {\n if (variant === 'segmented')\n return undefined;\n return active && activeColor ? activeColor : color;\n}\n\nfunction isActive(id: T, selected?: T | T[]): boolean {\n if (Array.isArray(selected))\n return selected.includes(id);\n\n return selected === id;\n}\n\nfunction onClick(id: T): void {\n const selected = get(modelValue);\n\n if (Array.isArray(selected)) {\n const index = selected.indexOf(id);\n if (index >= 0) {\n if (required && selected.length === 1)\n return;\n\n set(modelValue, selected.filter((_, i) => i !== index));\n }\n else {\n set(modelValue, [...selected, id]);\n }\n }\n else if (required) {\n set(modelValue, id);\n }\n else {\n set(modelValue, isActive(id, selected) ? undefined : id);\n }\n}\n\n// a button that sets its own size keeps it; the rest take the group's\nprovide(ButtonGroupKey, {\n variant: () => variant === 'segmented' ? 'text' : variant,\n size: () => size,\n disabled: () => disabled,\n color: buttonColor,\n itemClass: () => get(ui).button(),\n isActive: (value: T) => isActive(value, get(modelValue)),\n toggle: onClick,\n} satisfies ButtonGroupContext<T>);\n</script>\n\n<template>\n <div\n :class=\"ui.root({ class: cn($attrs.class) })\"\n data-button-group\n v-bind=\"{ ...$attrs, class: undefined }\"\n >\n <slot />\n </div>\n</template>\n"],"mappings":""}