@rotki/ui-library 2.21.0 → 2.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (321) hide show
  1. package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js +1 -1
  2. package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
  3. package/dist/components/accordions/accordions/RuiAccordions.vue_vue_type_script_setup_true_lang.js +2 -2
  4. package/dist/components/accordions/accordions/RuiAccordions.vue_vue_type_script_setup_true_lang.js.map +1 -1
  5. package/dist/components/alerts/RuiAlert.vue_vue_type_script_setup_true_lang.js +1 -1
  6. package/dist/components/alerts/RuiAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
  7. package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js +1 -1
  8. package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  9. package/dist/components/avatars/RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js +1 -1
  10. package/dist/components/avatars/RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  11. package/dist/components/avatars/avatar-props.js +1 -1
  12. package/dist/components/avatars/avatar-props.js.map +1 -1
  13. package/dist/components/avatars/use-avatar-group.js.map +1 -1
  14. package/dist/components/buttons/button/RuiButton.js.map +1 -1
  15. package/dist/components/buttons/button/RuiButton.vue.d.ts +2 -2
  16. package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js +3 -3
  17. package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  18. package/dist/components/buttons/button/button-props.js.map +1 -1
  19. package/dist/components/buttons/button/button-styles.js.map +1 -1
  20. package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js +2 -2
  21. package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  22. package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js +3 -3
  23. package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  24. package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js +2 -2
  25. package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
  26. package/dist/components/calendar/RuiCalendarHeader.vue_vue_type_script_setup_true_lang.js +3 -3
  27. package/dist/components/calendar/RuiCalendarHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  28. package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js +3 -3
  29. package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  30. package/dist/components/calendar/state.js.map +1 -1
  31. package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js +1 -1
  32. package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  33. package/dist/components/cards/RuiCardHeader.vue_vue_type_script_setup_true_lang.js +1 -1
  34. package/dist/components/cards/RuiCardHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  35. package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js +1 -1
  36. package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  37. package/dist/components/chips/chip-props.js.map +1 -1
  38. package/dist/components/color-picker/RuiColorBoard.vue_vue_type_script_setup_true_lang.js +1 -1
  39. package/dist/components/color-picker/RuiColorBoard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  40. package/dist/components/color-picker/RuiColorDisplay.vue_vue_type_script_setup_true_lang.js +1 -1
  41. package/dist/components/color-picker/RuiColorDisplay.vue_vue_type_script_setup_true_lang.js.map +1 -1
  42. package/dist/components/color-picker/RuiColorHue.vue_vue_type_script_setup_true_lang.js +1 -1
  43. package/dist/components/color-picker/RuiColorHue.vue_vue_type_script_setup_true_lang.js.map +1 -1
  44. package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js +1 -1
  45. package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  46. package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js +1 -1
  47. package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  48. package/dist/components/color-picker/utils.js.map +1 -1
  49. package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js +2 -2
  50. package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  51. package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js +3 -3
  52. package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  53. package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js +2 -2
  54. package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  55. package/dist/components/date-time-picker/date-time-picker-styles.js.map +1 -1
  56. package/dist/components/date-time-picker/dayjs-setup.js.map +1 -1
  57. package/dist/components/date-time-picker/segment-config.js.map +1 -1
  58. package/dist/components/date-time-picker/segment-utils.js.map +1 -1
  59. package/dist/components/date-time-picker/timezones.js.map +1 -1
  60. package/dist/components/date-time-picker/types.js +1 -1
  61. package/dist/components/date-time-picker/types.js.map +1 -1
  62. package/dist/components/date-time-picker/use-date-time-selection.js +2 -2
  63. package/dist/components/date-time-picker/use-date-time-selection.js.map +1 -1
  64. package/dist/components/date-time-picker/use-input-handler.js.map +1 -1
  65. package/dist/components/date-time-picker/use-keyboard-handler.js.map +1 -1
  66. package/dist/components/date-time-picker/utils.js.map +1 -1
  67. package/dist/components/divider/RuiDivider.vue_vue_type_script_setup_true_lang.js +1 -1
  68. package/dist/components/divider/RuiDivider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  69. package/dist/components/forms/auto-complete/RuiAutoComplete.js.map +1 -1
  70. package/dist/components/forms/auto-complete/RuiAutoComplete.vue.d.ts +14 -1
  71. package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js +15 -5
  72. package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  73. package/dist/components/forms/auto-complete/auto-complete-styles.js.map +1 -1
  74. package/dist/components/forms/category-picker/RuiCategoryPicker.js +7 -0
  75. package/dist/components/forms/category-picker/RuiCategoryPicker.js.map +1 -0
  76. package/dist/components/forms/category-picker/RuiCategoryPicker.vue.d.ts +134 -0
  77. package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js +561 -0
  78. package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  79. package/dist/components/forms/category-picker/category-picker-styles.d.ts +432 -0
  80. package/dist/components/forms/category-picker/category-picker-styles.js +59 -0
  81. package/dist/components/forms/category-picker/category-picker-styles.js.map +1 -0
  82. package/dist/components/forms/check-control-styles.js.map +1 -1
  83. package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js +2 -2
  84. package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  85. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js +2 -2
  86. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  87. package/dist/components/forms/checkbox/checkbox-group/context.js.map +1 -1
  88. package/dist/components/forms/file-upload/RuiFileUpload.js.map +1 -1
  89. package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js +5 -5
  90. package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
  91. package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js +2 -2
  92. package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
  93. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue_vue_type_script_setup_true_lang.js +2 -2
  94. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  95. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js +2 -2
  96. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  97. package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js +2 -2
  98. package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  99. package/dist/components/forms/select/RuiSimpleSelect.vue_vue_type_script_setup_true_lang.js +2 -2
  100. package/dist/components/forms/select/RuiSimpleSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  101. package/dist/components/forms/select/menu-select-styles.js.map +1 -1
  102. package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js +2 -2
  103. package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  104. package/dist/components/forms/slider/slider-styles.js.map +1 -1
  105. package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js +2 -2
  106. package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  107. package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js +3 -3
  108. package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  109. package/dist/components/forms/text-area/text-area-styles.js.map +1 -1
  110. package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js +3 -3
  111. package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  112. package/dist/components/forms/text-field/text-field-styles.js.map +1 -1
  113. package/dist/components/forms/text-input-styles.js.map +1 -1
  114. package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js +1 -1
  115. package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js.map +1 -1
  116. package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js +1 -1
  117. package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  118. package/dist/components/index.d.ts +3 -2
  119. package/dist/components/index.js +3 -2
  120. package/dist/components/loaders/RuiSkeletonBase.vue_vue_type_script_setup_true_lang.js +1 -1
  121. package/dist/components/loaders/RuiSkeletonBase.vue_vue_type_script_setup_true_lang.js.map +1 -1
  122. package/dist/components/loaders/RuiSkeletonLoader.vue_vue_type_script_setup_true_lang.js +1 -1
  123. package/dist/components/loaders/RuiSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  124. package/dist/components/loaders/skeleton-type.js.map +1 -1
  125. package/dist/components/logos/RuiLogo.vue_vue_type_script_setup_true_lang.js +1 -1
  126. package/dist/components/logos/RuiLogo.vue_vue_type_script_setup_true_lang.js.map +1 -1
  127. package/dist/components/logos/use-logo-sources.js.map +1 -1
  128. package/dist/components/overlays/badge/RuiBadge.vue_vue_type_script_setup_true_lang.js +1 -1
  129. package/dist/components/overlays/badge/RuiBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
  130. package/dist/components/overlays/badge/badge-props.js.map +1 -1
  131. package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue_vue_type_script_setup_true_lang.js +2 -2
  132. package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue_vue_type_script_setup_true_lang.js.map +1 -1
  133. package/dist/components/overlays/dialog/RuiDialog.vue_vue_type_script_setup_true_lang.js +3 -3
  134. package/dist/components/overlays/dialog/RuiDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  135. package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js +2 -2
  136. package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  137. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js +3 -3
  138. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  139. package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js +2 -2
  140. package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js.map +1 -1
  141. package/dist/components/overlays/tooltip/RuiTooltip.vue_vue_type_script_setup_true_lang.js +1 -1
  142. package/dist/components/overlays/tooltip/RuiTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  143. package/dist/components/overlays/tooltip/tooltip-styles.js.map +1 -1
  144. package/dist/components/progress/RuiProgress.vue_vue_type_script_setup_true_lang.js +1 -1
  145. package/dist/components/progress/RuiProgress.vue_vue_type_script_setup_true_lang.js.map +1 -1
  146. package/dist/components/progress/progress-props.js.map +1 -1
  147. package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js +2 -2
  148. package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  149. package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js +1 -1
  150. package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  151. package/dist/components/steppers/RuiStepperCustomIcon.vue_vue_type_script_setup_true_lang.js +1 -1
  152. package/dist/components/steppers/RuiStepperCustomIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  153. package/dist/components/steppers/RuiStepperIcon.vue_vue_type_script_setup_true_lang.js +1 -1
  154. package/dist/components/steppers/RuiStepperIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
  155. package/dist/components/steppers/footer-stepper-variant.js.map +1 -1
  156. package/dist/components/tables/RuiDataTable.js.map +1 -1
  157. package/dist/components/tables/RuiDataTable.vue.d.ts +23 -2
  158. package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js +186 -217
  159. package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  160. package/dist/components/tables/RuiExpandButton.vue_vue_type_script_setup_true_lang.js +1 -1
  161. package/dist/components/tables/RuiExpandButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  162. package/dist/components/tables/RuiTableEmptyState.vue_vue_type_script_setup_true_lang.js +1 -1
  163. package/dist/components/tables/RuiTableEmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
  164. package/dist/components/tables/RuiTableHead.js.map +1 -1
  165. package/dist/components/tables/RuiTableHead.vue.d.ts +11 -1
  166. package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js +1 -2
  167. package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js.map +1 -1
  168. package/dist/components/tables/RuiTablePagination.js.map +1 -1
  169. package/dist/components/tables/RuiTablePagination.vue.d.ts +5 -0
  170. package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js +24 -8
  171. package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  172. package/dist/components/tables/data-table/RuiDataTableBody.js +7 -0
  173. package/dist/components/tables/data-table/RuiDataTableBody.js.map +1 -0
  174. package/dist/components/tables/data-table/RuiDataTableBody.vue.d.ts +55 -0
  175. package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js +78 -0
  176. package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js.map +1 -0
  177. package/dist/components/tables/data-table/RuiDataTableCell.js +7 -0
  178. package/dist/components/tables/data-table/RuiDataTableCell.js.map +1 -0
  179. package/dist/components/tables/data-table/RuiDataTableCell.vue.d.ts +30 -0
  180. package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js +54 -0
  181. package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js.map +1 -0
  182. package/dist/components/tables/data-table/RuiDataTableEmptyRow.js +7 -0
  183. package/dist/components/tables/data-table/RuiDataTableEmptyRow.js.map +1 -0
  184. package/dist/components/tables/data-table/RuiDataTableEmptyRow.vue.d.ts +19 -0
  185. package/dist/components/tables/data-table/RuiDataTableEmptyRow.vue_vue_type_script_setup_true_lang.js +43 -0
  186. package/dist/components/tables/data-table/RuiDataTableEmptyRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
  187. package/dist/components/tables/data-table/RuiDataTableExpandedRow.js +7 -0
  188. package/dist/components/tables/data-table/RuiDataTableExpandedRow.js.map +1 -0
  189. package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue.d.ts +26 -0
  190. package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js +31 -0
  191. package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
  192. package/dist/components/tables/data-table/RuiDataTableGroupRow.js +7 -0
  193. package/dist/components/tables/data-table/RuiDataTableGroupRow.js.map +1 -0
  194. package/dist/components/tables/data-table/RuiDataTableGroupRow.vue.d.ts +32 -0
  195. package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js +85 -0
  196. package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
  197. package/dist/components/tables/data-table/RuiDataTableLoadingRow.js +7 -0
  198. package/dist/components/tables/data-table/RuiDataTableLoadingRow.js.map +1 -0
  199. package/dist/components/tables/data-table/RuiDataTableLoadingRow.vue.d.ts +3 -0
  200. package/dist/components/tables/data-table/RuiDataTableLoadingRow.vue_vue_type_script_setup_true_lang.js +26 -0
  201. package/dist/components/tables/data-table/RuiDataTableLoadingRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
  202. package/dist/components/tables/data-table/RuiDataTableMobileSort.js +7 -0
  203. package/dist/components/tables/data-table/RuiDataTableMobileSort.js.map +1 -0
  204. package/dist/components/tables/data-table/RuiDataTableMobileSort.vue.d.ts +33 -0
  205. package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js +101 -0
  206. package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js.map +1 -0
  207. package/dist/components/tables/data-table/RuiDataTableRow.js +7 -0
  208. package/dist/components/tables/data-table/RuiDataTableRow.js.map +1 -0
  209. package/dist/components/tables/data-table/RuiDataTableRow.vue.d.ts +31 -0
  210. package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js +142 -0
  211. package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
  212. package/dist/components/tables/data-table/context.d.ts +73 -0
  213. package/dist/components/tables/data-table/context.js +100 -0
  214. package/dist/components/tables/data-table/context.js.map +1 -0
  215. package/dist/components/tables/data-table-styles.d.ts +30 -1
  216. package/dist/components/tables/data-table-styles.js +9 -2
  217. package/dist/components/tables/data-table-styles.js.map +1 -1
  218. package/dist/components/tables/table-props.d.ts +5 -0
  219. package/dist/components/tables/table-props.js +5 -1
  220. package/dist/components/tables/table-props.js.map +1 -1
  221. package/dist/components/tables/use-pagination-navigation.js.map +1 -1
  222. package/dist/components/tabs/tab/RuiTab.vue_vue_type_script_setup_true_lang.js +1 -1
  223. package/dist/components/tabs/tab/RuiTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
  224. package/dist/components/tabs/tab/use-tab-link.js.map +1 -1
  225. package/dist/components/tabs/tab-item/RuiTabItem.vue_vue_type_script_setup_true_lang.js +1 -1
  226. package/dist/components/tabs/tab-item/RuiTabItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  227. package/dist/components/tabs/tab-items/RuiTabItems.js.map +1 -1
  228. package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js +2 -2
  229. package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js.map +1 -1
  230. package/dist/components/tabs/tab-props.js.map +1 -1
  231. package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js +2 -2
  232. package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  233. package/dist/components/tabs/tabs/use-tab-routing.js +1 -1
  234. package/dist/components/tabs/tabs/use-tab-routing.js.map +1 -1
  235. package/dist/components/tabs/tabs/use-tab-scroll.js.map +1 -1
  236. package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js +2 -2
  237. package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  238. package/dist/components/time-picker/time-picker-styles.js.map +1 -1
  239. package/dist/composables/breakpoint.js.map +1 -1
  240. package/dist/composables/defaults/table.d.ts +12 -0
  241. package/dist/composables/defaults/table.js.map +1 -1
  242. package/dist/composables/dropdown-menu.js.map +1 -1
  243. package/dist/composables/floating.js +1 -1
  244. package/dist/composables/floating.js.map +1 -1
  245. package/dist/composables/forms/auto-complete/focus.js.map +1 -1
  246. package/dist/composables/forms/auto-complete/index.js +5 -4
  247. package/dist/composables/forms/auto-complete/keyboard-navigation.js.map +1 -1
  248. package/dist/composables/forms/auto-complete/search.d.ts +6 -1
  249. package/dist/composables/forms/auto-complete/search.js +12 -1
  250. package/dist/composables/forms/auto-complete/search.js.map +1 -1
  251. package/dist/composables/forms/auto-complete/value.js.map +1 -1
  252. package/dist/composables/forms/category-picker/use-category-picker.d.ts +76 -0
  253. package/dist/composables/forms/category-picker/use-category-picker.js +141 -0
  254. package/dist/composables/forms/category-picker/use-category-picker.js.map +1 -0
  255. package/dist/composables/forms/use-prepend-append-width.js.map +1 -1
  256. package/dist/composables/icons.js.map +1 -1
  257. package/dist/composables/popper.js.map +1 -1
  258. package/dist/composables/sticky-header.js.map +1 -1
  259. package/dist/composables/tables/data-table/columns.d.ts +7 -1
  260. package/dist/composables/tables/data-table/columns.js +18 -10
  261. package/dist/composables/tables/data-table/columns.js.map +1 -1
  262. package/dist/composables/tables/data-table/expansion.js.map +1 -1
  263. package/dist/composables/tables/data-table/grouping.d.ts +4 -6
  264. package/dist/composables/tables/data-table/grouping.js +38 -24
  265. package/dist/composables/tables/data-table/grouping.js.map +1 -1
  266. package/dist/composables/tables/data-table/pagination.d.ts +4 -4
  267. package/dist/composables/tables/data-table/pagination.js +63 -21
  268. package/dist/composables/tables/data-table/pagination.js.map +1 -1
  269. package/dist/composables/tables/data-table/selection.js +16 -6
  270. package/dist/composables/tables/data-table/selection.js.map +1 -1
  271. package/dist/composables/tables/data-table/sort.d.ts +4 -3
  272. package/dist/composables/tables/data-table/sort.js +78 -40
  273. package/dist/composables/tables/data-table/sort.js.map +1 -1
  274. package/dist/composables/tables/data-table/types.d.ts +3 -1
  275. package/dist/composables/tables/data-table/types.js +6 -2
  276. package/dist/composables/tables/data-table/types.js.map +1 -1
  277. package/dist/composables/theme.js.map +1 -1
  278. package/dist/composables/timeout-manager.js.map +1 -1
  279. package/dist/composables/use-rui-i18n.js.map +1 -1
  280. package/dist/consts/colors.js.map +1 -1
  281. package/dist/consts/time-accuracy.js.map +1 -1
  282. package/dist/i18n/keys.js.map +1 -1
  283. package/dist/icons/icons_1.d.ts +12 -12
  284. package/dist/icons/icons_1.js +140 -157
  285. package/dist/icons/icons_1.js.map +1 -1
  286. package/dist/icons/icons_2.d.ts +13 -13
  287. package/dist/icons/icons_2.js +128 -149
  288. package/dist/icons/icons_2.js.map +1 -1
  289. package/dist/icons/icons_3.d.ts +18 -18
  290. package/dist/icons/icons_3.js +244 -282
  291. package/dist/icons/icons_3.js.map +1 -1
  292. package/dist/icons/icons_4.d.ts +251 -6
  293. package/dist/icons/icons_4.js +3016 -75
  294. package/dist/icons/icons_4.js.map +1 -1
  295. package/dist/icons/icons_5.d.ts +20 -0
  296. package/dist/icons/icons_5.js +221 -0
  297. package/dist/icons/icons_5.js.map +1 -0
  298. package/dist/icons/index.d.ts +2 -1
  299. package/dist/icons/index.js +297 -32
  300. package/dist/icons/index.js.map +1 -1
  301. package/dist/index.js +8 -6
  302. package/dist/index.js.map +1 -1
  303. package/dist/library-icons.json +1 -0
  304. package/dist/style.css +152 -0
  305. package/dist/theme/index.js.map +1 -1
  306. package/dist/types/stepper.js.map +1 -1
  307. package/dist/types/theme.js.map +1 -1
  308. package/dist/utils/assert.js.map +1 -1
  309. package/dist/utils/blockie.js.map +1 -1
  310. package/dist/utils/form-text-detail.js.map +1 -1
  311. package/dist/utils/helpers.js.map +1 -1
  312. package/dist/utils/is-equal.js.map +1 -1
  313. package/dist/utils/tv.js.map +1 -1
  314. package/dist/vite-plugin/index.js +6 -5
  315. package/dist/vite-plugin/index.js.map +1 -1
  316. package/dist/vite-plugin/scanner.d.ts +1 -1
  317. package/dist/vite-plugin/scanner.js +10 -7
  318. package/dist/vite-plugin/scanner.js.map +1 -1
  319. package/dist/vite-plugin/types.d.ts +9 -0
  320. package/dist/web-types.json +2042 -1108
  321. package/package.json +35 -35
@@ -1 +1 @@
1
- {"version":3,"file":"grouping.js","names":[],"sources":["../../../../src/composables/tables/data-table/grouping.ts"],"sourcesContent":["import type { ComputedRef, Ref } from 'vue';\nimport type { GroupData, TableRowKey, TableRowKeyData } from '@/components/tables/RuiTableHead.vue';\nimport {\n type GroupedTableRow,\n type GroupHeader,\n isRow,\n} from '@/composables/tables/data-table/types';\nimport { assert } from '@/utils/assert';\n\nexport interface UseTableGroupingOptions<T extends object, IdType extends keyof T> {\n /** The property on each row used as the unique row identifier. */\n rowAttr: IdType;\n}\n\nexport interface UseTableGroupingDeps<T extends object> {\n group: Ref<TableRowKeyData<T>>;\n collapsed: Ref<T[] | undefined>;\n sorted: ComputedRef<T[]>;\n emitCopyGroup: (value: GroupData<T>) => void;\n}\n\nexport interface UseTableGroupingReturn<T extends object> {\n groupKeys: ComputedRef<TableRowKey<T>[]>;\n groupKey: ComputedRef<string>;\n isGrouped: ComputedRef<boolean>;\n mappedGroups: ComputedRef<Record<string, GroupedTableRow<T>[]>>;\n grouped: ComputedRef<GroupedTableRow<T>[]>;\n getRowGroup: (row: T) => Partial<T>;\n getGroupRows: (groupVal: string) => T[];\n compareGroupsFn: (a: T, b: Partial<T>) => boolean;\n isExpandedGroup: (value: Partial<T>) => boolean;\n isHiddenRow: (row: GroupedTableRow<T>) => boolean;\n onToggleExpandGroup: (group: Partial<T>, value?: string) => void;\n onUngroup: () => void;\n onCopyGroup: (value: GroupData<T>) => void;\n}\n\n// Null character separator prevents false collisions when group values contain commas\nconst GROUP_KEY_SEPARATOR = '\\0';\n\nexport function useTableGrouping<T extends object, IdType extends keyof T>(\n options: UseTableGroupingOptions<T, IdType>,\n deps: UseTableGroupingDeps<T>,\n): UseTableGroupingReturn<T> {\n const { rowAttr } = options;\n const { group, collapsed, sorted, emitCopyGroup } = deps;\n\n const collapsedRows: Ref<T[]> = ref([]);\n\n watch(collapsed, value => set(collapsedRows, value ?? []), { immediate: true });\n\n const groupKeys: ComputedRef<TableRowKey<T>[]> = computed(() => {\n const groupBy = get(group);\n\n if (!groupBy)\n return [];\n\n if (!Array.isArray(groupBy))\n return [groupBy];\n\n return groupBy;\n });\n\n const groupKey = computed<string>(() => get(groupKeys).join(':'));\n\n const isGrouped = computed<boolean>(() => !!get(groupKey));\n\n const collapsedIdentifierSet = computed<Set<T[IdType]>>(\n () => new Set(get(collapsedRows).map(row => row[rowAttr])),\n );\n\n const collapsedGroupKeySet = computed<Set<string>>(() => {\n const grouping = get(groupKeys);\n if (grouping.length === 0)\n return new Set<string>();\n\n const seen = new Set<string>();\n for (const row of get(collapsedRows)) {\n const groupVal = grouping\n .map(key => row[key])\n .filter(isDefined)\n .join(GROUP_KEY_SEPARATOR);\n seen.add(groupVal);\n }\n return seen;\n });\n\n function getRowGroup(row: T): Partial<T> {\n const result: Partial<T> = {};\n for (const key of get(groupKeys)) {\n result[key] = row[key];\n }\n return result;\n }\n\n function compareGroupsFn(a: T, b: Partial<T>): boolean {\n const grouping = get(groupKeys);\n if (grouping.length === 0)\n return false;\n\n return grouping.every(key => a[key] === b[key]);\n }\n\n function isExpandedGroup(value: Partial<T>): boolean {\n const groupVal = Object.values(value).filter(isDefined).join(GROUP_KEY_SEPARATOR);\n return !get(collapsedGroupKeySet).has(groupVal);\n }\n\n function isHiddenRow(row: GroupedTableRow<T>): boolean {\n if (!get(isGrouped))\n return false;\n if (!isRow(row))\n return false;\n return get(collapsedIdentifierSet).has(row[rowAttr]);\n }\n\n const mappedGroups = computed<Record<string, GroupedTableRow<T>[]>>(() => {\n if (!get(isGrouped))\n return {};\n\n const result = get(sorted);\n const identifier = rowAttr;\n\n return result.reduce((acc: Record<string, GroupedTableRow<T>[]>, row) => {\n if (!isDefined(row[identifier]) || row[identifier] === '')\n return acc;\n\n const rowGroup = getRowGroup(row);\n const groupVal = Object.values(rowGroup).filter(isDefined).join(GROUP_KEY_SEPARATOR);\n if (!acc[groupVal]) {\n acc[groupVal] = [\n {\n __header__: true,\n group: rowGroup,\n identifier: groupVal,\n } satisfies GroupHeader<T>,\n ];\n }\n\n acc[groupVal].push(row);\n\n return acc;\n }, {});\n });\n\n const grouped = computed<GroupedTableRow<T>[]>(() => {\n const result = get(sorted);\n const groupByKey = get(groupKey);\n\n if (!groupByKey)\n return result;\n\n return Object.values(get(mappedGroups)).flat();\n });\n\n function getGroupRows(groupVal: string): T[] {\n if (!get(isGrouped))\n return [];\n\n const groupRows = get(mappedGroups)[groupVal];\n assert(groupRows);\n return groupRows.filter(isRow);\n }\n\n function onToggleExpandGroup(groupPartial: Partial<T>, value?: string): void {\n if (!value)\n return;\n\n const currentCollapsed = get(collapsedRows);\n\n const groupExpanded = isExpandedGroup(groupPartial);\n\n const groupRows = getGroupRows(value);\n\n set(\n collapsedRows,\n groupExpanded\n ? [...currentCollapsed, ...groupRows]\n : currentCollapsed.filter(row => !compareGroupsFn(row, groupPartial)),\n );\n\n set(collapsed, get(collapsedRows));\n }\n\n function onUngroup(): void {\n set(collapsedRows, []);\n\n set(collapsed, []);\n set(group, Array.isArray(get(group)) ? [] : undefined);\n }\n\n function onCopyGroup(value: GroupData<T>): void {\n emitCopyGroup(value);\n }\n\n return {\n groupKeys,\n groupKey,\n isGrouped,\n mappedGroups,\n grouped,\n getRowGroup,\n getGroupRows,\n compareGroupsFn,\n isExpandedGroup,\n isHiddenRow,\n onToggleExpandGroup,\n onUngroup,\n onCopyGroup,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"grouping.js","names":[],"sources":["../../../../src/composables/tables/data-table/grouping.ts"],"sourcesContent":["import type { ComputedRef, Ref } from 'vue';\nimport type { TableRowKey, TableRowKeyData } from '@/components/tables/RuiTableHead.vue';\nimport {\n GROUP_HEADER_BRAND,\n type GroupedTableRow,\n type GroupHeader,\n isRow,\n} from '@/composables/tables/data-table/types';\nimport { assert } from '@/utils/assert';\n\nexport interface UseTableGroupingOptions<T extends object, IdType extends keyof T> {\n /** The property on each row used as the unique row identifier. */\n rowAttr: IdType;\n}\n\nexport interface UseTableGroupingDeps<T extends object> {\n group: Ref<TableRowKeyData<T>>;\n collapsed: Ref<T[] | undefined>;\n sorted: ComputedRef<readonly T[]>;\n}\n\nexport interface UseTableGroupingReturn<T extends object> {\n groupKeys: ComputedRef<TableRowKey<T>[]>;\n groupKey: ComputedRef<string | undefined>;\n isGrouped: ComputedRef<boolean>;\n mappedGroups: ComputedRef<Record<string, GroupedTableRow<T>[]>>;\n grouped: ComputedRef<readonly GroupedTableRow<T>[]>;\n getRowGroup: (row: T) => Partial<T>;\n getGroupRows: (groupVal: string) => T[];\n compareGroupsFn: (a: T, b: Partial<T>) => boolean;\n isExpandedGroup: (value: Partial<T>) => boolean;\n isHiddenRow: (row: GroupedTableRow<T>) => boolean;\n onToggleExpandGroup: (group: Partial<T>, value?: string) => void;\n onUngroup: () => void;\n}\n\n// Null character separator prevents false collisions when group values contain commas\nconst GROUP_KEY_SEPARATOR = '\\0';\n\nexport function useTableGrouping<T extends object, IdType extends keyof T>(\n options: UseTableGroupingOptions<T, IdType>,\n deps: UseTableGroupingDeps<T>,\n): UseTableGroupingReturn<T> {\n const { rowAttr } = options;\n const { group, collapsed, sorted } = deps;\n\n const collapsedRows: Ref<T[]> = ref([]);\n\n watch(collapsed, value => set(collapsedRows, value ?? []), { immediate: true });\n\n const groupKeys: ComputedRef<TableRowKey<T>[]> = computed(() => {\n const groupBy = get(group);\n\n if (!groupBy)\n return [];\n\n if (!Array.isArray(groupBy))\n return [groupBy];\n\n return groupBy;\n });\n\n const groupKey = computed<string | undefined>(() => {\n const key = get(groupKeys).join(':');\n return key || undefined;\n });\n\n const isGrouped = computed<boolean>(() => get(groupKey) !== undefined);\n\n const collapsedIdentifierSet = computed<Set<T[IdType]>>(\n () => new Set(get(collapsedRows).map(row => row[rowAttr])),\n );\n\n const collapsedGroupKeySet = computed<Set<string>>(() => {\n const grouping = get(groupKeys);\n if (grouping.length === 0)\n return new Set<string>();\n\n const seen = new Set<string>();\n for (const row of get(collapsedRows))\n seen.add(computeGroupKey(row, grouping));\n return seen;\n });\n\n function getRowGroup(row: T): Partial<T> {\n const result: Partial<T> = {};\n for (const key of get(groupKeys)) {\n result[key] = row[key];\n }\n return result;\n }\n\n function compareGroupsFn(a: T, b: Partial<T>): boolean {\n const grouping = get(groupKeys);\n if (grouping.length === 0)\n return false;\n\n return grouping.every(key => a[key] === b[key]);\n }\n\n function isExpandedGroup(value: Partial<T>): boolean {\n const grouping = get(groupKeys);\n let groupVal = '';\n for (const gk of grouping) {\n if (groupVal)\n groupVal += GROUP_KEY_SEPARATOR;\n const val = value[gk];\n groupVal += isDefined(val) ? val : '';\n }\n return !get(collapsedGroupKeySet).has(groupVal);\n }\n\n function isHiddenRow(row: GroupedTableRow<T>): boolean {\n if (!get(isGrouped))\n return false;\n if (!isRow(row))\n return false;\n return get(collapsedIdentifierSet).has(row[rowAttr]);\n }\n\n function computeGroupKey(row: T, grouping: TableRowKey<T>[]): string {\n let key = '';\n for (const gk of grouping) {\n if (key)\n key += GROUP_KEY_SEPARATOR;\n const val = row[gk];\n key += isDefined(val) ? val : '';\n }\n return key;\n }\n\n const mappedGroups = computed<Record<string, GroupedTableRow<T>[]>>(() => {\n const grouping = get(groupKeys);\n if (grouping.length === 0)\n return {};\n\n const result = get(sorted);\n const identifier = rowAttr;\n const acc: Record<string, GroupedTableRow<T>[]> = {};\n\n for (const row of result) {\n if (!isDefined(row[identifier]) || row[identifier] === '')\n continue;\n\n const groupVal = computeGroupKey(row, grouping);\n if (!acc[groupVal]) {\n acc[groupVal] = [\n {\n [GROUP_HEADER_BRAND]: true,\n group: getRowGroup(row),\n identifier: groupVal,\n } satisfies GroupHeader<T>,\n ];\n }\n\n acc[groupVal].push(row);\n }\n\n return acc;\n });\n\n const grouped = computed<readonly GroupedTableRow<T>[]>(() => {\n const result = get(sorted);\n const groupByKey = get(groupKey);\n\n if (!groupByKey)\n return result;\n\n const groups = get(mappedGroups);\n const out: GroupedTableRow<T>[] = [];\n for (const items of Object.values(groups)) {\n for (const item of items)\n out.push(item);\n }\n return out;\n });\n\n function getGroupRows(groupVal: string): T[] {\n if (!get(isGrouped))\n return [];\n\n const groupRows = get(mappedGroups)[groupVal];\n assert(groupRows);\n return groupRows.filter(isRow);\n }\n\n function onToggleExpandGroup(groupPartial: Partial<T>, value?: string): void {\n if (!value)\n return;\n\n const currentCollapsed = get(collapsedRows);\n\n const groupExpanded = isExpandedGroup(groupPartial);\n\n const groupRows = getGroupRows(value);\n\n set(\n collapsedRows,\n groupExpanded\n ? [...currentCollapsed, ...groupRows]\n : currentCollapsed.filter(row => !compareGroupsFn(row, groupPartial)),\n );\n\n set(collapsed, get(collapsedRows));\n }\n\n function onUngroup(): void {\n set(collapsedRows, []);\n\n set(collapsed, []);\n set(group, Array.isArray(get(group)) ? [] : undefined);\n }\n\n return {\n groupKeys,\n groupKey,\n isGrouped,\n mappedGroups,\n grouped,\n getRowGroup,\n getGroupRows,\n compareGroupsFn,\n isExpandedGroup,\n isHiddenRow,\n onToggleExpandGroup,\n onUngroup,\n };\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { ComputedRef, Ref } from 'vue';
1
+ import type { ComputedRef, DeepReadonly, Ref, ShallowRef } from 'vue';
2
2
  import type { TableSortData } from '../../../components/tables/RuiTableHead.vue';
3
3
  import type { TablePaginationData } from '../../../components/tables/RuiTablePagination.vue';
4
4
  import type { TableOptions as TableDefaultOptions } from '../../../composables/defaults/table.js';
@@ -13,7 +13,7 @@ export interface UseTablePaginationOptions {
13
13
  }
14
14
  export interface UseTablePaginationDeps<T extends object> {
15
15
  pagination: Ref<TablePaginationData | undefined>;
16
- grouped: ComputedRef<GroupedTableRow<T>[]>;
16
+ grouped: ComputedRef<readonly GroupedTableRow<T>[]>;
17
17
  isHiddenRow: (row: GroupedTableRow<T>) => boolean;
18
18
  sort: Ref<TableSortData<T>>;
19
19
  emitUpdateOptions: (options: {
@@ -25,9 +25,9 @@ export interface UseTablePaginationDeps<T extends object> {
25
25
  export interface UseTablePaginationReturn<T extends object> {
26
26
  paginationData: Ref<TablePaginationData>;
27
27
  filtered: ComputedRef<GroupedTableRow<T>[]>;
28
- itemsLength: Ref<number>;
28
+ itemsLength: DeepReadonly<ShallowRef<number>>;
29
29
  globalItemsPerPageSettings: ComputedRef<boolean>;
30
- setInternalTotal: (items: GroupedTableRow<T>[]) => void;
30
+ setInternalTotal: (items: readonly GroupedTableRow<T>[]) => void;
31
31
  resetPagination: () => void;
32
32
  }
33
33
  export declare function useTablePagination<T extends object>(options: UseTablePaginationOptions, deps: UseTablePaginationDeps<T>): UseTablePaginationReturn<T>;
@@ -1,8 +1,62 @@
1
- import { assert } from "../../../utils/assert.js";
2
1
  import { isRow } from "./types.js";
3
- import { computed, ref, shallowRef, watch } from "vue";
2
+ import { computed, readonly, ref, shallowRef, watch } from "vue";
4
3
  import { get, set } from "@vueuse/shared";
5
4
  //#region src/composables/tables/data-table/pagination.ts
5
+ /**
6
+ * Skip data rows until the page start offset, tracking the last group header seen.
7
+ * Returns the index where collection should begin and the last group header before the slice.
8
+ */
9
+ function skipToPageStart(result, start) {
10
+ let dataCount = 0;
11
+ let lastGroupHeader;
12
+ for (const [i, item] of result.entries()) if (isRow(item)) {
13
+ dataCount++;
14
+ if (dataCount > start) return {
15
+ startIndex: i,
16
+ dataCount,
17
+ lastGroupHeader
18
+ };
19
+ } else if (dataCount < start) lastGroupHeader = item;
20
+ else return {
21
+ startIndex: i,
22
+ dataCount,
23
+ lastGroupHeader
24
+ };
25
+ return {
26
+ startIndex: result.length,
27
+ dataCount,
28
+ lastGroupHeader
29
+ };
30
+ }
31
+ /**
32
+ * Collect data rows (and interleaved group headers) for the current page.
33
+ */
34
+ function collectPageRows(items, limit) {
35
+ const data = [];
36
+ let collected = 0;
37
+ for (const item of items) {
38
+ data.push(item);
39
+ if (isRow(item)) {
40
+ collected++;
41
+ if (collected >= limit) break;
42
+ }
43
+ }
44
+ return data;
45
+ }
46
+ /**
47
+ * Single-pass pagination that counts only data rows while preserving group headers.
48
+ * Prepends the nearest group header when a page starts mid-group, and removes
49
+ * trailing group headers with no data rows after them.
50
+ */
51
+ function paginateGroupedRows(result, start, limit) {
52
+ const { startIndex, lastGroupHeader } = skipToPageStart(result, start);
53
+ const data = collectPageRows(result.slice(startIndex), limit);
54
+ const firstItem = data[0];
55
+ if (firstItem && isRow(firstItem) && lastGroupHeader) data.unshift(lastGroupHeader);
56
+ const lastItem = data.at(-1);
57
+ if (lastItem && !isRow(lastItem)) data.pop();
58
+ return data;
59
+ }
6
60
  function useTablePagination(options, deps) {
7
61
  const { itemsPerPage, paginationModifiersExternal, globalItemsPerPage } = options;
8
62
  const { pagination, grouped, isHiddenRow, sort, emitUpdateOptions, tableDefaults } = deps;
@@ -40,27 +94,15 @@ function useTablePagination(options, deps) {
40
94
  const filtered = computed(() => {
41
95
  const result = get(grouped);
42
96
  const paginated = get(paginationData);
43
- const limit = paginated.limit;
44
- if (!paginationModifiersExternal) {
45
- const start = (paginated.page - 1) * limit;
46
- const end = start + limit;
47
- const preGroups = result.slice(0, start + 1).filter((item) => !isRow(item));
48
- const postGroups = result.slice(start + 1, end + preGroups.length).filter((item) => !isRow(item));
49
- const data = result.slice(start + preGroups.length, end + preGroups.length + postGroups.length);
50
- const nearestGroup = preGroups.at(-1);
51
- if (data.length > 0) {
52
- const firstItem = data[0];
53
- assert(firstItem);
54
- if (isRow(firstItem) && nearestGroup) data.unshift(nearestGroup);
55
- const lastItem = data.at(-1);
56
- if (lastItem && !isRow(lastItem)) data.pop();
57
- }
58
- return data.filter((row) => !isHiddenRow(row));
59
- }
97
+ if (!paginationModifiersExternal) return paginateGroupedRows(result, (paginated.page - 1) * paginated.limit, paginated.limit).filter((row) => !isHiddenRow(row));
60
98
  return result.filter((row) => !isHiddenRow(row));
61
99
  });
62
100
  function setInternalTotal(items) {
63
- if (!paginationModifiersExternal) set(itemsLength, items.filter(isRow).length);
101
+ if (!paginationModifiersExternal) {
102
+ let count = 0;
103
+ for (const item of items) if (isRow(item)) count++;
104
+ set(itemsLength, count);
105
+ }
64
106
  }
65
107
  function resetPagination() {
66
108
  set(paginationData, {
@@ -90,7 +132,7 @@ function useTablePagination(options, deps) {
90
132
  return {
91
133
  paginationData,
92
134
  filtered,
93
- itemsLength,
135
+ itemsLength: readonly(itemsLength),
94
136
  globalItemsPerPageSettings,
95
137
  setInternalTotal,
96
138
  resetPagination
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.js","names":[],"sources":["../../../../src/composables/tables/data-table/pagination.ts"],"sourcesContent":["import type { ComputedRef, Ref } from 'vue';\nimport type { TableSortData } from '@/components/tables/RuiTableHead.vue';\nimport type { TablePaginationData } from '@/components/tables/RuiTablePagination.vue';\nimport type { TableOptions as TableDefaultOptions } from '@/composables/defaults/table';\nimport { type GroupedTableRow, isRow } from '@/composables/tables/data-table/types';\nimport { assert } from '@/utils/assert';\n\nexport interface UseTablePaginationOptions {\n /** The default number of items displayed per page. */\n itemsPerPage: number;\n /** Whether pagination is managed externally (e.g. server-side). */\n paginationModifiersExternal: boolean | undefined;\n /** Whether to share the items-per-page setting across all tables. */\n globalItemsPerPage: boolean | undefined;\n}\n\nexport interface UseTablePaginationDeps<T extends object> {\n pagination: Ref<TablePaginationData | undefined>;\n grouped: ComputedRef<GroupedTableRow<T>[]>;\n isHiddenRow: (row: GroupedTableRow<T>) => boolean;\n sort: Ref<TableSortData<T>>;\n emitUpdateOptions: (options: {\n sort?: TableSortData<T>;\n pagination?: TablePaginationData;\n }) => void;\n tableDefaults: TableDefaultOptions;\n}\n\nexport interface UseTablePaginationReturn<T extends object> {\n paginationData: Ref<TablePaginationData>;\n filtered: ComputedRef<GroupedTableRow<T>[]>;\n itemsLength: Ref<number>;\n globalItemsPerPageSettings: ComputedRef<boolean>;\n setInternalTotal: (items: GroupedTableRow<T>[]) => void;\n resetPagination: () => void;\n}\n\nexport function useTablePagination<T extends object>(\n options: UseTablePaginationOptions,\n deps: UseTablePaginationDeps<T>,\n): UseTablePaginationReturn<T> {\n const { itemsPerPage, paginationModifiersExternal, globalItemsPerPage } = options;\n const { pagination, grouped, isHiddenRow, sort, emitUpdateOptions, tableDefaults } = deps;\n\n const itemsLength = shallowRef<number>(0);\n const internalPaginationState: Ref<TablePaginationData | undefined> = ref();\n\n const globalItemsPerPageSettings = computed<boolean>(() => {\n if (globalItemsPerPage !== undefined)\n return globalItemsPerPage;\n\n return get(tableDefaults.globalItemsPerPage);\n });\n\n const paginationData: Ref<TablePaginationData> = computed({\n get(): TablePaginationData {\n const paginated = get(internalPaginationState);\n if (!paginated) {\n return {\n total: get(itemsLength),\n limit: itemsPerPage,\n page: 1,\n };\n }\n\n if (paginationModifiersExternal)\n return paginated;\n\n return {\n total: get(itemsLength),\n limit: paginated.limit,\n page: paginated.page,\n limits: paginated.limits,\n };\n },\n set(value: TablePaginationData) {\n set(internalPaginationState, value);\n set(pagination, value);\n emitUpdateOptions({\n pagination: value,\n sort: get(sort),\n });\n },\n });\n\n const filtered = computed<GroupedTableRow<T>[]>(() => {\n const result = get(grouped);\n\n const paginated = get(paginationData);\n const limit = paginated.limit;\n if (!paginationModifiersExternal) {\n const start = (paginated.page - 1) * limit;\n const end = start + limit;\n const preGroups = result.slice(0, start + 1).filter(item => !isRow(item));\n const postGroups = result\n .slice(start + 1, end + preGroups.length)\n .filter(item => !isRow(item));\n const data = result.slice(\n start + preGroups.length,\n end + preGroups.length + postGroups.length,\n );\n const nearestGroup = preGroups.at(-1);\n if (data.length > 0) {\n const firstItem = data[0];\n assert(firstItem);\n if (isRow(firstItem) && nearestGroup)\n data.unshift(nearestGroup);\n const lastItem = data.at(-1);\n if (lastItem && !isRow(lastItem))\n data.pop();\n }\n\n return data.filter(row => !isHiddenRow(row));\n }\n\n return result.filter(row => !isHiddenRow(row));\n });\n\n function setInternalTotal(items: GroupedTableRow<T>[]): void {\n if (!paginationModifiersExternal)\n set(itemsLength, items.filter(isRow).length);\n }\n\n function resetPagination(): void {\n set(paginationData, {\n ...get(paginationData),\n page: 1,\n });\n }\n\n // Sync external pagination model to internal state\n watch(pagination, val => set(internalPaginationState, val), { immediate: true });\n\n // Sync pagination limit to global table defaults\n watch(internalPaginationState, (paginationState) => {\n if (paginationState?.limit && get(globalItemsPerPageSettings))\n set(tableDefaults.itemsPerPage, paginationState.limit);\n });\n\n // Sync global table defaults to pagination limit\n watch(\n tableDefaults.itemsPerPage,\n (perPage) => {\n if (!get(globalItemsPerPageSettings))\n return;\n\n set(paginationData, {\n ...get(paginationData),\n limit: perPage,\n });\n },\n { immediate: true },\n );\n\n // Auto-adjust page when current page exceeds max available pages\n watch(paginationData, (paginationState) => {\n const { total, limit, page } = paginationState;\n const maxPages = Math.ceil(total / limit);\n\n if (maxPages > 0 && page > maxPages) {\n set(paginationData, {\n ...paginationState,\n page: maxPages,\n });\n }\n });\n\n return {\n paginationData,\n filtered,\n itemsLength,\n globalItemsPerPageSettings,\n setInternalTotal,\n resetPagination,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"pagination.js","names":[],"sources":["../../../../src/composables/tables/data-table/pagination.ts"],"sourcesContent":["import type { ComputedRef, DeepReadonly, Ref, ShallowRef } from 'vue';\nimport type { TableSortData } from '@/components/tables/RuiTableHead.vue';\nimport type { TablePaginationData } from '@/components/tables/RuiTablePagination.vue';\nimport type { TableOptions as TableDefaultOptions } from '@/composables/defaults/table';\nimport { type GroupedTableRow, isRow } from '@/composables/tables/data-table/types';\n\nexport interface UseTablePaginationOptions {\n /** The default number of items displayed per page. */\n itemsPerPage: number;\n /** Whether pagination is managed externally (e.g. server-side). */\n paginationModifiersExternal: boolean | undefined;\n /** Whether to share the items-per-page setting across all tables. */\n globalItemsPerPage: boolean | undefined;\n}\n\nexport interface UseTablePaginationDeps<T extends object> {\n pagination: Ref<TablePaginationData | undefined>;\n grouped: ComputedRef<readonly GroupedTableRow<T>[]>;\n isHiddenRow: (row: GroupedTableRow<T>) => boolean;\n sort: Ref<TableSortData<T>>;\n emitUpdateOptions: (options: {\n sort?: TableSortData<T>;\n pagination?: TablePaginationData;\n }) => void;\n tableDefaults: TableDefaultOptions;\n}\n\nexport interface UseTablePaginationReturn<T extends object> {\n paginationData: Ref<TablePaginationData>;\n filtered: ComputedRef<GroupedTableRow<T>[]>;\n itemsLength: DeepReadonly<ShallowRef<number>>;\n globalItemsPerPageSettings: ComputedRef<boolean>;\n setInternalTotal: (items: readonly GroupedTableRow<T>[]) => void;\n resetPagination: () => void;\n}\n\n/**\n * Skip data rows until the page start offset, tracking the last group header seen.\n * Returns the index where collection should begin and the last group header before the slice.\n */\nfunction skipToPageStart<T extends object>(\n result: readonly GroupedTableRow<T>[],\n start: number,\n): { startIndex: number; dataCount: number; lastGroupHeader: GroupedTableRow<T> | undefined } {\n let dataCount = 0;\n let lastGroupHeader: GroupedTableRow<T> | undefined;\n\n for (const [i, item] of result.entries()) {\n if (isRow(item)) {\n dataCount++;\n if (dataCount > start)\n return { startIndex: i, dataCount, lastGroupHeader };\n }\n else if (dataCount < start) {\n lastGroupHeader = item;\n }\n else {\n return { startIndex: i, dataCount, lastGroupHeader };\n }\n }\n\n return { startIndex: result.length, dataCount, lastGroupHeader };\n}\n\n/**\n * Collect data rows (and interleaved group headers) for the current page.\n */\nfunction collectPageRows<T extends object>(\n items: readonly GroupedTableRow<T>[],\n limit: number,\n): GroupedTableRow<T>[] {\n const data: GroupedTableRow<T>[] = [];\n let collected = 0;\n\n for (const item of items) {\n data.push(item);\n\n if (isRow(item)) {\n collected++;\n if (collected >= limit)\n break;\n }\n }\n\n return data;\n}\n\n/**\n * Single-pass pagination that counts only data rows while preserving group headers.\n * Prepends the nearest group header when a page starts mid-group, and removes\n * trailing group headers with no data rows after them.\n */\nfunction paginateGroupedRows<T extends object>(\n result: readonly GroupedTableRow<T>[],\n start: number,\n limit: number,\n): GroupedTableRow<T>[] {\n const { startIndex, lastGroupHeader } = skipToPageStart(result, start);\n const data = collectPageRows(result.slice(startIndex), limit);\n\n // Prepend the nearest group header if the first item is a data row\n const firstItem = data[0];\n if (firstItem && isRow(firstItem) && lastGroupHeader)\n data.unshift(lastGroupHeader);\n\n // Remove trailing group header with no data rows after it\n const lastItem = data.at(-1);\n if (lastItem && !isRow(lastItem))\n data.pop();\n\n return data;\n}\n\nexport function useTablePagination<T extends object>(\n options: UseTablePaginationOptions,\n deps: UseTablePaginationDeps<T>,\n): UseTablePaginationReturn<T> {\n const { itemsPerPage, paginationModifiersExternal, globalItemsPerPage } = options;\n const { pagination, grouped, isHiddenRow, sort, emitUpdateOptions, tableDefaults } = deps;\n\n const itemsLength = shallowRef<number>(0);\n const internalPaginationState: Ref<TablePaginationData | undefined> = ref();\n\n const globalItemsPerPageSettings = computed<boolean>(() => {\n if (globalItemsPerPage !== undefined)\n return globalItemsPerPage;\n\n return get(tableDefaults.globalItemsPerPage);\n });\n\n const paginationData: Ref<TablePaginationData> = computed({\n get(): TablePaginationData {\n const paginated = get(internalPaginationState);\n if (!paginated) {\n return {\n total: get(itemsLength),\n limit: itemsPerPage,\n page: 1,\n };\n }\n\n if (paginationModifiersExternal)\n return paginated;\n\n return {\n total: get(itemsLength),\n limit: paginated.limit,\n page: paginated.page,\n limits: paginated.limits,\n };\n },\n set(value: TablePaginationData) {\n set(internalPaginationState, value);\n set(pagination, value);\n emitUpdateOptions({\n pagination: value,\n sort: get(sort),\n });\n },\n });\n\n const filtered = computed<GroupedTableRow<T>[]>(() => {\n const result = get(grouped);\n\n const paginated = get(paginationData);\n if (!paginationModifiersExternal) {\n const start = (paginated.page - 1) * paginated.limit;\n const data = paginateGroupedRows(result, start, paginated.limit);\n return data.filter(row => !isHiddenRow(row));\n }\n\n return result.filter(row => !isHiddenRow(row));\n });\n\n function setInternalTotal(items: readonly GroupedTableRow<T>[]): void {\n if (!paginationModifiersExternal) {\n let count = 0;\n for (const item of items) {\n if (isRow(item))\n count++;\n }\n set(itemsLength, count);\n }\n }\n\n function resetPagination(): void {\n set(paginationData, {\n ...get(paginationData),\n page: 1,\n });\n }\n\n // Sync external pagination model to internal state\n watch(pagination, val => set(internalPaginationState, val), { immediate: true });\n\n // Sync pagination limit to global table defaults\n watch(internalPaginationState, (paginationState) => {\n if (paginationState?.limit && get(globalItemsPerPageSettings))\n set(tableDefaults.itemsPerPage, paginationState.limit);\n });\n\n // Sync global table defaults to pagination limit\n watch(\n tableDefaults.itemsPerPage,\n (perPage) => {\n if (!get(globalItemsPerPageSettings))\n return;\n\n set(paginationData, {\n ...get(paginationData),\n limit: perPage,\n });\n },\n { immediate: true },\n );\n\n // Auto-adjust page when current page exceeds max available pages\n watch(paginationData, (paginationState) => {\n const { total, limit, page } = paginationState;\n const maxPages = Math.ceil(total / limit);\n\n if (maxPages > 0 && page > maxPages) {\n set(paginationData, {\n ...paginationState,\n page: maxPages,\n });\n }\n });\n\n return {\n paginationData,\n filtered,\n itemsLength: readonly(itemsLength),\n globalItemsPerPageSettings,\n setInternalTotal,\n resetPagination,\n };\n}\n"],"mappings":";;;;;;;;AAwCA,SAAS,gBACP,QACA,OAC4F;CAC5F,IAAI,YAAY;CAChB,IAAI;CAEJ,KAAK,MAAM,CAAC,GAAG,SAAS,OAAO,QAAQ,GACrC,IAAI,MAAM,IAAI,GAAG;EACf;EACA,IAAI,YAAY,OACd,OAAO;GAAE,YAAY;GAAG;GAAW;EAAgB;CACvD,OACK,IAAI,YAAY,OACnB,kBAAkB;MAGlB,OAAO;EAAE,YAAY;EAAG;EAAW;CAAgB;CAIvD,OAAO;EAAE,YAAY,OAAO;EAAQ;EAAW;CAAgB;AACjE;;;;AAKA,SAAS,gBACP,OACA,OACsB;CACtB,MAAM,OAA6B,CAAC;CACpC,IAAI,YAAY;CAEhB,KAAK,MAAM,QAAQ,OAAO;EACxB,KAAK,KAAK,IAAI;EAEd,IAAI,MAAM,IAAI,GAAG;GACf;GACA,IAAI,aAAa,OACf;EACJ;CACF;CAEA,OAAO;AACT;;;;;;AAOA,SAAS,oBACP,QACA,OACA,OACsB;CACtB,MAAM,EAAE,YAAY,oBAAoB,gBAAgB,QAAQ,KAAK;CACrE,MAAM,OAAO,gBAAgB,OAAO,MAAM,UAAU,GAAG,KAAK;CAG5D,MAAM,YAAY,KAAK;CACvB,IAAI,aAAa,MAAM,SAAS,KAAK,iBACnC,KAAK,QAAQ,eAAe;CAG9B,MAAM,WAAW,KAAK,GAAG,EAAE;CAC3B,IAAI,YAAY,CAAC,MAAM,QAAQ,GAC7B,KAAK,IAAI;CAEX,OAAO;AACT;AAEA,SAAgB,mBACd,SACA,MAC6B;CAC7B,MAAM,EAAE,cAAc,6BAA6B,uBAAuB;CAC1E,MAAM,EAAE,YAAY,SAAS,aAAa,MAAM,mBAAmB,kBAAkB;CAErF,MAAM,cAAc,WAAmB,CAAC;CACxC,MAAM,0BAAgE,IAAI;CAE1E,MAAM,6BAA6B,eAAwB;EACzD,IAAI,uBAAuB,KAAA,GACzB,OAAO;EAET,OAAO,IAAI,cAAc,kBAAkB;CAC7C,CAAC;CAED,MAAM,iBAA2C,SAAS;EACxD,MAA2B;GACzB,MAAM,YAAY,IAAI,uBAAuB;GAC7C,IAAI,CAAC,WACH,OAAO;IACL,OAAO,IAAI,WAAW;IACtB,OAAO;IACP,MAAM;GACR;GAGF,IAAI,6BACF,OAAO;GAET,OAAO;IACL,OAAO,IAAI,WAAW;IACtB,OAAO,UAAU;IACjB,MAAM,UAAU;IAChB,QAAQ,UAAU;GACpB;EACF;EACA,IAAI,OAA4B;GAC9B,IAAI,yBAAyB,KAAK;GAClC,IAAI,YAAY,KAAK;GACrB,kBAAkB;IAChB,YAAY;IACZ,MAAM,IAAI,IAAI;GAChB,CAAC;EACH;CACF,CAAC;CAED,MAAM,WAAW,eAAqC;EACpD,MAAM,SAAS,IAAI,OAAO;EAE1B,MAAM,YAAY,IAAI,cAAc;EACpC,IAAI,CAAC,6BAGH,OADa,oBAAoB,SADlB,UAAU,OAAO,KAAK,UAAU,OACC,UAAU,KACnD,CAAA,CAAK,QAAO,QAAO,CAAC,YAAY,GAAG,CAAC;EAG7C,OAAO,OAAO,QAAO,QAAO,CAAC,YAAY,GAAG,CAAC;CAC/C,CAAC;CAED,SAAS,iBAAiB,OAA4C;EACpE,IAAI,CAAC,6BAA6B;GAChC,IAAI,QAAQ;GACZ,KAAK,MAAM,QAAQ,OACjB,IAAI,MAAM,IAAI,GACZ;GAEJ,IAAI,aAAa,KAAK;EACxB;CACF;CAEA,SAAS,kBAAwB;EAC/B,IAAI,gBAAgB;GAClB,GAAG,IAAI,cAAc;GACrB,MAAM;EACR,CAAC;CACH;CAGA,MAAM,aAAY,QAAO,IAAI,yBAAyB,GAAG,GAAG,EAAE,WAAW,KAAK,CAAC;CAG/E,MAAM,0BAA0B,oBAAoB;EAClD,IAAI,iBAAiB,SAAS,IAAI,0BAA0B,GAC1D,IAAI,cAAc,cAAc,gBAAgB,KAAK;CACzD,CAAC;CAGD,MACE,cAAc,eACb,YAAY;EACX,IAAI,CAAC,IAAI,0BAA0B,GACjC;EAEF,IAAI,gBAAgB;GAClB,GAAG,IAAI,cAAc;GACrB,OAAO;EACT,CAAC;CACH,GACA,EAAE,WAAW,KAAK,CACpB;CAGA,MAAM,iBAAiB,oBAAoB;EACzC,MAAM,EAAE,OAAO,OAAO,SAAS;EAC/B,MAAM,WAAW,KAAK,KAAK,QAAQ,KAAK;EAExC,IAAI,WAAW,KAAK,OAAO,UACzB,IAAI,gBAAgB;GAClB,GAAG;GACH,MAAM;EACR,CAAC;CAEL,CAAC;CAED,OAAO;EACL;EACA;EACA,aAAa,SAAS,WAAW;EACjC;EACA;EACA;CACF;AACF"}
@@ -1,7 +1,7 @@
1
1
  import { assert } from "../../../utils/assert.js";
2
2
  import { useTimeoutManager } from "../../timeout-manager.js";
3
3
  import { isRow } from "./types.js";
4
- import { computed, ref, shallowRef, toValue, watch } from "vue";
4
+ import { computed, shallowRef, toValue, watch } from "vue";
5
5
  import { isDefined } from "@vueuse/core";
6
6
  import { get as get$1, set as set$1 } from "@vueuse/shared";
7
7
  //#region src/composables/tables/data-table/selection.ts
@@ -10,9 +10,9 @@ function useTableSelection(options, deps) {
10
10
  const { selectedData, filtered } = deps;
11
11
  const shiftClicked = shallowRef(false);
12
12
  const lastSelectedIndex = shallowRef(-1);
13
- const internalSelectedData = ref([]);
13
+ const internalSelectedData = shallowRef([]);
14
14
  const { create: scheduleShiftSelect } = useTimeoutManager();
15
- watch(selectedData, (val) => set$1(internalSelectedData, val), { immediate: true });
15
+ watch(selectedData, (val) => set$1(internalSelectedData, val ?? []), { immediate: true });
16
16
  const visibleIdentifiers = computed(() => get$1(filtered).filter(isRow).map((row) => row[rowAttr]));
17
17
  const selectedSet = computed(() => new Set(get$1(selectedData) ?? []));
18
18
  const disabledRowKeySet = computed(() => {
@@ -52,7 +52,7 @@ function useTableSelection(options, deps) {
52
52
  if (!isDefined(selectedRows)) return;
53
53
  if (!multiPageSelect) if (checked) set$1(selectedData, get$1(visibleIdentifiers).filter(isSelectable));
54
54
  else set$1(selectedData, get$1(visibleIdentifiers).filter(mustSelect));
55
- else if (checked) set$1(selectedData, Array.from(new Set([...selectedRows, ...get$1(visibleIdentifiers).filter(isSelectable)])));
55
+ else if (checked) set$1(selectedData, Array.from(/* @__PURE__ */ new Set([...selectedRows, ...get$1(visibleIdentifiers).filter(isSelectable)])));
56
56
  else {
57
57
  const visibleSet = new Set(get$1(visibleIdentifiers));
58
58
  const mustSelectSet = new Set(get$1(visibleIdentifiers).filter(mustSelect));
@@ -65,7 +65,7 @@ function useTableSelection(options, deps) {
65
65
  if (!selectedRows) return;
66
66
  const selected = isSelected(value);
67
67
  if (checked && !selected) set$1(internalSelectedData, [...selectedRows, value]);
68
- else if (!checked && selected) set$1(internalSelectedData, [...selectedRows].filter((r) => r !== value));
68
+ else if (!checked && selected) set$1(internalSelectedData, selectedRows.filter((r) => r !== value));
69
69
  if (userAction) set$1(selectedData, get$1(internalSelectedData));
70
70
  }
71
71
  function onCheckboxClick(event, value, index) {
@@ -88,10 +88,20 @@ function useTableSelection(options, deps) {
88
88
  else {
89
89
  const from = Math.min(lastIndex, index);
90
90
  const to = Math.max(lastIndex, index);
91
+ const currentSelected = get$1(internalSelectedData);
92
+ const rangeIds = [];
91
93
  for (let i = from; i <= to; i++) {
92
94
  const currSelectedData = tableData[i];
93
95
  assert(currSelectedData);
94
- if (isRow(currSelectedData) && !isDisabledRow(currSelectedData[rowAttr])) onSelect(valueToApply, currSelectedData[rowAttr]);
96
+ if (isRow(currSelectedData) && !isDisabledRow(currSelectedData[rowAttr])) rangeIds.push(currSelectedData[rowAttr]);
97
+ }
98
+ if (valueToApply) {
99
+ const existing = new Set(currentSelected);
100
+ const toAdd = rangeIds.filter((id) => !existing.has(id));
101
+ set$1(internalSelectedData, [...currentSelected, ...toAdd]);
102
+ } else {
103
+ const toRemove = new Set(rangeIds);
104
+ set$1(internalSelectedData, currentSelected.filter((id) => !toRemove.has(id)));
95
105
  }
96
106
  }
97
107
  set$1(lastSelectedIndex, index);
@@ -1 +1 @@
1
- {"version":3,"file":"selection.js","names":[],"sources":["../../../../src/composables/tables/data-table/selection.ts"],"sourcesContent":["import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';\nimport { type GroupedTableRow, isRow } from '@/composables/tables/data-table/types';\nimport { useTimeoutManager } from '@/composables/timeout-manager';\nimport { assert } from '@/utils/assert';\n\nexport interface UseTableSelectionOptions<T extends object, IdType extends keyof T> {\n /** The property on each row used as the unique row identifier. */\n rowAttr: IdType;\n /** Whether selection persists across pages. */\n multiPageSelect: boolean;\n /** Rows that cannot be selected or deselected by the user. */\n disabledRows: MaybeRefOrGetter<readonly T[] | undefined>;\n}\n\nexport interface UseTableSelectionDeps<T extends object, IdType extends keyof T> {\n selectedData: Ref<T[IdType][] | undefined>;\n filtered: ComputedRef<GroupedTableRow<T>[]>;\n}\n\nexport interface UseTableSelectionReturn<T extends object, IdType extends keyof T> {\n visibleIdentifiers: ComputedRef<T[IdType][]>;\n isAllSelected: ComputedRef<boolean>;\n indeterminate: ComputedRef<boolean>;\n isSelected: (identifier: T[IdType]) => boolean;\n isDisabledRow: (rowKey: T[IdType]) => boolean;\n isSelectable: (rowKey: T[IdType]) => boolean;\n mustSelect: (rowKey: T[IdType]) => boolean;\n onToggleAll: (checked: boolean) => void;\n onSelect: (checked: boolean, value: T[IdType], userAction?: boolean) => void;\n onCheckboxClick: (event: MouseEvent, value: T[IdType], index: number) => void;\n deselectRemovedRows: () => void;\n resetCheckboxShiftState: () => void;\n}\n\nexport function useTableSelection<T extends object, IdType extends keyof T>(\n options: UseTableSelectionOptions<T, IdType>,\n deps: UseTableSelectionDeps<T, IdType>,\n): UseTableSelectionReturn<T, IdType> {\n const { rowAttr, multiPageSelect, disabledRows } = options;\n const { selectedData, filtered } = deps;\n\n const shiftClicked: Ref<boolean> = shallowRef(false);\n const lastSelectedIndex: Ref<number> = shallowRef(-1);\n const internalSelectedData: Ref<T[IdType][]> = ref([]);\n const { create: scheduleShiftSelect } = useTimeoutManager();\n\n // Sync external selection model to internal state\n watch(selectedData, val => set(internalSelectedData, val), { immediate: true });\n\n const visibleIdentifiers = computed<T[IdType][]>(() =>\n get(filtered)\n .filter(isRow)\n .map(row => row[rowAttr]),\n );\n\n const selectedSet = computed<Set<T[IdType]>>(() => new Set(get(selectedData) ?? []));\n\n const disabledRowKeySet = computed<Set<T[IdType]>>(() => {\n const currentDisabledRows = toValue(disabledRows);\n if (!currentDisabledRows || !rowAttr)\n return new Set<T[IdType]>();\n return new Set<T[IdType]>(currentDisabledRows.map((row: T) => row[rowAttr]));\n });\n\n const isAllSelected = computed<boolean>(() => {\n const selectedRows = get(selectedData);\n if (!selectedRows || selectedRows.length === 0)\n return false;\n\n const selected = get(selectedSet);\n return get(visibleIdentifiers).every(id => selected.has(id));\n });\n\n const indeterminate = computed<boolean>(() => {\n const selectedRows = get(selectedData);\n if (!selectedRows)\n return false;\n\n return selectedRows.length > 0 && !get(isAllSelected);\n });\n\n function isSelected(identifier: T[IdType]): boolean {\n return get(selectedSet).has(identifier);\n }\n\n function isDisabledRow(rowKey: T[IdType]): boolean {\n return get(disabledRowKeySet).has(rowKey);\n }\n\n function isSelectable(rowKey: T[IdType]): boolean {\n return isSelected(rowKey) || !isDisabledRow(rowKey);\n }\n\n function mustSelect(rowKey: T[IdType]): boolean {\n return isSelected(rowKey) && isDisabledRow(rowKey);\n }\n\n function resetCheckboxShiftState(): void {\n set(shiftClicked, false);\n set(lastSelectedIndex, -1);\n }\n\n function onToggleAll(checked: boolean): void {\n const selectedRows = get(selectedData);\n\n if (!isDefined(selectedRows))\n return;\n\n if (!multiPageSelect) {\n if (checked)\n set(selectedData, get(visibleIdentifiers).filter(isSelectable));\n else set(selectedData, get(visibleIdentifiers).filter(mustSelect));\n }\n else {\n if (checked) {\n set(\n selectedData,\n Array.from(new Set([...selectedRows, ...get(visibleIdentifiers).filter(isSelectable)])),\n );\n }\n else {\n const visibleSet = new Set(get(visibleIdentifiers));\n const mustSelectSet = new Set(get(visibleIdentifiers).filter(mustSelect));\n set(\n selectedData,\n selectedRows.filter(rowKey => !visibleSet.has(rowKey) || mustSelectSet.has(rowKey)),\n );\n }\n }\n }\n\n function onSelect(checked: boolean, value: T[IdType], userAction: boolean = false): void {\n if (get(shiftClicked) && userAction)\n return;\n\n const selectedRows = get(internalSelectedData);\n if (!selectedRows)\n return;\n\n const selected = isSelected(value);\n\n if (checked && !selected) {\n set(internalSelectedData, [...selectedRows, value]);\n }\n else if (!checked && selected) {\n set(\n internalSelectedData,\n [...selectedRows].filter(r => r !== value),\n );\n }\n\n if (userAction)\n set(selectedData, get(internalSelectedData));\n }\n\n function onCheckboxClick(event: MouseEvent, value: T[IdType], index: number): void {\n const currentTarget = event.currentTarget;\n if (!(currentTarget instanceof HTMLElement))\n return;\n\n const input = currentTarget.querySelector('input');\n const target = event.target;\n const nodeName = target instanceof HTMLElement ? target.nodeName : undefined;\n\n const shiftKey = event.shiftKey;\n set(shiftClicked, shiftKey);\n\n if (input && nodeName !== 'INPUT') {\n if (shiftKey) {\n scheduleShiftSelect(() => {\n let lastIndex = get(lastSelectedIndex);\n if (lastIndex === -1)\n lastIndex = index;\n const tableData = get(filtered);\n const lastSelectedData = tableData[lastIndex];\n assert(lastSelectedData);\n\n if (isRow(lastSelectedData)) {\n const valueToApply = isSelected(lastSelectedData[rowAttr]);\n\n if (lastIndex === index) {\n onSelect(!valueToApply, value);\n }\n else {\n const from = Math.min(lastIndex, index);\n const to = Math.max(lastIndex, index);\n\n for (let i = from; i <= to; i++) {\n const currSelectedData = tableData[i];\n assert(currSelectedData);\n if (isRow(currSelectedData) && !isDisabledRow(currSelectedData[rowAttr]))\n onSelect(valueToApply, currSelectedData[rowAttr]);\n }\n }\n\n set(lastSelectedIndex, index);\n set(selectedData, get(internalSelectedData));\n }\n }, 1);\n }\n else {\n set(lastSelectedIndex, index);\n }\n }\n }\n\n function deselectRemovedRows(): void {\n const currentSelected = get(selectedData);\n if (!currentSelected)\n return;\n\n const visibleSet = new Set(get(visibleIdentifiers));\n const remaining = currentSelected.filter(key => visibleSet.has(key));\n\n if (remaining.length !== currentSelected.length)\n set(selectedData, remaining);\n }\n\n return {\n visibleIdentifiers,\n isAllSelected,\n indeterminate,\n isSelected,\n isDisabledRow,\n isSelectable,\n mustSelect,\n onToggleAll,\n onSelect,\n onCheckboxClick,\n deselectRemovedRows,\n resetCheckboxShiftState,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"selection.js","names":[],"sources":["../../../../src/composables/tables/data-table/selection.ts"],"sourcesContent":["import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';\nimport { type GroupedTableRow, isRow } from '@/composables/tables/data-table/types';\nimport { useTimeoutManager } from '@/composables/timeout-manager';\nimport { assert } from '@/utils/assert';\n\nexport interface UseTableSelectionOptions<T extends object, IdType extends keyof T> {\n /** The property on each row used as the unique row identifier. */\n rowAttr: IdType;\n /** Whether selection persists across pages. */\n multiPageSelect: boolean;\n /** Rows that cannot be selected or deselected by the user. */\n disabledRows: MaybeRefOrGetter<readonly T[] | undefined>;\n}\n\nexport interface UseTableSelectionDeps<T extends object, IdType extends keyof T> {\n selectedData: Ref<T[IdType][] | undefined>;\n filtered: ComputedRef<GroupedTableRow<T>[]>;\n}\n\nexport interface UseTableSelectionReturn<T extends object, IdType extends keyof T> {\n visibleIdentifiers: ComputedRef<T[IdType][]>;\n isAllSelected: ComputedRef<boolean>;\n indeterminate: ComputedRef<boolean>;\n isSelected: (identifier: T[IdType]) => boolean;\n isDisabledRow: (rowKey: T[IdType]) => boolean;\n isSelectable: (rowKey: T[IdType]) => boolean;\n mustSelect: (rowKey: T[IdType]) => boolean;\n onToggleAll: (checked: boolean) => void;\n onSelect: (checked: boolean, value: T[IdType], userAction?: boolean) => void;\n onCheckboxClick: (event: MouseEvent, value: T[IdType], index: number) => void;\n deselectRemovedRows: () => void;\n resetCheckboxShiftState: () => void;\n}\n\nexport function useTableSelection<T extends object, IdType extends keyof T>(\n options: UseTableSelectionOptions<T, IdType>,\n deps: UseTableSelectionDeps<T, IdType>,\n): UseTableSelectionReturn<T, IdType> {\n const { rowAttr, multiPageSelect, disabledRows } = options;\n const { selectedData, filtered } = deps;\n\n const shiftClicked: Ref<boolean> = shallowRef(false);\n const lastSelectedIndex: Ref<number> = shallowRef(-1);\n const internalSelectedData: Ref<T[IdType][]> = shallowRef([]);\n const { create: scheduleShiftSelect } = useTimeoutManager();\n\n // Sync external selection model to internal state\n watch(selectedData, val => set(internalSelectedData, val ?? []), { immediate: true });\n\n const visibleIdentifiers = computed<T[IdType][]>(() =>\n get(filtered)\n .filter(isRow)\n .map(row => row[rowAttr]),\n );\n\n const selectedSet = computed<Set<T[IdType]>>(() => new Set(get(selectedData) ?? []));\n\n const disabledRowKeySet = computed<Set<T[IdType]>>(() => {\n const currentDisabledRows = toValue(disabledRows);\n if (!currentDisabledRows || !rowAttr)\n return new Set<T[IdType]>();\n return new Set<T[IdType]>(currentDisabledRows.map((row: T) => row[rowAttr]));\n });\n\n const isAllSelected = computed<boolean>(() => {\n const selectedRows = get(selectedData);\n if (!selectedRows || selectedRows.length === 0)\n return false;\n\n const selected = get(selectedSet);\n return get(visibleIdentifiers).every(id => selected.has(id));\n });\n\n const indeterminate = computed<boolean>(() => {\n const selectedRows = get(selectedData);\n if (!selectedRows)\n return false;\n\n return selectedRows.length > 0 && !get(isAllSelected);\n });\n\n function isSelected(identifier: T[IdType]): boolean {\n return get(selectedSet).has(identifier);\n }\n\n function isDisabledRow(rowKey: T[IdType]): boolean {\n return get(disabledRowKeySet).has(rowKey);\n }\n\n function isSelectable(rowKey: T[IdType]): boolean {\n return isSelected(rowKey) || !isDisabledRow(rowKey);\n }\n\n function mustSelect(rowKey: T[IdType]): boolean {\n return isSelected(rowKey) && isDisabledRow(rowKey);\n }\n\n function resetCheckboxShiftState(): void {\n set(shiftClicked, false);\n set(lastSelectedIndex, -1);\n }\n\n function onToggleAll(checked: boolean): void {\n const selectedRows = get(selectedData);\n\n if (!isDefined(selectedRows))\n return;\n\n if (!multiPageSelect) {\n if (checked)\n set(selectedData, get(visibleIdentifiers).filter(isSelectable));\n else set(selectedData, get(visibleIdentifiers).filter(mustSelect));\n }\n else {\n if (checked) {\n set(\n selectedData,\n Array.from(new Set([...selectedRows, ...get(visibleIdentifiers).filter(isSelectable)])),\n );\n }\n else {\n const visibleSet = new Set(get(visibleIdentifiers));\n const mustSelectSet = new Set(get(visibleIdentifiers).filter(mustSelect));\n set(\n selectedData,\n selectedRows.filter(rowKey => !visibleSet.has(rowKey) || mustSelectSet.has(rowKey)),\n );\n }\n }\n }\n\n function onSelect(checked: boolean, value: T[IdType], userAction: boolean = false): void {\n if (get(shiftClicked) && userAction)\n return;\n\n const selectedRows = get(internalSelectedData);\n if (!selectedRows)\n return;\n\n const selected = isSelected(value);\n\n if (checked && !selected) {\n set(internalSelectedData, [...selectedRows, value]);\n }\n else if (!checked && selected) {\n set(\n internalSelectedData,\n selectedRows.filter(r => r !== value),\n );\n }\n\n if (userAction)\n set(selectedData, get(internalSelectedData));\n }\n\n function onCheckboxClick(event: MouseEvent, value: T[IdType], index: number): void {\n const currentTarget = event.currentTarget;\n if (!(currentTarget instanceof HTMLElement))\n return;\n\n const input = currentTarget.querySelector('input');\n const target = event.target;\n const nodeName = target instanceof HTMLElement ? target.nodeName : undefined;\n\n const shiftKey = event.shiftKey;\n set(shiftClicked, shiftKey);\n\n if (input && nodeName !== 'INPUT') {\n if (shiftKey) {\n scheduleShiftSelect(() => {\n let lastIndex = get(lastSelectedIndex);\n if (lastIndex === -1)\n lastIndex = index;\n const tableData = get(filtered);\n const lastSelectedData = tableData[lastIndex];\n assert(lastSelectedData);\n\n if (isRow(lastSelectedData)) {\n const valueToApply = isSelected(lastSelectedData[rowAttr]);\n\n if (lastIndex === index) {\n onSelect(!valueToApply, value);\n }\n else {\n const from = Math.min(lastIndex, index);\n const to = Math.max(lastIndex, index);\n\n // Batch: collect all IDs in range, then update once\n const currentSelected = get(internalSelectedData);\n const rangeIds: T[IdType][] = [];\n for (let i = from; i <= to; i++) {\n const currSelectedData = tableData[i];\n assert(currSelectedData);\n if (isRow(currSelectedData) && !isDisabledRow(currSelectedData[rowAttr]))\n rangeIds.push(currSelectedData[rowAttr]);\n }\n\n if (valueToApply) {\n const existing = new Set(currentSelected);\n const toAdd = rangeIds.filter(id => !existing.has(id));\n set(internalSelectedData, [...currentSelected, ...toAdd]);\n }\n else {\n const toRemove = new Set(rangeIds);\n set(internalSelectedData, currentSelected.filter(id => !toRemove.has(id)));\n }\n }\n\n set(lastSelectedIndex, index);\n set(selectedData, get(internalSelectedData));\n }\n }, 1);\n }\n else {\n set(lastSelectedIndex, index);\n }\n }\n }\n\n function deselectRemovedRows(): void {\n const currentSelected = get(selectedData);\n if (!currentSelected)\n return;\n\n const visibleSet = new Set(get(visibleIdentifiers));\n const remaining = currentSelected.filter(key => visibleSet.has(key));\n\n if (remaining.length !== currentSelected.length)\n set(selectedData, remaining);\n }\n\n return {\n visibleIdentifiers,\n isAllSelected,\n indeterminate,\n isSelected,\n isDisabledRow,\n isSelectable,\n mustSelect,\n onToggleAll,\n onSelect,\n onCheckboxClick,\n deselectRemovedRows,\n resetCheckboxShiftState,\n };\n}\n"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';
2
2
  import type { SortColumn, TableRowKey, TableSortData } from '../../../components/tables/RuiTableHead.vue';
3
3
  import type { TablePaginationData } from '../../../components/tables/RuiTablePagination.vue';
4
+ import { SortDirection } from '../../../components/tables/table-props.js';
4
5
  export interface UseTableSortOptions<T extends object> {
5
6
  /** The data rows to sort. */
6
7
  rows: MaybeRefOrGetter<readonly T[]>;
@@ -20,13 +21,13 @@ export interface UseTableSortDeps<T extends object> {
20
21
  export interface UseTableSortReturn<T extends object> {
21
22
  sortData: ComputedRef<TableSortData<T>>;
22
23
  sortedMap: ComputedRef<Partial<Record<TableRowKey<T>, SortColumn<T>>>>;
23
- searchData: ComputedRef<T[]>;
24
- sorted: ComputedRef<T[]>;
24
+ searchData: ComputedRef<readonly T[]>;
25
+ sorted: ComputedRef<readonly T[]>;
25
26
  isSortedBy: (key: TableRowKey<T>) => boolean;
26
27
  getSortIndex: (key: TableRowKey<T>) => number;
27
28
  onSort: (payload: {
28
29
  key: TableRowKey<T>;
29
- direction?: 'asc' | 'desc';
30
+ direction?: SortDirection;
30
31
  }) => void;
31
32
  }
32
33
  export declare function useTableSort<T extends object>(options: UseTableSortOptions<T>, deps: UseTableSortDeps<T>): UseTableSortReturn<T>;
@@ -1,4 +1,6 @@
1
1
  import { assert } from "../../../utils/assert.js";
2
+ import { SortDirection } from "../../../components/tables/table-props.js";
3
+ import { getObjectKeys } from "./types.js";
2
4
  import { computed, toValue } from "vue";
3
5
  import { get, set } from "@vueuse/shared";
4
6
  //#region src/composables/tables/data-table/sort.ts
@@ -6,10 +8,26 @@ var SORT_COLLATOR = new Intl.Collator(void 0, {
6
8
  sensitivity: "accent",
7
9
  usage: "sort"
8
10
  });
11
+ function toggleDirection(direction) {
12
+ return direction === SortDirection.asc ? SortDirection.desc : SortDirection.asc;
13
+ }
14
+ /**
15
+ * Detect whether each column contains numeric data by sampling the first non-null value.
16
+ */
17
+ function detectNumericColumns(activeColumns, data) {
18
+ const isNumericCol = /* @__PURE__ */ new Map();
19
+ for (const key of activeColumns) for (const row of data) {
20
+ const val = row[key];
21
+ if (val != null) {
22
+ isNumericCol.set(key, !Number.isNaN(Number(val)));
23
+ break;
24
+ }
25
+ }
26
+ return isNumericCol;
27
+ }
9
28
  function useTableSort(options, deps) {
10
29
  const { rows, search, sortModifiersExternal } = options;
11
30
  const { sort, pagination, emitUpdateOptions } = deps;
12
- const getKeys = (t) => Object.keys(t);
13
31
  const sortData = computed({
14
32
  get() {
15
33
  return get(sort);
@@ -36,30 +54,47 @@ function useTableSort(options, deps) {
36
54
  return acc;
37
55
  }, mapped);
38
56
  });
57
+ const searchIndex = computed(() => {
58
+ if (!toValue(search)) return /* @__PURE__ */ new Map();
59
+ const currentRows = toValue(rows);
60
+ const index = /* @__PURE__ */ new Map();
61
+ for (const row of currentRows) {
62
+ const parts = [];
63
+ for (const key of getObjectKeys(row)) parts.push(`${row[key]}`);
64
+ index.set(row, parts.join("\0").toLocaleLowerCase());
65
+ }
66
+ return index;
67
+ });
39
68
  const searchData = computed(() => {
40
69
  const currentRows = toValue(rows);
41
70
  const query = toValue(search)?.toLocaleLowerCase();
42
- if (!query) return [...currentRows];
43
- return currentRows.filter((row) => getKeys(row).some((key) => `${row[key]}`.toLocaleLowerCase().includes(query)));
71
+ if (!query) return currentRows;
72
+ const index = get(searchIndex);
73
+ return currentRows.filter((row) => {
74
+ return index.get(row)?.includes(query) ?? false;
75
+ });
44
76
  });
45
77
  const sorted = computed(() => {
46
78
  const sortBy = get(sortData);
47
79
  if (!sortBy || sortModifiersExternal) return get(searchData);
48
80
  const data = [...get(searchData)];
49
- const sortFn = (by) => {
50
- data.sort((a, b) => {
51
- const column = by.column;
52
- if (!column) return 0;
53
- let [aValue, bValue] = [a[column], b[column]];
54
- if (by.direction === "desc") [aValue, bValue] = [bValue, aValue];
55
- const aNumber = Number(aValue);
56
- const bNumber = Number(bValue);
57
- if (!isNaN(aNumber) && !isNaN(bNumber)) return aNumber - bNumber;
58
- return SORT_COLLATOR.compare(`${aValue}`, `${bValue}`);
59
- });
60
- };
61
- if (!Array.isArray(sortBy)) sortFn(sortBy);
62
- else [...sortBy].reverse().forEach(sortFn);
81
+ const sortColumns = Array.isArray(sortBy) ? sortBy : [sortBy];
82
+ const activeColumns = sortColumns.map((col) => col.column).filter((col) => !!col);
83
+ if (activeColumns.length === 0) return data;
84
+ const isNumericCol = detectNumericColumns(activeColumns, data);
85
+ const directionMap = /* @__PURE__ */ new Map();
86
+ for (const col of sortColumns) if (col.column) directionMap.set(col.column, col.direction ?? SortDirection.asc);
87
+ data.sort((a, b) => {
88
+ for (const key of activeColumns) {
89
+ let [aVal, bVal] = [a[key], b[key]];
90
+ if (directionMap.get(key) === SortDirection.desc) [aVal, bVal] = [bVal, aVal];
91
+ let result;
92
+ if (isNumericCol.get(key)) result = Number(aVal) - Number(bVal);
93
+ else result = SORT_COLLATOR.compare(`${aVal}`, `${bVal}`);
94
+ if (result !== 0) return result;
95
+ }
96
+ return 0;
97
+ });
63
98
  return data;
64
99
  });
65
100
  function isSortedBy(key) {
@@ -70,42 +105,45 @@ function useTableSort(options, deps) {
70
105
  if (!sortBy || !Array.isArray(sortBy) || !isSortedBy(key)) return -1;
71
106
  return sortBy.findIndex((s) => s.column === key);
72
107
  }
73
- function onSort({ key, direction }) {
74
- const sortBy = get(sortData);
75
- if (!sortBy) return;
76
- if (!Array.isArray(sortBy)) {
77
- if (isSortedBy(key)) {
78
- const newDirection = !direction || direction === "asc" ? "desc" : "asc";
79
- if (sortBy.direction === newDirection) set(sortData, {
80
- ...sortBy,
81
- column: void 0,
82
- direction: "asc"
83
- });
84
- else set(sortData, {
85
- ...sortBy,
86
- direction: sortBy.direction === "asc" ? "desc" : "asc"
87
- });
88
- } else set(sortData, {
89
- column: key,
90
- direction: direction || "asc"
108
+ function onSortSingle(sortBy, key, direction) {
109
+ if (isSortedBy(key)) {
110
+ const newDirection = toggleDirection(direction ?? SortDirection.asc);
111
+ if (sortBy.direction === newDirection) set(sortData, {
112
+ ...sortBy,
113
+ column: void 0,
114
+ direction: SortDirection.asc
91
115
  });
92
- return;
93
- }
116
+ else set(sortData, {
117
+ ...sortBy,
118
+ direction: toggleDirection(sortBy.direction)
119
+ });
120
+ } else set(sortData, {
121
+ column: key,
122
+ direction: direction ?? SortDirection.asc
123
+ });
124
+ }
125
+ function onSortMulti(sortBy, key, direction) {
94
126
  if (isSortedBy(key)) {
95
- const newDirection = !direction || direction === "asc" ? "desc" : "asc";
127
+ const newDirection = toggleDirection(direction ?? SortDirection.asc);
96
128
  const index = getSortIndex(key);
97
129
  const sortByCol = sortBy[index];
98
130
  assert(sortByCol);
99
131
  if (sortByCol.direction === newDirection) set(sortData, sortBy.filter((_, i) => i !== index));
100
132
  else set(sortData, sortBy.map((col, i) => i === index ? {
101
133
  ...col,
102
- direction: col.direction === "asc" ? "desc" : "asc"
134
+ direction: toggleDirection(col.direction)
103
135
  } : col));
104
136
  } else set(sortData, [...sortBy, {
105
137
  column: key,
106
- direction: direction || "asc"
138
+ direction: direction ?? SortDirection.asc
107
139
  }]);
108
140
  }
141
+ function onSort({ key, direction }) {
142
+ const sortBy = get(sortData);
143
+ if (!sortBy) return;
144
+ if (Array.isArray(sortBy)) onSortMulti(sortBy, key, direction);
145
+ else onSortSingle(sortBy, key, direction);
146
+ }
109
147
  return {
110
148
  sortData,
111
149
  sortedMap,
@@ -1 +1 @@
1
- {"version":3,"file":"sort.js","names":[],"sources":["../../../../src/composables/tables/data-table/sort.ts"],"sourcesContent":["import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';\nimport type { SortColumn, TableRowKey, TableSortData } from '@/components/tables/RuiTableHead.vue';\nimport type { TablePaginationData } from '@/components/tables/RuiTablePagination.vue';\nimport { assert } from '@/utils/assert';\n\nconst SORT_COLLATOR = new Intl.Collator(undefined, { sensitivity: 'accent', usage: 'sort' });\n\nexport interface UseTableSortOptions<T extends object> {\n /** The data rows to sort. */\n rows: MaybeRefOrGetter<readonly T[]>;\n /** The current search query used to filter rows before sorting. */\n search: MaybeRefOrGetter<string>;\n /** Whether sorting is managed externally (e.g. server-side). */\n sortModifiersExternal: boolean | undefined;\n}\n\nexport interface UseTableSortDeps<T extends object> {\n sort: Ref<TableSortData<T>>;\n pagination: Ref<TablePaginationData | undefined>;\n emitUpdateOptions: (options: {\n sort?: TableSortData<T>;\n pagination?: TablePaginationData;\n }) => void;\n}\n\nexport interface UseTableSortReturn<T extends object> {\n sortData: ComputedRef<TableSortData<T>>;\n sortedMap: ComputedRef<Partial<Record<TableRowKey<T>, SortColumn<T>>>>;\n searchData: ComputedRef<T[]>;\n sorted: ComputedRef<T[]>;\n isSortedBy: (key: TableRowKey<T>) => boolean;\n getSortIndex: (key: TableRowKey<T>) => number;\n onSort: (payload: { key: TableRowKey<T>; direction?: 'asc' | 'desc' }) => void;\n}\n\nexport function useTableSort<T extends object>(\n options: UseTableSortOptions<T>,\n deps: UseTableSortDeps<T>,\n): UseTableSortReturn<T> {\n const { rows, search, sortModifiersExternal } = options;\n const { sort, pagination, emitUpdateOptions } = deps;\n\n const getKeys = <O extends object>(t: O): TableRowKey<O>[] => Object.keys(t) as TableRowKey<O>[];\n\n const sortData = computed<TableSortData<T>>({\n get(): TableSortData<T> {\n return get(sort);\n },\n set(value: TableSortData<T>) {\n set(sort, value);\n emitUpdateOptions({\n sort: value,\n pagination: get(pagination),\n });\n },\n });\n\n const sortedMap = computed<Partial<Record<TableRowKey<T>, SortColumn<T>>>>(() => {\n const mapped: Partial<Record<TableRowKey<T>, SortColumn<T>>> = {};\n const sortBy = get(sortData);\n if (!sortBy)\n return mapped;\n\n if (!Array.isArray(sortBy)) {\n if (sortBy.column)\n mapped[sortBy.column] = sortBy;\n\n return mapped;\n }\n\n return sortBy.reduce((acc, curr) => {\n if (!curr.column)\n return acc;\n\n acc[curr.column] = curr;\n return acc;\n }, mapped);\n });\n\n const searchData = computed<T[]>(() => {\n const currentRows = toValue(rows);\n const query = toValue(search)?.toLocaleLowerCase();\n if (!query)\n return [...currentRows];\n\n return currentRows.filter(row =>\n getKeys(row).some(key => `${row[key]}`.toLocaleLowerCase().includes(query)),\n );\n });\n\n const sorted: ComputedRef<T[]> = computed(() => {\n const sortBy = get(sortData);\n if (!sortBy || sortModifiersExternal)\n return get(searchData);\n\n const data = [...get(searchData)];\n\n const sortFn = (by: SortColumn<T>): void => {\n data.sort((a, b) => {\n const column = by.column;\n if (!column)\n return 0;\n\n let [aValue, bValue] = [a[column], b[column]];\n if (by.direction === 'desc')\n [aValue, bValue] = [bValue, aValue];\n\n const aNumber = Number(aValue);\n const bNumber = Number(bValue);\n if (!isNaN(aNumber) && !isNaN(bNumber))\n return aNumber - bNumber;\n\n return SORT_COLLATOR.compare(`${aValue}`, `${bValue}`);\n });\n };\n\n if (!Array.isArray(sortBy))\n sortFn(sortBy);\n else [...sortBy].reverse().forEach(sortFn);\n\n return data;\n });\n\n function isSortedBy(key: TableRowKey<T>): boolean {\n return key in get(sortedMap);\n }\n\n function getSortIndex(key: TableRowKey<T>): number {\n const sortBy = get(sortData);\n\n if (!sortBy || !Array.isArray(sortBy) || !isSortedBy(key))\n return -1;\n\n return sortBy.findIndex(s => s.column === key);\n }\n\n function onSort({ key, direction }: { key: TableRowKey<T>; direction?: 'asc' | 'desc' }): void {\n const sortBy = get(sortData);\n if (!sortBy)\n return;\n\n if (!Array.isArray(sortBy)) {\n if (isSortedBy(key)) {\n const newDirection = !direction || direction === 'asc' ? 'desc' : 'asc';\n\n if (sortBy.direction === newDirection) {\n set(sortData, { ...sortBy, column: undefined, direction: 'asc' });\n }\n else {\n set(sortData, {\n ...sortBy,\n direction: sortBy.direction === 'asc' ? 'desc' : 'asc',\n });\n }\n }\n else {\n set(sortData, { column: key, direction: direction || 'asc' });\n }\n return;\n }\n\n if (isSortedBy(key)) {\n const newDirection = !direction || direction === 'asc' ? 'desc' : 'asc';\n\n const index = getSortIndex(key);\n const sortByCol = sortBy[index];\n assert(sortByCol);\n\n if (sortByCol.direction === newDirection) {\n set(\n sortData,\n sortBy.filter((_, i) => i !== index),\n );\n }\n else {\n set(\n sortData,\n sortBy.map((col, i) =>\n i === index ? { ...col, direction: col.direction === 'asc' ? 'desc' : 'asc' } : col,\n ),\n );\n }\n }\n else {\n set(sortData, [...sortBy, { column: key, direction: direction || 'asc' }]);\n }\n }\n\n return {\n sortData,\n sortedMap,\n searchData,\n sorted,\n isSortedBy,\n getSortIndex,\n onSort,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sort.js","names":[],"sources":["../../../../src/composables/tables/data-table/sort.ts"],"sourcesContent":["import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';\nimport type { SortColumn, TableRowKey, TableSortData } from '@/components/tables/RuiTableHead.vue';\nimport type { TablePaginationData } from '@/components/tables/RuiTablePagination.vue';\nimport { SortDirection } from '@/components/tables/table-props';\nimport { getObjectKeys } from '@/composables/tables/data-table/types';\nimport { assert } from '@/utils/assert';\n\nconst SORT_COLLATOR = new Intl.Collator(undefined, { sensitivity: 'accent', usage: 'sort' });\n\nfunction toggleDirection(direction: SortDirection): SortDirection {\n return direction === SortDirection.asc ? SortDirection.desc : SortDirection.asc;\n}\n\nexport interface UseTableSortOptions<T extends object> {\n /** The data rows to sort. */\n rows: MaybeRefOrGetter<readonly T[]>;\n /** The current search query used to filter rows before sorting. */\n search: MaybeRefOrGetter<string>;\n /** Whether sorting is managed externally (e.g. server-side). */\n sortModifiersExternal: boolean | undefined;\n}\n\nexport interface UseTableSortDeps<T extends object> {\n sort: Ref<TableSortData<T>>;\n pagination: Ref<TablePaginationData | undefined>;\n emitUpdateOptions: (options: {\n sort?: TableSortData<T>;\n pagination?: TablePaginationData;\n }) => void;\n}\n\nexport interface UseTableSortReturn<T extends object> {\n sortData: ComputedRef<TableSortData<T>>;\n sortedMap: ComputedRef<Partial<Record<TableRowKey<T>, SortColumn<T>>>>;\n searchData: ComputedRef<readonly T[]>;\n sorted: ComputedRef<readonly T[]>;\n isSortedBy: (key: TableRowKey<T>) => boolean;\n getSortIndex: (key: TableRowKey<T>) => number;\n onSort: (payload: { key: TableRowKey<T>; direction?: SortDirection }) => void;\n}\n\n/**\n * Detect whether each column contains numeric data by sampling the first non-null value.\n */\nfunction detectNumericColumns<T extends object>(\n activeColumns: TableRowKey<T>[],\n data: readonly T[],\n): Map<TableRowKey<T>, boolean> {\n const isNumericCol = new Map<TableRowKey<T>, boolean>();\n for (const key of activeColumns) {\n for (const row of data) {\n const val = row[key];\n if (val != null) {\n isNumericCol.set(key, !Number.isNaN(Number(val)));\n break;\n }\n }\n }\n return isNumericCol;\n}\n\nexport function useTableSort<T extends object>(\n options: UseTableSortOptions<T>,\n deps: UseTableSortDeps<T>,\n): UseTableSortReturn<T> {\n const { rows, search, sortModifiersExternal } = options;\n const { sort, pagination, emitUpdateOptions } = deps;\n\n const sortData = computed<TableSortData<T>>({\n get(): TableSortData<T> {\n return get(sort);\n },\n set(value: TableSortData<T>) {\n set(sort, value);\n emitUpdateOptions({\n sort: value,\n pagination: get(pagination),\n });\n },\n });\n\n const sortedMap = computed<Partial<Record<TableRowKey<T>, SortColumn<T>>>>(() => {\n const mapped: Partial<Record<TableRowKey<T>, SortColumn<T>>> = {};\n const sortBy = get(sortData);\n if (!sortBy)\n return mapped;\n\n if (!Array.isArray(sortBy)) {\n if (sortBy.column)\n mapped[sortBy.column] = sortBy;\n\n return mapped;\n }\n\n return sortBy.reduce((acc, curr) => {\n if (!curr.column)\n return acc;\n\n acc[curr.column] = curr;\n return acc;\n }, mapped);\n });\n\n // Pre-compute a single lowercased searchable string per row, recomputed only when rows change\n const searchIndex = computed<Map<T, string>>(() => {\n if (!toValue(search))\n return new Map<T, string>();\n\n const currentRows = toValue(rows);\n const index = new Map<T, string>();\n for (const row of currentRows) {\n const parts: string[] = [];\n for (const key of getObjectKeys(row))\n parts.push(`${row[key]}`);\n index.set(row, parts.join('\\0').toLocaleLowerCase());\n }\n return index;\n });\n\n const searchData = computed<readonly T[]>(() => {\n const currentRows = toValue(rows);\n const query = toValue(search)?.toLocaleLowerCase();\n if (!query)\n return currentRows;\n\n const index = get(searchIndex);\n return currentRows.filter((row) => {\n const searchStr = index.get(row);\n return searchStr?.includes(query) ?? false;\n });\n });\n\n const sorted: ComputedRef<readonly T[]> = computed(() => {\n const sortBy = get(sortData);\n if (!sortBy || sortModifiersExternal)\n return get(searchData);\n\n const data = [...get(searchData)];\n const sortColumns = Array.isArray(sortBy) ? sortBy : [sortBy];\n const activeColumns = sortColumns\n .map(col => col.column)\n .filter((col): col is TableRowKey<T> => !!col);\n\n if (activeColumns.length === 0)\n return data;\n\n const isNumericCol = detectNumericColumns(activeColumns, data);\n\n // Build a lookup for direction per column\n const directionMap = new Map<TableRowKey<T>, SortDirection>();\n for (const col of sortColumns) {\n if (col.column)\n directionMap.set(col.column, col.direction ?? SortDirection.asc);\n }\n\n data.sort((a, b) => {\n for (const key of activeColumns) {\n let [aVal, bVal] = [a[key], b[key]];\n if (directionMap.get(key) === SortDirection.desc)\n [aVal, bVal] = [bVal, aVal];\n\n let result: number;\n if (isNumericCol.get(key))\n result = Number(aVal) - Number(bVal);\n else\n result = SORT_COLLATOR.compare(`${aVal}`, `${bVal}`);\n\n if (result !== 0)\n return result;\n }\n return 0;\n });\n\n return data;\n });\n\n function isSortedBy(key: TableRowKey<T>): boolean {\n return key in get(sortedMap);\n }\n\n function getSortIndex(key: TableRowKey<T>): number {\n const sortBy = get(sortData);\n\n if (!sortBy || !Array.isArray(sortBy) || !isSortedBy(key))\n return -1;\n\n return sortBy.findIndex(s => s.column === key);\n }\n\n function onSortSingle(\n sortBy: SortColumn<T>,\n key: TableRowKey<T>,\n direction?: SortDirection,\n ): void {\n if (isSortedBy(key)) {\n const newDirection = toggleDirection(direction ?? SortDirection.asc);\n\n if (sortBy.direction === newDirection) {\n set(sortData, { ...sortBy, column: undefined, direction: SortDirection.asc });\n }\n else {\n set(sortData, {\n ...sortBy,\n direction: toggleDirection(sortBy.direction),\n });\n }\n }\n else {\n set(sortData, { column: key, direction: direction ?? SortDirection.asc });\n }\n }\n\n function onSortMulti(\n sortBy: SortColumn<T>[],\n key: TableRowKey<T>,\n direction?: SortDirection,\n ): void {\n if (isSortedBy(key)) {\n const newDirection = toggleDirection(direction ?? SortDirection.asc);\n\n const index = getSortIndex(key);\n const sortByCol = sortBy[index];\n assert(sortByCol);\n\n if (sortByCol.direction === newDirection) {\n set(sortData, sortBy.filter((_, i) => i !== index));\n }\n else {\n set(\n sortData,\n sortBy.map((col, i) =>\n i === index ? { ...col, direction: toggleDirection(col.direction) } : col,\n ),\n );\n }\n }\n else {\n set(sortData, [...sortBy, { column: key, direction: direction ?? SortDirection.asc }]);\n }\n }\n\n function onSort({ key, direction }: { key: TableRowKey<T>; direction?: SortDirection }): void {\n const sortBy = get(sortData);\n if (!sortBy)\n return;\n\n if (Array.isArray(sortBy))\n onSortMulti(sortBy, key, direction);\n else\n onSortSingle(sortBy, key, direction);\n }\n\n return {\n sortData,\n sortedMap,\n searchData,\n sorted,\n isSortedBy,\n getSortIndex,\n onSort,\n };\n}\n"],"mappings":";;;;;;AAOA,IAAM,gBAAgB,IAAI,KAAK,SAAS,KAAA,GAAW;CAAE,aAAa;CAAU,OAAO;AAAO,CAAC;AAE3F,SAAS,gBAAgB,WAAyC;CAChE,OAAO,cAAc,cAAc,MAAM,cAAc,OAAO,cAAc;AAC9E;;;;AAiCA,SAAS,qBACP,eACA,MAC8B;CAC9B,MAAM,+BAAe,IAAI,IAA6B;CACtD,KAAK,MAAM,OAAO,eAChB,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,MAAM,IAAI;EAChB,IAAI,OAAO,MAAM;GACf,aAAa,IAAI,KAAK,CAAC,OAAO,MAAM,OAAO,GAAG,CAAC,CAAC;GAChD;EACF;CACF;CAEF,OAAO;AACT;AAEA,SAAgB,aACd,SACA,MACuB;CACvB,MAAM,EAAE,MAAM,QAAQ,0BAA0B;CAChD,MAAM,EAAE,MAAM,YAAY,sBAAsB;CAEhD,MAAM,WAAW,SAA2B;EAC1C,MAAwB;GACtB,OAAO,IAAI,IAAI;EACjB;EACA,IAAI,OAAyB;GAC3B,IAAI,MAAM,KAAK;GACf,kBAAkB;IAChB,MAAM;IACN,YAAY,IAAI,UAAU;GAC5B,CAAC;EACH;CACF,CAAC;CAED,MAAM,YAAY,eAA+D;EAC/E,MAAM,SAAyD,CAAC;EAChE,MAAM,SAAS,IAAI,QAAQ;EAC3B,IAAI,CAAC,QACH,OAAO;EAET,IAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;GAC1B,IAAI,OAAO,QACT,OAAO,OAAO,UAAU;GAE1B,OAAO;EACT;EAEA,OAAO,OAAO,QAAQ,KAAK,SAAS;GAClC,IAAI,CAAC,KAAK,QACR,OAAO;GAET,IAAI,KAAK,UAAU;GACnB,OAAO;EACT,GAAG,MAAM;CACX,CAAC;CAGD,MAAM,cAAc,eAA+B;EACjD,IAAI,CAAC,QAAQ,MAAM,GACjB,uBAAO,IAAI,IAAe;EAE5B,MAAM,cAAc,QAAQ,IAAI;EAChC,MAAM,wBAAQ,IAAI,IAAe;EACjC,KAAK,MAAM,OAAO,aAAa;GAC7B,MAAM,QAAkB,CAAC;GACzB,KAAK,MAAM,OAAO,cAAc,GAAG,GACjC,MAAM,KAAK,GAAG,IAAI,MAAM;GAC1B,MAAM,IAAI,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,kBAAkB,CAAC;EACrD;EACA,OAAO;CACT,CAAC;CAED,MAAM,aAAa,eAA6B;EAC9C,MAAM,cAAc,QAAQ,IAAI;EAChC,MAAM,QAAQ,QAAQ,MAAM,CAAC,EAAE,kBAAkB;EACjD,IAAI,CAAC,OACH,OAAO;EAET,MAAM,QAAQ,IAAI,WAAW;EAC7B,OAAO,YAAY,QAAQ,QAAQ;GAEjC,OADkB,MAAM,IAAI,GACrB,CAAA,EAAW,SAAS,KAAK,KAAK;EACvC,CAAC;CACH,CAAC;CAED,MAAM,SAAoC,eAAe;EACvD,MAAM,SAAS,IAAI,QAAQ;EAC3B,IAAI,CAAC,UAAU,uBACb,OAAO,IAAI,UAAU;EAEvB,MAAM,OAAO,CAAC,GAAG,IAAI,UAAU,CAAC;EAChC,MAAM,cAAc,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;EAC5D,MAAM,gBAAgB,YACnB,KAAI,QAAO,IAAI,MAAM,CAAC,CACtB,QAAQ,QAA+B,CAAC,CAAC,GAAG;EAE/C,IAAI,cAAc,WAAW,GAC3B,OAAO;EAET,MAAM,eAAe,qBAAqB,eAAe,IAAI;EAG7D,MAAM,+BAAe,IAAI,IAAmC;EAC5D,KAAK,MAAM,OAAO,aAChB,IAAI,IAAI,QACN,aAAa,IAAI,IAAI,QAAQ,IAAI,aAAa,cAAc,GAAG;EAGnE,KAAK,MAAM,GAAG,MAAM;GAClB,KAAK,MAAM,OAAO,eAAe;IAC/B,IAAI,CAAC,MAAM,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI;IAClC,IAAI,aAAa,IAAI,GAAG,MAAM,cAAc,MAC1C,CAAC,MAAM,QAAQ,CAAC,MAAM,IAAI;IAE5B,IAAI;IACJ,IAAI,aAAa,IAAI,GAAG,GACtB,SAAS,OAAO,IAAI,IAAI,OAAO,IAAI;SAEnC,SAAS,cAAc,QAAQ,GAAG,QAAQ,GAAG,MAAM;IAErD,IAAI,WAAW,GACb,OAAO;GACX;GACA,OAAO;EACT,CAAC;EAED,OAAO;CACT,CAAC;CAED,SAAS,WAAW,KAA8B;EAChD,OAAO,OAAO,IAAI,SAAS;CAC7B;CAEA,SAAS,aAAa,KAA6B;EACjD,MAAM,SAAS,IAAI,QAAQ;EAE3B,IAAI,CAAC,UAAU,CAAC,MAAM,QAAQ,MAAM,KAAK,CAAC,WAAW,GAAG,GACtD,OAAO;EAET,OAAO,OAAO,WAAU,MAAK,EAAE,WAAW,GAAG;CAC/C;CAEA,SAAS,aACP,QACA,KACA,WACM;EACN,IAAI,WAAW,GAAG,GAAG;GACnB,MAAM,eAAe,gBAAgB,aAAa,cAAc,GAAG;GAEnE,IAAI,OAAO,cAAc,cACvB,IAAI,UAAU;IAAE,GAAG;IAAQ,QAAQ,KAAA;IAAW,WAAW,cAAc;GAAI,CAAC;QAG5E,IAAI,UAAU;IACZ,GAAG;IACH,WAAW,gBAAgB,OAAO,SAAS;GAC7C,CAAC;EAEL,OAEE,IAAI,UAAU;GAAE,QAAQ;GAAK,WAAW,aAAa,cAAc;EAAI,CAAC;CAE5E;CAEA,SAAS,YACP,QACA,KACA,WACM;EACN,IAAI,WAAW,GAAG,GAAG;GACnB,MAAM,eAAe,gBAAgB,aAAa,cAAc,GAAG;GAEnE,MAAM,QAAQ,aAAa,GAAG;GAC9B,MAAM,YAAY,OAAO;GACzB,OAAO,SAAS;GAEhB,IAAI,UAAU,cAAc,cAC1B,IAAI,UAAU,OAAO,QAAQ,GAAG,MAAM,MAAM,KAAK,CAAC;QAGlD,IACE,UACA,OAAO,KAAK,KAAK,MACf,MAAM,QAAQ;IAAE,GAAG;IAAK,WAAW,gBAAgB,IAAI,SAAS;GAAE,IAAI,GACxE,CACF;EAEJ,OAEE,IAAI,UAAU,CAAC,GAAG,QAAQ;GAAE,QAAQ;GAAK,WAAW,aAAa,cAAc;EAAI,CAAC,CAAC;CAEzF;CAEA,SAAS,OAAO,EAAE,KAAK,aAAuE;EAC5F,MAAM,SAAS,IAAI,QAAQ;EAC3B,IAAI,CAAC,QACH;EAEF,IAAI,MAAM,QAAQ,MAAM,GACtB,YAAY,QAAQ,KAAK,SAAS;OAElC,aAAa,QAAQ,KAAK,SAAS;CACvC;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF"}
@@ -4,11 +4,13 @@ export interface TableOptions<T> {
4
4
  pagination?: TablePaginationData;
5
5
  sort?: TableSortData<T>;
6
6
  }
7
+ export declare const GROUP_HEADER_BRAND: unique symbol;
7
8
  export interface GroupHeader<T> {
8
- __header__: true;
9
+ [GROUP_HEADER_BRAND]: true;
9
10
  identifier: string;
10
11
  group: Partial<T>;
11
12
  }
12
13
  export type GroupedTableRow<T> = T | GroupHeader<T>;
13
14
  export declare function isRow<T extends object>(item: GroupedTableRow<T>): item is T;
14
15
  export declare function isHeaderSlot(slotName: string): slotName is `header.${string}`;
16
+ export declare function getObjectKeys<O extends object>(obj: O): (string & keyof O)[];