@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.
- package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/accordions/accordions/RuiAccordions.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/accordions/accordions/RuiAccordions.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/alerts/RuiAlert.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/alerts/RuiAlert.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/avatars/RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/avatars/RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/avatars/avatar-props.js +1 -1
- package/dist/components/avatars/avatar-props.js.map +1 -1
- package/dist/components/avatars/use-avatar-group.js.map +1 -1
- package/dist/components/buttons/button/RuiButton.js.map +1 -1
- package/dist/components/buttons/button/RuiButton.vue.d.ts +2 -2
- package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/buttons/button/button-props.js.map +1 -1
- package/dist/components/buttons/button/button-styles.js.map +1 -1
- package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/RuiCalendarHeader.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/calendar/RuiCalendarHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/state.js.map +1 -1
- package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/cards/RuiCardHeader.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/cards/RuiCardHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/chips/chip-props.js.map +1 -1
- package/dist/components/color-picker/RuiColorBoard.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/color-picker/RuiColorBoard.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/RuiColorDisplay.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/color-picker/RuiColorDisplay.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/RuiColorHue.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/color-picker/RuiColorHue.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-picker/utils.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-time-picker/date-time-picker-styles.js.map +1 -1
- package/dist/components/date-time-picker/dayjs-setup.js.map +1 -1
- package/dist/components/date-time-picker/segment-config.js.map +1 -1
- package/dist/components/date-time-picker/segment-utils.js.map +1 -1
- package/dist/components/date-time-picker/timezones.js.map +1 -1
- package/dist/components/date-time-picker/types.js +1 -1
- package/dist/components/date-time-picker/types.js.map +1 -1
- package/dist/components/date-time-picker/use-date-time-selection.js +2 -2
- package/dist/components/date-time-picker/use-date-time-selection.js.map +1 -1
- package/dist/components/date-time-picker/use-input-handler.js.map +1 -1
- package/dist/components/date-time-picker/use-keyboard-handler.js.map +1 -1
- package/dist/components/date-time-picker/utils.js.map +1 -1
- package/dist/components/divider/RuiDivider.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/divider/RuiDivider.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoComplete.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue.d.ts +14 -1
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js +15 -5
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/auto-complete/auto-complete-styles.js.map +1 -1
- package/dist/components/forms/category-picker/RuiCategoryPicker.js +7 -0
- package/dist/components/forms/category-picker/RuiCategoryPicker.js.map +1 -0
- package/dist/components/forms/category-picker/RuiCategoryPicker.vue.d.ts +134 -0
- package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js +561 -0
- package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/forms/category-picker/category-picker-styles.d.ts +432 -0
- package/dist/components/forms/category-picker/category-picker-styles.js +59 -0
- package/dist/components/forms/category-picker/category-picker-styles.js.map +1 -0
- package/dist/components/forms/check-control-styles.js.map +1 -1
- package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/checkbox/checkbox-group/context.js.map +1 -1
- package/dist/components/forms/file-upload/RuiFileUpload.js.map +1 -1
- package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/select/RuiSimpleSelect.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/select/RuiSimpleSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/select/menu-select-styles.js.map +1 -1
- package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/slider/slider-styles.js.map +1 -1
- package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/text-area/text-area-styles.js.map +1 -1
- package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/text-field/text-field-styles.js.map +1 -1
- package/dist/components/forms/text-input-styles.js.map +1 -1
- package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/index.d.ts +3 -2
- package/dist/components/index.js +3 -2
- package/dist/components/loaders/RuiSkeletonBase.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/loaders/RuiSkeletonBase.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/loaders/RuiSkeletonLoader.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/loaders/RuiSkeletonLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/loaders/skeleton-type.js.map +1 -1
- package/dist/components/logos/RuiLogo.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/logos/RuiLogo.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/logos/use-logo-sources.js.map +1 -1
- package/dist/components/overlays/badge/RuiBadge.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/overlays/badge/RuiBadge.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/badge/badge-props.js.map +1 -1
- package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/dialog/RuiDialog.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/overlays/dialog/RuiDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/tooltip/RuiTooltip.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/overlays/tooltip/RuiTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/overlays/tooltip/tooltip-styles.js.map +1 -1
- package/dist/components/progress/RuiProgress.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/progress/RuiProgress.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/progress/progress-props.js.map +1 -1
- package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/steppers/RuiStepperCustomIcon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/steppers/RuiStepperCustomIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/steppers/RuiStepperIcon.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/steppers/RuiStepperIcon.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/steppers/footer-stepper-variant.js.map +1 -1
- package/dist/components/tables/RuiDataTable.js.map +1 -1
- package/dist/components/tables/RuiDataTable.vue.d.ts +23 -2
- package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js +186 -217
- package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiExpandButton.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/tables/RuiExpandButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiTableEmptyState.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/tables/RuiTableEmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiTableHead.js.map +1 -1
- package/dist/components/tables/RuiTableHead.vue.d.ts +11 -1
- package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js +1 -2
- package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiTablePagination.js.map +1 -1
- package/dist/components/tables/RuiTablePagination.vue.d.ts +5 -0
- package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js +24 -8
- package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableBody.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableBody.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableBody.vue.d.ts +55 -0
- package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js +78 -0
- package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableCell.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableCell.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableCell.vue.d.ts +30 -0
- package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js +54 -0
- package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableEmptyRow.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableEmptyRow.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableEmptyRow.vue.d.ts +19 -0
- package/dist/components/tables/data-table/RuiDataTableEmptyRow.vue_vue_type_script_setup_true_lang.js +43 -0
- package/dist/components/tables/data-table/RuiDataTableEmptyRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue.d.ts +26 -0
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js +31 -0
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableGroupRow.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableGroupRow.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableGroupRow.vue.d.ts +32 -0
- package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js +85 -0
- package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableLoadingRow.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableLoadingRow.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableLoadingRow.vue.d.ts +3 -0
- package/dist/components/tables/data-table/RuiDataTableLoadingRow.vue_vue_type_script_setup_true_lang.js +26 -0
- package/dist/components/tables/data-table/RuiDataTableLoadingRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableMobileSort.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableMobileSort.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableMobileSort.vue.d.ts +33 -0
- package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js +101 -0
- package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableRow.js +7 -0
- package/dist/components/tables/data-table/RuiDataTableRow.js.map +1 -0
- package/dist/components/tables/data-table/RuiDataTableRow.vue.d.ts +31 -0
- package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js +142 -0
- package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tables/data-table/context.d.ts +73 -0
- package/dist/components/tables/data-table/context.js +100 -0
- package/dist/components/tables/data-table/context.js.map +1 -0
- package/dist/components/tables/data-table-styles.d.ts +30 -1
- package/dist/components/tables/data-table-styles.js +9 -2
- package/dist/components/tables/data-table-styles.js.map +1 -1
- package/dist/components/tables/table-props.d.ts +5 -0
- package/dist/components/tables/table-props.js +5 -1
- package/dist/components/tables/table-props.js.map +1 -1
- package/dist/components/tables/use-pagination-navigation.js.map +1 -1
- package/dist/components/tabs/tab/RuiTab.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/tabs/tab/RuiTab.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tab/use-tab-link.js.map +1 -1
- package/dist/components/tabs/tab-item/RuiTabItem.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/tabs/tab-item/RuiTabItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tab-items/RuiTabItems.js.map +1 -1
- package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tab-props.js.map +1 -1
- package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/tabs/use-tab-routing.js +1 -1
- package/dist/components/tabs/tabs/use-tab-routing.js.map +1 -1
- package/dist/components/tabs/tabs/use-tab-scroll.js.map +1 -1
- package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/time-picker/time-picker-styles.js.map +1 -1
- package/dist/composables/breakpoint.js.map +1 -1
- package/dist/composables/defaults/table.d.ts +12 -0
- package/dist/composables/defaults/table.js.map +1 -1
- package/dist/composables/dropdown-menu.js.map +1 -1
- package/dist/composables/floating.js +1 -1
- package/dist/composables/floating.js.map +1 -1
- package/dist/composables/forms/auto-complete/focus.js.map +1 -1
- package/dist/composables/forms/auto-complete/index.js +5 -4
- package/dist/composables/forms/auto-complete/keyboard-navigation.js.map +1 -1
- package/dist/composables/forms/auto-complete/search.d.ts +6 -1
- package/dist/composables/forms/auto-complete/search.js +12 -1
- package/dist/composables/forms/auto-complete/search.js.map +1 -1
- package/dist/composables/forms/auto-complete/value.js.map +1 -1
- package/dist/composables/forms/category-picker/use-category-picker.d.ts +76 -0
- package/dist/composables/forms/category-picker/use-category-picker.js +141 -0
- package/dist/composables/forms/category-picker/use-category-picker.js.map +1 -0
- package/dist/composables/forms/use-prepend-append-width.js.map +1 -1
- package/dist/composables/icons.js.map +1 -1
- package/dist/composables/popper.js.map +1 -1
- package/dist/composables/sticky-header.js.map +1 -1
- package/dist/composables/tables/data-table/columns.d.ts +7 -1
- package/dist/composables/tables/data-table/columns.js +18 -10
- package/dist/composables/tables/data-table/columns.js.map +1 -1
- package/dist/composables/tables/data-table/expansion.js.map +1 -1
- package/dist/composables/tables/data-table/grouping.d.ts +4 -6
- package/dist/composables/tables/data-table/grouping.js +38 -24
- package/dist/composables/tables/data-table/grouping.js.map +1 -1
- package/dist/composables/tables/data-table/pagination.d.ts +4 -4
- package/dist/composables/tables/data-table/pagination.js +63 -21
- package/dist/composables/tables/data-table/pagination.js.map +1 -1
- package/dist/composables/tables/data-table/selection.js +16 -6
- package/dist/composables/tables/data-table/selection.js.map +1 -1
- package/dist/composables/tables/data-table/sort.d.ts +4 -3
- package/dist/composables/tables/data-table/sort.js +78 -40
- package/dist/composables/tables/data-table/sort.js.map +1 -1
- package/dist/composables/tables/data-table/types.d.ts +3 -1
- package/dist/composables/tables/data-table/types.js +6 -2
- package/dist/composables/tables/data-table/types.js.map +1 -1
- package/dist/composables/theme.js.map +1 -1
- package/dist/composables/timeout-manager.js.map +1 -1
- package/dist/composables/use-rui-i18n.js.map +1 -1
- package/dist/consts/colors.js.map +1 -1
- package/dist/consts/time-accuracy.js.map +1 -1
- package/dist/i18n/keys.js.map +1 -1
- package/dist/icons/icons_1.d.ts +12 -12
- package/dist/icons/icons_1.js +140 -157
- package/dist/icons/icons_1.js.map +1 -1
- package/dist/icons/icons_2.d.ts +13 -13
- package/dist/icons/icons_2.js +128 -149
- package/dist/icons/icons_2.js.map +1 -1
- package/dist/icons/icons_3.d.ts +18 -18
- package/dist/icons/icons_3.js +244 -282
- package/dist/icons/icons_3.js.map +1 -1
- package/dist/icons/icons_4.d.ts +251 -6
- package/dist/icons/icons_4.js +3016 -75
- package/dist/icons/icons_4.js.map +1 -1
- package/dist/icons/icons_5.d.ts +20 -0
- package/dist/icons/icons_5.js +221 -0
- package/dist/icons/icons_5.js.map +1 -0
- package/dist/icons/index.d.ts +2 -1
- package/dist/icons/index.js +297 -32
- package/dist/icons/index.js.map +1 -1
- package/dist/index.js +8 -6
- package/dist/index.js.map +1 -1
- package/dist/library-icons.json +1 -0
- package/dist/style.css +152 -0
- package/dist/theme/index.js.map +1 -1
- package/dist/types/stepper.js.map +1 -1
- package/dist/types/theme.js.map +1 -1
- package/dist/utils/assert.js.map +1 -1
- package/dist/utils/blockie.js.map +1 -1
- package/dist/utils/form-text-detail.js.map +1 -1
- package/dist/utils/helpers.js.map +1 -1
- package/dist/utils/is-equal.js.map +1 -1
- package/dist/utils/tv.js.map +1 -1
- package/dist/vite-plugin/index.js +6 -5
- package/dist/vite-plugin/index.js.map +1 -1
- package/dist/vite-plugin/scanner.d.ts +1 -1
- package/dist/vite-plugin/scanner.js +10 -7
- package/dist/vite-plugin/scanner.js.map +1 -1
- package/dist/vite-plugin/types.d.ts +9 -0
- package/dist/web-types.json +2042 -1108
- package/package.json +35 -35
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { MaybeRefOrGetter, Ref } from 'vue';
|
|
2
|
+
import { type KeyOfType } from '../../../composables/dropdown-menu.js';
|
|
3
|
+
/**
|
|
4
|
+
* A resolved category and the items that belong to it.
|
|
5
|
+
*/
|
|
6
|
+
export interface CategoryGroup<TItem> {
|
|
7
|
+
category: string;
|
|
8
|
+
items: TItem[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A single entry in the category rail. `category` is `null` for the synthetic
|
|
12
|
+
* "All" pseudo-category, which aggregates every currently visible item.
|
|
13
|
+
*/
|
|
14
|
+
export interface CategoryRailEntry {
|
|
15
|
+
category: string | null;
|
|
16
|
+
label: string;
|
|
17
|
+
count: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A row rendered in the detail pane. Item rows carry a running `index` used for
|
|
21
|
+
* `aria-activedescendant`; header rows are visual separators shown in the
|
|
22
|
+
* flattened "All" view and never receive focus.
|
|
23
|
+
*/
|
|
24
|
+
export type DetailRow<TItem> = {
|
|
25
|
+
type: 'header';
|
|
26
|
+
category: string;
|
|
27
|
+
} | {
|
|
28
|
+
type: 'item';
|
|
29
|
+
item: TItem;
|
|
30
|
+
index: number;
|
|
31
|
+
};
|
|
32
|
+
export interface UseCategoryPickerOptions<TValue, TItem> {
|
|
33
|
+
/** The full catalogue of selectable items. */
|
|
34
|
+
items: MaybeRefOrGetter<TItem[]>;
|
|
35
|
+
/** Resolve an item's category label. */
|
|
36
|
+
categoryOf: (item: TItem) => string;
|
|
37
|
+
/** Property whose value becomes the model value. */
|
|
38
|
+
keyAttr?: KeyOfType<TItem, TValue extends (infer U)[] ? U : TValue>;
|
|
39
|
+
/** Property (or getter) that produces an item's display text. */
|
|
40
|
+
textAttr?: keyof TItem | ((item: TItem) => string);
|
|
41
|
+
/** The current search query. */
|
|
42
|
+
search: Ref<string>;
|
|
43
|
+
/** Whether the search query is applied. */
|
|
44
|
+
searchable: MaybeRefOrGetter<boolean>;
|
|
45
|
+
/** Custom predicate receiving the resolved category as the third argument. */
|
|
46
|
+
filter?: MaybeRefOrGetter<((item: TItem, query: string, category: string) => boolean) | undefined>;
|
|
47
|
+
/** Whether the synthetic "All" pseudo-category is offered. */
|
|
48
|
+
showAll: MaybeRefOrGetter<boolean>;
|
|
49
|
+
/** Label used for the "All" pseudo-category. */
|
|
50
|
+
allLabel: MaybeRefOrGetter<string>;
|
|
51
|
+
/** The picker's current selection. */
|
|
52
|
+
modelValue: Ref<TValue | undefined>;
|
|
53
|
+
}
|
|
54
|
+
export interface UseCategoryPickerReturn<TItem> {
|
|
55
|
+
getText: (item: TItem) => string | undefined;
|
|
56
|
+
getIdentifier: (item: TItem) => any;
|
|
57
|
+
filteredGroups: Ref<CategoryGroup<TItem>[]>;
|
|
58
|
+
railEntries: Ref<CategoryRailEntry[]>;
|
|
59
|
+
activeCategory: Readonly<Ref<string | null>>;
|
|
60
|
+
detailGroups: Ref<CategoryGroup<TItem>[]>;
|
|
61
|
+
detailRows: Ref<DetailRow<TItem>[]>;
|
|
62
|
+
detailItems: Ref<TItem[]>;
|
|
63
|
+
isEmpty: Ref<boolean>;
|
|
64
|
+
setActiveCategory: (category: string | null) => void;
|
|
65
|
+
syncActiveToSelection: () => void;
|
|
66
|
+
isSelected: (item: TItem) => boolean;
|
|
67
|
+
categoryOf: (item: TItem) => string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Owns the grouping, filtering and selection state for `RuiCategoryPicker`.
|
|
71
|
+
*
|
|
72
|
+
* The component keeps DOM concerns (focus, keyboard, scrolling); this composable
|
|
73
|
+
* keeps the data: which categories exist, which survive the current search, and
|
|
74
|
+
* which items belong in the detail pane for the active category.
|
|
75
|
+
*/
|
|
76
|
+
export declare function useCategoryPicker<TValue, TItem>(options: UseCategoryPickerOptions<TValue, TItem>): UseCategoryPickerReturn<TItem>;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { useDropdownOptionProperty } from "../../dropdown-menu.js";
|
|
2
|
+
import { computed, readonly, shallowRef, toValue, watch } from "vue";
|
|
3
|
+
import { get, set } from "@vueuse/shared";
|
|
4
|
+
//#region src/composables/forms/category-picker/use-category-picker.ts
|
|
5
|
+
/**
|
|
6
|
+
* Owns the grouping, filtering and selection state for `RuiCategoryPicker`.
|
|
7
|
+
*
|
|
8
|
+
* The component keeps DOM concerns (focus, keyboard, scrolling); this composable
|
|
9
|
+
* keeps the data: which categories exist, which survive the current search, and
|
|
10
|
+
* which items belong in the detail pane for the active category.
|
|
11
|
+
*/
|
|
12
|
+
function useCategoryPicker(options) {
|
|
13
|
+
const { allLabel, categoryOf, filter, items, keyAttr, modelValue, search, searchable, showAll, textAttr } = options;
|
|
14
|
+
const { getIdentifier, getText } = useDropdownOptionProperty({
|
|
15
|
+
keyAttr,
|
|
16
|
+
textAttr
|
|
17
|
+
});
|
|
18
|
+
function defaultFilter(item, query, category) {
|
|
19
|
+
const needle = query.toLowerCase();
|
|
20
|
+
return (getText(item) ?? "").toLowerCase().includes(needle) || category.toLowerCase().includes(needle);
|
|
21
|
+
}
|
|
22
|
+
const allGroups = computed(() => {
|
|
23
|
+
const map = /* @__PURE__ */ new Map();
|
|
24
|
+
for (const item of toValue(items)) {
|
|
25
|
+
const category = categoryOf(item);
|
|
26
|
+
const bucket = map.get(category);
|
|
27
|
+
if (bucket) bucket.push(item);
|
|
28
|
+
else map.set(category, [item]);
|
|
29
|
+
}
|
|
30
|
+
return Array.from(map, ([category, groupItems]) => ({
|
|
31
|
+
category,
|
|
32
|
+
items: groupItems
|
|
33
|
+
}));
|
|
34
|
+
});
|
|
35
|
+
const query = computed(() => get(search).trim());
|
|
36
|
+
const filteredGroups = computed(() => {
|
|
37
|
+
const currentQuery = get(query);
|
|
38
|
+
if (!toValue(searchable) || !currentQuery) return get(allGroups);
|
|
39
|
+
const filterFn = toValue(filter) ?? defaultFilter;
|
|
40
|
+
return get(allGroups).map((group) => ({
|
|
41
|
+
category: group.category,
|
|
42
|
+
items: group.items.filter((item) => filterFn(item, currentQuery, group.category))
|
|
43
|
+
})).filter((group) => group.items.length > 0);
|
|
44
|
+
});
|
|
45
|
+
const railEntries = computed(() => {
|
|
46
|
+
const groups = get(filteredGroups);
|
|
47
|
+
const entries = [];
|
|
48
|
+
if (toValue(showAll)) {
|
|
49
|
+
const total = groups.reduce((sum, group) => sum + group.items.length, 0);
|
|
50
|
+
entries.push({
|
|
51
|
+
category: null,
|
|
52
|
+
count: total,
|
|
53
|
+
label: toValue(allLabel)
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
for (const group of groups) entries.push({
|
|
57
|
+
category: group.category,
|
|
58
|
+
count: group.items.length,
|
|
59
|
+
label: group.category
|
|
60
|
+
});
|
|
61
|
+
return entries;
|
|
62
|
+
});
|
|
63
|
+
const activeCategory = shallowRef(null);
|
|
64
|
+
function firstCategory() {
|
|
65
|
+
return get(filteredGroups)[0]?.category ?? null;
|
|
66
|
+
}
|
|
67
|
+
function fallbackCategory() {
|
|
68
|
+
return toValue(showAll) ? null : firstCategory();
|
|
69
|
+
}
|
|
70
|
+
function setActiveCategory(category) {
|
|
71
|
+
set(activeCategory, category);
|
|
72
|
+
}
|
|
73
|
+
watch(filteredGroups, (groups) => {
|
|
74
|
+
const active = get(activeCategory);
|
|
75
|
+
if (active === null) return;
|
|
76
|
+
if (!groups.some((group) => group.category === active)) set(activeCategory, fallbackCategory());
|
|
77
|
+
});
|
|
78
|
+
watch(query, (current, previous) => {
|
|
79
|
+
if (current && !previous && toValue(showAll)) set(activeCategory, null);
|
|
80
|
+
});
|
|
81
|
+
const detailGroups = computed(() => {
|
|
82
|
+
const groups = get(filteredGroups);
|
|
83
|
+
const active = get(activeCategory);
|
|
84
|
+
if (active === null) return groups;
|
|
85
|
+
const match = groups.find((group) => group.category === active);
|
|
86
|
+
return match ? [match] : [];
|
|
87
|
+
});
|
|
88
|
+
const detailItems = computed(() => get(detailGroups).flatMap((group) => group.items));
|
|
89
|
+
const detailRows = computed(() => {
|
|
90
|
+
const groups = get(detailGroups);
|
|
91
|
+
const flattened = get(activeCategory) === null && groups.length > 1;
|
|
92
|
+
const rows = [];
|
|
93
|
+
let index = 0;
|
|
94
|
+
for (const group of groups) {
|
|
95
|
+
if (flattened) rows.push({
|
|
96
|
+
type: "header",
|
|
97
|
+
category: group.category
|
|
98
|
+
});
|
|
99
|
+
for (const item of group.items) rows.push({
|
|
100
|
+
index: index++,
|
|
101
|
+
item,
|
|
102
|
+
type: "item"
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return rows;
|
|
106
|
+
});
|
|
107
|
+
const isEmpty = computed(() => get(detailItems).length === 0);
|
|
108
|
+
function isSelected(item) {
|
|
109
|
+
const value = get(modelValue);
|
|
110
|
+
if (value === void 0) return false;
|
|
111
|
+
return getIdentifier(item) === value;
|
|
112
|
+
}
|
|
113
|
+
function syncActiveToSelection() {
|
|
114
|
+
const value = get(modelValue);
|
|
115
|
+
if (value === void 0) {
|
|
116
|
+
set(activeCategory, fallbackCategory());
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const selected = toValue(items).find((item) => getIdentifier(item) === value);
|
|
120
|
+
set(activeCategory, selected ? categoryOf(selected) : fallbackCategory());
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
activeCategory: readonly(activeCategory),
|
|
124
|
+
categoryOf,
|
|
125
|
+
detailGroups,
|
|
126
|
+
detailItems,
|
|
127
|
+
detailRows,
|
|
128
|
+
filteredGroups,
|
|
129
|
+
getIdentifier,
|
|
130
|
+
getText,
|
|
131
|
+
isEmpty,
|
|
132
|
+
isSelected,
|
|
133
|
+
railEntries,
|
|
134
|
+
setActiveCategory,
|
|
135
|
+
syncActiveToSelection
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
//#endregion
|
|
139
|
+
export { useCategoryPicker };
|
|
140
|
+
|
|
141
|
+
//# sourceMappingURL=use-category-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-category-picker.js","names":[],"sources":["../../../../src/composables/forms/category-picker/use-category-picker.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref } from 'vue';\nimport { type KeyOfType, useDropdownOptionProperty } from '@/composables/dropdown-menu';\n\n/**\n * A resolved category and the items that belong to it.\n */\nexport interface CategoryGroup<TItem> {\n category: string;\n items: TItem[];\n}\n\n/**\n * A single entry in the category rail. `category` is `null` for the synthetic\n * \"All\" pseudo-category, which aggregates every currently visible item.\n */\nexport interface CategoryRailEntry {\n category: string | null;\n label: string;\n count: number;\n}\n\n/**\n * A row rendered in the detail pane. Item rows carry a running `index` used for\n * `aria-activedescendant`; header rows are visual separators shown in the\n * flattened \"All\" view and never receive focus.\n */\nexport type DetailRow<TItem>\n = | { type: 'header'; category: string }\n | { type: 'item'; item: TItem; index: number };\n\nexport interface UseCategoryPickerOptions<TValue, TItem> {\n /** The full catalogue of selectable items. */\n items: MaybeRefOrGetter<TItem[]>;\n /** Resolve an item's category label. */\n categoryOf: (item: TItem) => string;\n /** Property whose value becomes the model value. */\n keyAttr?: KeyOfType<TItem, TValue extends (infer U)[] ? U : TValue>;\n /** Property (or getter) that produces an item's display text. */\n textAttr?: keyof TItem | ((item: TItem) => string);\n /** The current search query. */\n search: Ref<string>;\n /** Whether the search query is applied. */\n searchable: MaybeRefOrGetter<boolean>;\n /** Custom predicate receiving the resolved category as the third argument. */\n filter?: MaybeRefOrGetter<((item: TItem, query: string, category: string) => boolean) | undefined>;\n /** Whether the synthetic \"All\" pseudo-category is offered. */\n showAll: MaybeRefOrGetter<boolean>;\n /** Label used for the \"All\" pseudo-category. */\n allLabel: MaybeRefOrGetter<string>;\n /** The picker's current selection. */\n modelValue: Ref<TValue | undefined>;\n}\n\nexport interface UseCategoryPickerReturn<TItem> {\n getText: (item: TItem) => string | undefined;\n getIdentifier: (item: TItem) => any;\n filteredGroups: Ref<CategoryGroup<TItem>[]>;\n railEntries: Ref<CategoryRailEntry[]>;\n activeCategory: Readonly<Ref<string | null>>;\n detailGroups: Ref<CategoryGroup<TItem>[]>;\n detailRows: Ref<DetailRow<TItem>[]>;\n detailItems: Ref<TItem[]>;\n isEmpty: Ref<boolean>;\n setActiveCategory: (category: string | null) => void;\n syncActiveToSelection: () => void;\n isSelected: (item: TItem) => boolean;\n categoryOf: (item: TItem) => string;\n}\n\n/**\n * Owns the grouping, filtering and selection state for `RuiCategoryPicker`.\n *\n * The component keeps DOM concerns (focus, keyboard, scrolling); this composable\n * keeps the data: which categories exist, which survive the current search, and\n * which items belong in the detail pane for the active category.\n */\nexport function useCategoryPicker<TValue, TItem>(\n options: UseCategoryPickerOptions<TValue, TItem>,\n): UseCategoryPickerReturn<TItem> {\n const { allLabel, categoryOf, filter, items, keyAttr, modelValue, search, searchable, showAll, textAttr } = options;\n\n const { getIdentifier, getText } = useDropdownOptionProperty<TValue, TItem>({\n keyAttr,\n textAttr,\n });\n\n function defaultFilter(item: TItem, query: string, category: string): boolean {\n const needle = query.toLowerCase();\n const text = (getText(item) ?? '').toLowerCase();\n return text.includes(needle) || category.toLowerCase().includes(needle);\n }\n\n // All items grouped by category, preserving first-seen category order.\n const allGroups = computed<CategoryGroup<TItem>[]>(() => {\n const map = new Map<string, TItem[]>();\n for (const item of toValue(items)) {\n const category = categoryOf(item);\n const bucket = map.get(category);\n if (bucket)\n bucket.push(item);\n else\n map.set(category, [item]);\n }\n return Array.from(map, ([category, groupItems]) => ({ category, items: groupItems }));\n });\n\n const query = computed<string>(() => get(search).trim());\n\n const filteredGroups = computed<CategoryGroup<TItem>[]>(() => {\n const currentQuery = get(query);\n if (!toValue(searchable) || !currentQuery)\n return get(allGroups);\n\n const filterFn = toValue(filter) ?? defaultFilter;\n return get(allGroups)\n .map(group => ({\n category: group.category,\n items: group.items.filter(item => filterFn(item, currentQuery, group.category)),\n }))\n .filter(group => group.items.length > 0);\n });\n\n const railEntries = computed<CategoryRailEntry[]>(() => {\n const groups = get(filteredGroups);\n const entries: CategoryRailEntry[] = [];\n\n if (toValue(showAll)) {\n const total = groups.reduce((sum, group) => sum + group.items.length, 0);\n entries.push({ category: null, count: total, label: toValue(allLabel) });\n }\n\n for (const group of groups)\n entries.push({ category: group.category, count: group.items.length, label: group.category });\n\n return entries;\n });\n\n const activeCategory = shallowRef<string | null>(null);\n\n function firstCategory(): string | null {\n return get(filteredGroups)[0]?.category ?? null;\n }\n\n function fallbackCategory(): string | null {\n return toValue(showAll) ? null : firstCategory();\n }\n\n function setActiveCategory(category: string | null): void {\n set(activeCategory, category);\n }\n\n // Keep the active category valid as the search narrows the rail. If the\n // active category disappears, fall back to \"All\" (when shown) or the first\n // remaining category.\n watch(filteredGroups, (groups) => {\n const active = get(activeCategory);\n if (active === null)\n return;\n if (!groups.some(group => group.category === active))\n set(activeCategory, fallbackCategory());\n });\n\n // When the user starts typing, surface matches across every category so the\n // top hit is global rather than scoped to whatever category was active.\n watch(query, (current, previous) => {\n if (current && !previous && toValue(showAll))\n set(activeCategory, null);\n });\n\n const detailGroups = computed<CategoryGroup<TItem>[]>(() => {\n const groups = get(filteredGroups);\n const active = get(activeCategory);\n if (active === null)\n return groups;\n const match = groups.find(group => group.category === active);\n return match ? [match] : [];\n });\n\n const detailItems = computed<TItem[]>(() => get(detailGroups).flatMap(group => group.items));\n\n const detailRows = computed<DetailRow<TItem>[]>(() => {\n const groups = get(detailGroups);\n const flattened = get(activeCategory) === null && groups.length > 1;\n const rows: DetailRow<TItem>[] = [];\n let index = 0;\n for (const group of groups) {\n if (flattened)\n rows.push({ type: 'header', category: group.category });\n for (const item of group.items)\n rows.push({ index: index++, item, type: 'item' });\n }\n return rows;\n });\n\n const isEmpty = computed<boolean>(() => get(detailItems).length === 0);\n\n function isSelected(item: TItem): boolean {\n const value = get(modelValue);\n if (value === undefined)\n return false;\n return getIdentifier(item) === value;\n }\n\n // Point the rail at the selected item's category so it is visible on open.\n function syncActiveToSelection(): void {\n const value = get(modelValue);\n if (value === undefined) {\n set(activeCategory, fallbackCategory());\n return;\n }\n const selected = toValue(items).find(item => getIdentifier(item) === value);\n set(activeCategory, selected ? categoryOf(selected) : fallbackCategory());\n }\n\n return {\n activeCategory: readonly(activeCategory),\n categoryOf,\n detailGroups,\n detailItems,\n detailRows,\n filteredGroups,\n getIdentifier,\n getText,\n isEmpty,\n isSelected,\n railEntries,\n setActiveCategory,\n syncActiveToSelection,\n };\n}\n"],"mappings":";;;;;;;;;;;AA4EA,SAAgB,kBACd,SACgC;CAChC,MAAM,EAAE,UAAU,YAAY,QAAQ,OAAO,SAAS,YAAY,QAAQ,YAAY,SAAS,aAAa;CAE5G,MAAM,EAAE,eAAe,YAAY,0BAAyC;EAC1E;EACA;CACF,CAAC;CAED,SAAS,cAAc,MAAa,OAAe,UAA2B;EAC5E,MAAM,SAAS,MAAM,YAAY;EAEjC,QADc,QAAQ,IAAI,KAAK,GAAA,CAAI,YAC5B,CAAA,CAAK,SAAS,MAAM,KAAK,SAAS,YAAY,CAAC,CAAC,SAAS,MAAM;CACxE;CAGA,MAAM,YAAY,eAAuC;EACvD,MAAM,sBAAM,IAAI,IAAqB;EACrC,KAAK,MAAM,QAAQ,QAAQ,KAAK,GAAG;GACjC,MAAM,WAAW,WAAW,IAAI;GAChC,MAAM,SAAS,IAAI,IAAI,QAAQ;GAC/B,IAAI,QACF,OAAO,KAAK,IAAI;QAEhB,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC;EAC5B;EACA,OAAO,MAAM,KAAK,MAAM,CAAC,UAAU,iBAAiB;GAAE;GAAU,OAAO;EAAW,EAAE;CACtF,CAAC;CAED,MAAM,QAAQ,eAAuB,IAAI,MAAM,CAAC,CAAC,KAAK,CAAC;CAEvD,MAAM,iBAAiB,eAAuC;EAC5D,MAAM,eAAe,IAAI,KAAK;EAC9B,IAAI,CAAC,QAAQ,UAAU,KAAK,CAAC,cAC3B,OAAO,IAAI,SAAS;EAEtB,MAAM,WAAW,QAAQ,MAAM,KAAK;EACpC,OAAO,IAAI,SAAS,CAAC,CAClB,KAAI,WAAU;GACb,UAAU,MAAM;GAChB,OAAO,MAAM,MAAM,QAAO,SAAQ,SAAS,MAAM,cAAc,MAAM,QAAQ,CAAC;EAChF,EAAE,CAAC,CACF,QAAO,UAAS,MAAM,MAAM,SAAS,CAAC;CAC3C,CAAC;CAED,MAAM,cAAc,eAAoC;EACtD,MAAM,SAAS,IAAI,cAAc;EACjC,MAAM,UAA+B,CAAC;EAEtC,IAAI,QAAQ,OAAO,GAAG;GACpB,MAAM,QAAQ,OAAO,QAAQ,KAAK,UAAU,MAAM,MAAM,MAAM,QAAQ,CAAC;GACvE,QAAQ,KAAK;IAAE,UAAU;IAAM,OAAO;IAAO,OAAO,QAAQ,QAAQ;GAAE,CAAC;EACzE;EAEA,KAAK,MAAM,SAAS,QAClB,QAAQ,KAAK;GAAE,UAAU,MAAM;GAAU,OAAO,MAAM,MAAM;GAAQ,OAAO,MAAM;EAAS,CAAC;EAE7F,OAAO;CACT,CAAC;CAED,MAAM,iBAAiB,WAA0B,IAAI;CAErD,SAAS,gBAA+B;EACtC,OAAO,IAAI,cAAc,CAAC,CAAC,EAAE,EAAE,YAAY;CAC7C;CAEA,SAAS,mBAAkC;EACzC,OAAO,QAAQ,OAAO,IAAI,OAAO,cAAc;CACjD;CAEA,SAAS,kBAAkB,UAA+B;EACxD,IAAI,gBAAgB,QAAQ;CAC9B;CAKA,MAAM,iBAAiB,WAAW;EAChC,MAAM,SAAS,IAAI,cAAc;EACjC,IAAI,WAAW,MACb;EACF,IAAI,CAAC,OAAO,MAAK,UAAS,MAAM,aAAa,MAAM,GACjD,IAAI,gBAAgB,iBAAiB,CAAC;CAC1C,CAAC;CAID,MAAM,QAAQ,SAAS,aAAa;EAClC,IAAI,WAAW,CAAC,YAAY,QAAQ,OAAO,GACzC,IAAI,gBAAgB,IAAI;CAC5B,CAAC;CAED,MAAM,eAAe,eAAuC;EAC1D,MAAM,SAAS,IAAI,cAAc;EACjC,MAAM,SAAS,IAAI,cAAc;EACjC,IAAI,WAAW,MACb,OAAO;EACT,MAAM,QAAQ,OAAO,MAAK,UAAS,MAAM,aAAa,MAAM;EAC5D,OAAO,QAAQ,CAAC,KAAK,IAAI,CAAC;CAC5B,CAAC;CAED,MAAM,cAAc,eAAwB,IAAI,YAAY,CAAC,CAAC,SAAQ,UAAS,MAAM,KAAK,CAAC;CAE3F,MAAM,aAAa,eAAmC;EACpD,MAAM,SAAS,IAAI,YAAY;EAC/B,MAAM,YAAY,IAAI,cAAc,MAAM,QAAQ,OAAO,SAAS;EAClE,MAAM,OAA2B,CAAC;EAClC,IAAI,QAAQ;EACZ,KAAK,MAAM,SAAS,QAAQ;GAC1B,IAAI,WACF,KAAK,KAAK;IAAE,MAAM;IAAU,UAAU,MAAM;GAAS,CAAC;GACxD,KAAK,MAAM,QAAQ,MAAM,OACvB,KAAK,KAAK;IAAE,OAAO;IAAS;IAAM,MAAM;GAAO,CAAC;EACpD;EACA,OAAO;CACT,CAAC;CAED,MAAM,UAAU,eAAwB,IAAI,WAAW,CAAC,CAAC,WAAW,CAAC;CAErE,SAAS,WAAW,MAAsB;EACxC,MAAM,QAAQ,IAAI,UAAU;EAC5B,IAAI,UAAU,KAAA,GACZ,OAAO;EACT,OAAO,cAAc,IAAI,MAAM;CACjC;CAGA,SAAS,wBAA8B;EACrC,MAAM,QAAQ,IAAI,UAAU;EAC5B,IAAI,UAAU,KAAA,GAAW;GACvB,IAAI,gBAAgB,iBAAiB,CAAC;GACtC;EACF;EACA,MAAM,WAAW,QAAQ,KAAK,CAAC,CAAC,MAAK,SAAQ,cAAc,IAAI,MAAM,KAAK;EAC1E,IAAI,gBAAgB,WAAW,WAAW,QAAQ,IAAI,iBAAiB,CAAC;CAC1E;CAEA,OAAO;EACL,gBAAgB,SAAS,cAAc;EACvC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-prepend-append-width.js","names":[],"sources":["../../../src/composables/forms/use-prepend-append-width.ts"],"sourcesContent":["import type { Ref, ShallowRef } from 'vue';\nimport { assert } from '@/utils/assert';\n\nexport interface PrependAppendWidth {\n prependWidth: Ref<string>;\n appendWidth: Ref<string>;\n}\n\nexport function usePrependAppendWidth(\n prepend: Readonly<ShallowRef<HTMLDivElement | null>>,\n append: Readonly<ShallowRef<HTMLDivElement | null>>,\n offset: number = 0,\n): PrependAppendWidth {\n const prependWidth = shallowRef<string>('0px');\n const appendWidth = shallowRef<string>('0px');\n\n // Measure the element's outer (border-box) width so callers get the full\n // space the prepend/append region occupies — including both left and\n // right padding. The previous `contentRect.width + contentRect.left` form\n // added padding-left but silently dropped padding-right, so a prepend\n // slot styled with `pr-3` (only) reported 12px short of its real width\n // and the floated label landed under the icon's trailing padding instead\n // of aligned with the input text.\n useResizeObserver(prepend, () => {\n const target = get(prepend);\n assert(target);\n set(prependWidth, `${target.offsetWidth + offset}px`);\n });\n\n useResizeObserver(append, () => {\n const target = get(append);\n assert(target);\n set(appendWidth, `${target.offsetWidth + offset}px`);\n });\n\n return { prependWidth, appendWidth };\n}\n"],"mappings":";;;;;AAQA,SAAgB,sBACd,SACA,QACA,SAAiB,GACG;CACpB,MAAM,eAAe,WAAmB,
|
|
1
|
+
{"version":3,"file":"use-prepend-append-width.js","names":[],"sources":["../../../src/composables/forms/use-prepend-append-width.ts"],"sourcesContent":["import type { Ref, ShallowRef } from 'vue';\nimport { assert } from '@/utils/assert';\n\nexport interface PrependAppendWidth {\n prependWidth: Ref<string>;\n appendWidth: Ref<string>;\n}\n\nexport function usePrependAppendWidth(\n prepend: Readonly<ShallowRef<HTMLDivElement | null>>,\n append: Readonly<ShallowRef<HTMLDivElement | null>>,\n offset: number = 0,\n): PrependAppendWidth {\n const prependWidth = shallowRef<string>('0px');\n const appendWidth = shallowRef<string>('0px');\n\n // Measure the element's outer (border-box) width so callers get the full\n // space the prepend/append region occupies — including both left and\n // right padding. The previous `contentRect.width + contentRect.left` form\n // added padding-left but silently dropped padding-right, so a prepend\n // slot styled with `pr-3` (only) reported 12px short of its real width\n // and the floated label landed under the icon's trailing padding instead\n // of aligned with the input text.\n useResizeObserver(prepend, () => {\n const target = get(prepend);\n assert(target);\n set(prependWidth, `${target.offsetWidth + offset}px`);\n });\n\n useResizeObserver(append, () => {\n const target = get(append);\n assert(target);\n set(appendWidth, `${target.offsetWidth + offset}px`);\n });\n\n return { prependWidth, appendWidth };\n}\n"],"mappings":";;;;;AAQA,SAAgB,sBACd,SACA,QACA,SAAiB,GACG;CACpB,MAAM,eAAe,WAAmB,KAAK;CAC7C,MAAM,cAAc,WAAmB,KAAK;CAS5C,kBAAkB,eAAe;EAC/B,MAAM,SAAS,MAAI,OAAO;EAC1B,OAAO,MAAM;EACb,MAAI,cAAc,GAAG,OAAO,cAAc,OAAO,GAAG;CACtD,CAAC;CAED,kBAAkB,cAAc;EAC9B,MAAM,SAAS,MAAI,MAAM;EACzB,OAAO,MAAM;EACb,MAAI,aAAa,GAAG,OAAO,cAAc,OAAO,GAAG;CACrD,CAAC;CAED,OAAO;EAAE;EAAc;CAAY;AACrC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icons.js","names":[],"sources":["../../src/composables/icons.ts"],"sourcesContent":["import type { InjectionKey } from 'vue';\nimport type { GeneratedIcon } from '@/types/icons';\nimport {\n LuArrowDown,\n LuArrowLeft,\n LuArrowRight,\n LuArrowUp,\n LuCheck,\n LuCheckboxBlank,\n LuCheckboxBlankCircle,\n LuCheckboxBlankCircleFill,\n LuCheckboxFill,\n LuCheckboxIndeterminateFill,\n LuChevronDown,\n LuChevronLeft,\n LuChevronRight,\n LuChevronsLeft,\n LuChevronsRight,\n LuChevronsUpDown,\n LuChevronUp,\n LuCircleAlert,\n LuCircleCheck,\n LuCircleX,\n LuClock,\n LuEllipsis,\n LuEye,\n LuEyeOff,\n LuInfo,\n LuRadioButtonFill,\n LuTriangleAlert,\n LuX,\n} from '@/icons';\nimport { assert } from '@/utils/assert';\n\nconst requiredIcons: GeneratedIcon[] = [\n LuChevronsUpDown,\n LuEllipsis,\n LuTriangleAlert,\n LuX,\n LuInfo,\n LuArrowUp,\n LuArrowDown,\n LuArrowLeft,\n LuArrowRight,\n LuChevronUp,\n LuChevronDown,\n LuChevronLeft,\n LuChevronRight,\n LuChevronsLeft,\n LuChevronsRight,\n LuCircleAlert,\n LuEye,\n LuEyeOff,\n LuCheck,\n LuCircleX,\n LuCircleCheck,\n LuCheckboxBlank,\n LuCheckboxFill,\n LuCheckboxIndeterminateFill,\n LuCheckboxBlankCircle,\n LuCheckboxBlankCircleFill,\n LuRadioButtonFill,\n LuClock,\n];\n\nexport interface IconsOptions {\n registeredIcons: GeneratedIcon[];\n}\n\nexport interface UseIconsReturn {\n registeredIcons: Readonly<Record<string, [string, Record<string, string>][]>>;\n}\n\nexport const IconsSymbol: InjectionKey<UseIconsReturn> = Symbol.for('rui:icons');\n\nexport function createIconDefaults(options?: Partial<IconsOptions>): UseIconsReturn {\n const iconsToAdd = options?.registeredIcons || [];\n return {\n registeredIcons: {\n ...Object.fromEntries(\n [\n ...requiredIcons,\n ...iconsToAdd,\n ].map(({ components, name }) => [name, components]),\n ),\n },\n };\n}\n\nexport function useIcons(): UseIconsReturn {\n const icons = inject(IconsSymbol);\n assert(icons, 'Could not find icons injection');\n return icons;\n}\n"],"mappings":";;;;;;AAkCA,IAAM,gBAAiC;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;
|
|
1
|
+
{"version":3,"file":"icons.js","names":[],"sources":["../../src/composables/icons.ts"],"sourcesContent":["import type { InjectionKey } from 'vue';\nimport type { GeneratedIcon } from '@/types/icons';\nimport {\n LuArrowDown,\n LuArrowLeft,\n LuArrowRight,\n LuArrowUp,\n LuCheck,\n LuCheckboxBlank,\n LuCheckboxBlankCircle,\n LuCheckboxBlankCircleFill,\n LuCheckboxFill,\n LuCheckboxIndeterminateFill,\n LuChevronDown,\n LuChevronLeft,\n LuChevronRight,\n LuChevronsLeft,\n LuChevronsRight,\n LuChevronsUpDown,\n LuChevronUp,\n LuCircleAlert,\n LuCircleCheck,\n LuCircleX,\n LuClock,\n LuEllipsis,\n LuEye,\n LuEyeOff,\n LuInfo,\n LuRadioButtonFill,\n LuTriangleAlert,\n LuX,\n} from '@/icons';\nimport { assert } from '@/utils/assert';\n\nconst requiredIcons: GeneratedIcon[] = [\n LuChevronsUpDown,\n LuEllipsis,\n LuTriangleAlert,\n LuX,\n LuInfo,\n LuArrowUp,\n LuArrowDown,\n LuArrowLeft,\n LuArrowRight,\n LuChevronUp,\n LuChevronDown,\n LuChevronLeft,\n LuChevronRight,\n LuChevronsLeft,\n LuChevronsRight,\n LuCircleAlert,\n LuEye,\n LuEyeOff,\n LuCheck,\n LuCircleX,\n LuCircleCheck,\n LuCheckboxBlank,\n LuCheckboxFill,\n LuCheckboxIndeterminateFill,\n LuCheckboxBlankCircle,\n LuCheckboxBlankCircleFill,\n LuRadioButtonFill,\n LuClock,\n];\n\nexport interface IconsOptions {\n registeredIcons: GeneratedIcon[];\n}\n\nexport interface UseIconsReturn {\n registeredIcons: Readonly<Record<string, [string, Record<string, string>][]>>;\n}\n\nexport const IconsSymbol: InjectionKey<UseIconsReturn> = Symbol.for('rui:icons');\n\nexport function createIconDefaults(options?: Partial<IconsOptions>): UseIconsReturn {\n const iconsToAdd = options?.registeredIcons || [];\n return {\n registeredIcons: {\n ...Object.fromEntries(\n [\n ...requiredIcons,\n ...iconsToAdd,\n ].map(({ components, name }) => [name, components]),\n ),\n },\n };\n}\n\nexport function useIcons(): UseIconsReturn {\n const icons = inject(IconsSymbol);\n assert(icons, 'Could not find icons injection');\n return icons;\n}\n"],"mappings":";;;;;;AAkCA,IAAM,gBAAiC;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAUA,IAAa,cAA4C,OAAO,IAAI,WAAW;AAE/E,SAAgB,mBAAmB,SAAiD;CAClF,MAAM,aAAa,SAAS,mBAAmB,CAAC;CAChD,OAAO,EACL,iBAAiB,EACf,GAAG,OAAO,YACR,CACE,GAAG,eACH,GAAG,UACL,CAAC,CAAC,KAAK,EAAE,YAAY,WAAW,CAAC,MAAM,UAAU,CAAC,CACpD,EACF,EACF;AACF;AAEA,SAAgB,WAA2B;CACzC,MAAM,QAAQ,OAAO,WAAW;CAChC,OAAO,OAAO,gCAAgC;CAC9C,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"popper.js","names":[],"sources":["../../src/composables/popper.ts"],"sourcesContent":["import { type FloatingOptions, Placement, Strategy } from './floating';\n\n/** @deprecated Use FloatingOptions instead */\nexport interface PopperOptions {\n locked?: boolean;\n overflowPadding?: number;\n offsetDistance?: number;\n offsetSkid?: number;\n placement?: Placement;\n strategy?: Strategy;\n gpuAcceleration?: boolean;\n adaptive?: boolean;\n scroll?: boolean;\n resize?: boolean;\n}\n\n/** @deprecated Use FloatingOptions directly. Will be removed in next major. */\nexport function toFloatingOptions(opts: PopperOptions): FloatingOptions {\n return {\n autoUpdate: {\n resize: opts.resize ?? true,\n scroll: opts.scroll ?? true,\n },\n flip: !(opts.locked ?? false),\n offset: {\n crossAxis: opts.offsetSkid ?? 0,\n mainAxis: opts.offsetDistance ?? 8,\n },\n placement: opts.placement ?? Placement.bottom,\n shiftPadding: opts.overflowPadding ?? 8,\n strategy: opts.strategy ?? Strategy.absolute,\n };\n}\n"],"mappings":";;;AAiBA,SAAgB,kBAAkB,MAAsC;
|
|
1
|
+
{"version":3,"file":"popper.js","names":[],"sources":["../../src/composables/popper.ts"],"sourcesContent":["import { type FloatingOptions, Placement, Strategy } from './floating';\n\n/** @deprecated Use FloatingOptions instead */\nexport interface PopperOptions {\n locked?: boolean;\n overflowPadding?: number;\n offsetDistance?: number;\n offsetSkid?: number;\n placement?: Placement;\n strategy?: Strategy;\n gpuAcceleration?: boolean;\n adaptive?: boolean;\n scroll?: boolean;\n resize?: boolean;\n}\n\n/** @deprecated Use FloatingOptions directly. Will be removed in next major. */\nexport function toFloatingOptions(opts: PopperOptions): FloatingOptions {\n return {\n autoUpdate: {\n resize: opts.resize ?? true,\n scroll: opts.scroll ?? true,\n },\n flip: !(opts.locked ?? false),\n offset: {\n crossAxis: opts.offsetSkid ?? 0,\n mainAxis: opts.offsetDistance ?? 8,\n },\n placement: opts.placement ?? Placement.bottom,\n shiftPadding: opts.overflowPadding ?? 8,\n strategy: opts.strategy ?? Strategy.absolute,\n };\n}\n"],"mappings":";;;AAiBA,SAAgB,kBAAkB,MAAsC;CACtE,OAAO;EACL,YAAY;GACV,QAAQ,KAAK,UAAU;GACvB,QAAQ,KAAK,UAAU;EACzB;EACA,MAAM,EAAE,KAAK,UAAU;EACvB,QAAQ;GACN,WAAW,KAAK,cAAc;GAC9B,UAAU,KAAK,kBAAkB;EACnC;EACA,WAAW,KAAK,aAAa,UAAU;EACvC,cAAc,KAAK,mBAAmB;EACtC,UAAU,KAAK,YAAY,SAAS;CACtC;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sticky-header.js","names":[],"sources":["../../src/composables/sticky-header.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref, ShallowRef } from 'vue';\n\nexport interface UseStickyTableHeaderRefs {\n table: Readonly<ShallowRef<HTMLTableElement | null>>;\n tableScroller: Readonly<ShallowRef<HTMLElement | null>>;\n}\n\ninterface StickyElements {\n head: HTMLElement;\n theadClone: HTMLElement;\n root: HTMLTableElement;\n}\n\ninterface UseStickyTableHeaderReturn {\n stick: Readonly<Ref<boolean>>;\n}\n\nconst SELECTORS = {\n head: ':scope > thead[data-id=head-main]',\n headClone: ':scope > thead[data-id=head-clone]',\n row: ':scope > tbody > tr:not([hidden])',\n th: ':scope > th',\n} as const;\n\nconst BORDER_PRECISION = -0.5;\n\nfunction queryHeadRow(root: HTMLTableElement, selector: string): HTMLTableRowElement | null {\n return root.querySelector(`${selector} > tr`);\n}\n\nfunction queryColumns(row: HTMLTableRowElement | null): HTMLElement[] {\n if (!row)\n return [];\n return Array.from(row.querySelectorAll<HTMLElement>(SELECTORS.th));\n}\n\nfunction readColumnWidths(columns: HTMLElement[]): number[] {\n return columns.map(col => col.getBoundingClientRect().width);\n}\n\nfunction applyColumnWidths(columns: HTMLElement[], widths: number[]): void {\n for (const [i, column] of columns.entries()) {\n const width = widths[i];\n if (width !== undefined)\n column.style.width = `${width}px`;\n }\n}\n\nfunction positionHeadAtRest(head: HTMLElement): void {\n head.style.left = `${BORDER_PRECISION}px`;\n head.style.top = '0';\n}\n\ninterface StuckPosition {\n clonedRect: DOMRect;\n tableRect: DOMRect;\n lastRowHeight: number;\n top: number;\n}\n\nfunction positionHeadStuck(head: HTMLElement, { clonedRect, lastRowHeight, tableRect, top }: StuckPosition): void {\n head.style.left = `${clonedRect.left + BORDER_PRECISION}px`;\n\n const isNearBottom = tableRect.bottom <= lastRowHeight + clonedRect.height + top;\n head.style.top = isNearBottom\n ? `${tableRect.bottom - lastRowHeight - clonedRect.height}px`\n : `${top}px`;\n}\n\nfunction isInStickyRange(tableRect: DOMRect, top: number): boolean {\n return tableRect.top <= top && tableRect.bottom > top;\n}\n\nfunction getLastRowHeight(root: HTMLTableElement): number | undefined {\n const rows = root.querySelectorAll(SELECTORS.row);\n if (rows.length <= 1)\n return undefined;\n return rows.item(rows.length - 1)?.getBoundingClientRect().height ?? 0;\n}\n\n/**\n * Setup sticky table header\n */\nexport function useStickyTableHeader(\n sticky: MaybeRefOrGetter<boolean> = shallowRef(false),\n offsetTop: MaybeRefOrGetter<number | undefined>,\n tableRefs: UseStickyTableHeaderRefs,\n): UseStickyTableHeaderReturn {\n const { table, tableScroller } = tableRefs;\n const stick = shallowRef<boolean>(false);\n\n let resizeCleanups: (() => void)[] = [];\n let syncRafId: number | null = null;\n let rafId: number | null = null;\n\n function cleanupResizeObservers(): void {\n for (const cleanup of resizeCleanups)\n cleanup();\n resizeCleanups = [];\n }\n\n function cancelPendingSync(): void {\n if (syncRafId !== null)\n cancelAnimationFrame(syncRafId);\n syncRafId = null;\n }\n\n function scheduleSyncWidths(cloneColumns: HTMLElement[], mainColumns: HTMLElement[]): void {\n cancelPendingSync();\n\n // Single-frame sync: the main thead is position absolute/fixed so clearing\n // its widths is unnecessary — clone widths are independent of main widths.\n syncRafId = requestAnimationFrame(() => {\n syncRafId = null;\n applyColumnWidths(mainColumns, readColumnWidths(cloneColumns));\n });\n }\n\n function observeColumnResizes(cloneColumns: HTMLElement[], mainColumns: HTMLElement[]): void {\n cleanupResizeObservers();\n\n for (const th of cloneColumns) {\n const { stop } = useResizeObserver(th, () => {\n scheduleSyncWidths(cloneColumns, mainColumns);\n });\n resizeCleanups.push(stop);\n }\n }\n\n function watchCellWidth(): void {\n const root = get(table);\n if (!toValue(sticky) || !root)\n return;\n\n const cloneRow = queryHeadRow(root, SELECTORS.headClone);\n const mainRow = queryHeadRow(root, SELECTORS.head);\n const cloneColumns = queryColumns(cloneRow);\n const mainColumns = queryColumns(mainRow);\n\n useMutationObserver(cloneRow, (mutations) => {\n const hasRelevantMutation = mutations.some(\n m => m.type === 'childList' || m.type === 'attributes',\n );\n if (hasRelevantMutation)\n observeColumnResizes(queryColumns(cloneRow), queryColumns(mainRow));\n }, { attributes: true, childList: true, subtree: true });\n\n observeColumnResizes(cloneColumns, mainColumns);\n }\n\n function queryStickyElements(): StickyElements | undefined {\n const root = get(table);\n if (!toValue(sticky) || !root)\n return undefined;\n\n const theadClone = root.querySelector<HTMLElement>(SELECTORS.headClone);\n const head = root.querySelector<HTMLElement>(SELECTORS.head);\n if (!theadClone || !head)\n return undefined;\n\n return { head, root, theadClone };\n }\n\n function toggleStickyClass(): void {\n const elements = queryStickyElements();\n if (!elements)\n return;\n\n const { head, root, theadClone } = elements;\n const clonedRect = theadClone.getBoundingClientRect();\n const tableRect = root.getBoundingClientRect();\n const top = toValue(offsetTop) ?? 0;\n\n head.style.width = `${clonedRect.width}px`;\n\n const lastRowHeight = getLastRowHeight(root);\n if (lastRowHeight === undefined) {\n set(stick, false);\n positionHeadAtRest(head);\n return;\n }\n\n if (isInStickyRange(tableRect, top)) {\n set(stick, true);\n positionHeadStuck(head, { clonedRect, lastRowHeight, tableRect, top });\n }\n else {\n set(stick, false);\n positionHeadAtRest(head);\n }\n }\n\n function throttledToggleStickyClass(): void {\n if (rafId !== null)\n return;\n rafId = requestAnimationFrame(() => {\n toggleStickyClass();\n rafId = null;\n });\n }\n\n onMounted(() => {\n toggleStickyClass();\n useEventListener(tableScroller, 'scroll', throttledToggleStickyClass);\n useEventListener(document.body, 'scroll', throttledToggleStickyClass);\n useEventListener(window, 'resize', throttledToggleStickyClass);\n watchCellWidth();\n });\n\n return {\n stick: readonly(stick),\n };\n}\n"],"mappings":";;;;AAiBA,IAAM,YAAY;CAChB,MAAM;CACN,WAAW;CACX,KAAK;CACL,IAAI;
|
|
1
|
+
{"version":3,"file":"sticky-header.js","names":[],"sources":["../../src/composables/sticky-header.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref, ShallowRef } from 'vue';\n\nexport interface UseStickyTableHeaderRefs {\n table: Readonly<ShallowRef<HTMLTableElement | null>>;\n tableScroller: Readonly<ShallowRef<HTMLElement | null>>;\n}\n\ninterface StickyElements {\n head: HTMLElement;\n theadClone: HTMLElement;\n root: HTMLTableElement;\n}\n\ninterface UseStickyTableHeaderReturn {\n stick: Readonly<Ref<boolean>>;\n}\n\nconst SELECTORS = {\n head: ':scope > thead[data-id=head-main]',\n headClone: ':scope > thead[data-id=head-clone]',\n row: ':scope > tbody > tr:not([hidden])',\n th: ':scope > th',\n} as const;\n\nconst BORDER_PRECISION = -0.5;\n\nfunction queryHeadRow(root: HTMLTableElement, selector: string): HTMLTableRowElement | null {\n return root.querySelector(`${selector} > tr`);\n}\n\nfunction queryColumns(row: HTMLTableRowElement | null): HTMLElement[] {\n if (!row)\n return [];\n return Array.from(row.querySelectorAll<HTMLElement>(SELECTORS.th));\n}\n\nfunction readColumnWidths(columns: HTMLElement[]): number[] {\n return columns.map(col => col.getBoundingClientRect().width);\n}\n\nfunction applyColumnWidths(columns: HTMLElement[], widths: number[]): void {\n for (const [i, column] of columns.entries()) {\n const width = widths[i];\n if (width !== undefined)\n column.style.width = `${width}px`;\n }\n}\n\nfunction positionHeadAtRest(head: HTMLElement): void {\n head.style.left = `${BORDER_PRECISION}px`;\n head.style.top = '0';\n}\n\ninterface StuckPosition {\n clonedRect: DOMRect;\n tableRect: DOMRect;\n lastRowHeight: number;\n top: number;\n}\n\nfunction positionHeadStuck(head: HTMLElement, { clonedRect, lastRowHeight, tableRect, top }: StuckPosition): void {\n head.style.left = `${clonedRect.left + BORDER_PRECISION}px`;\n\n const isNearBottom = tableRect.bottom <= lastRowHeight + clonedRect.height + top;\n head.style.top = isNearBottom\n ? `${tableRect.bottom - lastRowHeight - clonedRect.height}px`\n : `${top}px`;\n}\n\nfunction isInStickyRange(tableRect: DOMRect, top: number): boolean {\n return tableRect.top <= top && tableRect.bottom > top;\n}\n\nfunction getLastRowHeight(root: HTMLTableElement): number | undefined {\n const rows = root.querySelectorAll(SELECTORS.row);\n if (rows.length <= 1)\n return undefined;\n return rows.item(rows.length - 1)?.getBoundingClientRect().height ?? 0;\n}\n\n/**\n * Setup sticky table header\n */\nexport function useStickyTableHeader(\n sticky: MaybeRefOrGetter<boolean> = shallowRef(false),\n offsetTop: MaybeRefOrGetter<number | undefined>,\n tableRefs: UseStickyTableHeaderRefs,\n): UseStickyTableHeaderReturn {\n const { table, tableScroller } = tableRefs;\n const stick = shallowRef<boolean>(false);\n\n let resizeCleanups: (() => void)[] = [];\n let syncRafId: number | null = null;\n let rafId: number | null = null;\n\n function cleanupResizeObservers(): void {\n for (const cleanup of resizeCleanups)\n cleanup();\n resizeCleanups = [];\n }\n\n function cancelPendingSync(): void {\n if (syncRafId !== null)\n cancelAnimationFrame(syncRafId);\n syncRafId = null;\n }\n\n function scheduleSyncWidths(cloneColumns: HTMLElement[], mainColumns: HTMLElement[]): void {\n cancelPendingSync();\n\n // Single-frame sync: the main thead is position absolute/fixed so clearing\n // its widths is unnecessary — clone widths are independent of main widths.\n syncRafId = requestAnimationFrame(() => {\n syncRafId = null;\n applyColumnWidths(mainColumns, readColumnWidths(cloneColumns));\n });\n }\n\n function observeColumnResizes(cloneColumns: HTMLElement[], mainColumns: HTMLElement[]): void {\n cleanupResizeObservers();\n\n for (const th of cloneColumns) {\n const { stop } = useResizeObserver(th, () => {\n scheduleSyncWidths(cloneColumns, mainColumns);\n });\n resizeCleanups.push(stop);\n }\n }\n\n function watchCellWidth(): void {\n const root = get(table);\n if (!toValue(sticky) || !root)\n return;\n\n const cloneRow = queryHeadRow(root, SELECTORS.headClone);\n const mainRow = queryHeadRow(root, SELECTORS.head);\n const cloneColumns = queryColumns(cloneRow);\n const mainColumns = queryColumns(mainRow);\n\n useMutationObserver(cloneRow, (mutations) => {\n const hasRelevantMutation = mutations.some(\n m => m.type === 'childList' || m.type === 'attributes',\n );\n if (hasRelevantMutation)\n observeColumnResizes(queryColumns(cloneRow), queryColumns(mainRow));\n }, { attributes: true, childList: true, subtree: true });\n\n observeColumnResizes(cloneColumns, mainColumns);\n }\n\n function queryStickyElements(): StickyElements | undefined {\n const root = get(table);\n if (!toValue(sticky) || !root)\n return undefined;\n\n const theadClone = root.querySelector<HTMLElement>(SELECTORS.headClone);\n const head = root.querySelector<HTMLElement>(SELECTORS.head);\n if (!theadClone || !head)\n return undefined;\n\n return { head, root, theadClone };\n }\n\n function toggleStickyClass(): void {\n const elements = queryStickyElements();\n if (!elements)\n return;\n\n const { head, root, theadClone } = elements;\n const clonedRect = theadClone.getBoundingClientRect();\n const tableRect = root.getBoundingClientRect();\n const top = toValue(offsetTop) ?? 0;\n\n head.style.width = `${clonedRect.width}px`;\n\n const lastRowHeight = getLastRowHeight(root);\n if (lastRowHeight === undefined) {\n set(stick, false);\n positionHeadAtRest(head);\n return;\n }\n\n if (isInStickyRange(tableRect, top)) {\n set(stick, true);\n positionHeadStuck(head, { clonedRect, lastRowHeight, tableRect, top });\n }\n else {\n set(stick, false);\n positionHeadAtRest(head);\n }\n }\n\n function throttledToggleStickyClass(): void {\n if (rafId !== null)\n return;\n rafId = requestAnimationFrame(() => {\n toggleStickyClass();\n rafId = null;\n });\n }\n\n onMounted(() => {\n toggleStickyClass();\n useEventListener(tableScroller, 'scroll', throttledToggleStickyClass);\n useEventListener(document.body, 'scroll', throttledToggleStickyClass);\n useEventListener(window, 'resize', throttledToggleStickyClass);\n watchCellWidth();\n });\n\n return {\n stick: readonly(stick),\n };\n}\n"],"mappings":"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"}
|
|
@@ -15,11 +15,17 @@ export interface UseTableColumnsOptions<T extends object, IdType extends keyof T
|
|
|
15
15
|
selectedData: Ref<T[IdType][] | undefined>;
|
|
16
16
|
/** Template slots provided to the table component. */
|
|
17
17
|
slots: Record<string, any>;
|
|
18
|
+
/** Pre-computes td class per column to avoid per-cell tv() calls. */
|
|
19
|
+
tdResolver?: (options: {
|
|
20
|
+
class?: string;
|
|
21
|
+
}) => string;
|
|
22
|
+
/** Whether the table is currently rendered in its stacked mobile layout. */
|
|
23
|
+
isMobile?: MaybeRefOrGetter<boolean>;
|
|
18
24
|
}
|
|
19
25
|
export interface UseTableColumnsReturn<T extends object> {
|
|
20
26
|
columns: ComputedRef<TableColumn<T>[]>;
|
|
21
27
|
colspan: ComputedRef<number>;
|
|
22
|
-
headerSlots:
|
|
28
|
+
headerSlots: `header.${string}`[];
|
|
23
29
|
cellValue: (row: T, key: TableColumn<T>['key']) => T[TableRowKey<T>];
|
|
24
30
|
}
|
|
25
31
|
export declare function useTableColumns<T extends object, IdType extends keyof T>(options: UseTableColumnsOptions<T, IdType>): UseTableColumnsReturn<T>;
|
|
@@ -1,35 +1,43 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TableAlign, getAlignClass } from "../../../components/tables/table-props.js";
|
|
2
|
+
import { getObjectKeys, isHeaderSlot } from "./types.js";
|
|
2
3
|
import { computed, toValue } from "vue";
|
|
3
4
|
import { get } from "@vueuse/shared";
|
|
4
5
|
//#region src/composables/tables/data-table/columns.ts
|
|
5
6
|
function useTableColumns(options) {
|
|
6
|
-
const { cols, columnAttr, expandable, groupKeys, rows, selectedData, slots } = options;
|
|
7
|
-
|
|
7
|
+
const { cols, columnAttr, expandable, groupKeys, isMobile, rows, selectedData, slots, tdResolver } = options;
|
|
8
|
+
function attachTdClass(columnList) {
|
|
9
|
+
if (!tdResolver) return columnList;
|
|
10
|
+
return columnList.map((col) => ({
|
|
11
|
+
...col,
|
|
12
|
+
tdClass: tdResolver({ class: getAlignClass(col.align) })
|
|
13
|
+
}));
|
|
14
|
+
}
|
|
8
15
|
const columns = computed(() => {
|
|
9
16
|
const currentCols = toValue(cols);
|
|
10
17
|
const currentRows = toValue(rows);
|
|
11
|
-
const
|
|
18
|
+
const allColumns = currentCols ?? getObjectKeys(currentRows[0] ?? {}).map((key) => ({
|
|
12
19
|
key,
|
|
13
20
|
[columnAttr]: String(key)
|
|
14
21
|
}));
|
|
22
|
+
const data = toValue(isMobile) ? allColumns.filter((column) => !column.mobileHidden) : allColumns;
|
|
15
23
|
const hasExpandColumn = data.some((row) => row.key === "expand");
|
|
16
|
-
if (get(expandable) && !hasExpandColumn) return [...data, {
|
|
24
|
+
if (get(expandable) && !hasExpandColumn) return attachTdClass([...data, {
|
|
17
25
|
key: "expand",
|
|
18
26
|
sortable: false,
|
|
19
27
|
class: "w-16",
|
|
20
28
|
cellClass: "!py-0 w-16",
|
|
21
|
-
align:
|
|
22
|
-
}];
|
|
29
|
+
align: TableAlign.end
|
|
30
|
+
}]);
|
|
23
31
|
const groupByKeys = get(groupKeys);
|
|
24
|
-
if (groupByKeys.length === 0) return data;
|
|
25
|
-
return data.filter((column) => !groupByKeys.includes(column.key));
|
|
32
|
+
if (groupByKeys.length === 0) return attachTdClass(data);
|
|
33
|
+
return attachTdClass(data.filter((column) => !groupByKeys.includes(column.key)));
|
|
26
34
|
});
|
|
27
35
|
const colspan = computed(() => {
|
|
28
36
|
let columnLength = get(columns).length;
|
|
29
37
|
if (get(selectedData)) columnLength++;
|
|
30
38
|
return columnLength;
|
|
31
39
|
});
|
|
32
|
-
const headerSlots =
|
|
40
|
+
const headerSlots = Object.keys(slots).filter(isHeaderSlot);
|
|
33
41
|
function cellValue(row, key) {
|
|
34
42
|
return row[key];
|
|
35
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"columns.js","names":[],"sources":["../../../../src/composables/tables/data-table/columns.ts"],"sourcesContent":["import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';\nimport type {\n NoneSortableTableColumn,\n TableColumn,\n TableRowKey,\n} from '@/components/tables/RuiTableHead.vue';\nimport { isHeaderSlot } from '@/composables/tables/data-table/types';\n\nexport interface UseTableColumnsOptions<T extends object, IdType extends keyof T> {\n /** Column definitions for the table. When omitted, columns are inferred from row data. */\n cols: MaybeRefOrGetter<TableColumn<T>[] | undefined>;\n /** The property on each column definition used as the column identifier. */\n columnAttr: keyof TableColumn<T>;\n /** The data rows to display in the table. */\n rows: MaybeRefOrGetter<readonly T[]>;\n /** Whether row expansion is enabled. */\n expandable: ComputedRef<boolean>;\n /** The keys currently used for grouping rows. */\n groupKeys: ComputedRef<TableRowKey<T>[]>;\n /** The currently selected row identifiers. */\n selectedData: Ref<T[IdType][] | undefined>;\n /** Template slots provided to the table component. */\n slots: Record<string, any>;\n}\n\nexport interface UseTableColumnsReturn<T extends object> {\n columns: ComputedRef<TableColumn<T>[]>;\n colspan: ComputedRef<number>;\n headerSlots:
|
|
1
|
+
{"version":3,"file":"columns.js","names":[],"sources":["../../../../src/composables/tables/data-table/columns.ts"],"sourcesContent":["import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';\nimport type {\n NoneSortableTableColumn,\n TableColumn,\n TableRowKey,\n} from '@/components/tables/RuiTableHead.vue';\nimport { getAlignClass, TableAlign } from '@/components/tables/table-props';\nimport { getObjectKeys, isHeaderSlot } from '@/composables/tables/data-table/types';\n\nexport interface UseTableColumnsOptions<T extends object, IdType extends keyof T> {\n /** Column definitions for the table. When omitted, columns are inferred from row data. */\n cols: MaybeRefOrGetter<TableColumn<T>[] | undefined>;\n /** The property on each column definition used as the column identifier. */\n columnAttr: keyof TableColumn<T>;\n /** The data rows to display in the table. */\n rows: MaybeRefOrGetter<readonly T[]>;\n /** Whether row expansion is enabled. */\n expandable: ComputedRef<boolean>;\n /** The keys currently used for grouping rows. */\n groupKeys: ComputedRef<TableRowKey<T>[]>;\n /** The currently selected row identifiers. */\n selectedData: Ref<T[IdType][] | undefined>;\n /** Template slots provided to the table component. */\n slots: Record<string, any>;\n /** Pre-computes td class per column to avoid per-cell tv() calls. */\n tdResolver?: (options: { class?: string }) => string;\n /** Whether the table is currently rendered in its stacked mobile layout. */\n isMobile?: MaybeRefOrGetter<boolean>;\n}\n\nexport interface UseTableColumnsReturn<T extends object> {\n columns: ComputedRef<TableColumn<T>[]>;\n colspan: ComputedRef<number>;\n headerSlots: `header.${string}`[];\n cellValue: (row: T, key: TableColumn<T>['key']) => T[TableRowKey<T>];\n}\n\nexport function useTableColumns<T extends object, IdType extends keyof T>(\n options: UseTableColumnsOptions<T, IdType>,\n): UseTableColumnsReturn<T> {\n const { cols, columnAttr, expandable, groupKeys, isMobile, rows, selectedData, slots, tdResolver } = options;\n\n function attachTdClass(columnList: TableColumn<T>[]): TableColumn<T>[] {\n if (!tdResolver)\n return columnList;\n\n return columnList.map(col => ({\n ...col,\n tdClass: tdResolver({ class: getAlignClass(col.align) }),\n }));\n }\n\n const columns = computed<TableColumn<T>[]>(() => {\n const currentCols = toValue(cols);\n const currentRows = toValue(rows);\n const allColumns =\n currentCols ??\n getObjectKeys(currentRows[0] ?? {}).map(\n key =>\n ({\n key,\n [columnAttr]: String(key),\n }) satisfies NoneSortableTableColumn<T>,\n );\n\n const data = toValue(isMobile)\n ? allColumns.filter(column => !column.mobileHidden)\n : allColumns;\n\n const hasExpandColumn = data.some(row => row.key === 'expand');\n\n if (get(expandable) && !hasExpandColumn) {\n return attachTdClass([\n ...data,\n {\n key: 'expand' as TableRowKey<T>,\n sortable: false,\n class: 'w-16',\n cellClass: '!py-0 w-16',\n align: TableAlign.end,\n } satisfies NoneSortableTableColumn<T>,\n ]);\n }\n\n const groupByKeys = get(groupKeys);\n\n if (groupByKeys.length === 0)\n return attachTdClass(data);\n\n return attachTdClass(data.filter(column => !groupByKeys.includes(column.key as TableRowKey<T>)));\n });\n\n const colspan = computed<number>(() => {\n let columnLength = get(columns).length;\n if (get(selectedData))\n columnLength++;\n\n return columnLength;\n });\n\n // Slot keys are static for the component lifetime — no reactivity needed\n const headerSlots: `header.${string}`[] = Object.keys(slots).filter(isHeaderSlot);\n\n function cellValue(row: T, key: TableColumn<T>['key']): T[TableRowKey<T>] {\n return row[key as TableRowKey<T>];\n }\n\n return {\n columns,\n colspan,\n headerSlots,\n cellValue,\n };\n}\n"],"mappings":";;;;;AAqCA,SAAgB,gBACd,SAC0B;CAC1B,MAAM,EAAE,MAAM,YAAY,YAAY,WAAW,UAAU,MAAM,cAAc,OAAO,eAAe;CAErG,SAAS,cAAc,YAAgD;EACrE,IAAI,CAAC,YACH,OAAO;EAET,OAAO,WAAW,KAAI,SAAQ;GAC5B,GAAG;GACH,SAAS,WAAW,EAAE,OAAO,cAAc,IAAI,KAAK,EAAE,CAAC;EACzD,EAAE;CACJ;CAEA,MAAM,UAAU,eAAiC;EAC/C,MAAM,cAAc,QAAQ,IAAI;EAChC,MAAM,cAAc,QAAQ,IAAI;EAChC,MAAM,aACJ,eACA,cAAc,YAAY,MAAM,CAAC,CAAC,CAAC,CAAC,KAClC,SACG;GACC;IACC,aAAa,OAAO,GAAG;EAC1B,EACJ;EAEF,MAAM,OAAO,QAAQ,QAAQ,IACzB,WAAW,QAAO,WAAU,CAAC,OAAO,YAAY,IAChD;EAEJ,MAAM,kBAAkB,KAAK,MAAK,QAAO,IAAI,QAAQ,QAAQ;EAE7D,IAAI,IAAI,UAAU,KAAK,CAAC,iBACtB,OAAO,cAAc,CACnB,GAAG,MACH;GACE,KAAK;GACL,UAAU;GACV,OAAO;GACP,WAAW;GACX,OAAO,WAAW;EACpB,CACF,CAAC;EAGH,MAAM,cAAc,IAAI,SAAS;EAEjC,IAAI,YAAY,WAAW,GACzB,OAAO,cAAc,IAAI;EAE3B,OAAO,cAAc,KAAK,QAAO,WAAU,CAAC,YAAY,SAAS,OAAO,GAAqB,CAAC,CAAC;CACjG,CAAC;CAED,MAAM,UAAU,eAAuB;EACrC,IAAI,eAAe,IAAI,OAAO,CAAC,CAAC;EAChC,IAAI,IAAI,YAAY,GAClB;EAEF,OAAO;CACT,CAAC;CAGD,MAAM,cAAoC,OAAO,KAAK,KAAK,CAAC,CAAC,OAAO,YAAY;CAEhF,SAAS,UAAU,KAAQ,KAA+C;EACxE,OAAO,IAAI;CACb;CAEA,OAAO;EACL;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expansion.js","names":[],"sources":["../../../../src/composables/tables/data-table/expansion.ts"],"sourcesContent":["import type { ComputedRef, Ref } from 'vue';\n\nexport interface UseTableExpansionOptions<T extends object, IdType extends keyof T> {\n /** The property on each row used as the unique row identifier. */\n rowAttr: IdType;\n /** Whether only one row can be expanded at a time. */\n singleExpand: boolean;\n}\n\nexport interface UseTableExpansionDeps<T extends object> {\n expanded: Ref<T[] | undefined>;\n}\n\nexport interface UseTableExpansionReturn<T extends object, IdType extends keyof T> {\n expandable: ComputedRef<boolean>;\n isExpanded: (identifier: T[IdType]) => boolean;\n onToggleExpand: (row: T) => void;\n}\n\nexport function useTableExpansion<T extends object, IdType extends keyof T>(\n options: UseTableExpansionOptions<T, IdType>,\n deps: UseTableExpansionDeps<T>,\n): UseTableExpansionReturn<T, IdType> {\n const { rowAttr, singleExpand } = options;\n const { expanded } = deps;\n\n // `expandable` only tracks whether the consumer has wired a two-way\n // `expanded` model. Whether an `#expanded-item` slot is present is\n // checked fresh in the template (`!!$slots['expanded-item']`) so that\n // consumers which gate the slot with `v-if` (e.g. only after data\n // loads) don't get stuck on the first-render slot snapshot — Vue's\n // `slots` object is not reactive to property access inside a computed.\n const expandable = computed<boolean>(() => !!get(expanded));\n\n const expandedSet = computed<Set<T[IdType]>>(() => {\n const expandedVal = get(expanded);\n if (!expandedVal?.length)\n return new Set<T[IdType]>();\n return new Set<T[IdType]>(expandedVal.map(row => row[rowAttr]));\n });\n\n function isExpanded(identifier: T[IdType]): boolean {\n return get(expandedSet).has(identifier);\n }\n\n function onToggleExpand(row: T): void {\n const expandedVal = get(expanded);\n if (!expandedVal)\n return;\n\n const key = rowAttr;\n const rowExpanded = isExpanded(row[key]);\n\n if (singleExpand)\n return set(expanded, rowExpanded ? [] : [row]);\n\n return set(\n expanded,\n rowExpanded ? expandedVal.filter(item => item[key] !== row[key]) : [...expandedVal, row],\n );\n }\n\n return {\n expandable,\n isExpanded,\n onToggleExpand,\n };\n}\n"],"mappings":";;;AAmBA,SAAgB,kBACd,SACA,MACoC;CACpC,MAAM,EAAE,SAAS,iBAAiB;CAClC,MAAM,EAAE,aAAa;CAQrB,MAAM,aAAa,eAAwB,CAAC,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"expansion.js","names":[],"sources":["../../../../src/composables/tables/data-table/expansion.ts"],"sourcesContent":["import type { ComputedRef, Ref } from 'vue';\n\nexport interface UseTableExpansionOptions<T extends object, IdType extends keyof T> {\n /** The property on each row used as the unique row identifier. */\n rowAttr: IdType;\n /** Whether only one row can be expanded at a time. */\n singleExpand: boolean;\n}\n\nexport interface UseTableExpansionDeps<T extends object> {\n expanded: Ref<T[] | undefined>;\n}\n\nexport interface UseTableExpansionReturn<T extends object, IdType extends keyof T> {\n expandable: ComputedRef<boolean>;\n isExpanded: (identifier: T[IdType]) => boolean;\n onToggleExpand: (row: T) => void;\n}\n\nexport function useTableExpansion<T extends object, IdType extends keyof T>(\n options: UseTableExpansionOptions<T, IdType>,\n deps: UseTableExpansionDeps<T>,\n): UseTableExpansionReturn<T, IdType> {\n const { rowAttr, singleExpand } = options;\n const { expanded } = deps;\n\n // `expandable` only tracks whether the consumer has wired a two-way\n // `expanded` model. Whether an `#expanded-item` slot is present is\n // checked fresh in the template (`!!$slots['expanded-item']`) so that\n // consumers which gate the slot with `v-if` (e.g. only after data\n // loads) don't get stuck on the first-render slot snapshot — Vue's\n // `slots` object is not reactive to property access inside a computed.\n const expandable = computed<boolean>(() => !!get(expanded));\n\n const expandedSet = computed<Set<T[IdType]>>(() => {\n const expandedVal = get(expanded);\n if (!expandedVal?.length)\n return new Set<T[IdType]>();\n return new Set<T[IdType]>(expandedVal.map(row => row[rowAttr]));\n });\n\n function isExpanded(identifier: T[IdType]): boolean {\n return get(expandedSet).has(identifier);\n }\n\n function onToggleExpand(row: T): void {\n const expandedVal = get(expanded);\n if (!expandedVal)\n return;\n\n const key = rowAttr;\n const rowExpanded = isExpanded(row[key]);\n\n if (singleExpand)\n return set(expanded, rowExpanded ? [] : [row]);\n\n return set(\n expanded,\n rowExpanded ? expandedVal.filter(item => item[key] !== row[key]) : [...expandedVal, row],\n );\n }\n\n return {\n expandable,\n isExpanded,\n onToggleExpand,\n };\n}\n"],"mappings":";;;AAmBA,SAAgB,kBACd,SACA,MACoC;CACpC,MAAM,EAAE,SAAS,iBAAiB;CAClC,MAAM,EAAE,aAAa;CAQrB,MAAM,aAAa,eAAwB,CAAC,CAAC,IAAI,QAAQ,CAAC;CAE1D,MAAM,cAAc,eAA+B;EACjD,MAAM,cAAc,IAAI,QAAQ;EAChC,IAAI,CAAC,aAAa,QAChB,uBAAO,IAAI,IAAe;EAC5B,OAAO,IAAI,IAAe,YAAY,KAAI,QAAO,IAAI,QAAQ,CAAC;CAChE,CAAC;CAED,SAAS,WAAW,YAAgC;EAClD,OAAO,IAAI,WAAW,CAAC,CAAC,IAAI,UAAU;CACxC;CAEA,SAAS,eAAe,KAAc;EACpC,MAAM,cAAc,IAAI,QAAQ;EAChC,IAAI,CAAC,aACH;EAEF,MAAM,MAAM;EACZ,MAAM,cAAc,WAAW,IAAI,IAAI;EAEvC,IAAI,cACF,OAAO,IAAI,UAAU,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC;EAE/C,OAAO,IACL,UACA,cAAc,YAAY,QAAO,SAAQ,KAAK,SAAS,IAAI,IAAI,IAAI,CAAC,GAAG,aAAa,GAAG,CACzF;CACF;CAEA,OAAO;EACL;EACA;EACA;CACF;AACF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ComputedRef, Ref } from 'vue';
|
|
2
|
-
import type {
|
|
2
|
+
import type { TableRowKey, TableRowKeyData } from '../../../components/tables/RuiTableHead.vue';
|
|
3
3
|
import { type GroupedTableRow } from '../../../composables/tables/data-table/types.js';
|
|
4
4
|
export interface UseTableGroupingOptions<T extends object, IdType extends keyof T> {
|
|
5
5
|
/** The property on each row used as the unique row identifier. */
|
|
@@ -8,15 +8,14 @@ export interface UseTableGroupingOptions<T extends object, IdType extends keyof
|
|
|
8
8
|
export interface UseTableGroupingDeps<T extends object> {
|
|
9
9
|
group: Ref<TableRowKeyData<T>>;
|
|
10
10
|
collapsed: Ref<T[] | undefined>;
|
|
11
|
-
sorted: ComputedRef<T[]>;
|
|
12
|
-
emitCopyGroup: (value: GroupData<T>) => void;
|
|
11
|
+
sorted: ComputedRef<readonly T[]>;
|
|
13
12
|
}
|
|
14
13
|
export interface UseTableGroupingReturn<T extends object> {
|
|
15
14
|
groupKeys: ComputedRef<TableRowKey<T>[]>;
|
|
16
|
-
groupKey: ComputedRef<string>;
|
|
15
|
+
groupKey: ComputedRef<string | undefined>;
|
|
17
16
|
isGrouped: ComputedRef<boolean>;
|
|
18
17
|
mappedGroups: ComputedRef<Record<string, GroupedTableRow<T>[]>>;
|
|
19
|
-
grouped: ComputedRef<GroupedTableRow<T>[]>;
|
|
18
|
+
grouped: ComputedRef<readonly GroupedTableRow<T>[]>;
|
|
20
19
|
getRowGroup: (row: T) => Partial<T>;
|
|
21
20
|
getGroupRows: (groupVal: string) => T[];
|
|
22
21
|
compareGroupsFn: (a: T, b: Partial<T>) => boolean;
|
|
@@ -24,6 +23,5 @@ export interface UseTableGroupingReturn<T extends object> {
|
|
|
24
23
|
isHiddenRow: (row: GroupedTableRow<T>) => boolean;
|
|
25
24
|
onToggleExpandGroup: (group: Partial<T>, value?: string) => void;
|
|
26
25
|
onUngroup: () => void;
|
|
27
|
-
onCopyGroup: (value: GroupData<T>) => void;
|
|
28
26
|
}
|
|
29
27
|
export declare function useTableGrouping<T extends object, IdType extends keyof T>(options: UseTableGroupingOptions<T, IdType>, deps: UseTableGroupingDeps<T>): UseTableGroupingReturn<T>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { assert } from "../../../utils/assert.js";
|
|
2
|
-
import { isRow } from "./types.js";
|
|
2
|
+
import { GROUP_HEADER_BRAND, isRow } from "./types.js";
|
|
3
3
|
import { computed, ref, watch } from "vue";
|
|
4
4
|
import { isDefined } from "@vueuse/core";
|
|
5
5
|
import { get as get$1, set as set$1 } from "@vueuse/shared";
|
|
@@ -7,7 +7,7 @@ import { get as get$1, set as set$1 } from "@vueuse/shared";
|
|
|
7
7
|
var GROUP_KEY_SEPARATOR = "\0";
|
|
8
8
|
function useTableGrouping(options, deps) {
|
|
9
9
|
const { rowAttr } = options;
|
|
10
|
-
const { group, collapsed, sorted
|
|
10
|
+
const { group, collapsed, sorted } = deps;
|
|
11
11
|
const collapsedRows = ref([]);
|
|
12
12
|
watch(collapsed, (value) => set$1(collapsedRows, value ?? []), { immediate: true });
|
|
13
13
|
const groupKeys = computed(() => {
|
|
@@ -16,17 +16,16 @@ function useTableGrouping(options, deps) {
|
|
|
16
16
|
if (!Array.isArray(groupBy)) return [groupBy];
|
|
17
17
|
return groupBy;
|
|
18
18
|
});
|
|
19
|
-
const groupKey = computed(() =>
|
|
20
|
-
|
|
19
|
+
const groupKey = computed(() => {
|
|
20
|
+
return get$1(groupKeys).join(":") || void 0;
|
|
21
|
+
});
|
|
22
|
+
const isGrouped = computed(() => get$1(groupKey) !== void 0);
|
|
21
23
|
const collapsedIdentifierSet = computed(() => new Set(get$1(collapsedRows).map((row) => row[rowAttr])));
|
|
22
24
|
const collapsedGroupKeySet = computed(() => {
|
|
23
25
|
const grouping = get$1(groupKeys);
|
|
24
26
|
if (grouping.length === 0) return /* @__PURE__ */ new Set();
|
|
25
27
|
const seen = /* @__PURE__ */ new Set();
|
|
26
|
-
for (const row of get$1(collapsedRows))
|
|
27
|
-
const groupVal = grouping.map((key) => row[key]).filter(isDefined).join(GROUP_KEY_SEPARATOR);
|
|
28
|
-
seen.add(groupVal);
|
|
29
|
-
}
|
|
28
|
+
for (const row of get$1(collapsedRows)) seen.add(computeGroupKey(row, grouping));
|
|
30
29
|
return seen;
|
|
31
30
|
});
|
|
32
31
|
function getRowGroup(row) {
|
|
@@ -40,7 +39,13 @@ function useTableGrouping(options, deps) {
|
|
|
40
39
|
return grouping.every((key) => a[key] === b[key]);
|
|
41
40
|
}
|
|
42
41
|
function isExpandedGroup(value) {
|
|
43
|
-
const
|
|
42
|
+
const grouping = get$1(groupKeys);
|
|
43
|
+
let groupVal = "";
|
|
44
|
+
for (const gk of grouping) {
|
|
45
|
+
if (groupVal) groupVal += GROUP_KEY_SEPARATOR;
|
|
46
|
+
const val = value[gk];
|
|
47
|
+
groupVal += isDefined(val) ? val : "";
|
|
48
|
+
}
|
|
44
49
|
return !get$1(collapsedGroupKeySet).has(groupVal);
|
|
45
50
|
}
|
|
46
51
|
function isHiddenRow(row) {
|
|
@@ -48,27 +53,40 @@ function useTableGrouping(options, deps) {
|
|
|
48
53
|
if (!isRow(row)) return false;
|
|
49
54
|
return get$1(collapsedIdentifierSet).has(row[rowAttr]);
|
|
50
55
|
}
|
|
56
|
+
function computeGroupKey(row, grouping) {
|
|
57
|
+
let key = "";
|
|
58
|
+
for (const gk of grouping) {
|
|
59
|
+
if (key) key += GROUP_KEY_SEPARATOR;
|
|
60
|
+
const val = row[gk];
|
|
61
|
+
key += isDefined(val) ? val : "";
|
|
62
|
+
}
|
|
63
|
+
return key;
|
|
64
|
+
}
|
|
51
65
|
const mappedGroups = computed(() => {
|
|
52
|
-
|
|
66
|
+
const grouping = get$1(groupKeys);
|
|
67
|
+
if (grouping.length === 0) return {};
|
|
53
68
|
const result = get$1(sorted);
|
|
54
69
|
const identifier = rowAttr;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const groupVal =
|
|
70
|
+
const acc = {};
|
|
71
|
+
for (const row of result) {
|
|
72
|
+
if (!isDefined(row[identifier]) || row[identifier] === "") continue;
|
|
73
|
+
const groupVal = computeGroupKey(row, grouping);
|
|
59
74
|
if (!acc[groupVal]) acc[groupVal] = [{
|
|
60
|
-
|
|
61
|
-
group:
|
|
75
|
+
[GROUP_HEADER_BRAND]: true,
|
|
76
|
+
group: getRowGroup(row),
|
|
62
77
|
identifier: groupVal
|
|
63
78
|
}];
|
|
64
79
|
acc[groupVal].push(row);
|
|
65
|
-
|
|
66
|
-
|
|
80
|
+
}
|
|
81
|
+
return acc;
|
|
67
82
|
});
|
|
68
83
|
const grouped = computed(() => {
|
|
69
84
|
const result = get$1(sorted);
|
|
70
85
|
if (!get$1(groupKey)) return result;
|
|
71
|
-
|
|
86
|
+
const groups = get$1(mappedGroups);
|
|
87
|
+
const out = [];
|
|
88
|
+
for (const items of Object.values(groups)) for (const item of items) out.push(item);
|
|
89
|
+
return out;
|
|
72
90
|
});
|
|
73
91
|
function getGroupRows(groupVal) {
|
|
74
92
|
if (!get$1(isGrouped)) return [];
|
|
@@ -89,9 +107,6 @@ function useTableGrouping(options, deps) {
|
|
|
89
107
|
set$1(collapsed, []);
|
|
90
108
|
set$1(group, Array.isArray(get$1(group)) ? [] : void 0);
|
|
91
109
|
}
|
|
92
|
-
function onCopyGroup(value) {
|
|
93
|
-
emitCopyGroup(value);
|
|
94
|
-
}
|
|
95
110
|
return {
|
|
96
111
|
groupKeys,
|
|
97
112
|
groupKey,
|
|
@@ -104,8 +119,7 @@ function useTableGrouping(options, deps) {
|
|
|
104
119
|
isExpandedGroup,
|
|
105
120
|
isHiddenRow,
|
|
106
121
|
onToggleExpandGroup,
|
|
107
|
-
onUngroup
|
|
108
|
-
onCopyGroup
|
|
122
|
+
onUngroup
|
|
109
123
|
};
|
|
110
124
|
}
|
|
111
125
|
//#endregion
|