@rotki/ui-library 2.27.0 → 3.0.0-beta.1

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 (391) hide show
  1. package/README.md +36 -15
  2. package/dist/components/accordions/accordion/RuiAccordion.js.map +1 -1
  3. package/dist/components/accordions/accordion/RuiAccordion.vue.d.ts +0 -4
  4. package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js +6 -7
  5. package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
  6. package/dist/components/accordions/accordions/RuiAccordions.js.map +1 -1
  7. package/dist/components/accordions/accordions/RuiAccordions.vue_vue_type_script_setup_true_lang.js +15 -2
  8. package/dist/components/accordions/accordions/RuiAccordions.vue_vue_type_script_setup_true_lang.js.map +1 -1
  9. package/dist/components/alerts/RuiAlert.js.map +1 -1
  10. package/dist/components/alerts/RuiAlert.vue_vue_type_script_setup_true_lang.js +43 -212
  11. package/dist/components/alerts/RuiAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
  12. package/dist/components/avatars/RuiAvatar.js.map +1 -1
  13. package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js +21 -31
  14. package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  15. package/dist/components/avatars/RuiAvatarGroup.js.map +1 -1
  16. package/dist/components/avatars/RuiAvatarGroup.vue.d.ts +6 -0
  17. package/dist/components/avatars/RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js +16 -12
  18. package/dist/components/avatars/RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  19. package/dist/components/avatars/avatar-props.d.ts +16 -3
  20. package/dist/components/avatars/avatar-props.js +42 -5
  21. package/dist/components/avatars/avatar-props.js.map +1 -1
  22. package/dist/components/buttons/button/RuiButton.js.map +1 -1
  23. package/dist/components/buttons/button/RuiButton.vue.d.ts +0 -1
  24. package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js +29 -16
  25. package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  26. package/dist/components/buttons/button/button-props.d.ts +0 -2
  27. package/dist/components/buttons/button/button-props.js +5 -5
  28. package/dist/components/buttons/button/button-props.js.map +1 -1
  29. package/dist/components/buttons/button/button-styles.d.ts +4 -1
  30. package/dist/components/buttons/button/button-styles.js +127 -54
  31. package/dist/components/buttons/button/button-styles.js.map +1 -1
  32. package/dist/components/buttons/button-group/RuiButtonGroup.js.map +1 -1
  33. package/dist/components/buttons/button-group/RuiButtonGroup.vue.d.ts +8 -2
  34. package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js +65 -96
  35. package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  36. package/dist/components/buttons/button-group/button-group-context.d.ts +28 -0
  37. package/dist/components/buttons/button-group/button-group-context.js +22 -0
  38. package/dist/components/buttons/button-group/button-group-context.js.map +1 -0
  39. package/dist/components/calendar/RuiCalendar.js.map +1 -1
  40. package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js +5 -2
  41. package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  42. package/dist/components/calendar/RuiCalendarGrid.js.map +1 -1
  43. package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js +11 -7
  44. package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
  45. package/dist/components/calendar/RuiCalendarHeader.js.map +1 -1
  46. package/dist/components/calendar/RuiCalendarHeader.vue_vue_type_script_setup_true_lang.js +20 -21
  47. package/dist/components/calendar/RuiCalendarHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  48. package/dist/components/calendar/RuiCalendarMenu.js.map +1 -1
  49. package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js +16 -20
  50. package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  51. package/dist/components/cards/RuiCard.js.map +1 -1
  52. package/dist/components/cards/RuiCard.vue.d.ts +0 -3
  53. package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js +31 -19
  54. package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  55. package/dist/components/cards/RuiCardHeader.js.map +1 -1
  56. package/dist/components/cards/RuiCardHeader.vue_vue_type_script_setup_true_lang.js +13 -25
  57. package/dist/components/cards/RuiCardHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  58. package/dist/components/chips/RuiChip.js.map +1 -1
  59. package/dist/components/chips/RuiChip.vue.d.ts +5 -2
  60. package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js +127 -78
  61. package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  62. package/dist/components/chips/chip-props.d.ts +2 -0
  63. package/dist/components/chips/chip-props.js +5 -3
  64. package/dist/components/chips/chip-props.js.map +1 -1
  65. package/dist/components/color-picker/RuiColorBoard.js.map +1 -1
  66. package/dist/components/color-picker/RuiColorBoard.vue_vue_type_script_setup_true_lang.js +4 -4
  67. package/dist/components/color-picker/RuiColorBoard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  68. package/dist/components/color-picker/RuiColorHue.js.map +1 -1
  69. package/dist/components/color-picker/RuiColorHue.vue_vue_type_script_setup_true_lang.js +1 -1
  70. package/dist/components/color-picker/RuiColorHue.vue_vue_type_script_setup_true_lang.js.map +1 -1
  71. package/dist/components/color-picker/RuiColorInput.js.map +1 -1
  72. package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js +38 -27
  73. package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  74. package/dist/components/color-picker/RuiColorPicker.js.map +1 -1
  75. package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js +1 -1
  76. package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  77. package/dist/components/date-time-picker/RuiDateTimePicker.js.map +1 -1
  78. package/dist/components/date-time-picker/RuiDateTimePicker.vue.d.ts +3 -2
  79. package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js +48 -47
  80. package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  81. package/dist/components/date-time-picker/RuiDateTimePickerMenu.js.map +1 -1
  82. package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js +2 -2
  83. package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  84. package/dist/components/date-time-picker/RuiTimezoneSelect.js.map +1 -1
  85. package/dist/components/date-time-picker/RuiTimezoneSelect.vue.d.ts +4 -3
  86. package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js +3 -3
  87. package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  88. package/dist/components/date-time-picker/date-time-picker-styles.d.ts +128 -219
  89. package/dist/components/date-time-picker/date-time-picker-styles.js +1 -2
  90. package/dist/components/date-time-picker/date-time-picker-styles.js.map +1 -1
  91. package/dist/components/forms/auto-complete/RuiAutoComplete.js.map +1 -1
  92. package/dist/components/forms/auto-complete/RuiAutoComplete.vue.d.ts +1 -68
  93. package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js +184 -179
  94. package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  95. package/dist/components/forms/auto-complete/RuiAutoCompleteOption.js.map +1 -1
  96. package/dist/components/forms/auto-complete/RuiAutoCompleteOption.vue_vue_type_script_setup_true_lang.js +1 -0
  97. package/dist/components/forms/auto-complete/RuiAutoCompleteOption.vue_vue_type_script_setup_true_lang.js.map +1 -1
  98. package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.js.map +1 -1
  99. package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.vue.d.ts +2 -0
  100. package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.vue_vue_type_script_setup_true_lang.js +8 -3
  101. package/dist/components/forms/auto-complete/RuiAutoCompleteOptionList.vue_vue_type_script_setup_true_lang.js.map +1 -1
  102. package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.js.map +1 -1
  103. package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.vue.d.ts +4 -0
  104. package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.vue_vue_type_script_setup_true_lang.js +24 -10
  105. package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.vue_vue_type_script_setup_true_lang.js.map +1 -1
  106. package/dist/components/forms/auto-complete/auto-complete-props.d.ts +66 -0
  107. package/dist/components/forms/auto-complete/auto-complete-styles.d.ts +128 -218
  108. package/dist/components/forms/auto-complete/auto-complete-styles.js +4 -2
  109. package/dist/components/forms/auto-complete/auto-complete-styles.js.map +1 -1
  110. package/dist/components/forms/category-picker/RuiCategoryPicker.js.map +1 -1
  111. package/dist/components/forms/category-picker/RuiCategoryPicker.vue.d.ts +3 -6
  112. package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js +105 -105
  113. package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  114. package/dist/components/forms/category-picker/category-picker-styles.d.ts +83 -232
  115. package/dist/components/forms/category-picker/category-picker-styles.js +20 -26
  116. package/dist/components/forms/category-picker/category-picker-styles.js.map +1 -1
  117. package/dist/components/forms/check-control-styles.d.ts +61 -2
  118. package/dist/components/forms/check-control-styles.js +53 -46
  119. package/dist/components/forms/check-control-styles.js.map +1 -1
  120. package/dist/components/forms/checkbox/RuiCheckbox.js.map +1 -1
  121. package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js +31 -18
  122. package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  123. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.js.map +1 -1
  124. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js +3 -3
  125. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  126. package/dist/components/forms/field-defaults/RuiFieldDefaults.js +7 -0
  127. package/dist/components/forms/field-defaults/RuiFieldDefaults.js.map +1 -0
  128. package/dist/components/forms/field-defaults/RuiFieldDefaults.vue.d.ts +16 -0
  129. package/dist/components/forms/field-defaults/RuiFieldDefaults.vue_vue_type_script_setup_true_lang.js +18 -0
  130. package/dist/components/forms/field-defaults/RuiFieldDefaults.vue_vue_type_script_setup_true_lang.js.map +1 -0
  131. package/dist/components/forms/field-label/RuiFieldLabel.js +7 -0
  132. package/dist/components/forms/field-label/RuiFieldLabel.js.map +1 -0
  133. package/dist/components/forms/field-label/RuiFieldLabel.vue.d.ts +17 -0
  134. package/dist/components/forms/field-label/RuiFieldLabel.vue_vue_type_script_setup_true_lang.js +57 -0
  135. package/dist/components/forms/field-label/RuiFieldLabel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  136. package/dist/components/forms/file-upload/RuiFileUpload.js.map +1 -1
  137. package/dist/components/forms/file-upload/RuiFileUpload.vue.d.ts +1 -1
  138. package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js +39 -20
  139. package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
  140. package/dist/components/forms/radio-button/radio/RuiRadio.js.map +1 -1
  141. package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js +13 -14
  142. package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
  143. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.js.map +1 -1
  144. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue_vue_type_script_setup_true_lang.js +3 -3
  145. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  146. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.js.map +1 -1
  147. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js +6 -6
  148. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  149. package/dist/components/forms/select/RuiMenuSelect.js.map +1 -1
  150. package/dist/components/forms/select/RuiMenuSelect.vue.d.ts +3 -12
  151. package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js +50 -45
  152. package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  153. package/dist/components/forms/select/RuiSimpleSelect.js.map +1 -1
  154. package/dist/components/forms/select/RuiSimpleSelect.vue.d.ts +0 -1
  155. package/dist/components/forms/select/RuiSimpleSelect.vue_vue_type_script_setup_true_lang.js +13 -20
  156. package/dist/components/forms/select/RuiSimpleSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  157. package/dist/components/forms/select/menu-select-styles.d.ts +99 -221
  158. package/dist/components/forms/select/menu-select-styles.js +1 -4
  159. package/dist/components/forms/select/menu-select-styles.js.map +1 -1
  160. package/dist/components/forms/slider/RuiSlider.js.map +1 -1
  161. package/dist/components/forms/slider/RuiSlider.vue.d.ts +0 -4
  162. package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js +113 -90
  163. package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  164. package/dist/components/forms/slider/slider-styles.d.ts +40 -40
  165. package/dist/components/forms/slider/slider-styles.js +67 -109
  166. package/dist/components/forms/slider/slider-styles.js.map +1 -1
  167. package/dist/components/forms/switch/RuiSwitch.js.map +1 -1
  168. package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js +32 -44
  169. package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  170. package/dist/components/forms/text-area/RuiTextArea.js.map +1 -1
  171. package/dist/components/forms/text-area/RuiTextArea.vue.d.ts +3 -2
  172. package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js +120 -99
  173. package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  174. package/dist/components/forms/text-area/text-area-styles.d.ts +41 -115
  175. package/dist/components/forms/text-area/text-area-styles.js +34 -194
  176. package/dist/components/forms/text-area/text-area-styles.js.map +1 -1
  177. package/dist/components/forms/text-field/RuiTextField.js.map +1 -1
  178. package/dist/components/forms/text-field/RuiTextField.vue.d.ts +3 -2
  179. package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js +93 -90
  180. package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  181. package/dist/components/forms/text-field/text-field-styles.d.ts +37 -145
  182. package/dist/components/forms/text-field/text-field-styles.js +24 -267
  183. package/dist/components/forms/text-field/text-field-styles.js.map +1 -1
  184. package/dist/components/forms/text-input-styles.d.ts +98 -229
  185. package/dist/components/forms/text-input-styles.js +63 -193
  186. package/dist/components/forms/text-input-styles.js.map +1 -1
  187. package/dist/components/helpers/RuiFormTextDetail.js.map +1 -1
  188. package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js +2 -2
  189. package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js.map +1 -1
  190. package/dist/components/icons/RuiIcon.js.map +1 -1
  191. package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js +6 -3
  192. package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  193. package/dist/components/index.d.ts +5 -3
  194. package/dist/components/index.js +4 -3
  195. package/dist/components/loaders/RuiSkeletonBase.js.map +1 -1
  196. package/dist/components/loaders/RuiSkeletonBase.vue_vue_type_script_setup_true_lang.js +6 -5
  197. package/dist/components/loaders/RuiSkeletonBase.vue_vue_type_script_setup_true_lang.js.map +1 -1
  198. package/dist/components/loaders/RuiSkeletonLoader.js.map +1 -1
  199. package/dist/components/loaders/RuiSkeletonLoader.vue_vue_type_script_setup_true_lang.js +8 -8
  200. package/dist/components/loaders/RuiSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  201. package/dist/components/logos/RuiLogo.js.map +1 -1
  202. package/dist/components/logos/RuiLogo.vue_vue_type_script_setup_true_lang.js +1 -1
  203. package/dist/components/logos/RuiLogo.vue_vue_type_script_setup_true_lang.js.map +1 -1
  204. package/dist/components/overlays/badge/RuiBadge.js.map +1 -1
  205. package/dist/components/overlays/badge/RuiBadge.vue_vue_type_script_setup_true_lang.js +75 -47
  206. package/dist/components/overlays/badge/RuiBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
  207. package/dist/components/overlays/dialog/RuiDialog.js.map +1 -1
  208. package/dist/components/overlays/dialog/RuiDialog.vue.d.ts +3 -2
  209. package/dist/components/overlays/dialog/RuiDialog.vue_vue_type_script_setup_true_lang.js +16 -12
  210. package/dist/components/overlays/dialog/RuiDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  211. package/dist/components/overlays/menu/RuiMenu.js.map +1 -1
  212. package/dist/components/overlays/menu/RuiMenu.vue.d.ts +9 -7
  213. package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js +16 -12
  214. package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  215. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.js.map +1 -1
  216. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue.d.ts +6 -2
  217. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js +40 -16
  218. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  219. package/dist/components/overlays/notification/RuiNotification.js.map +1 -1
  220. package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js +4 -4
  221. package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js.map +1 -1
  222. package/dist/components/overlays/tooltip/RuiTooltip.js.map +1 -1
  223. package/dist/components/overlays/tooltip/RuiTooltip.vue.d.ts +0 -5
  224. package/dist/components/overlays/tooltip/RuiTooltip.vue_vue_type_script_setup_true_lang.js +16 -10
  225. package/dist/components/overlays/tooltip/RuiTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  226. package/dist/components/overlays/tooltip/tooltip-styles.d.ts +5 -12
  227. package/dist/components/overlays/tooltip/tooltip-styles.js +11 -18
  228. package/dist/components/overlays/tooltip/tooltip-styles.js.map +1 -1
  229. package/dist/components/progress/RuiProgress.js.map +1 -1
  230. package/dist/components/progress/RuiProgress.vue.d.ts +4 -0
  231. package/dist/components/progress/RuiProgress.vue_vue_type_script_setup_true_lang.js +72 -46
  232. package/dist/components/progress/RuiProgress.vue_vue_type_script_setup_true_lang.js.map +1 -1
  233. package/dist/components/steppers/RuiFooterStepper.js.map +1 -1
  234. package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js +27 -28
  235. package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  236. package/dist/components/steppers/RuiStepper.js.map +1 -1
  237. package/dist/components/steppers/RuiStepper.vue.d.ts +0 -4
  238. package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js +25 -23
  239. package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  240. package/dist/components/steppers/RuiStepperIcon.js.map +1 -1
  241. package/dist/components/steppers/RuiStepperIcon.vue.d.ts +2 -0
  242. package/dist/components/steppers/RuiStepperIcon.vue_vue_type_script_setup_true_lang.js +47 -47
  243. package/dist/components/steppers/RuiStepperIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  244. package/dist/components/tables/RuiDataTable.js.map +1 -1
  245. package/dist/components/tables/RuiDataTable.vue.d.ts +3 -6
  246. package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js +65 -47
  247. package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  248. package/dist/components/tables/RuiExpandButton.js.map +1 -1
  249. package/dist/components/tables/RuiExpandButton.vue_vue_type_script_setup_true_lang.js +1 -0
  250. package/dist/components/tables/RuiExpandButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  251. package/dist/components/tables/RuiTable.js.map +1 -1
  252. package/dist/components/tables/RuiTable.vue_vue_type_script_setup_true_lang.js +8 -5
  253. package/dist/components/tables/RuiTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  254. package/dist/components/tables/RuiTableEmptyState.js.map +1 -1
  255. package/dist/components/tables/RuiTableEmptyState.vue_vue_type_script_setup_true_lang.js +1 -1
  256. package/dist/components/tables/RuiTableEmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
  257. package/dist/components/tables/RuiTableHead.js.map +1 -1
  258. package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js +88 -66
  259. package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js.map +1 -1
  260. package/dist/components/tables/RuiTablePagination.js.map +1 -1
  261. package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js +8 -11
  262. package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  263. package/dist/components/tables/data-table/RuiDataTableExpandedRow.js.map +1 -1
  264. package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js +3 -3
  265. package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  266. package/dist/components/tables/data-table/RuiDataTableGroupRow.js.map +1 -1
  267. package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js +7 -3
  268. package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  269. package/dist/components/tables/data-table/RuiDataTableMobileSort.js.map +1 -1
  270. package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js +1 -1
  271. package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js.map +1 -1
  272. package/dist/components/tables/data-table/RuiDataTableRow.js.map +1 -1
  273. package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js +58 -19
  274. package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  275. package/dist/components/tables/data-table-styles.d.ts +24 -0
  276. package/dist/components/tables/data-table-styles.js +35 -20
  277. package/dist/components/tables/data-table-styles.js.map +1 -1
  278. package/dist/components/tables/table_no_data_placeholder.js +1 -1
  279. package/dist/components/tables/table_no_data_placeholder.js.map +1 -1
  280. package/dist/components/tables/table_no_data_placeholder_dark.js +1 -1
  281. package/dist/components/tables/table_no_data_placeholder_dark.js.map +1 -1
  282. package/dist/components/tabs/tab/RuiTab.js.map +1 -1
  283. package/dist/components/tabs/tab/RuiTab.vue.d.ts +2 -5
  284. package/dist/components/tabs/tab/RuiTab.vue_vue_type_script_setup_true_lang.js +94 -68
  285. package/dist/components/tabs/tab/RuiTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
  286. package/dist/components/tabs/tab-item/RuiTabItem.js.map +1 -1
  287. package/dist/components/tabs/tab-item/RuiTabItem.vue.d.ts +0 -1
  288. package/dist/components/tabs/tab-item/RuiTabItem.vue_vue_type_script_setup_true_lang.js +5 -11
  289. package/dist/components/tabs/tab-item/RuiTabItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  290. package/dist/components/tabs/tab-items/RuiTabItems.js.map +1 -1
  291. package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js +3 -8
  292. package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js.map +1 -1
  293. package/dist/components/tabs/tab-props.d.ts +7 -1
  294. package/dist/components/tabs/tab-props.js +7 -1
  295. package/dist/components/tabs/tab-props.js.map +1 -1
  296. package/dist/components/tabs/tabs/RuiTabs.js.map +1 -1
  297. package/dist/components/tabs/tabs/RuiTabs.vue.d.ts +2 -1
  298. package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js +178 -32
  299. package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  300. package/dist/components/tabs/tabs/use-tab-indicator.d.ts +27 -0
  301. package/dist/components/tabs/tabs/use-tab-indicator.js +67 -0
  302. package/dist/components/tabs/tabs/use-tab-indicator.js.map +1 -0
  303. package/dist/components/tabs/tabs/use-tab-keyboard.d.ts +17 -0
  304. package/dist/components/tabs/tabs/use-tab-keyboard.js +57 -0
  305. package/dist/components/tabs/tabs/use-tab-keyboard.js.map +1 -0
  306. package/dist/components/tabs/tabs/use-tab-routing.js +1 -2
  307. package/dist/components/tabs/tabs/use-tab-routing.js.map +1 -1
  308. package/dist/components/time-picker/RuiTimePicker.js.map +1 -1
  309. package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js +35 -32
  310. package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  311. package/dist/components/time-picker/time-picker-styles.d.ts +18 -0
  312. package/dist/components/time-picker/time-picker-styles.js +16 -10
  313. package/dist/components/time-picker/time-picker-styles.js.map +1 -1
  314. package/dist/composables/defaults/field.d.ts +22 -0
  315. package/dist/composables/defaults/field.js +29 -0
  316. package/dist/composables/defaults/field.js.map +1 -0
  317. package/dist/composables/dropdown-menu.d.ts +14 -2
  318. package/dist/composables/dropdown-menu.js +12 -2
  319. package/dist/composables/dropdown-menu.js.map +1 -1
  320. package/dist/composables/floating.d.ts +0 -2
  321. package/dist/composables/floating.js +5 -2
  322. package/dist/composables/floating.js.map +1 -1
  323. package/dist/composables/forms/auto-complete/chips.d.ts +22 -0
  324. package/dist/composables/forms/auto-complete/chips.js +42 -0
  325. package/dist/composables/forms/auto-complete/chips.js.map +1 -0
  326. package/dist/composables/forms/auto-complete/combobox.d.ts +25 -0
  327. package/dist/composables/forms/auto-complete/combobox.js +35 -0
  328. package/dist/composables/forms/auto-complete/combobox.js.map +1 -0
  329. package/dist/composables/forms/auto-complete/focus.d.ts +5 -2
  330. package/dist/composables/forms/auto-complete/focus.js +36 -10
  331. package/dist/composables/forms/auto-complete/focus.js.map +1 -1
  332. package/dist/composables/forms/auto-complete/index.d.ts +3 -0
  333. package/dist/composables/forms/auto-complete/keyboard-navigation.d.ts +8 -1
  334. package/dist/composables/forms/auto-complete/keyboard-navigation.js +48 -20
  335. package/dist/composables/forms/auto-complete/keyboard-navigation.js.map +1 -1
  336. package/dist/composables/forms/auto-complete/selection.d.ts +37 -0
  337. package/dist/composables/forms/auto-complete/selection.js +60 -0
  338. package/dist/composables/forms/auto-complete/selection.js.map +1 -0
  339. package/dist/composables/forms/auto-complete/value.js +19 -0
  340. package/dist/composables/forms/auto-complete/value.js.map +1 -1
  341. package/dist/composables/keyboard-scroll.d.ts +17 -0
  342. package/dist/composables/keyboard-scroll.js +58 -0
  343. package/dist/composables/keyboard-scroll.js.map +1 -0
  344. package/dist/composables/sticky-header.d.ts +8 -0
  345. package/dist/composables/sticky-header.js +13 -2
  346. package/dist/composables/sticky-header.js.map +1 -1
  347. package/dist/composables/tables/data-table/page-scroll.d.ts +30 -0
  348. package/dist/composables/tables/data-table/page-scroll.js +113 -0
  349. package/dist/composables/tables/data-table/page-scroll.js.map +1 -0
  350. package/dist/consts/colors.d.ts +4 -0
  351. package/dist/consts/colors.js +1 -37
  352. package/dist/consts/colors.js.map +1 -1
  353. package/dist/consts/tokens.d.ts +56 -0
  354. package/dist/consts/tokens.js +46 -0
  355. package/dist/consts/tokens.js.map +1 -0
  356. package/dist/consts/typography.d.ts +51 -18
  357. package/dist/index.d.ts +5 -0
  358. package/dist/index.js +9 -5
  359. package/dist/index.js.map +1 -1
  360. package/dist/library-icons.json +0 -10
  361. package/dist/style.css +5644 -4677
  362. package/dist/styles/colors.css +315 -0
  363. package/dist/styles/tokens.css +50 -0
  364. package/dist/tailwind.css +145 -0
  365. package/dist/theme/theme.css +403 -0
  366. package/dist/theme.css +403 -0
  367. package/dist/utils/helpers.d.ts +0 -8
  368. package/dist/utils/helpers.js +0 -1
  369. package/dist/utils/helpers.js.map +1 -1
  370. package/dist/utils/tv.js +13 -21
  371. package/dist/utils/tv.js.map +1 -1
  372. package/dist/web-types.json +275 -407
  373. package/package.json +13 -16
  374. package/dist/components/icons/LazyIcon.vue.d.ts +0 -8
  375. package/dist/components/steppers/RuiStepperCustomIcon.js +0 -7
  376. package/dist/components/steppers/RuiStepperCustomIcon.js.map +0 -1
  377. package/dist/components/steppers/RuiStepperCustomIcon.vue.d.ts +0 -8
  378. package/dist/components/steppers/RuiStepperCustomIcon.vue_vue_type_script_setup_true_lang.js +0 -43
  379. package/dist/components/steppers/RuiStepperCustomIcon.vue_vue_type_script_setup_true_lang.js.map +0 -1
  380. package/dist/composables/colors/common.d.ts +0 -20
  381. package/dist/composables/colors/index.d.ts +0 -3
  382. package/dist/composables/colors/text-input.d.ts +0 -27
  383. package/dist/composables/forms/use-label-with-quote.d.ts +0 -2
  384. package/dist/composables/popper.d.ts +0 -16
  385. package/dist/composables/popper.js +0 -23
  386. package/dist/composables/popper.js.map +0 -1
  387. package/dist/consts/forms/auto-complete/index.d.ts +0 -4
  388. package/dist/theme/index.d.ts +0 -5
  389. package/dist/theme/index.js +0 -162
  390. package/dist/theme/index.js.map +0 -1
  391. package/dist/utils/forms/auto-complete/index.d.ts +0 -2
@@ -1,76 +1,83 @@
1
- import { type TextInputVariant } from '../text-input-styles.js';
2
- export type AutoCompleteVariant = TextInputVariant;
3
1
  /**
4
2
  * Overrides the `value` slot for flex-wrap chip layout.
5
3
  */
6
4
  export declare const autoCompleteStyles: import("tailwind-variants").TVReturnType<{
7
- filled: {
8
- true: {};
5
+ [key: string]: {
6
+ [key: string]: import("tailwind-variants").ClassValue | {
7
+ value?: import("tailwind-variants").ClassValue;
8
+ prepend?: import("tailwind-variants").ClassValue;
9
+ };
9
10
  };
10
- }, {
11
- value: string;
12
- }, undefined, {
11
+ } | {
13
12
  dense: {
14
- true: {
15
- activator: string;
13
+ true: import("tailwind-variants").ClassValue | {
14
+ value?: import("tailwind-variants").ClassValue;
15
+ prepend?: import("tailwind-variants").ClassValue;
16
16
  };
17
17
  };
18
18
  disabled: {
19
- true: {
20
- activator: string;
19
+ true: import("tailwind-variants").ClassValue | {
20
+ value?: import("tailwind-variants").ClassValue;
21
+ prepend?: import("tailwind-variants").ClassValue;
21
22
  };
22
23
  };
23
24
  readonly: {
24
- true: {
25
- activator: string;
25
+ true: import("tailwind-variants").ClassValue | {
26
+ value?: import("tailwind-variants").ClassValue;
27
+ prepend?: import("tailwind-variants").ClassValue;
26
28
  };
27
29
  };
28
- filled: {
29
- true: {
30
- activator: string;
30
+ hovered: {
31
+ true: import("tailwind-variants").ClassValue | {
32
+ value?: import("tailwind-variants").ClassValue;
33
+ prepend?: import("tailwind-variants").ClassValue;
31
34
  };
32
35
  };
33
- outlined: {
34
- true: {
35
- activator: string;
36
- label: string;
37
- fieldset: string;
38
- };
39
- false: {
40
- activator: string;
36
+ opened: {
37
+ true: import("tailwind-variants").ClassValue | {
38
+ value?: import("tailwind-variants").ClassValue;
39
+ prepend?: import("tailwind-variants").ClassValue;
41
40
  };
42
41
  };
43
- float: {
44
- true: {
45
- label: string;
42
+ hasError: {
43
+ true: import("tailwind-variants").ClassValue | {
44
+ value?: import("tailwind-variants").ClassValue;
45
+ prepend?: import("tailwind-variants").ClassValue;
46
46
  };
47
47
  };
48
- opened: {
49
- true: {
50
- icon: string;
48
+ hasSuccess: {
49
+ true: import("tailwind-variants").ClassValue | {
50
+ value?: import("tailwind-variants").ClassValue;
51
+ prepend?: import("tailwind-variants").ClassValue;
51
52
  };
52
53
  };
53
54
  active: {
54
- true: {
55
- highlighted: string;
55
+ true: import("tailwind-variants").ClassValue | {
56
+ value?: import("tailwind-variants").ClassValue;
57
+ prepend?: import("tailwind-variants").ClassValue;
56
58
  };
57
59
  };
58
- hasError: {
59
- true: {};
60
- };
61
- hasSuccess: {
62
- true: {};
63
- };
64
- hovered: {
65
- true: {};
60
+ }, {
61
+ value: string;
62
+ prepend: string;
63
+ }, undefined, {
64
+ dense: {
65
+ true: {
66
+ activator: string;
67
+ };
66
68
  };
67
- showLabel: {
68
- true: {};
69
+ disabled: {
70
+ true: {
71
+ activator: string;
72
+ icon: string;
73
+ fieldset: string;
74
+ };
69
75
  };
70
- } & {
71
- focused: {
76
+ readonly: {
72
77
  true: {
78
+ activator: string;
73
79
  fieldset: string;
80
+ iconWrapper: string;
74
81
  };
75
82
  };
76
83
  hovered: {
@@ -78,42 +85,31 @@ export declare const autoCompleteStyles: import("tailwind-variants").TVReturnTyp
78
85
  fieldset: string;
79
86
  };
80
87
  };
81
- disabled: {
88
+ opened: {
82
89
  true: {
90
+ icon: string;
83
91
  fieldset: string;
84
- label: string;
85
92
  };
86
93
  };
87
- active: {
88
- true: {};
89
- };
90
- showLabel: {
91
- true: {};
92
- };
93
- validation: {
94
- error: {
94
+ hasError: {
95
+ true: {
95
96
  fieldset: string;
96
- label: string;
97
97
  };
98
- success: {
98
+ };
99
+ hasSuccess: {
100
+ true: {
99
101
  fieldset: string;
100
- label: string;
101
102
  };
102
103
  };
103
- color: {
104
- primary: {};
105
- secondary: {};
106
- error: {};
107
- warning: {};
108
- info: {};
109
- success: {};
104
+ active: {
105
+ true: {
106
+ highlighted: string;
107
+ };
110
108
  };
111
109
  }, {
112
- fieldset: string;
113
- legend: string;
114
110
  wrapper: string;
115
111
  activator: string;
116
- label: string;
112
+ fieldset: string;
117
113
  value: string;
118
114
  clear: string;
119
115
  menu: string;
@@ -121,11 +117,6 @@ export declare const autoCompleteStyles: import("tailwind-variants").TVReturnTyp
121
117
  progress: string;
122
118
  icon: string;
123
119
  iconWrapper: string;
124
- required: string;
125
- } & {
126
- label: string;
127
- fieldset: string;
128
- legend: string;
129
120
  }, import("tailwind-variants").TVReturnType<{
130
121
  dense: {
131
122
  true: {
@@ -135,36 +126,36 @@ export declare const autoCompleteStyles: import("tailwind-variants").TVReturnTyp
135
126
  disabled: {
136
127
  true: {
137
128
  activator: string;
129
+ icon: string;
130
+ fieldset: string;
138
131
  };
139
132
  };
140
133
  readonly: {
141
134
  true: {
142
135
  activator: string;
136
+ fieldset: string;
137
+ iconWrapper: string;
143
138
  };
144
139
  };
145
- filled: {
140
+ hovered: {
146
141
  true: {
147
- activator: string;
142
+ fieldset: string;
148
143
  };
149
144
  };
150
- outlined: {
145
+ opened: {
151
146
  true: {
152
- activator: string;
153
- label: string;
147
+ icon: string;
154
148
  fieldset: string;
155
149
  };
156
- false: {
157
- activator: string;
158
- };
159
150
  };
160
- float: {
151
+ hasError: {
161
152
  true: {
162
- label: string;
153
+ fieldset: string;
163
154
  };
164
155
  };
165
- opened: {
156
+ hasSuccess: {
166
157
  true: {
167
- icon: string;
158
+ fieldset: string;
168
159
  };
169
160
  };
170
161
  active: {
@@ -172,24 +163,10 @@ export declare const autoCompleteStyles: import("tailwind-variants").TVReturnTyp
172
163
  highlighted: string;
173
164
  };
174
165
  };
175
- hasError: {
176
- true: {};
177
- };
178
- hasSuccess: {
179
- true: {};
180
- };
181
- hovered: {
182
- true: {};
183
- };
184
- showLabel: {
185
- true: {};
186
- };
187
166
  }, {
188
- fieldset: string;
189
- legend: string;
190
167
  wrapper: string;
191
168
  activator: string;
192
- label: string;
169
+ fieldset: string;
193
170
  value: string;
194
171
  clear: string;
195
172
  menu: string;
@@ -197,185 +174,118 @@ export declare const autoCompleteStyles: import("tailwind-variants").TVReturnTyp
197
174
  progress: string;
198
175
  icon: string;
199
176
  iconWrapper: string;
200
- required: string;
201
177
  }, undefined, {
202
- focused: {
178
+ dense: {
203
179
  true: {
204
- fieldset: string;
180
+ activator: string;
205
181
  };
206
182
  };
207
- hovered: {
183
+ disabled: {
208
184
  true: {
185
+ activator: string;
186
+ icon: string;
209
187
  fieldset: string;
210
188
  };
211
189
  };
212
- disabled: {
190
+ readonly: {
213
191
  true: {
192
+ activator: string;
214
193
  fieldset: string;
215
- label: string;
194
+ iconWrapper: string;
216
195
  };
217
196
  };
218
- active: {
219
- true: {};
220
- };
221
- showLabel: {
222
- true: {};
223
- };
224
- validation: {
225
- error: {
226
- fieldset: string;
227
- label: string;
228
- };
229
- success: {
197
+ hovered: {
198
+ true: {
230
199
  fieldset: string;
231
- label: string;
232
200
  };
233
201
  };
234
- color: {
235
- primary: {};
236
- secondary: {};
237
- error: {};
238
- warning: {};
239
- info: {};
240
- success: {};
241
- };
242
- }, {
243
- label: string;
244
- fieldset: string;
245
- legend: string;
246
- }, import("tailwind-variants").TVReturnType<{
247
- focused: {
202
+ opened: {
248
203
  true: {
204
+ icon: string;
249
205
  fieldset: string;
250
206
  };
251
207
  };
252
- hovered: {
208
+ hasError: {
253
209
  true: {
254
210
  fieldset: string;
255
211
  };
256
212
  };
257
- disabled: {
213
+ hasSuccess: {
258
214
  true: {
259
215
  fieldset: string;
260
- label: string;
261
216
  };
262
217
  };
263
218
  active: {
264
- true: {};
265
- };
266
- showLabel: {
267
- true: {};
268
- };
269
- validation: {
270
- error: {
271
- fieldset: string;
272
- label: string;
273
- };
274
- success: {
275
- fieldset: string;
276
- label: string;
219
+ true: {
220
+ highlighted: string;
277
221
  };
278
222
  };
279
- color: {
280
- primary: {};
281
- secondary: {};
282
- error: {};
283
- warning: {};
284
- info: {};
285
- success: {};
286
- };
287
223
  }, {
288
- label: string;
224
+ wrapper: string;
225
+ activator: string;
289
226
  fieldset: string;
290
- legend: string;
291
- }, undefined, {
292
- focused: {
227
+ value: string;
228
+ clear: string;
229
+ menu: string;
230
+ highlighted: string;
231
+ progress: string;
232
+ icon: string;
233
+ iconWrapper: string;
234
+ }, import("tailwind-variants").TVReturnTypeLike<{
235
+ dense: {
293
236
  true: {
294
- fieldset: string;
237
+ activator: string;
295
238
  };
296
239
  };
297
- hovered: {
240
+ disabled: {
298
241
  true: {
242
+ activator: string;
243
+ icon: string;
299
244
  fieldset: string;
300
245
  };
301
246
  };
302
- disabled: {
247
+ readonly: {
303
248
  true: {
249
+ activator: string;
304
250
  fieldset: string;
305
- label: string;
251
+ iconWrapper: string;
306
252
  };
307
253
  };
308
- active: {
309
- true: {};
310
- };
311
- showLabel: {
312
- true: {};
313
- };
314
- validation: {
315
- error: {
316
- fieldset: string;
317
- label: string;
318
- };
319
- success: {
254
+ hovered: {
255
+ true: {
320
256
  fieldset: string;
321
- label: string;
322
257
  };
323
258
  };
324
- color: {
325
- primary: {};
326
- secondary: {};
327
- error: {};
328
- warning: {};
329
- info: {};
330
- success: {};
331
- };
332
- }, {
333
- label: string;
334
- fieldset: string;
335
- legend: string;
336
- }, import("tailwind-variants").TVReturnTypeLike<{
337
- focused: {
259
+ opened: {
338
260
  true: {
261
+ icon: string;
339
262
  fieldset: string;
340
263
  };
341
264
  };
342
- hovered: {
265
+ hasError: {
343
266
  true: {
344
267
  fieldset: string;
345
268
  };
346
269
  };
347
- disabled: {
270
+ hasSuccess: {
348
271
  true: {
349
272
  fieldset: string;
350
- label: string;
351
273
  };
352
274
  };
353
275
  active: {
354
- true: {};
355
- };
356
- showLabel: {
357
- true: {};
358
- };
359
- validation: {
360
- error: {
361
- fieldset: string;
362
- label: string;
363
- };
364
- success: {
365
- fieldset: string;
366
- label: string;
276
+ true: {
277
+ highlighted: string;
367
278
  };
368
279
  };
369
- color: {
370
- primary: {};
371
- secondary: {};
372
- error: {};
373
- warning: {};
374
- info: {};
375
- success: {};
376
- };
377
280
  }, {
378
- label: string;
281
+ wrapper: string;
282
+ activator: string;
379
283
  fieldset: string;
380
- legend: string;
381
- }>>>>;
284
+ value: string;
285
+ clear: string;
286
+ menu: string;
287
+ highlighted: string;
288
+ progress: string;
289
+ icon: string;
290
+ iconWrapper: string;
291
+ }>>>;
@@ -6,8 +6,10 @@ import { activatorStyles } from "../text-input-styles.js";
6
6
  */
7
7
  var autoCompleteStyles = tv({
8
8
  extend: activatorStyles,
9
- slots: { value: "flex gap-1 flex-wrap flex-1 transition-all duration-75" },
10
- variants: { filled: { true: {} } }
9
+ slots: {
10
+ value: "flex gap-1 flex-wrap flex-1 transition-all duration-75",
11
+ prepend: "flex items-center shrink-0 me-2 text-rui-neutral-500 dark:text-rui-neutral-400"
12
+ }
11
13
  });
12
14
  //#endregion
13
15
  export { autoCompleteStyles };
@@ -1 +1 @@
1
- {"version":3,"file":"auto-complete-styles.js","names":[],"sources":["../../../../src/components/forms/auto-complete/auto-complete-styles.ts"],"sourcesContent":["import { activatorStyles, type TextInputVariant } from '@/components/forms/text-input-styles';\nimport { tv } from '@/utils/tv';\n\nexport type AutoCompleteVariant = TextInputVariant;\n\n/**\n * Overrides the `value` slot for flex-wrap chip layout.\n */\nexport const autoCompleteStyles = tv({\n extend: activatorStyles,\n slots: {\n value: 'flex gap-1 flex-wrap flex-1 transition-all duration-75',\n },\n variants: {\n // Re-declare for type inference — actual styles are in activatorStyles\n filled: { true: {} },\n },\n});\n"],"mappings":";;;;;;AAQA,IAAa,qBAAqB,GAAG;CACnC,QAAQ;CACR,OAAO,EACL,OAAO,yDACT;CACA,UAAU,EAER,QAAQ,EAAE,MAAM,CAAC,EAAE,EACrB;AACF,CAAC"}
1
+ {"version":3,"file":"auto-complete-styles.js","names":[],"sources":["../../../../src/components/forms/auto-complete/auto-complete-styles.ts"],"sourcesContent":["import { activatorStyles } from '@/components/forms/text-input-styles';\nimport { tv } from '@/utils/tv';\n\n/**\n * Overrides the `value` slot for flex-wrap chip layout.\n */\nexport const autoCompleteStyles = tv({\n extend: activatorStyles,\n slots: {\n value: 'flex gap-1 flex-wrap flex-1 transition-all duration-75',\n prepend: 'flex items-center shrink-0 me-2 text-rui-neutral-500 dark:text-rui-neutral-400',\n },\n});\n"],"mappings":";;;;;;AAMA,IAAa,qBAAqB,GAAG;CACnC,QAAQ;CACR,OAAO;EACL,OAAO;EACP,SAAS;CACX;AACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiCategoryPicker.js","names":[],"sources":["../../../../src/components/forms/category-picker/RuiCategoryPicker.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"TValue, TItem\">\nimport type { KeyOfType } from '@/composables/dropdown-menu';\nimport type { VueClassValue } from '@/types/class-value';\nimport { breakpointsTailwind, useBreakpoints } from '@vueuse/core';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport { categoryPickerActivatorStyles, categoryPickerStyles, type CategoryPickerVariant } from '@/components/forms/category-picker/category-picker-styles';\nimport RuiTextField from '@/components/forms/text-field/RuiTextField.vue';\nimport RuiFormTextDetail from '@/components/helpers/RuiFormTextDetail.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport RuiDialog, { type DialogProps } from '@/components/overlays/dialog/RuiDialog.vue';\nimport { activatorHandlers } from '@/components/overlays/menu/activator-handlers';\nimport RuiMenu from '@/components/overlays/menu/RuiMenu.vue';\nimport RuiProgress from '@/components/progress/RuiProgress.vue';\nimport { Placement } from '@/composables/floating';\nimport { useCategoryPicker } from '@/composables/forms/category-picker/use-category-picker';\nimport { useFormTextDetail } from '@/utils/form-text-detail';\nimport { cn } from '@/utils/tv';\n\nexport interface RuiCategoryPickerClassNames {\n root?: VueClassValue;\n rail?: VueClassValue;\n detail?: VueClassValue;\n search?: VueClassValue;\n}\n\nexport type CategoryPickerBreakpoint = 'sm' | 'md' | 'lg' | 'xl' | '2xl';\n\nexport interface RuiCategoryPickerProps<TValue, TItem> {\n /** The full catalogue of selectable items. */\n items: TItem[];\n /** Resolve an item's category label. Takes precedence over `categoryAttr`. */\n categoryOf?: (item: TItem) => string;\n /** Resolve an item's category from one of its own properties. */\n categoryAttr?: keyof TItem;\n /** Property whose value becomes the model value. Omit to use the item itself. */\n keyAttr?: KeyOfType<TItem, TValue extends (infer U)[] ? U : TValue>;\n /** Property that produces an item's display text. */\n textAttr?: keyof TItem;\n /** Field label, and the title of the mobile sheet. */\n label?: string;\n /** Placeholder shown in the field while it is empty or being searched. */\n placeholder?: string;\n /** Allow filtering: type in the field (desktop) or the sheet's search box (mobile). */\n searchable?: boolean;\n /**\n * Custom predicate. Receives the resolved category label as the third\n * argument, matching the `RuiAutoComplete` filter signature.\n */\n filter?: (item: TItem, query: string, category: string) => boolean;\n /** Show the synthetic \"All\" pseudo-category as the first rail entry. */\n showAll?: boolean;\n /** Label for the \"All\" pseudo-category. */\n allLabel?: string;\n /** Text shown when no item matches the current search. */\n emptyText?: string;\n disabled?: boolean;\n readOnly?: boolean;\n dense?: boolean;\n clearable?: boolean;\n loading?: boolean;\n /** Trigger field style: underline (`default`), `outlined`, or `filled`. */\n variant?: CategoryPickerVariant;\n /** Marks the trigger field as required (renders the asterisk). */\n required?: boolean;\n /** Validation errors rendered under the trigger field. */\n errorMessages?: string | string[];\n /** Success messages rendered under the trigger field. */\n successMessages?: string | string[];\n /** Hint rendered under the trigger field. */\n hint?: string;\n /** Hide the details row (errors/success/hint) under the trigger field. */\n hideDetails?: boolean;\n /** Below this breakpoint the picker collapses to a single-pane drill-in. */\n mobileBreakpoint?: CategoryPickerBreakpoint;\n /** Forwarded to the mobile bottom-sheet (`RuiDialog`). */\n dialogOptions?: DialogProps;\n classNames?: RuiCategoryPickerClassNames;\n}\n\ndefineOptions({\n name: 'RuiCategoryPicker',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<TValue>();\nconst searchInput = defineModel<string>('search', { default: '' });\n\nconst {\n items,\n categoryOf = undefined,\n categoryAttr = undefined,\n keyAttr = undefined,\n textAttr = undefined,\n label = 'Select',\n placeholder = 'Search',\n searchable = true,\n filter = undefined,\n showAll = true,\n allLabel = 'All',\n emptyText = 'No results',\n disabled = false,\n readOnly = false,\n dense = false,\n clearable = false,\n loading = false,\n variant = 'outlined',\n required = false,\n errorMessages = [],\n successMessages = [],\n hint = '',\n hideDetails = false,\n mobileBreakpoint = 'md',\n dialogOptions = undefined,\n classNames = undefined,\n} = defineProps<RuiCategoryPickerProps<TValue, TItem>>();\n\nconst emit = defineEmits<{\n select: [item: TItem];\n}>();\n\ndefineSlots<{\n 'activator'?: (props: { attrs: { onClick?: () => void; onMouseover?: () => void; onMouseleave?: () => void }; isOpen: boolean; open: () => void; item: TItem | undefined; text: string | undefined }) => any;\n 'activator.label'?: (props: { item: TItem | undefined }) => any;\n 'selection'?: (props: { item: TItem }) => any;\n 'selection.prepend'?: (props: { item: TItem }) => any;\n 'category'?: (props: { category: string | null; label: string; active: boolean; count: number }) => any;\n 'item'?: (props: { item: TItem; active: boolean; selected: boolean }) => any;\n 'item.prepend'?: (props: { item: TItem; active: boolean; selected: boolean }) => any;\n 'item.append'?: (props: { item: TItem; active: boolean; selected: boolean }) => any;\n 'empty'?: () => any;\n 'header'?: () => any;\n 'footer'?: (props: { close: () => void }) => any;\n}>();\n\nconst isOpen = ref<boolean>(false);\nconst focusedPane = ref<'rail' | 'detail'>('rail');\nconst highlightedItemIndex = ref<number>(0);\nconst drillStep = ref<'category' | 'detail'>('category');\n\nconst railRef = useTemplateRef<HTMLDivElement>('railRef');\nconst detailRef = useTemplateRef<HTMLDivElement>('detailRef');\nconst activatorRef = useTemplateRef<HTMLInputElement>('activatorRef');\nconst fieldRef = useTemplateRef<HTMLElement>('fieldRef');\nconst isHovered = ref<boolean>(false);\n\nconst { focused } = useFocus(activatorRef);\nconst { hasError, hasSuccess } = useFormTextDetail(() => errorMessages, () => successMessages);\n\nconst baseId = useId();\nconst breakpoints = useBreakpoints(breakpointsTailwind);\n\nfunction resolveCategory(item: TItem): string {\n if (categoryOf)\n return categoryOf(item);\n if (categoryAttr !== undefined)\n return String(item[categoryAttr] ?? '');\n return '';\n}\n\nconst {\n activeCategory,\n detailItems,\n detailRows,\n getIdentifier,\n getText,\n isEmpty,\n isSelected,\n railEntries,\n setActiveCategory,\n syncActiveToSelection,\n} = useCategoryPicker<TValue, TItem>({\n allLabel: () => allLabel,\n categoryOf: resolveCategory,\n filter: () => filter,\n items: () => items,\n keyAttr,\n modelValue,\n search: searchInput,\n searchable: () => searchable,\n showAll: () => showAll,\n textAttr,\n});\n\nconst isMobile = computed<boolean>(() => get(breakpoints.smaller(mobileBreakpoint)));\n\nconst mode = computed<'twoPane' | 'drill'>(() => (get(isMobile) ? 'drill' : 'twoPane'));\n\n/**\n * Desktop anchors an outside-click popover under the field (RuiMenu); narrow\n * width shows a full-width bottom sheet (RuiDialog).\n */\nconst shell = computed<typeof RuiMenu | typeof RuiDialog>(() => (get(isMobile) ? RuiDialog : RuiMenu));\n\n/**\n * The bottom sheet's props. Each shell is given only its own props, so the\n * other component's never leak through as attributes.\n */\nfunction dialogShellProps(): Record<string, unknown> {\n return {\n ariaLabel: dialogOptions?.ariaLabel ?? label,\n bottomSheet: dialogOptions?.bottomSheet ?? true,\n maxWidth: dialogOptions?.maxWidth,\n persistent: dialogOptions?.persistent,\n width: dialogOptions?.width ?? '100%',\n };\n}\n\n/**\n * The popover's props. It anchors to the field box rather than the wrapper, so\n * it sits directly under the input instead of below the reserved details row,\n * and drops the menu's default vertical padding so the popover box equals the\n * panel: the size middleware caps the panel to the available height, and any\n * extra chrome padding would push the popover past the viewport edge.\n */\nfunction menuShellProps(): Record<string, unknown> {\n return {\n anchorEl: get(fieldRef) ?? undefined,\n classNames: { content: 'py-0', menu: 'z-[9999]' },\n closeOnContentClick: false,\n disableAutoFocus: true,\n fullWidth: true,\n options: { placement: Placement.bottomStart, size: true },\n persistent: dialogOptions?.persistent,\n persistOnActivatorClick: true,\n };\n}\n\nconst shellProps = computed<Record<string, unknown>>(() =>\n get(isMobile) ? dialogShellProps() : menuShellProps());\n\nconst ui = computed<ReturnType<typeof categoryPickerStyles>>(() => categoryPickerStyles({\n dense,\n mode: get(mode),\n}));\n\nconst selectedItem = computed<TItem | undefined>(() => {\n const value = get(modelValue);\n if (value === undefined)\n return undefined;\n return items.find(item => getIdentifier(item) === value);\n});\n\nconst selectedText = computed<string | undefined>(() => {\n const selected = get(selectedItem);\n return selected ? getText(selected) : undefined;\n});\n\nconst outlined = computed<boolean>(() => variant === 'outlined');\n\n/**\n * Desktop lets the user type in the field itself (no separate search box);\n * narrow width keeps a read-only trigger that opens the sheet's own search.\n */\nconst canType = computed<boolean>(() => searchable && !get(isMobile) && !readOnly && !disabled);\n\nconst isTyping = computed<boolean>(() => get(isOpen) && get(canType));\n\nconst float = computed<boolean>(() => (get(isOpen) || get(selectedItem) !== undefined || get(focused)) && get(outlined));\n\nconst legendText = computed<string>(() => {\n if (!get(float) || !label)\n return '';\n return required ? `${label} ﹡` : label;\n});\n\n/**\n * Drives both the clear button itself and the room the selection overlay has\n * to leave for it, so the two can never disagree.\n */\nconst showClear = computed<boolean>(() =>\n clearable && get(selectedItem) !== undefined && !disabled && !readOnly);\n\nconst activatorUi = computed<ReturnType<typeof categoryPickerActivatorStyles>>(() => categoryPickerActivatorStyles({\n dense,\n disabled,\n filled: variant === 'filled',\n float: get(float),\n hasError: get(hasError),\n hasSuccess: get(hasSuccess) && !get(hasError),\n hovered: get(isHovered),\n opened: get(isOpen),\n outlined: get(outlined),\n readonly: readOnly,\n withClear: get(showClear),\n}));\n\nconst activeRailIndex = computed<number>(() =>\n get(railEntries).findIndex(entry => entry.category === get(activeCategory)));\n\nconst showRail = computed<boolean>(() => get(mode) === 'twoPane' || get(drillStep) === 'category');\nconst showDetail = computed<boolean>(() => get(mode) === 'twoPane' || get(drillStep) === 'detail');\n\nfunction clamp(value: number, max: number): number {\n if (value < 0)\n return 0;\n if (value > max)\n return max;\n return value;\n}\n\nfunction open(): void {\n if (disabled)\n return;\n set(isOpen, true);\n}\n\nfunction close(): void {\n set(isOpen, false);\n}\n\nfunction onInput(event: Event): void {\n const target = event.target;\n if (!(target instanceof HTMLInputElement))\n return;\n set(searchInput, target.value);\n if (!get(isOpen))\n open();\n}\n\nfunction selectItem(item: TItem): void {\n if (readOnly)\n return;\n set(modelValue, getIdentifier(item));\n emit('select', item);\n close();\n}\n\nfunction clearSelection(): void {\n set(modelValue, undefined);\n}\n\nfunction onCategoryClick(category: string | null): void {\n setActiveCategory(category);\n if (get(mode) === 'drill')\n set(drillStep, 'detail');\n else\n focusPane('detail');\n}\n\n/**\n * Moves focus to one of the panes. The focus call prevents scrolling because\n * the panes sit inside a teleported popover, and without it the browser\n * scrolls the page behind to reveal the pane.\n */\nfunction focusPane(pane: 'rail' | 'detail'): void {\n set(focusedPane, pane);\n nextTick(() => {\n (pane === 'rail' ? get(railRef) : get(detailRef))?.focus({ preventScroll: true });\n });\n}\n\nfunction moveRail(direction: 1 | -1): void {\n const entries = get(railEntries);\n if (entries.length === 0)\n return;\n const next = clamp(get(activeRailIndex) + direction, entries.length - 1);\n setActiveCategory(entries[next]?.category ?? null);\n}\n\nfunction moveItem(direction: 1 | -1): void {\n const total = get(detailItems).length;\n if (total === 0)\n return;\n set(highlightedItemIndex, clamp(get(highlightedItemIndex) + direction, total - 1));\n}\n\nfunction enterDetail(): void {\n if (get(detailItems).length === 0)\n return;\n resetHighlightToSelection();\n if (get(mode) === 'drill')\n set(drillStep, 'detail');\n focusPane('detail');\n}\n\nfunction selectHighlighted(): void {\n const item = get(detailItems)[get(highlightedItemIndex)];\n if (item !== undefined)\n selectItem(item);\n}\n\n/**\n * Enter from the field commits the best match for the current query, so a\n * type-to-pick flow (type a few letters, press Enter) works without leaving\n * the input. Does nothing when the field is empty.\n */\nfunction selectTopResult(): void {\n if (!get(searchInput).trim())\n return;\n const item = get(detailItems)[0];\n if (item !== undefined)\n selectItem(item);\n}\n\nfunction resetHighlightToSelection(): void {\n const index = get(detailItems).findIndex(item => isSelected(item));\n set(highlightedItemIndex, index >= 0 ? index : 0);\n}\n\nfunction backToRail(): void {\n if (get(mode) === 'drill')\n set(drillStep, 'category');\n else\n focusPane('rail');\n}\n\nfunction scrollActiveDescendantIntoView(container: HTMLElement | null, id: string): void {\n if (!container)\n return;\n nextTick(() => {\n container.querySelector(`#${id}`)?.scrollIntoView({ block: 'nearest' });\n });\n}\n\n// Reset the item highlight whenever the active category changes.\nwatch(activeCategory, () => {\n resetHighlightToSelection();\n});\n\nwatch(highlightedItemIndex, (index) => {\n scrollActiveDescendantIntoView(get(detailRef), `${baseId}-opt-${index}`);\n});\n\nwatch(activeRailIndex, (index) => {\n if (index >= 0)\n scrollActiveDescendantIntoView(get(railRef), `${baseId}-cat-${index}`);\n});\n\n/**\n * Opening takes focus where the user types next: desktop is a combobox, so\n * focus stays in the field and ArrowDown moves into the panes, while the\n * mobile sheet has no typing field and focuses the rail instead. Closing\n * resets the query, so the field shows the selection again next time, and\n * returns focus to the trigger, which the APG dialog contract asks for.\n */\nfunction onOpenChanged(value: boolean): void {\n if (value) {\n syncActiveToSelection();\n set(focusedPane, 'rail');\n set(drillStep, 'category');\n resetHighlightToSelection();\n nextTick(() => (get(canType) ? get(activatorRef) : get(railRef))?.focus({ preventScroll: true }));\n }\n else {\n set(searchInput, '');\n nextTick(() => get(activatorRef)?.focus({ preventScroll: true }));\n }\n}\n\nwatch(isOpen, onOpenChanged);\n</script>\n\n<template>\n <component\n :is=\"shell\"\n v-model=\"isOpen\"\n v-bind=\"{ ...$attrs, ...shellProps }\"\n >\n <template #activator=\"{ attrs }\">\n <slot\n name=\"activator\"\n v-bind=\"{ attrs, isOpen, item: selectedItem, open, text: selectedText }\"\n >\n <div :class=\"activatorUi.wrapper()\">\n <div\n ref=\"fieldRef\"\n role=\"combobox\"\n data-id=\"activator\"\n :class=\"activatorUi.activator()\"\n aria-haspopup=\"dialog\"\n :aria-controls=\"isOpen ? `${baseId}-panel` : undefined\"\n :aria-expanded=\"isOpen\"\n :aria-disabled=\"disabled || undefined\"\n :aria-readonly=\"(readOnly || !canType) || undefined\"\n :aria-required=\"required || undefined\"\n :aria-invalid=\"hasError || undefined\"\n :aria-busy=\"loading || undefined\"\n v-bind=\"readOnly ? {} : activatorHandlers(attrs)\"\n @mouseenter=\"isHovered = true\"\n @mouseleave=\"isHovered = false\"\n >\n <span\n v-if=\"outlined || (!selectedItem && !isTyping)\"\n :class=\"activatorUi.label()\"\n >\n <slot\n name=\"activator.label\"\n v-bind=\"{ item: selectedItem }\"\n >\n {{ label }}\n </slot>\n <span\n v-if=\"required\"\n :class=\"activatorUi.required()\"\n >\n ﹡\n </span>\n </span>\n <span\n v-if=\"selectedItem && !isTyping && $slots.selection\"\n data-id=\"selection\"\n :class=\"activatorUi.selection()\"\n >\n <slot\n name=\"selection.prepend\"\n v-bind=\"{ item: selectedItem }\"\n />\n <slot\n name=\"selection\"\n v-bind=\"{ item: selectedItem }\"\n />\n </span>\n <input\n ref=\"activatorRef\"\n data-id=\"search-input\"\n :value=\"isTyping ? searchInput : (($slots.selection && selectedItem) ? '' : (selectedText ?? ''))\"\n :placeholder=\"isTyping ? placeholder : ''\"\n :readonly=\"!canType\"\n :disabled=\"disabled\"\n :aria-invalid=\"hasError || undefined\"\n class=\"bg-transparent outline-none\"\n :class=\"[activatorUi.value(), !canType && 'cursor-pointer']\"\n @input=\"onInput($event)\"\n @keydown.down.prevent=\"focusPane('rail')\"\n @keydown.enter.prevent=\"selectTopResult()\"\n @keydown.esc=\"close()\"\n />\n <span\n v-if=\"showClear\"\n data-id=\"clear\"\n :class=\"[activatorUi.clear(), focused && '!visible', { 'mr-2': !dense }]\"\n @click.stop.prevent=\"clearSelection()\"\n >\n <RuiIcon\n color=\"error\"\n name=\"lu-x\"\n size=\"18\"\n />\n </span>\n <span\n data-id=\"chevron\"\n :class=\"activatorUi.iconWrapper()\"\n >\n <RuiIcon\n :class=\"activatorUi.icon()\"\n :size=\"dense ? 16 : 24\"\n name=\"lu-chevron-down\"\n />\n </span>\n <RuiProgress\n v-if=\"loading\"\n :class=\"activatorUi.progress()\"\n color=\"primary\"\n thickness=\"3\"\n variant=\"indeterminate\"\n />\n <fieldset\n v-if=\"outlined\"\n :class=\"activatorUi.fieldset()\"\n >\n <legend :class=\"activatorUi.legend()\">\n {{ legendText }}\n </legend>\n </fieldset>\n </div>\n <RuiFormTextDetail\n v-if=\"!hideDetails\"\n class=\"px-3 pt-1\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n />\n </div>\n </slot>\n </template>\n\n <div\n :id=\"`${baseId}-panel`\"\n :class=\"ui.root({ class: cn(classNames?.root) })\"\n data-id=\"panel\"\n >\n <!-- On desktop the field itself is the search input, so the panel only\n needs its own search box in the mobile sheet. -->\n <div\n v-if=\"isMobile || $slots.header\"\n :class=\"ui.header()\"\n >\n <slot name=\"header\">\n <div :class=\"ui.title()\">\n {{ label }}\n </div>\n </slot>\n <RuiTextField\n v-if=\"searchable && isMobile\"\n v-model=\"searchInput\"\n :class=\"cn(classNames?.search)\"\n :placeholder=\"placeholder\"\n :dense=\"dense\"\n variant=\"outlined\"\n prepend-icon=\"lu-search\"\n hide-details\n clearable\n data-id=\"search\"\n />\n </div>\n\n <div :class=\"ui.body()\">\n <!-- Category rail (master) -->\n <div\n v-show=\"showRail\"\n ref=\"railRef\"\n :class=\"ui.rail({ class: cn(classNames?.rail) })\"\n role=\"tablist\"\n aria-orientation=\"vertical\"\n :aria-label=\"label\"\n :aria-activedescendant=\"focusedPane === 'rail' && activeRailIndex >= 0 ? `${baseId}-cat-${activeRailIndex}` : undefined\"\n tabindex=\"0\"\n data-id=\"rail\"\n @focus=\"focusedPane = 'rail'\"\n @keydown.down.prevent=\"moveRail(1)\"\n @keydown.up.prevent=\"moveRail(-1)\"\n @keydown.right.prevent=\"enterDetail()\"\n @keydown.enter.prevent=\"enterDetail()\"\n @keydown.home.prevent=\"setActiveCategory(railEntries[0]?.category ?? null)\"\n @keydown.end.prevent=\"setActiveCategory(railEntries[railEntries.length - 1]?.category ?? null)\"\n >\n <RuiButton\n v-for=\"(entry, index) in railEntries\"\n :id=\"`${baseId}-cat-${index}`\"\n :key=\"entry.category ?? '__all__'\"\n role=\"tab\"\n variant=\"list\"\n :size=\"dense ? 'sm' : undefined\"\n :active=\"entry.category === activeCategory\"\n :aria-selected=\"entry.category === activeCategory\"\n tabindex=\"-1\"\n :data-highlighted=\"focusedPane === 'rail' && index === activeRailIndex\"\n :data-category=\"entry.category ?? '__all__'\"\n @click=\"onCategoryClick(entry.category)\"\n >\n <slot\n name=\"category\"\n v-bind=\"{ active: entry.category === activeCategory, category: entry.category, count: entry.count, label: entry.label }\"\n >\n <span class=\"truncate\">{{ entry.label }}</span>\n <span :class=\"ui.railCount()\">{{ entry.count }}</span>\n </slot>\n </RuiButton>\n </div>\n\n <!-- Detail pane -->\n <div\n v-show=\"showDetail\"\n ref=\"detailRef\"\n :class=\"ui.detail({ class: cn(classNames?.detail) })\"\n role=\"listbox\"\n :aria-label=\"activeCategory ?? allLabel\"\n :aria-activedescendant=\"focusedPane === 'detail' && !isEmpty ? `${baseId}-opt-${highlightedItemIndex}` : undefined\"\n tabindex=\"0\"\n data-id=\"detail\"\n @focus=\"focusedPane = 'detail'\"\n @keydown.down.prevent=\"moveItem(1)\"\n @keydown.up.prevent=\"moveItem(-1)\"\n @keydown.left.prevent=\"backToRail()\"\n @keydown.home.prevent=\"highlightedItemIndex = 0\"\n @keydown.end.prevent=\"highlightedItemIndex = detailItems.length - 1\"\n @keydown.enter.prevent=\"selectHighlighted()\"\n @keydown.space.prevent=\"selectHighlighted()\"\n >\n <template v-if=\"mode === 'drill' && showDetail\">\n <button\n type=\"button\"\n :class=\"ui.backButton()\"\n data-id=\"back\"\n @click=\"backToRail()\"\n >\n <RuiIcon\n name=\"lu-chevron-left\"\n size=\"18\"\n />\n <span>{{ activeCategory ?? allLabel }}</span>\n </button>\n </template>\n\n <slot\n v-if=\"isEmpty\"\n name=\"empty\"\n >\n <div :class=\"ui.empty()\">\n {{ emptyText }}\n </div>\n </slot>\n\n <template\n v-for=\"row in detailRows\"\n v-else\n :key=\"row.type === 'header' ? `h-${row.category}` : `i-${row.index}`\"\n >\n <div\n v-if=\"row.type === 'header'\"\n :class=\"ui.subheader()\"\n role=\"presentation\"\n >\n {{ row.category }}\n </div>\n <RuiButton\n v-else\n :id=\"`${baseId}-opt-${row.index}`\"\n role=\"option\"\n variant=\"list\"\n :size=\"dense ? 'sm' : undefined\"\n :active=\"isSelected(row.item)\"\n :aria-selected=\"isSelected(row.item)\"\n tabindex=\"-1\"\n :data-highlighted=\"focusedPane === 'detail' && row.index === highlightedItemIndex\"\n :class=\"{ [ui.highlighted()]: focusedPane === 'detail' && row.index === highlightedItemIndex && !isSelected(row.item) }\"\n @click=\"selectItem(row.item)\"\n >\n <template\n v-if=\"$slots['item.prepend']\"\n #prepend\n >\n <slot\n name=\"item.prepend\"\n v-bind=\"{ active: row.index === highlightedItemIndex, item: row.item, selected: isSelected(row.item) }\"\n />\n </template>\n <slot\n name=\"item\"\n v-bind=\"{ active: row.index === highlightedItemIndex, item: row.item, selected: isSelected(row.item) }\"\n >\n {{ getText(row.item) }}\n </slot>\n <template\n v-if=\"$slots['item.append']\"\n #append\n >\n <slot\n name=\"item.append\"\n v-bind=\"{ active: row.index === highlightedItemIndex, item: row.item, selected: isSelected(row.item) }\"\n />\n </template>\n </RuiButton>\n </template>\n </div>\n </div>\n\n <div\n v-if=\"$slots.footer\"\n :class=\"ui.footer()\"\n >\n <slot\n name=\"footer\"\n v-bind=\"{ close }\"\n />\n </div>\n </div>\n </component>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiCategoryPicker.js","names":[],"sources":["../../../../src/components/forms/category-picker/RuiCategoryPicker.vue"],"sourcesContent":["<script lang=\"ts\" setup generic=\"TValue, TItem\">\nimport type { KeyOfType } from '@/composables/dropdown-menu';\nimport type { VueClassValue } from '@/types/class-value';\nimport { breakpointsTailwind, useBreakpoints } from '@vueuse/core';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport { categoryPickerActivatorStyles, categoryPickerStyles } from '@/components/forms/category-picker/category-picker-styles';\nimport RuiFieldLabel from '@/components/forms/field-label/RuiFieldLabel.vue';\nimport RuiTextField from '@/components/forms/text-field/RuiTextField.vue';\nimport RuiFormTextDetail from '@/components/helpers/RuiFormTextDetail.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport RuiDialog, { type DialogProps } from '@/components/overlays/dialog/RuiDialog.vue';\nimport { activatorHandlers } from '@/components/overlays/menu/activator-handlers';\nimport RuiMenu from '@/components/overlays/menu/RuiMenu.vue';\nimport RuiProgress from '@/components/progress/RuiProgress.vue';\nimport { type LabelPlacement, useLabelPlacement } from '@/composables/defaults/field';\nimport { Placement } from '@/composables/floating';\nimport { useCategoryPicker } from '@/composables/forms/category-picker/use-category-picker';\nimport { useFormTextDetail } from '@/utils/form-text-detail';\nimport { cn } from '@/utils/tv';\n\nexport interface RuiCategoryPickerClassNames {\n root?: VueClassValue;\n rail?: VueClassValue;\n detail?: VueClassValue;\n search?: VueClassValue;\n}\n\nexport type CategoryPickerBreakpoint = 'sm' | 'md' | 'lg' | 'xl' | '2xl';\n\nexport interface RuiCategoryPickerProps<TValue, TItem> {\n /** The full catalogue of selectable items. */\n items: TItem[];\n /** Resolve an item's category label. Takes precedence over `categoryAttr`. */\n categoryOf?: (item: TItem) => string;\n /** Resolve an item's category from one of its own properties. */\n categoryAttr?: keyof TItem;\n /** Property whose value becomes the model value. Omit to use the item itself. */\n keyAttr?: KeyOfType<TItem, TValue extends (infer U)[] ? U : TValue>;\n /** Property that produces an item's display text. */\n textAttr?: keyof TItem;\n /** Field label, and the title of the mobile sheet. */\n label?: string;\n /** Placeholder shown in the field while it is empty or being searched. */\n placeholder?: string;\n /** Allow filtering: type in the field (desktop) or the sheet's search box (mobile). */\n searchable?: boolean;\n /**\n * Custom predicate. Receives the resolved category label as the third\n * argument, matching the `RuiAutoComplete` filter signature.\n */\n filter?: (item: TItem, query: string, category: string) => boolean;\n /** Show the synthetic \"All\" pseudo-category as the first rail entry. */\n showAll?: boolean;\n /** Label for the \"All\" pseudo-category. */\n allLabel?: string;\n /** Text shown when no item matches the current search. */\n emptyText?: string;\n disabled?: boolean;\n readOnly?: boolean;\n dense?: boolean;\n clearable?: boolean;\n loading?: boolean;\n /** Where the label shows; falls back to the nearest `RuiFieldDefaults`, then the app default, then `top`. */\n labelPlacement?: LabelPlacement;\n /** Marks the trigger field as required (renders the asterisk). */\n required?: boolean;\n /** Validation errors rendered under the trigger field. */\n errorMessages?: string | string[];\n /** Success messages rendered under the trigger field. */\n successMessages?: string | string[];\n /** Hint rendered under the trigger field. */\n hint?: string;\n /** Hide the details row (errors/success/hint) under the trigger field. */\n hideDetails?: boolean;\n /** Below this breakpoint the picker collapses to a single-pane drill-in. */\n mobileBreakpoint?: CategoryPickerBreakpoint;\n /** Forwarded to the mobile bottom-sheet (`RuiDialog`). */\n dialogOptions?: DialogProps;\n classNames?: RuiCategoryPickerClassNames;\n}\n\ndefineOptions({\n name: 'RuiCategoryPicker',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<TValue>();\nconst searchInput = defineModel<string>('search', { default: '' });\n\nconst {\n items,\n categoryOf = undefined,\n categoryAttr = undefined,\n keyAttr = undefined,\n textAttr = undefined,\n label = 'Select',\n placeholder = 'Search',\n searchable = true,\n filter = undefined,\n showAll = true,\n allLabel = 'All',\n emptyText = 'No results',\n disabled = false,\n readOnly = false,\n dense = false,\n clearable = false,\n loading = false,\n labelPlacement = undefined,\n required = false,\n errorMessages = [],\n successMessages = [],\n hint = '',\n hideDetails = false,\n mobileBreakpoint = 'md',\n dialogOptions = undefined,\n classNames = undefined,\n} = defineProps<RuiCategoryPickerProps<TValue, TItem>>();\n\nconst emit = defineEmits<{\n select: [item: TItem];\n}>();\n\ndefineSlots<{\n 'activator'?: (props: { attrs: { onClick?: () => void; onMouseover?: () => void; onMouseleave?: () => void }; isOpen: boolean; open: () => void; item: TItem | undefined; text: string | undefined }) => any;\n 'selection'?: (props: { item: TItem }) => any;\n 'selection.prepend'?: (props: { item: TItem }) => any;\n 'category'?: (props: { category: string | null; label: string; active: boolean; count: number }) => any;\n 'item'?: (props: { item: TItem; active: boolean; selected: boolean }) => any;\n 'item.prepend'?: (props: { item: TItem; active: boolean; selected: boolean }) => any;\n 'item.append'?: (props: { item: TItem; active: boolean; selected: boolean }) => any;\n 'empty'?: () => any;\n 'header'?: () => any;\n 'footer'?: (props: { close: () => void }) => any;\n}>();\n\nconst isOpen = ref<boolean>(false);\nconst focusedPane = ref<'rail' | 'detail'>('rail');\nconst highlightedItemIndex = ref<number>(0);\nconst drillStep = ref<'category' | 'detail'>('category');\n\nconst railRef = useTemplateRef<HTMLDivElement>('railRef');\nconst detailRef = useTemplateRef<HTMLDivElement>('detailRef');\nconst activatorRef = useTemplateRef<HTMLInputElement>('activatorRef');\nconst fieldRef = useTemplateRef<HTMLElement>('fieldRef');\nconst isHovered = ref<boolean>(false);\n\nconst { focused } = useFocus(activatorRef);\nconst { hasError, hasSuccess } = useFormTextDetail(() => errorMessages, () => successMessages);\n\nconst baseId = useId();\nconst breakpoints = useBreakpoints(breakpointsTailwind);\n\nfunction resolveCategory(item: TItem): string {\n if (categoryOf)\n return categoryOf(item);\n if (categoryAttr !== undefined)\n return String(item[categoryAttr] ?? '');\n return '';\n}\n\nconst {\n activeCategory,\n detailItems,\n detailRows,\n getIdentifier,\n getText,\n isEmpty,\n isSelected,\n railEntries,\n setActiveCategory,\n syncActiveToSelection,\n} = useCategoryPicker<TValue, TItem>({\n allLabel: () => allLabel,\n categoryOf: resolveCategory,\n filter: () => filter,\n items: () => items,\n keyAttr,\n modelValue,\n search: searchInput,\n searchable: () => searchable,\n showAll: () => showAll,\n textAttr,\n});\n\nconst isMobile = computed<boolean>(() => get(breakpoints.smaller(mobileBreakpoint)));\n\nconst mode = computed<'twoPane' | 'drill'>(() => (get(isMobile) ? 'drill' : 'twoPane'));\n\n/**\n * Desktop anchors an outside-click popover under the field (RuiMenu); narrow\n * width shows a full-width bottom sheet (RuiDialog).\n */\nconst shell = computed<typeof RuiMenu | typeof RuiDialog>(() => (get(isMobile) ? RuiDialog : RuiMenu));\n\n/**\n * The bottom sheet's props. Each shell is given only its own props, so the\n * other component's never leak through as attributes.\n */\nfunction dialogShellProps(): Record<string, unknown> {\n return {\n ariaLabel: dialogOptions?.ariaLabel ?? label,\n bottomSheet: dialogOptions?.bottomSheet ?? true,\n maxWidth: dialogOptions?.maxWidth,\n persistent: dialogOptions?.persistent,\n width: dialogOptions?.width ?? '100%',\n };\n}\n\n/**\n * The popover's props. It anchors to the field box rather than the wrapper, so\n * it sits directly under the input instead of below the reserved details row,\n * and drops the menu's default vertical padding so the popover box equals the\n * panel: the size middleware caps the panel to the available height, and any\n * extra chrome padding would push the popover past the viewport edge.\n */\nfunction menuShellProps(): Record<string, unknown> {\n return {\n anchorEl: get(fieldRef) ?? undefined,\n classNames: { content: 'py-0' },\n closeOnContentClick: false,\n disableAutoFocus: true,\n fullWidth: true,\n options: { placement: Placement.bottomStart, size: true },\n persistent: dialogOptions?.persistent,\n persistOnActivatorClick: true,\n };\n}\n\nconst shellProps = computed<Record<string, unknown>>(() =>\n get(isMobile) ? dialogShellProps() : menuShellProps());\n\nconst ui = computed<ReturnType<typeof categoryPickerStyles>>(() => categoryPickerStyles({\n dense,\n mode: get(mode),\n}));\n\nconst selectedItem = computed<TItem | undefined>(() => {\n const value = get(modelValue);\n if (value === undefined)\n return undefined;\n return items.find(item => getIdentifier(item) === value);\n});\n\nconst selectedText = computed<string | undefined>(() => {\n const selected = get(selectedItem);\n return selected ? getText(selected) : undefined;\n});\n\nconst placement = useLabelPlacement(() => labelPlacement);\n\n/**\n * Desktop lets the user type in the field itself (no separate search box);\n * narrow width keeps a read-only trigger that opens the sheet's own search.\n */\nconst canType = computed<boolean>(() => searchable && !get(isMobile) && !readOnly && !disabled);\n\nconst isTyping = computed<boolean>(() => get(isOpen) && get(canType));\n\n/**\n * Drives both the clear button itself and the room the selection overlay has\n * to leave for it, so the two can never disagree.\n */\nconst showClear = computed<boolean>(() =>\n clearable && get(selectedItem) !== undefined && !disabled && !readOnly);\n\nconst activatorUi = computed<ReturnType<typeof categoryPickerActivatorStyles>>(() => categoryPickerActivatorStyles({\n dense,\n disabled,\n hasError: get(hasError),\n hasSuccess: get(hasSuccess) && !get(hasError),\n hovered: get(isHovered),\n opened: get(isOpen),\n readonly: readOnly,\n withClear: get(showClear),\n}));\n\nconst activeRailIndex = computed<number>(() =>\n get(railEntries).findIndex(entry => entry.category === get(activeCategory)));\n\nconst showRail = computed<boolean>(() => get(mode) === 'twoPane' || get(drillStep) === 'category');\nconst showDetail = computed<boolean>(() => get(mode) === 'twoPane' || get(drillStep) === 'detail');\n\nfunction clamp(value: number, max: number): number {\n if (value < 0)\n return 0;\n if (value > max)\n return max;\n return value;\n}\n\nfunction open(): void {\n if (disabled)\n return;\n set(isOpen, true);\n}\n\nfunction close(): void {\n set(isOpen, false);\n}\n\nfunction onInput(event: Event): void {\n const target = event.target;\n if (!(target instanceof HTMLInputElement))\n return;\n set(searchInput, target.value);\n if (!get(isOpen))\n open();\n}\n\nfunction selectItem(item: TItem): void {\n if (readOnly)\n return;\n set(modelValue, getIdentifier(item));\n emit('select', item);\n close();\n}\n\nfunction clearSelection(): void {\n set(modelValue, undefined);\n}\n\nfunction onCategoryClick(category: string | null): void {\n setActiveCategory(category);\n if (get(mode) === 'drill')\n set(drillStep, 'detail');\n else\n focusPane('detail');\n}\n\n/**\n * Moves focus to one of the panes. The focus call prevents scrolling because\n * the panes sit inside a teleported popover, and without it the browser\n * scrolls the page behind to reveal the pane.\n */\nfunction focusPane(pane: 'rail' | 'detail'): void {\n set(focusedPane, pane);\n nextTick(() => {\n (pane === 'rail' ? get(railRef) : get(detailRef))?.focus({ preventScroll: true });\n });\n}\n\nfunction moveRail(direction: 1 | -1): void {\n const entries = get(railEntries);\n if (entries.length === 0)\n return;\n const next = clamp(get(activeRailIndex) + direction, entries.length - 1);\n setActiveCategory(entries[next]?.category ?? null);\n}\n\nfunction moveItem(direction: 1 | -1): void {\n const total = get(detailItems).length;\n if (total === 0)\n return;\n set(highlightedItemIndex, clamp(get(highlightedItemIndex) + direction, total - 1));\n}\n\nfunction enterDetail(): void {\n if (get(detailItems).length === 0)\n return;\n resetHighlightToSelection();\n if (get(mode) === 'drill')\n set(drillStep, 'detail');\n focusPane('detail');\n}\n\nfunction selectHighlighted(): void {\n const item = get(detailItems)[get(highlightedItemIndex)];\n if (item !== undefined)\n selectItem(item);\n}\n\n/**\n * Enter from the field commits the best match for the current query, so a\n * type-to-pick flow (type a few letters, press Enter) works without leaving\n * the input. Does nothing when the field is empty.\n */\nfunction selectTopResult(): void {\n if (!get(searchInput).trim())\n return;\n const item = get(detailItems)[0];\n if (item !== undefined)\n selectItem(item);\n}\n\nfunction resetHighlightToSelection(): void {\n const index = get(detailItems).findIndex(item => isSelected(item));\n set(highlightedItemIndex, index >= 0 ? index : 0);\n}\n\nfunction backToRail(): void {\n if (get(mode) === 'drill')\n set(drillStep, 'category');\n else\n focusPane('rail');\n}\n\nfunction scrollActiveDescendantIntoView(container: HTMLElement | null, id: string): void {\n if (!container)\n return;\n nextTick(() => {\n container.querySelector(`#${id}`)?.scrollIntoView({ block: 'nearest' });\n });\n}\n\n// Reset the item highlight whenever the active category changes.\nwatch(activeCategory, () => {\n resetHighlightToSelection();\n});\n\nwatch(highlightedItemIndex, (index) => {\n scrollActiveDescendantIntoView(get(detailRef), `${baseId}-opt-${index}`);\n});\n\nwatch(activeRailIndex, (index) => {\n if (index >= 0)\n scrollActiveDescendantIntoView(get(railRef), `${baseId}-cat-${index}`);\n});\n\n/**\n * Opening takes focus where the user types next: desktop is a combobox, so\n * focus stays in the field and ArrowDown moves into the panes, while the\n * mobile sheet has no typing field and focuses the rail instead. Closing\n * resets the query, so the field shows the selection again next time, and\n * returns focus to the trigger, which the APG dialog contract asks for.\n */\nfunction onOpenChanged(value: boolean): void {\n if (value) {\n syncActiveToSelection();\n set(focusedPane, 'rail');\n set(drillStep, 'category');\n resetHighlightToSelection();\n nextTick(() => (get(canType) ? get(activatorRef) : get(railRef))?.focus({ preventScroll: true }));\n }\n else {\n set(searchInput, '');\n nextTick(() => get(activatorRef)?.focus({ preventScroll: true }));\n }\n}\n\nwatch(isOpen, onOpenChanged);\n</script>\n\n<template>\n <component\n :is=\"shell\"\n v-model=\"isOpen\"\n v-bind=\"{ ...$attrs, ...shellProps }\"\n >\n <template #activator=\"{ attrs }\">\n <slot\n name=\"activator\"\n v-bind=\"{ attrs, isOpen, item: selectedItem, open, text: selectedText }\"\n >\n <div :class=\"activatorUi.wrapper()\">\n <RuiFieldLabel\n v-if=\"label\"\n :id=\"`${baseId}-label`\"\n :text=\"label\"\n :hidden=\"placement === 'hidden'\"\n :required=\"required\"\n :disabled=\"disabled\"\n />\n <div\n ref=\"fieldRef\"\n role=\"combobox\"\n data-id=\"activator\"\n :class=\"activatorUi.activator()\"\n :aria-labelledby=\"label ? `${baseId}-label` : undefined\"\n aria-haspopup=\"dialog\"\n :aria-controls=\"isOpen ? `${baseId}-panel` : undefined\"\n :aria-expanded=\"isOpen\"\n :aria-disabled=\"disabled || undefined\"\n :aria-readonly=\"(readOnly || !canType) || undefined\"\n :aria-required=\"required || undefined\"\n :aria-invalid=\"hasError || undefined\"\n :aria-busy=\"loading || undefined\"\n v-bind=\"readOnly ? {} : activatorHandlers(attrs)\"\n @mouseenter=\"isHovered = true\"\n @mouseleave=\"isHovered = false\"\n >\n <span\n v-if=\"selectedItem && !isTyping && $slots.selection\"\n data-id=\"selection\"\n :class=\"activatorUi.selection()\"\n >\n <slot\n name=\"selection.prepend\"\n v-bind=\"{ item: selectedItem }\"\n />\n <slot\n name=\"selection\"\n v-bind=\"{ item: selectedItem }\"\n />\n </span>\n <input\n ref=\"activatorRef\"\n data-id=\"search-input\"\n :value=\"isTyping ? searchInput : (($slots.selection && selectedItem) ? '' : (selectedText ?? ''))\"\n :placeholder=\"isTyping ? placeholder : ''\"\n :readonly=\"!canType\"\n :disabled=\"disabled\"\n :aria-invalid=\"hasError || undefined\"\n :aria-labelledby=\"label ? `${baseId}-label` : undefined\"\n class=\"bg-transparent outline-hidden\"\n :class=\"[activatorUi.value(), !canType && 'cursor-pointer']\"\n @input=\"onInput($event)\"\n @keydown.down.prevent=\"focusPane('rail')\"\n @keydown.enter.prevent=\"selectTopResult()\"\n @keydown.esc=\"close()\"\n />\n <span\n v-if=\"showClear\"\n data-id=\"clear\"\n :class=\"[activatorUi.clear(), focused && 'visible!', { 'mr-2': !dense }]\"\n @click.stop.prevent=\"clearSelection()\"\n >\n <RuiIcon\n name=\"lu-x\"\n size=\"16\"\n />\n </span>\n <span\n data-id=\"chevron\"\n :class=\"activatorUi.iconWrapper()\"\n >\n <RuiIcon\n :class=\"activatorUi.icon()\"\n :size=\"dense ? 16 : 20\"\n name=\"lu-chevron-down\"\n />\n </span>\n <RuiProgress\n v-if=\"loading\"\n :class=\"activatorUi.progress()\"\n color=\"primary\"\n thickness=\"3\"\n variant=\"indeterminate\"\n />\n <fieldset :class=\"activatorUi.fieldset()\" />\n </div>\n <RuiFormTextDetail\n v-if=\"!hideDetails\"\n class=\"pt-1\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hint=\"hint\"\n />\n </div>\n </slot>\n </template>\n\n <div\n :id=\"`${baseId}-panel`\"\n :class=\"ui.root({ class: cn(classNames?.root) })\"\n data-id=\"panel\"\n >\n <!-- On desktop the field itself is the search input, so the panel only\n needs its own search box in the mobile sheet. -->\n <div\n v-if=\"isMobile || $slots.header\"\n :class=\"ui.header()\"\n >\n <slot name=\"header\">\n <div :class=\"ui.title()\">\n {{ label }}\n </div>\n </slot>\n <RuiTextField\n v-if=\"searchable && isMobile\"\n v-model=\"searchInput\"\n :class=\"cn(classNames?.search)\"\n :placeholder=\"placeholder\"\n :dense=\"dense\"\n prepend-icon=\"lu-search\"\n hide-details\n clearable\n data-id=\"search\"\n />\n </div>\n\n <div :class=\"ui.body()\">\n <!-- Category rail (master) -->\n <div\n v-show=\"showRail\"\n ref=\"railRef\"\n :class=\"ui.rail({ class: cn(classNames?.rail) })\"\n role=\"tablist\"\n aria-orientation=\"vertical\"\n :aria-label=\"label\"\n :aria-activedescendant=\"focusedPane === 'rail' && activeRailIndex >= 0 ? `${baseId}-cat-${activeRailIndex}` : undefined\"\n tabindex=\"0\"\n data-id=\"rail\"\n @focus=\"focusedPane = 'rail'\"\n @keydown.down.prevent=\"moveRail(1)\"\n @keydown.up.prevent=\"moveRail(-1)\"\n @keydown.right.prevent=\"enterDetail()\"\n @keydown.enter.prevent=\"enterDetail()\"\n @keydown.home.prevent=\"setActiveCategory(railEntries[0]?.category ?? null)\"\n @keydown.end.prevent=\"setActiveCategory(railEntries[railEntries.length - 1]?.category ?? null)\"\n >\n <RuiButton\n v-for=\"(entry, index) in railEntries\"\n :id=\"`${baseId}-cat-${index}`\"\n :key=\"entry.category ?? '__all__'\"\n role=\"tab\"\n variant=\"list\"\n :size=\"dense ? 'sm' : undefined\"\n :active=\"entry.category === activeCategory\"\n :aria-selected=\"entry.category === activeCategory\"\n tabindex=\"-1\"\n :data-highlighted=\"focusedPane === 'rail' && index === activeRailIndex\"\n :data-category=\"entry.category ?? '__all__'\"\n @click=\"onCategoryClick(entry.category)\"\n >\n <slot\n name=\"category\"\n v-bind=\"{ active: entry.category === activeCategory, category: entry.category, count: entry.count, label: entry.label }\"\n >\n <span class=\"truncate\">{{ entry.label }}</span>\n <span :class=\"ui.railCount()\">{{ entry.count }}</span>\n </slot>\n </RuiButton>\n </div>\n\n <!-- Detail pane -->\n <div\n v-show=\"showDetail\"\n ref=\"detailRef\"\n :class=\"ui.detail({ class: cn(classNames?.detail) })\"\n role=\"listbox\"\n :aria-label=\"activeCategory ?? allLabel\"\n :aria-activedescendant=\"focusedPane === 'detail' && !isEmpty ? `${baseId}-opt-${highlightedItemIndex}` : undefined\"\n tabindex=\"0\"\n data-id=\"detail\"\n @focus=\"focusedPane = 'detail'\"\n @keydown.down.prevent=\"moveItem(1)\"\n @keydown.up.prevent=\"moveItem(-1)\"\n @keydown.left.prevent=\"backToRail()\"\n @keydown.home.prevent=\"highlightedItemIndex = 0\"\n @keydown.end.prevent=\"highlightedItemIndex = detailItems.length - 1\"\n @keydown.enter.prevent=\"selectHighlighted()\"\n @keydown.space.prevent=\"selectHighlighted()\"\n >\n <template v-if=\"mode === 'drill' && showDetail\">\n <button\n type=\"button\"\n :class=\"ui.backButton()\"\n data-id=\"back\"\n @click=\"backToRail()\"\n >\n <RuiIcon\n name=\"lu-chevron-left\"\n size=\"18\"\n />\n <span>{{ activeCategory ?? allLabel }}</span>\n </button>\n </template>\n\n <slot\n v-if=\"isEmpty\"\n name=\"empty\"\n >\n <div :class=\"ui.empty()\">\n {{ emptyText }}\n </div>\n </slot>\n\n <template\n v-for=\"row in detailRows\"\n v-else\n :key=\"row.type === 'header' ? `h-${row.category}` : `i-${row.index}`\"\n >\n <div\n v-if=\"row.type === 'header'\"\n :class=\"ui.subheader()\"\n role=\"presentation\"\n >\n {{ row.category }}\n </div>\n <RuiButton\n v-else\n :id=\"`${baseId}-opt-${row.index}`\"\n role=\"option\"\n variant=\"list\"\n :size=\"dense ? 'sm' : undefined\"\n :active=\"isSelected(row.item)\"\n :aria-selected=\"isSelected(row.item)\"\n tabindex=\"-1\"\n :data-highlighted=\"focusedPane === 'detail' && row.index === highlightedItemIndex\"\n :class=\"{ [ui.highlighted()]: focusedPane === 'detail' && row.index === highlightedItemIndex && !isSelected(row.item) }\"\n @click=\"selectItem(row.item)\"\n >\n <template\n v-if=\"$slots['item.prepend']\"\n #prepend\n >\n <slot\n name=\"item.prepend\"\n v-bind=\"{ active: row.index === highlightedItemIndex, item: row.item, selected: isSelected(row.item) }\"\n />\n </template>\n <slot\n name=\"item\"\n v-bind=\"{ active: row.index === highlightedItemIndex, item: row.item, selected: isSelected(row.item) }\"\n >\n {{ getText(row.item) }}\n </slot>\n <template\n v-if=\"$slots['item.append']\"\n #append\n >\n <slot\n name=\"item.append\"\n v-bind=\"{ active: row.index === highlightedItemIndex, item: row.item, selected: isSelected(row.item) }\"\n />\n </template>\n </RuiButton>\n </template>\n </div>\n </div>\n\n <div\n v-if=\"$slots.footer\"\n :class=\"ui.footer()\"\n >\n <slot\n name=\"footer\"\n v-bind=\"{ close }\"\n />\n </div>\n </div>\n </component>\n</template>\n"],"mappings":""}