@rotki/ui-library 2.12.2 → 2.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/accordions/accordion/RuiAccordion.vue.d.ts +6 -14
- package/dist/components/accordions/accordion/RuiAccordion.vue.js +3 -4
- package/dist/components/accordions/accordion/RuiAccordion.vue.js.map +1 -1
- package/dist/components/accordions/accordions/RuiAccordions.vue.d.ts +10 -9
- package/dist/components/accordions/accordions/RuiAccordions.vue.js +27 -26
- package/dist/components/accordions/accordions/RuiAccordions.vue.js.map +1 -1
- package/dist/components/alerts/RuiAlert.vue.d.ts +5 -15
- package/dist/components/alerts/RuiAlert.vue2.js +8 -16
- package/dist/components/alerts/RuiAlert.vue2.js.map +1 -1
- package/dist/components/buttons/button/RuiButton.vue.d.ts +5 -7
- package/dist/components/buttons/button/RuiButton.vue2.js +19 -20
- package/dist/components/buttons/button/RuiButton.vue2.js.map +1 -1
- package/dist/components/buttons/button-group/RuiButtonGroup.vue.d.ts +6 -5
- package/dist/components/buttons/button-group/RuiButtonGroup.vue2.js +42 -41
- package/dist/components/buttons/button-group/RuiButtonGroup.vue2.js.map +1 -1
- package/dist/components/calendar/RuiCalendar.vue.d.ts +1 -6
- package/dist/components/calendar/RuiCalendar.vue.js +6 -7
- package/dist/components/calendar/RuiCalendar.vue.js.map +1 -1
- package/dist/components/calendar/RuiCalendarGrid.vue.js +1 -1
- package/dist/components/calendar/RuiCalendarGrid.vue2.js +19 -17
- package/dist/components/calendar/RuiCalendarGrid.vue2.js.map +1 -1
- package/dist/components/calendar/RuiCalendarHeader.vue.js +1 -1
- package/dist/components/calendar/RuiCalendarHeader.vue2.js +2 -3
- package/dist/components/calendar/RuiCalendarHeader.vue2.js.map +1 -1
- package/dist/components/calendar/RuiCalendarMenu.vue.js +1 -1
- package/dist/components/calendar/RuiCalendarMenu.vue2.js +47 -39
- package/dist/components/calendar/RuiCalendarMenu.vue2.js.map +1 -1
- package/dist/components/cards/RuiCard.vue.d.ts +9 -24
- package/dist/components/cards/RuiCard.vue2.js +7 -7
- package/dist/components/cards/RuiCard.vue2.js.map +1 -1
- package/dist/components/cards/RuiCardHeader.vue.d.ts +5 -10
- package/dist/components/cards/RuiCardHeader.vue2.js.map +1 -1
- package/dist/components/chips/RuiChip.vue.d.ts +7 -21
- package/dist/components/chips/RuiChip.vue2.js +16 -21
- package/dist/components/chips/RuiChip.vue2.js.map +1 -1
- package/dist/components/color-picker/RuiColorBoard.vue.d.ts +1 -1
- package/dist/components/color-picker/RuiColorBoard.vue2.js +14 -18
- package/dist/components/color-picker/RuiColorBoard.vue2.js.map +1 -1
- package/dist/components/color-picker/RuiColorDisplay.vue.js +3 -5
- package/dist/components/color-picker/RuiColorDisplay.vue.js.map +1 -1
- package/dist/components/color-picker/RuiColorHue.vue2.js +10 -13
- package/dist/components/color-picker/RuiColorHue.vue2.js.map +1 -1
- package/dist/components/color-picker/RuiColorInput.vue.js +8 -6
- package/dist/components/color-picker/RuiColorInput.vue.js.map +1 -1
- package/dist/components/color-picker/RuiColorPicker.vue.d.ts +7 -9
- package/dist/components/color-picker/RuiColorPicker.vue.js +18 -13
- package/dist/components/color-picker/RuiColorPicker.vue.js.map +1 -1
- package/dist/components/color-picker/utils.js +22 -5
- package/dist/components/color-picker/utils.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePicker.vue.d.ts +2 -44
- package/dist/components/date-time-picker/RuiDateTimePicker.vue2.js +73 -77
- package/dist/components/date-time-picker/RuiDateTimePicker.vue2.js.map +1 -1
- package/dist/components/date-time-picker/dayjs-setup.d.ts +1 -0
- package/dist/components/date-time-picker/dayjs-setup.js +8 -0
- package/dist/components/date-time-picker/dayjs-setup.js.map +1 -0
- package/dist/components/date-time-picker/segment-config.d.ts +14 -0
- package/dist/components/date-time-picker/segment-config.js +23 -0
- package/dist/components/date-time-picker/segment-config.js.map +1 -0
- package/dist/components/date-time-picker/segment-utils.d.ts +5 -0
- package/dist/components/date-time-picker/segment-utils.js +36 -0
- package/dist/components/date-time-picker/segment-utils.js.map +1 -0
- package/dist/components/date-time-picker/use-date-time-selection.d.ts +1 -0
- package/dist/components/date-time-picker/use-date-time-selection.js +1 -0
- package/dist/components/date-time-picker/use-date-time-selection.js.map +1 -1
- package/dist/components/date-time-picker/use-keyboard-handler.d.ts +4 -8
- package/dist/components/date-time-picker/use-keyboard-handler.js +9 -54
- package/dist/components/date-time-picker/use-keyboard-handler.js.map +1 -1
- package/dist/components/date-time-picker/utils.d.ts +1 -0
- package/dist/components/date-time-picker/utils.js +1 -0
- package/dist/components/date-time-picker/utils.js.map +1 -1
- package/dist/components/divider/RuiDivider.vue.d.ts +1 -3
- package/dist/components/divider/RuiDivider.vue.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue.d.ts +9 -1120
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue2.js +144 -160
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue2.js.map +1 -1
- package/dist/components/forms/checkbox/RuiCheckbox.vue.d.ts +15 -24
- package/dist/components/forms/checkbox/RuiCheckbox.vue2.js +31 -31
- package/dist/components/forms/checkbox/RuiCheckbox.vue2.js.map +1 -1
- package/dist/components/forms/radio-button/radio/RuiRadio.vue.d.ts +1 -1
- package/dist/components/forms/radio-button/radio/RuiRadio.vue2.js +18 -21
- package/dist/components/forms/radio-button/radio/RuiRadio.vue2.js.map +1 -1
- package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue.d.ts +3 -1
- package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue2.js +12 -15
- package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue2.js.map +1 -1
- package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue.d.ts +5 -11
- package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue.js +6 -7
- package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue.js.map +1 -1
- package/dist/components/forms/select/RuiMenuSelect.vue.d.ts +9 -784
- package/dist/components/forms/select/RuiMenuSelect.vue2.js +48 -51
- package/dist/components/forms/select/RuiMenuSelect.vue2.js.map +1 -1
- package/dist/components/forms/select/RuiSimpleSelect.vue.d.ts +10 -11
- package/dist/components/forms/select/RuiSimpleSelect.vue2.js +15 -24
- package/dist/components/forms/select/RuiSimpleSelect.vue2.js.map +1 -1
- package/dist/components/forms/slider/RuiSlider.vue.d.ts +10 -26
- package/dist/components/forms/slider/RuiSlider.vue2.js +41 -46
- package/dist/components/forms/slider/RuiSlider.vue2.js.map +1 -1
- package/dist/components/forms/switch/RuiSwitch.vue.d.ts +12 -20
- package/dist/components/forms/switch/RuiSwitch.vue2.js +21 -20
- package/dist/components/forms/switch/RuiSwitch.vue2.js.map +1 -1
- package/dist/components/forms/text-area/RuiTextArea.vue.d.ts +5 -30
- package/dist/components/forms/text-area/RuiTextArea.vue2.js +43 -79
- package/dist/components/forms/text-area/RuiTextArea.vue2.js.map +1 -1
- package/dist/components/forms/text-field/RuiTextField.vue.d.ts +7 -27
- package/dist/components/forms/text-field/RuiTextField.vue2.js +35 -66
- package/dist/components/forms/text-field/RuiTextField.vue2.js.map +1 -1
- package/dist/components/helpers/RuiFormTextDetail.vue.d.ts +1 -5
- package/dist/components/helpers/RuiFormTextDetail.vue.js +5 -9
- package/dist/components/helpers/RuiFormTextDetail.vue.js.map +1 -1
- package/dist/components/icons/LazyIcon.vue.d.ts +1 -3
- package/dist/components/icons/RuiIcon.vue.d.ts +1 -4
- package/dist/components/icons/RuiIcon.vue2.js +8 -8
- package/dist/components/icons/RuiIcon.vue2.js.map +1 -1
- package/dist/components/index.d.ts +3 -3
- package/dist/components/loaders/RuiSkeletonBase.vue.d.ts +1 -3
- package/dist/components/loaders/RuiSkeletonBase.vue2.js +1 -1
- package/dist/components/loaders/RuiSkeletonBase.vue2.js.map +1 -1
- package/dist/components/loaders/RuiSkeletonLoader.vue.d.ts +1 -4
- package/dist/components/loaders/RuiSkeletonLoader.vue2.js +1 -1
- package/dist/components/loaders/RuiSkeletonLoader.vue2.js.map +1 -1
- package/dist/components/logos/RuiLogo.vue.d.ts +1 -7
- package/dist/components/logos/RuiLogo.vue.js +11 -13
- package/dist/components/logos/RuiLogo.vue.js.map +1 -1
- package/dist/components/overlays/badge/RuiBadge.vue.d.ts +5 -20
- package/dist/components/overlays/badge/RuiBadge.vue2.js +11 -13
- package/dist/components/overlays/badge/RuiBadge.vue2.js.map +1 -1
- package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue.d.ts +10 -5
- package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue.js +18 -7
- package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue.js.map +1 -1
- package/dist/components/overlays/dialog/RuiDialog.vue.d.ts +21 -27
- package/dist/components/overlays/dialog/RuiDialog.vue2.js +80 -63
- package/dist/components/overlays/dialog/RuiDialog.vue2.js.map +1 -1
- package/dist/components/overlays/menu/RuiMenu.vue.d.ts +24 -35
- package/dist/components/overlays/menu/RuiMenu.vue2.js +67 -76
- package/dist/components/overlays/menu/RuiMenu.vue2.js.map +1 -1
- package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue.d.ts +22 -30
- package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue2.js +71 -47
- package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue2.js.map +1 -1
- package/dist/components/overlays/notification/RuiNotification.vue.d.ts +12 -12
- package/dist/components/overlays/notification/RuiNotification.vue.js +25 -22
- package/dist/components/overlays/notification/RuiNotification.vue.js.map +1 -1
- package/dist/components/overlays/tooltip/RuiTooltip.vue.d.ts +7 -18
- package/dist/components/overlays/tooltip/RuiTooltip.vue2.js +11 -8
- package/dist/components/overlays/tooltip/RuiTooltip.vue2.js.map +1 -1
- package/dist/components/progress/RuiProgress.vue.d.ts +8 -10
- package/dist/components/progress/RuiProgress.vue2.js +18 -24
- package/dist/components/progress/RuiProgress.vue2.js.map +1 -1
- package/dist/components/steppers/RuiFooterStepper.vue.d.ts +10 -11
- package/dist/components/steppers/RuiFooterStepper.vue2.js +21 -21
- package/dist/components/steppers/RuiFooterStepper.vue2.js.map +1 -1
- package/dist/components/steppers/RuiStepper.vue.d.ts +6 -15
- package/dist/components/steppers/RuiStepper.vue2.js +31 -33
- package/dist/components/steppers/RuiStepper.vue2.js.map +1 -1
- package/dist/components/steppers/RuiStepperCustomIcon.vue.d.ts +1 -3
- package/dist/components/steppers/RuiStepperCustomIcon.vue2.js +1 -1
- package/dist/components/steppers/RuiStepperCustomIcon.vue2.js.map +1 -1
- package/dist/components/steppers/RuiStepperIcon.vue.d.ts +1 -3
- package/dist/components/steppers/RuiStepperIcon.vue2.js +1 -1
- package/dist/components/steppers/RuiStepperIcon.vue2.js.map +1 -1
- package/dist/components/tables/RuiDataTable.vue.d.ts +29 -81
- package/dist/components/tables/RuiDataTable.vue2.js +173 -582
- package/dist/components/tables/RuiDataTable.vue2.js.map +1 -1
- package/dist/components/tables/RuiDataTable.vue3.js +24 -27
- package/dist/components/tables/RuiDataTable.vue3.js.map +1 -1
- package/dist/components/tables/RuiExpandButton.vue.d.ts +3 -6
- package/dist/components/tables/RuiExpandButton.vue2.js +1 -0
- package/dist/components/tables/RuiExpandButton.vue2.js.map +1 -1
- package/dist/components/tables/RuiTableHead.vue.d.ts +4 -7
- package/dist/components/tables/RuiTableHead.vue2.js +19 -19
- package/dist/components/tables/RuiTableHead.vue2.js.map +1 -1
- package/dist/components/tables/RuiTablePagination.vue.d.ts +10 -10
- package/dist/components/tables/RuiTablePagination.vue2.js +17 -16
- package/dist/components/tables/RuiTablePagination.vue2.js.map +1 -1
- package/dist/components/tabs/tab/RuiTab.vue.d.ts +3 -18
- package/dist/components/tabs/tab/RuiTab.vue2.js +80 -51
- package/dist/components/tabs/tab/RuiTab.vue2.js.map +1 -1
- package/dist/components/tabs/tab-item/RuiTabItem.vue.d.ts +3 -11
- package/dist/components/tabs/tab-item/RuiTabItem.vue2.js +1 -1
- package/dist/components/tabs/tab-item/RuiTabItem.vue2.js.map +1 -1
- package/dist/components/tabs/tab-items/RuiTabItems.vue.d.ts +1 -4
- package/dist/components/tabs/tab-items/RuiTabItems.vue2.js +18 -18
- package/dist/components/tabs/tab-items/RuiTabItems.vue2.js.map +1 -1
- package/dist/components/tabs/tabs/RuiTabs.vue.d.ts +10 -14
- package/dist/components/tabs/tabs/RuiTabs.vue2.js +101 -94
- package/dist/components/tabs/tabs/RuiTabs.vue2.js.map +1 -1
- package/dist/components/time-picker/RuiTimePicker.vue.d.ts +1 -4
- package/dist/components/time-picker/RuiTimePicker.vue2.js +68 -35
- package/dist/components/time-picker/RuiTimePicker.vue2.js.map +1 -1
- package/dist/composables/breakpoint.js +8 -13
- package/dist/composables/breakpoint.js.map +1 -1
- package/dist/composables/dropdown-menu.d.ts +7 -4
- package/dist/composables/dropdown-menu.js +73 -50
- package/dist/composables/dropdown-menu.js.map +1 -1
- package/dist/composables/forms/auto-complete/focus.d.ts +7 -5
- package/dist/composables/forms/auto-complete/focus.js +28 -17
- package/dist/composables/forms/auto-complete/focus.js.map +1 -1
- package/dist/composables/forms/auto-complete/index.d.ts +0 -9
- package/dist/composables/forms/auto-complete/keyboard-navigation.d.ts +8 -3
- package/dist/composables/forms/auto-complete/keyboard-navigation.js +11 -5
- package/dist/composables/forms/auto-complete/keyboard-navigation.js.map +1 -1
- package/dist/composables/forms/auto-complete/search.d.ts +7 -0
- package/dist/composables/forms/auto-complete/search.js +10 -8
- package/dist/composables/forms/auto-complete/search.js.map +1 -1
- package/dist/composables/forms/auto-complete/value.d.ts +4 -0
- package/dist/composables/forms/auto-complete/value.js +24 -42
- package/dist/composables/forms/auto-complete/value.js.map +1 -1
- package/dist/composables/forms/use-label-with-quote.d.ts +2 -0
- package/dist/composables/forms/use-label-with-quote.js +14 -0
- package/dist/composables/forms/use-label-with-quote.js.map +1 -0
- package/dist/composables/forms/use-prepend-append-width.d.ts +6 -0
- package/dist/composables/forms/use-prepend-append-width.js +25 -0
- package/dist/composables/forms/use-prepend-append-width.js.map +1 -0
- package/dist/composables/popper.js +60 -46
- package/dist/composables/popper.js.map +1 -1
- package/dist/composables/sticky-header.d.ts +7 -5
- package/dist/composables/sticky-header.js +51 -41
- package/dist/composables/sticky-header.js.map +1 -1
- package/dist/composables/tables/data-table/columns.d.ts +25 -0
- package/dist/composables/tables/data-table/columns.js +54 -0
- package/dist/composables/tables/data-table/columns.js.map +1 -0
- package/dist/composables/tables/data-table/expansion.d.ts +17 -0
- package/dist/composables/tables/data-table/expansion.js +38 -0
- package/dist/composables/tables/data-table/expansion.js.map +1 -0
- package/dist/composables/tables/data-table/grouping.d.ts +29 -0
- package/dist/composables/tables/data-table/grouping.js +136 -0
- package/dist/composables/tables/data-table/grouping.js.map +1 -0
- package/dist/composables/tables/data-table/pagination.d.ts +33 -0
- package/dist/composables/tables/data-table/pagination.js +119 -0
- package/dist/composables/tables/data-table/pagination.js.map +1 -0
- package/dist/composables/tables/data-table/selection.d.ts +29 -0
- package/dist/composables/tables/data-table/selection.js +164 -0
- package/dist/composables/tables/data-table/selection.js.map +1 -0
- package/dist/composables/tables/data-table/sort.d.ts +32 -0
- package/dist/composables/tables/data-table/sort.js +136 -0
- package/dist/composables/tables/data-table/sort.js.map +1 -0
- package/dist/composables/tables/data-table/types.d.ts +14 -0
- package/dist/composables/tables/data-table/types.js +11 -0
- package/dist/composables/tables/data-table/types.js.map +1 -0
- package/dist/composables/theme.js +1 -20
- package/dist/composables/theme.js.map +1 -1
- package/dist/composables/timeout-manager.d.ts +4 -2
- package/dist/composables/timeout-manager.js +2 -1
- package/dist/composables/timeout-manager.js.map +1 -1
- package/dist/icons/icons_1.js +28 -28
- package/dist/icons/icons_1.js.map +1 -1
- package/dist/icons/icons_2.d.ts +8 -8
- package/dist/icons/icons_2.js +52 -52
- package/dist/icons/icons_2.js.map +1 -1
- package/dist/icons/icons_3.d.ts +18 -18
- package/dist/icons/icons_3.js +108 -108
- package/dist/icons/icons_3.js.map +1 -1
- package/dist/icons/icons_4.d.ts +35 -0
- package/dist/icons/icons_4.js +176 -1
- package/dist/icons/icons_4.js.map +1 -1
- package/dist/icons/index.d.ts +1 -1
- package/dist/icons/index.js +1 -1
- package/dist/icons/index.js.map +1 -1
- package/dist/index.js +43 -15
- package/dist/index.js.map +1 -1
- package/dist/style.css +189 -162
- package/dist/theme/index.js +15 -1
- package/dist/theme/index.js.map +1 -1
- package/dist/utils/assert.d.ts +1 -1
- package/dist/utils/assert.js.map +1 -1
- package/dist/utils/form-text-detail.d.ts +9 -8
- package/dist/utils/form-text-detail.js +1 -2
- package/dist/utils/form-text-detail.js.map +1 -1
- package/dist/utils/helpers.d.ts +4 -32
- package/dist/utils/helpers.js +8 -9
- package/dist/utils/helpers.js.map +1 -1
- package/dist/utils/is-equal.d.ts +1 -1
- package/dist/utils/is-equal.js +5 -3
- package/dist/utils/is-equal.js.map +1 -1
- package/dist/web-types.json +359 -359
- package/package.json +44 -35
- package/dist/utils/generate-id.d.ts +0 -5
- package/dist/utils/generate-id.js +0 -21
- package/dist/utils/generate-id.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"popper.js","sources":["../../src/composables/popper.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"popper.js","sources":["../../src/composables/popper.ts"],"sourcesContent":["import {\n createPopper,\n type Instance,\n type Placement,\n type PositioningStrategy,\n type StrictModifiers,\n type VirtualElement,\n} from '@popperjs/core';\nimport { type MaybeElement, unrefElement } from '@vueuse/core';\nimport { onMounted, type Ref, ref, watchEffect } from 'vue';\nimport { useTimeoutManager } from './timeout-manager';\n\nexport interface PopperOptions {\n locked?: boolean;\n overflowPadding?: number;\n offsetDistance?: number;\n offsetSkid?: number;\n placement?: Placement;\n strategy?: PositioningStrategy;\n gpuAcceleration?: boolean;\n adaptive?: boolean;\n scroll?: boolean;\n resize?: boolean;\n}\n\nexport const DEFAULT_POPPER_OPTIONS: PopperOptions = {\n adaptive: true,\n gpuAcceleration: true,\n locked: false,\n offsetDistance: 8,\n offsetSkid: 0,\n overflowPadding: 8,\n placement: 'bottom',\n resize: true,\n scroll: true,\n strategy: 'absolute',\n};\n\ninterface UsePopperReturn {\n instance: Ref<Instance | undefined>;\n leavePending: Ref<boolean>;\n onClose: (immediate?: boolean) => void;\n onLeavePending: () => void;\n onOpen: (immediate?: boolean) => void;\n onPopperLeave: () => void;\n open: Ref<boolean, boolean>;\n popper: Ref<MaybeElement>;\n popperEnter: Ref<boolean>;\n reference: Ref<HTMLElement | undefined>;\n updatePopper: () => Promise<void>;\n}\n\nexport function usePopper(\n options: Ref<PopperOptions>,\n disabled: Ref<boolean> = shallowRef(false),\n openDelay: Ref<number> = shallowRef(0),\n closeDelay: Ref<number> = shallowRef(0),\n virtualReference?: Ref<Element | VirtualElement>,\n): UsePopperReturn {\n const reference = ref<HTMLElement>();\n const popper = ref<MaybeElement>();\n const instance = ref<Instance>();\n const open = shallowRef<boolean>(false);\n const popperEnter = shallowRef<boolean>(false);\n const leavePending = shallowRef<boolean>(false);\n\n const openTimeoutManager = useTimeoutManager();\n const closeTimeoutManager = useTimeoutManager();\n\n const onPopperLeave = (): void => {\n set(popperEnter, false);\n };\n\n const updatePopper = async (): Promise<void> => {\n await get(instance)?.update();\n };\n\n const onOpen = (immediate: boolean = false): void => {\n if (get(disabled))\n return;\n\n closeTimeoutManager.clear();\n\n set(leavePending, false);\n if (!openTimeoutManager.isActive()) {\n set(popperEnter, true);\n\n openTimeoutManager.create(\n () => {\n set(open, true);\n },\n immediate ? 0 : get(openDelay),\n );\n }\n };\n\n const onClose = (immediate: boolean = false): void => {\n if (get(disabled))\n return;\n\n openTimeoutManager.clear();\n\n if (!closeTimeoutManager.isActive()) {\n closeTimeoutManager.create(\n () => {\n if (!get(open))\n onPopperLeave();\n\n set(open, false);\n },\n immediate ? 0 : get(closeDelay),\n );\n }\n };\n\n const onLeavePending = (): void => {\n set(leavePending, true);\n };\n\n const modifiers = computed<StrictModifiers[]>(() => {\n const {\n adaptive = DEFAULT_POPPER_OPTIONS.adaptive,\n gpuAcceleration = DEFAULT_POPPER_OPTIONS.gpuAcceleration,\n locked = DEFAULT_POPPER_OPTIONS.locked,\n offsetDistance = DEFAULT_POPPER_OPTIONS.offsetDistance,\n offsetSkid = DEFAULT_POPPER_OPTIONS.offsetSkid,\n overflowPadding = DEFAULT_POPPER_OPTIONS.overflowPadding,\n resize = DEFAULT_POPPER_OPTIONS.resize,\n scroll = DEFAULT_POPPER_OPTIONS.scroll,\n } = get(options);\n\n return [\n {\n enabled: false,\n name: 'hide',\n },\n {\n enabled: !locked,\n name: 'flip',\n },\n {\n name: 'preventOverflow',\n options: {\n padding: overflowPadding,\n },\n },\n {\n name: 'offset',\n options: {\n offset: [offsetSkid, offsetDistance],\n },\n },\n {\n name: 'computeStyles',\n options: {\n adaptive,\n gpuAcceleration,\n },\n },\n {\n name: 'eventListeners',\n options: {\n resize,\n scroll,\n },\n },\n {\n name: 'arrow',\n options: {\n padding: 4,\n },\n },\n ];\n });\n\n const popperConfig = computed<{\n modifiers: StrictModifiers[];\n placement: Placement | undefined;\n strategy: PositioningStrategy | undefined;\n }>(() => {\n const {\n placement = DEFAULT_POPPER_OPTIONS.placement,\n strategy = DEFAULT_POPPER_OPTIONS.strategy,\n } = get(options);\n\n return {\n modifiers: get(modifiers),\n placement,\n strategy,\n };\n });\n\n function getValidElements(): {\n popperEl: HTMLElement;\n referenceEl: Element | VirtualElement;\n } | null {\n if (!get(popper) || (!get(reference) && !get(virtualReference))) {\n return null;\n }\n\n const popperEl = unrefElement(popper);\n const referenceEl = get(virtualReference) || unrefElement(reference);\n\n if (!(popperEl instanceof HTMLElement) || !referenceEl) {\n return null;\n }\n\n return { popperEl, referenceEl };\n }\n\n function initializePopper(onInvalidate: (cleanupFn: () => void) => void): void {\n const elements = getValidElements();\n if (!elements)\n return;\n\n const { popperEl, referenceEl } = elements;\n\n const value = createPopper(referenceEl, popperEl, get(popperConfig));\n\n set(instance, value);\n onInvalidate(value.destroy);\n }\n\n useResizeObserver([reference, popper], async () => {\n if (isDefined(instance))\n await get(instance).update();\n });\n\n onMounted(() => {\n watchEffect((onInvalidate) => {\n initializePopper(onInvalidate);\n });\n });\n\n return {\n instance,\n leavePending,\n onClose,\n onLeavePending,\n onOpen,\n onPopperLeave,\n open,\n popper,\n popperEnter,\n reference,\n updatePopper,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import type { MaybeRef } from 'vue';
|
|
1
|
+
import type { MaybeRef, ShallowRef } from 'vue';
|
|
2
|
+
export interface UseStickyTableHeaderRefs {
|
|
3
|
+
table: Readonly<ShallowRef<HTMLTableElement | null>>;
|
|
4
|
+
tableScroller: Readonly<ShallowRef<HTMLElement | null>>;
|
|
5
|
+
}
|
|
2
6
|
/**
|
|
3
7
|
* Setup sticky table header
|
|
4
8
|
*/
|
|
5
|
-
export declare function useStickyTableHeader(sticky
|
|
6
|
-
stick:
|
|
7
|
-
table: globalThis.Ref<HTMLTableElement | null, HTMLTableElement | null>;
|
|
8
|
-
tableScroller: globalThis.Ref<HTMLElement | null, HTMLElement | null>;
|
|
9
|
+
export declare function useStickyTableHeader(sticky: MaybeRef<boolean> | undefined, offsetTop: MaybeRef<number | undefined>, refs: UseStickyTableHeaderRefs): {
|
|
10
|
+
stick: ShallowRef<boolean>;
|
|
9
11
|
};
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { assert } from "../utils/assert.js";
|
|
2
|
-
import {
|
|
2
|
+
import { shallowRef, onMounted } from "vue";
|
|
3
3
|
import { get, set } from "@vueuse/shared";
|
|
4
4
|
import { useEventListener, useMutationObserver, useResizeObserver } from "@vueuse/core";
|
|
5
|
-
function useStickyTableHeader(sticky =
|
|
6
|
-
const table =
|
|
7
|
-
const
|
|
8
|
-
const stick = ref(false);
|
|
5
|
+
function useStickyTableHeader(sticky = shallowRef(false), offsetTop, refs) {
|
|
6
|
+
const { table, tableScroller } = refs;
|
|
7
|
+
const stick = shallowRef(false);
|
|
9
8
|
const borderPrecision = -0.5;
|
|
10
9
|
const selectors = {
|
|
11
10
|
head: ":scope > thead[data-id=head-main]",
|
|
@@ -17,17 +16,18 @@ function useStickyTableHeader(sticky = ref(false), offsetTop) {
|
|
|
17
16
|
const root = get(table);
|
|
18
17
|
if (!get(sticky) || !root)
|
|
19
18
|
return;
|
|
20
|
-
const theadClone = root.querySelector(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const head = root.querySelector(`${selectors.head} > tr`) ?? null;
|
|
19
|
+
const theadClone = root.querySelector(`${selectors.headClone} > tr`);
|
|
20
|
+
const head = root.querySelector(`${selectors.head} > tr`);
|
|
21
|
+
let resizeCleanups = [];
|
|
24
22
|
const observeChildTh = () => {
|
|
25
|
-
|
|
23
|
+
resizeCleanups.forEach((cleanup) => cleanup());
|
|
24
|
+
resizeCleanups = [];
|
|
25
|
+
const columns = head?.querySelectorAll(selectors.th);
|
|
26
|
+
const clonedColumns = theadClone?.querySelectorAll(
|
|
26
27
|
selectors.th
|
|
27
28
|
);
|
|
28
|
-
const clonedColumns = theadClone?.querySelectorAll(selectors.th);
|
|
29
29
|
clonedColumns?.forEach((th, i) => {
|
|
30
|
-
useResizeObserver(th, (entries) => {
|
|
30
|
+
const { stop } = useResizeObserver(th, (entries) => {
|
|
31
31
|
const entry = entries[0];
|
|
32
32
|
assert(entry);
|
|
33
33
|
const cellRect = entry.target.getBoundingClientRect();
|
|
@@ -35,18 +35,23 @@ function useStickyTableHeader(sticky = ref(false), offsetTop) {
|
|
|
35
35
|
if (column)
|
|
36
36
|
column.style.width = `${cellRect.width}px`;
|
|
37
37
|
});
|
|
38
|
+
resizeCleanups.push(stop);
|
|
38
39
|
});
|
|
39
40
|
};
|
|
40
|
-
useMutationObserver(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
useMutationObserver(
|
|
42
|
+
theadClone,
|
|
43
|
+
(mutationsList) => {
|
|
44
|
+
for (const mutation of mutationsList) {
|
|
45
|
+
if (mutation.type === "childList" || mutation.type === "attributes")
|
|
46
|
+
observeChildTh();
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
attributes: true,
|
|
51
|
+
childList: true,
|
|
52
|
+
subtree: true
|
|
44
53
|
}
|
|
45
|
-
|
|
46
|
-
attributes: true,
|
|
47
|
-
childList: true,
|
|
48
|
-
subtree: true
|
|
49
|
-
});
|
|
54
|
+
);
|
|
50
55
|
observeChildTh();
|
|
51
56
|
};
|
|
52
57
|
const toggleStickyClass = () => {
|
|
@@ -54,49 +59,54 @@ function useStickyTableHeader(sticky = ref(false), offsetTop) {
|
|
|
54
59
|
if (!get(sticky) || !root)
|
|
55
60
|
return;
|
|
56
61
|
const rect = root.getBoundingClientRect();
|
|
57
|
-
const theadClone = root.querySelector(
|
|
58
|
-
selectors.headClone
|
|
59
|
-
);
|
|
62
|
+
const theadClone = root.querySelector(selectors.headClone);
|
|
60
63
|
const clonedRect = theadClone?.getBoundingClientRect();
|
|
61
|
-
const head = root.querySelector(selectors.head)
|
|
62
|
-
|
|
63
|
-
if (!rect || !clonedRect || !head || !theadClone || !headRect)
|
|
64
|
+
const head = root.querySelector(selectors.head);
|
|
65
|
+
if (!clonedRect || !head || !theadClone)
|
|
64
66
|
return;
|
|
65
|
-
const {
|
|
66
|
-
height: theadHeight,
|
|
67
|
-
left: theadLeft,
|
|
68
|
-
width: theadWidth
|
|
69
|
-
} = clonedRect;
|
|
67
|
+
const { height: theadHeight, left: theadLeft, width: theadWidth } = clonedRect;
|
|
70
68
|
const { bottom: tableBottom, top: tableTop } = rect;
|
|
71
69
|
const top = get(offsetTop) ?? 0;
|
|
72
70
|
head.style.width = `${theadWidth}px`;
|
|
73
71
|
const rows = root.querySelectorAll(selectors.row);
|
|
72
|
+
if (rows.length <= 1) {
|
|
73
|
+
set(stick, false);
|
|
74
|
+
head.style.left = `${borderPrecision}px`;
|
|
75
|
+
head.style.top = "0";
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
74
78
|
const lastRowRect = rows.item(rows.length - 1)?.getBoundingClientRect();
|
|
75
|
-
if (tableTop <= top && tableBottom > top
|
|
79
|
+
if (tableTop <= top && tableBottom > top) {
|
|
76
80
|
set(stick, true);
|
|
77
81
|
head.style.left = `${theadLeft + borderPrecision}px`;
|
|
78
82
|
const lastRowHeight = lastRowRect?.height ?? 0;
|
|
79
83
|
if (tableBottom <= lastRowHeight + theadHeight + top)
|
|
80
84
|
head.style.top = `${tableBottom - lastRowHeight - theadHeight}px`;
|
|
81
|
-
else
|
|
82
|
-
head.style.top = `${top}px`;
|
|
85
|
+
else head.style.top = `${top}px`;
|
|
83
86
|
} else {
|
|
84
87
|
set(stick, false);
|
|
85
88
|
head.style.left = `${borderPrecision}px`;
|
|
86
89
|
head.style.top = "0";
|
|
87
90
|
}
|
|
88
91
|
};
|
|
92
|
+
let rafId = null;
|
|
93
|
+
function throttledToggleStickyClass() {
|
|
94
|
+
if (rafId !== null)
|
|
95
|
+
return;
|
|
96
|
+
rafId = requestAnimationFrame(() => {
|
|
97
|
+
toggleStickyClass();
|
|
98
|
+
rafId = null;
|
|
99
|
+
});
|
|
100
|
+
}
|
|
89
101
|
onMounted(() => {
|
|
90
102
|
toggleStickyClass();
|
|
91
|
-
useEventListener(tableScroller, "scroll",
|
|
92
|
-
useEventListener(document.body, "scroll",
|
|
93
|
-
useEventListener(window, "resize",
|
|
103
|
+
useEventListener(tableScroller, "scroll", throttledToggleStickyClass);
|
|
104
|
+
useEventListener(document.body, "scroll", throttledToggleStickyClass);
|
|
105
|
+
useEventListener(window, "resize", throttledToggleStickyClass);
|
|
94
106
|
watchCellWidth();
|
|
95
107
|
});
|
|
96
108
|
return {
|
|
97
|
-
stick
|
|
98
|
-
table,
|
|
99
|
-
tableScroller
|
|
109
|
+
stick
|
|
100
110
|
};
|
|
101
111
|
}
|
|
102
112
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sticky-header.js","sources":["../../src/composables/sticky-header.ts"],"sourcesContent":["import type { MaybeRef } from 'vue';\nimport { assert } from '@/utils/assert';\n\n/**\n * Setup sticky table header\n */\nexport function useStickyTableHeader(sticky: MaybeRef<boolean> =
|
|
1
|
+
{"version":3,"file":"sticky-header.js","sources":["../../src/composables/sticky-header.ts"],"sourcesContent":["import type { MaybeRef, ShallowRef } from 'vue';\nimport { assert } from '@/utils/assert';\n\nexport interface UseStickyTableHeaderRefs {\n table: Readonly<ShallowRef<HTMLTableElement | null>>;\n tableScroller: Readonly<ShallowRef<HTMLElement | null>>;\n}\n\n/**\n * Setup sticky table header\n */\nexport function useStickyTableHeader(\n sticky: MaybeRef<boolean> = shallowRef(false),\n offsetTop: MaybeRef<number | undefined>,\n refs: UseStickyTableHeaderRefs,\n) {\n const { table, tableScroller } = refs;\n const stick = shallowRef<boolean>(false);\n const borderPrecision = -0.5;\n const 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 };\n\n const watchCellWidth = (): void => {\n const root = get(table);\n\n if (!get(sticky) || !root)\n return;\n\n const theadClone: HTMLHeadElement | null = root.querySelector(`${selectors.headClone} > tr`);\n\n const head: HTMLHeadElement | null = root.querySelector(`${selectors.head} > tr`);\n\n let resizeCleanups: (() => void)[] = [];\n\n const observeChildTh = (): void => {\n resizeCleanups.forEach(cleanup => cleanup());\n resizeCleanups = [];\n\n const columns: NodeListOf<HTMLElement> | undefined = head?.querySelectorAll(selectors.th);\n\n const clonedColumns: NodeListOf<HTMLElement> | undefined = theadClone?.querySelectorAll(\n selectors.th,\n );\n\n clonedColumns?.forEach((th: HTMLElement, i: number) => {\n const { stop } = useResizeObserver(th, (entries) => {\n const entry = entries[0];\n assert(entry);\n const cellRect = entry.target.getBoundingClientRect();\n const column = columns?.item(i);\n if (column)\n column.style.width = `${cellRect.width}px`;\n });\n resizeCleanups.push(stop);\n });\n };\n\n useMutationObserver(\n theadClone,\n (mutationsList) => {\n for (const mutation of mutationsList) {\n if (mutation.type === 'childList' || mutation.type === 'attributes')\n observeChildTh();\n }\n },\n {\n attributes: true,\n childList: true,\n subtree: true,\n },\n );\n\n observeChildTh();\n };\n\n const toggleStickyClass = (): void => {\n const root = get(table);\n\n if (!get(sticky) || !root)\n return;\n\n const rect = root.getBoundingClientRect();\n const theadClone: HTMLHeadElement | null = root.querySelector(selectors.headClone);\n\n const clonedRect: DOMRect | undefined = theadClone?.getBoundingClientRect();\n\n const head: HTMLHeadElement | null = root.querySelector(selectors.head);\n\n if (!clonedRect || !head || !theadClone)\n return;\n\n const { height: theadHeight, left: theadLeft, width: theadWidth } = clonedRect;\n\n const { bottom: tableBottom, top: tableTop } = rect;\n const top = get(offsetTop) ?? 0;\n\n head.style.width = `${theadWidth}px`;\n\n const rows = root.querySelectorAll(selectors.row);\n if (rows.length <= 1) {\n set(stick, false);\n head.style.left = `${borderPrecision}px`;\n head.style.top = '0';\n return;\n }\n\n const lastRowRect: DOMRect | undefined = rows.item(rows.length - 1)?.getBoundingClientRect();\n\n if (tableTop <= top && tableBottom > top) {\n set(stick, true);\n head.style.left = `${theadLeft + borderPrecision}px`;\n\n const lastRowHeight = lastRowRect?.height ?? 0;\n if (tableBottom <= lastRowHeight + theadHeight + top)\n head.style.top = `${tableBottom - lastRowHeight - theadHeight}px`;\n else head.style.top = `${top}px`;\n }\n else {\n set(stick, false);\n head.style.left = `${borderPrecision}px`;\n head.style.top = '0';\n }\n };\n\n let rafId: number | null = null;\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,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue';
|
|
2
|
+
import type { TableColumn, TableRowKey } from '../../../components/tables/RuiTableHead.vue.js';
|
|
3
|
+
export interface UseTableColumnsOptions<T extends object, IdType extends keyof T> {
|
|
4
|
+
/** Column definitions for the table. When omitted, columns are inferred from row data. */
|
|
5
|
+
cols: MaybeRefOrGetter<TableColumn<T>[] | undefined>;
|
|
6
|
+
/** The property on each column definition used as the column identifier. */
|
|
7
|
+
columnAttr: keyof TableColumn<T>;
|
|
8
|
+
/** The data rows to display in the table. */
|
|
9
|
+
rows: MaybeRefOrGetter<readonly T[]>;
|
|
10
|
+
/** Whether row expansion is enabled. */
|
|
11
|
+
expandable: ComputedRef<boolean>;
|
|
12
|
+
/** The keys currently used for grouping rows. */
|
|
13
|
+
groupKeys: ComputedRef<TableRowKey<T>[]>;
|
|
14
|
+
/** The currently selected row identifiers. */
|
|
15
|
+
selectedData: Ref<T[IdType][] | undefined>;
|
|
16
|
+
/** Template slots provided to the table component. */
|
|
17
|
+
slots: Record<string, any>;
|
|
18
|
+
}
|
|
19
|
+
export interface UseTableColumnsReturn<T extends object> {
|
|
20
|
+
columns: ComputedRef<TableColumn<T>[]>;
|
|
21
|
+
colspan: ComputedRef<number>;
|
|
22
|
+
headerSlots: ComputedRef<`header.${string}`[]>;
|
|
23
|
+
cellValue: (row: T, key: TableColumn<T>['key']) => T[TableRowKey<T>];
|
|
24
|
+
}
|
|
25
|
+
export declare function useTableColumns<T extends object, IdType extends keyof T>(options: UseTableColumnsOptions<T, IdType>): UseTableColumnsReturn<T>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { isHeaderSlot } from "./types.js";
|
|
2
|
+
import { computed, toValue } from "vue";
|
|
3
|
+
import { get } from "@vueuse/shared";
|
|
4
|
+
function useTableColumns(options) {
|
|
5
|
+
const { cols, columnAttr, expandable, groupKeys, rows, selectedData, slots } = options;
|
|
6
|
+
const getKeys = (t) => Object.keys(t);
|
|
7
|
+
const columns = computed(() => {
|
|
8
|
+
const currentCols = toValue(cols);
|
|
9
|
+
const currentRows = toValue(rows);
|
|
10
|
+
const data = currentCols ?? getKeys(currentRows[0] ?? {}).map(
|
|
11
|
+
(key) => ({
|
|
12
|
+
key,
|
|
13
|
+
[columnAttr]: String(key)
|
|
14
|
+
})
|
|
15
|
+
);
|
|
16
|
+
const hasExpandColumn = data.some((row) => row.key === "expand");
|
|
17
|
+
if (get(expandable) && !hasExpandColumn) {
|
|
18
|
+
return [
|
|
19
|
+
...data,
|
|
20
|
+
{
|
|
21
|
+
key: "expand",
|
|
22
|
+
sortable: false,
|
|
23
|
+
class: "w-16",
|
|
24
|
+
cellClass: "!py-0 w-16",
|
|
25
|
+
align: "end"
|
|
26
|
+
}
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
const groupByKeys = get(groupKeys);
|
|
30
|
+
if (groupByKeys.length === 0)
|
|
31
|
+
return data;
|
|
32
|
+
return data.filter((column) => !groupByKeys.includes(column.key));
|
|
33
|
+
});
|
|
34
|
+
const colspan = computed(() => {
|
|
35
|
+
let columnLength = get(columns).length;
|
|
36
|
+
if (get(selectedData))
|
|
37
|
+
columnLength++;
|
|
38
|
+
return columnLength;
|
|
39
|
+
});
|
|
40
|
+
const headerSlots = computed(() => Object.keys(slots).filter(isHeaderSlot));
|
|
41
|
+
function cellValue(row, key) {
|
|
42
|
+
return row[key];
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
columns,
|
|
46
|
+
colspan,
|
|
47
|
+
headerSlots,
|
|
48
|
+
cellValue
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
useTableColumns
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=columns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"columns.js","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: ComputedRef<`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, rows, selectedData, slots } = options;\n\n const getKeys = <O extends object>(t: O): TableRowKey<O>[] => Object.keys(t) as TableRowKey<O>[];\n\n const columns = computed<TableColumn<T>[]>(() => {\n const currentCols = toValue(cols);\n const currentRows = toValue(rows);\n const data =\n currentCols ??\n getKeys(currentRows[0] ?? {}).map(\n key =>\n ({\n key,\n [columnAttr]: String(key),\n }) satisfies NoneSortableTableColumn<T>,\n );\n\n const hasExpandColumn = data.some(row => row.key === 'expand');\n\n if (get(expandable) && !hasExpandColumn) {\n return [\n ...data,\n {\n key: 'expand' as TableRowKey<T>,\n sortable: false,\n class: 'w-16',\n cellClass: '!py-0 w-16',\n align: 'end',\n } satisfies NoneSortableTableColumn<T>,\n ];\n }\n\n const groupByKeys = get(groupKeys);\n\n if (groupByKeys.length === 0)\n return data;\n\n return 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 const headerSlots = computed<`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"],"names":[],"mappings":";;;AAgCO,SAAS,gBACd,SAC0B;AAC1B,QAAM,EAAE,MAAM,YAAY,YAAY,WAAW,MAAM,cAAc,UAAU;AAE/E,QAAM,UAAU,CAAmB,MAA2B,OAAO,KAAK,CAAC;AAE3E,QAAM,UAAU,SAA2B,MAAM;AAC/C,UAAM,cAAc,QAAQ,IAAI;AAChC,UAAM,cAAc,QAAQ,IAAI;AAChC,UAAM,OACJ,eACA,QAAQ,YAAY,CAAC,KAAK,CAAA,CAAE,EAAE;AAAA,MAC5B,CAAA,SACG;AAAA,QACC;AAAA,QACA,CAAC,UAAU,GAAG,OAAO,GAAG;AAAA,MAAA;AAAA,IAC1B;AAGN,UAAM,kBAAkB,KAAK,KAAK,CAAA,QAAO,IAAI,QAAQ,QAAQ;AAE7D,QAAI,IAAI,UAAU,KAAK,CAAC,iBAAiB;AACvC,aAAO;AAAA,QACL,GAAG;AAAA,QACH;AAAA,UACE,KAAK;AAAA,UACL,UAAU;AAAA,UACV,OAAO;AAAA,UACP,WAAW;AAAA,UACX,OAAO;AAAA,QAAA;AAAA,MACT;AAAA,IAEJ;AAEA,UAAM,cAAc,IAAI,SAAS;AAEjC,QAAI,YAAY,WAAW;AACzB,aAAO;AAET,WAAO,KAAK,OAAO,CAAA,WAAU,CAAC,YAAY,SAAS,OAAO,GAAqB,CAAC;AAAA,EAClF,CAAC;AAED,QAAM,UAAU,SAAiB,MAAM;AACrC,QAAI,eAAe,IAAI,OAAO,EAAE;AAChC,QAAI,IAAI,YAAY;AAClB;AAEF,WAAO;AAAA,EACT,CAAC;AAED,QAAM,cAAc,SAA+B,MAAM,OAAO,KAAK,KAAK,EAAE,OAAO,YAAY,CAAC;AAEhG,WAAS,UAAU,KAAQ,KAA+C;AACxE,WAAO,IAAI,GAAqB;AAAA,EAClC;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ComputedRef, Ref } from 'vue';
|
|
2
|
+
export interface UseTableExpansionOptions<T extends object, IdType extends keyof T> {
|
|
3
|
+
/** The property on each row used as the unique row identifier. */
|
|
4
|
+
rowAttr: IdType;
|
|
5
|
+
/** Whether only one row can be expanded at a time. */
|
|
6
|
+
singleExpand: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface UseTableExpansionDeps<T extends object> {
|
|
9
|
+
expanded: Ref<T[] | undefined>;
|
|
10
|
+
hasExpandedItemSlot: Ref<boolean>;
|
|
11
|
+
}
|
|
12
|
+
export interface UseTableExpansionReturn<T extends object, IdType extends keyof T> {
|
|
13
|
+
expandable: ComputedRef<boolean>;
|
|
14
|
+
isExpanded: (identifier: T[IdType]) => boolean;
|
|
15
|
+
onToggleExpand: (row: T) => void;
|
|
16
|
+
}
|
|
17
|
+
export declare function useTableExpansion<T extends object, IdType extends keyof T>(options: UseTableExpansionOptions<T, IdType>, deps: UseTableExpansionDeps<T>): UseTableExpansionReturn<T, IdType>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { computed } from "vue";
|
|
2
|
+
import { get, set } from "@vueuse/shared";
|
|
3
|
+
function useTableExpansion(options, deps) {
|
|
4
|
+
const { rowAttr, singleExpand } = options;
|
|
5
|
+
const { expanded, hasExpandedItemSlot } = deps;
|
|
6
|
+
const expandable = computed(() => !!get(expanded) && get(hasExpandedItemSlot));
|
|
7
|
+
const expandedSet = computed(() => {
|
|
8
|
+
const expandedVal = get(expanded);
|
|
9
|
+
if (!expandedVal?.length)
|
|
10
|
+
return /* @__PURE__ */ new Set();
|
|
11
|
+
return new Set(expandedVal.map((row) => row[rowAttr]));
|
|
12
|
+
});
|
|
13
|
+
function isExpanded(identifier) {
|
|
14
|
+
return get(expandedSet).has(identifier);
|
|
15
|
+
}
|
|
16
|
+
function onToggleExpand(row) {
|
|
17
|
+
const expandedVal = get(expanded);
|
|
18
|
+
if (!expandedVal)
|
|
19
|
+
return;
|
|
20
|
+
const key = rowAttr;
|
|
21
|
+
const rowExpanded = isExpanded(row[key]);
|
|
22
|
+
if (singleExpand)
|
|
23
|
+
return set(expanded, rowExpanded ? [] : [row]);
|
|
24
|
+
return set(
|
|
25
|
+
expanded,
|
|
26
|
+
rowExpanded ? expandedVal.filter((item) => item[key] !== row[key]) : [...expandedVal, row]
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
expandable,
|
|
31
|
+
isExpanded,
|
|
32
|
+
onToggleExpand
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
useTableExpansion
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=expansion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expansion.js","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 hasExpandedItemSlot: Ref<boolean>;\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, hasExpandedItemSlot } = deps;\n\n const expandable = computed<boolean>(() => !!get(expanded) && get(hasExpandedItemSlot));\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"],"names":[],"mappings":";;AAoBO,SAAS,kBACd,SACA,MACoC;AACpC,QAAM,EAAE,SAAS,aAAA,IAAiB;AAClC,QAAM,EAAE,UAAU,oBAAA,IAAwB;AAE1C,QAAM,aAAa,SAAkB,MAAM,CAAC,CAAC,IAAI,QAAQ,KAAK,IAAI,mBAAmB,CAAC;AAEtF,QAAM,cAAc,SAAyB,MAAM;AACjD,UAAM,cAAc,IAAI,QAAQ;AAChC,QAAI,CAAC,aAAa;AAChB,iCAAW,IAAA;AACb,WAAO,IAAI,IAAe,YAAY,IAAI,SAAO,IAAI,OAAO,CAAC,CAAC;AAAA,EAChE,CAAC;AAED,WAAS,WAAW,YAAgC;AAClD,WAAO,IAAI,WAAW,EAAE,IAAI,UAAU;AAAA,EACxC;AAEA,WAAS,eAAe,KAAc;AACpC,UAAM,cAAc,IAAI,QAAQ;AAChC,QAAI,CAAC;AACH;AAEF,UAAM,MAAM;AACZ,UAAM,cAAc,WAAW,IAAI,GAAG,CAAC;AAEvC,QAAI;AACF,aAAO,IAAI,UAAU,cAAc,CAAA,IAAK,CAAC,GAAG,CAAC;AAE/C,WAAO;AAAA,MACL;AAAA,MACA,cAAc,YAAY,OAAO,CAAA,SAAQ,KAAK,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,aAAa,GAAG;AAAA,IAAA;AAAA,EAE3F;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ComputedRef, Ref } from 'vue';
|
|
2
|
+
import type { GroupData, TableRowKey, TableRowKeyData } from '../../../components/tables/RuiTableHead.vue.js';
|
|
3
|
+
import { type GroupedTableRow } from '../../../composables/tables/data-table/types.js';
|
|
4
|
+
export interface UseTableGroupingOptions<T extends object, IdType extends keyof T> {
|
|
5
|
+
/** The property on each row used as the unique row identifier. */
|
|
6
|
+
rowAttr: IdType;
|
|
7
|
+
}
|
|
8
|
+
export interface UseTableGroupingDeps<T extends object> {
|
|
9
|
+
group: Ref<TableRowKeyData<T>>;
|
|
10
|
+
collapsed: Ref<T[] | undefined>;
|
|
11
|
+
sorted: ComputedRef<T[]>;
|
|
12
|
+
emitCopyGroup: (value: GroupData<T>) => void;
|
|
13
|
+
}
|
|
14
|
+
export interface UseTableGroupingReturn<T extends object> {
|
|
15
|
+
groupKeys: ComputedRef<TableRowKey<T>[]>;
|
|
16
|
+
groupKey: ComputedRef<string>;
|
|
17
|
+
isGrouped: ComputedRef<boolean>;
|
|
18
|
+
mappedGroups: ComputedRef<Record<string, GroupedTableRow<T>[]>>;
|
|
19
|
+
grouped: ComputedRef<GroupedTableRow<T>[]>;
|
|
20
|
+
getRowGroup: (row: T) => Partial<T>;
|
|
21
|
+
getGroupRows: (groupVal: string) => T[];
|
|
22
|
+
compareGroupsFn: (a: T, b: Partial<T>) => boolean;
|
|
23
|
+
isExpandedGroup: (value: Partial<T>) => boolean;
|
|
24
|
+
isHiddenRow: (row: GroupedTableRow<T>) => boolean;
|
|
25
|
+
onToggleExpandGroup: (group: Partial<T>, value?: string) => void;
|
|
26
|
+
onUngroup: () => void;
|
|
27
|
+
onCopyGroup: (value: GroupData<T>) => void;
|
|
28
|
+
}
|
|
29
|
+
export declare function useTableGrouping<T extends object, IdType extends keyof T>(options: UseTableGroupingOptions<T, IdType>, deps: UseTableGroupingDeps<T>): UseTableGroupingReturn<T>;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { isRow } from "./types.js";
|
|
2
|
+
import { assert } from "../../../utils/assert.js";
|
|
3
|
+
import { ref, watch, computed } from "vue";
|
|
4
|
+
import { set, get } from "@vueuse/shared";
|
|
5
|
+
import { isDefined } from "@vueuse/core";
|
|
6
|
+
const GROUP_KEY_SEPARATOR = "\0";
|
|
7
|
+
function useTableGrouping(options, deps) {
|
|
8
|
+
const { rowAttr } = options;
|
|
9
|
+
const { group, collapsed, sorted, emitCopyGroup } = deps;
|
|
10
|
+
const collapsedRows = ref([]);
|
|
11
|
+
watch(collapsed, (value) => set(collapsedRows, value ?? []), { immediate: true });
|
|
12
|
+
const groupKeys = computed(() => {
|
|
13
|
+
const groupBy = get(group);
|
|
14
|
+
if (!groupBy)
|
|
15
|
+
return [];
|
|
16
|
+
if (!Array.isArray(groupBy))
|
|
17
|
+
return [groupBy];
|
|
18
|
+
return groupBy;
|
|
19
|
+
});
|
|
20
|
+
const groupKey = computed(() => get(groupKeys).join(":"));
|
|
21
|
+
const isGrouped = computed(() => !!get(groupKey));
|
|
22
|
+
const collapsedIdentifierSet = computed(
|
|
23
|
+
() => new Set(get(collapsedRows).map((row) => row[rowAttr]))
|
|
24
|
+
);
|
|
25
|
+
const collapsedGroupKeySet = computed(() => {
|
|
26
|
+
const grouping = get(groupKeys);
|
|
27
|
+
if (grouping.length === 0)
|
|
28
|
+
return /* @__PURE__ */ new Set();
|
|
29
|
+
const seen = /* @__PURE__ */ new Set();
|
|
30
|
+
for (const row of get(collapsedRows)) {
|
|
31
|
+
const groupVal = grouping.map((key) => row[key]).filter(isDefined).join(GROUP_KEY_SEPARATOR);
|
|
32
|
+
seen.add(groupVal);
|
|
33
|
+
}
|
|
34
|
+
return seen;
|
|
35
|
+
});
|
|
36
|
+
function getRowGroup(row) {
|
|
37
|
+
const result = {};
|
|
38
|
+
for (const key of get(groupKeys)) {
|
|
39
|
+
result[key] = row[key];
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
function compareGroupsFn(a, b) {
|
|
44
|
+
const grouping = get(groupKeys);
|
|
45
|
+
if (grouping.length === 0)
|
|
46
|
+
return false;
|
|
47
|
+
return grouping.every((key) => a[key] === b[key]);
|
|
48
|
+
}
|
|
49
|
+
function isExpandedGroup(value) {
|
|
50
|
+
const groupVal = Object.values(value).filter(isDefined).join(GROUP_KEY_SEPARATOR);
|
|
51
|
+
return !get(collapsedGroupKeySet).has(groupVal);
|
|
52
|
+
}
|
|
53
|
+
function isHiddenRow(row) {
|
|
54
|
+
if (!get(isGrouped))
|
|
55
|
+
return false;
|
|
56
|
+
if (!isRow(row))
|
|
57
|
+
return false;
|
|
58
|
+
return get(collapsedIdentifierSet).has(row[rowAttr]);
|
|
59
|
+
}
|
|
60
|
+
const mappedGroups = computed(() => {
|
|
61
|
+
if (!get(isGrouped))
|
|
62
|
+
return {};
|
|
63
|
+
const result = get(sorted);
|
|
64
|
+
const identifier = rowAttr;
|
|
65
|
+
return result.reduce((acc, row) => {
|
|
66
|
+
if (!isDefined(row[identifier]) || row[identifier] === "")
|
|
67
|
+
return acc;
|
|
68
|
+
const rowGroup = getRowGroup(row);
|
|
69
|
+
const groupVal = Object.values(rowGroup).filter(isDefined).join(GROUP_KEY_SEPARATOR);
|
|
70
|
+
if (!acc[groupVal]) {
|
|
71
|
+
acc[groupVal] = [
|
|
72
|
+
{
|
|
73
|
+
__header__: true,
|
|
74
|
+
group: rowGroup,
|
|
75
|
+
identifier: groupVal
|
|
76
|
+
}
|
|
77
|
+
];
|
|
78
|
+
}
|
|
79
|
+
acc[groupVal].push(row);
|
|
80
|
+
return acc;
|
|
81
|
+
}, {});
|
|
82
|
+
});
|
|
83
|
+
const grouped = computed(() => {
|
|
84
|
+
const result = get(sorted);
|
|
85
|
+
const groupByKey = get(groupKey);
|
|
86
|
+
if (!groupByKey)
|
|
87
|
+
return result;
|
|
88
|
+
return Object.values(get(mappedGroups)).flat();
|
|
89
|
+
});
|
|
90
|
+
function getGroupRows(groupVal) {
|
|
91
|
+
if (!get(isGrouped))
|
|
92
|
+
return [];
|
|
93
|
+
const groupRows = get(mappedGroups)[groupVal];
|
|
94
|
+
assert(groupRows);
|
|
95
|
+
return groupRows.filter(isRow);
|
|
96
|
+
}
|
|
97
|
+
function onToggleExpandGroup(groupPartial, value) {
|
|
98
|
+
if (!value)
|
|
99
|
+
return;
|
|
100
|
+
const currentCollapsed = get(collapsedRows);
|
|
101
|
+
const groupExpanded = isExpandedGroup(groupPartial);
|
|
102
|
+
const groupRows = getGroupRows(value);
|
|
103
|
+
set(
|
|
104
|
+
collapsedRows,
|
|
105
|
+
groupExpanded ? [...currentCollapsed, ...groupRows] : currentCollapsed.filter((row) => !compareGroupsFn(row, groupPartial))
|
|
106
|
+
);
|
|
107
|
+
set(collapsed, get(collapsedRows));
|
|
108
|
+
}
|
|
109
|
+
function onUngroup() {
|
|
110
|
+
set(collapsedRows, []);
|
|
111
|
+
set(collapsed, []);
|
|
112
|
+
set(group, Array.isArray(get(group)) ? [] : void 0);
|
|
113
|
+
}
|
|
114
|
+
function onCopyGroup(value) {
|
|
115
|
+
emitCopyGroup(value);
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
groupKeys,
|
|
119
|
+
groupKey,
|
|
120
|
+
isGrouped,
|
|
121
|
+
mappedGroups,
|
|
122
|
+
grouped,
|
|
123
|
+
getRowGroup,
|
|
124
|
+
getGroupRows,
|
|
125
|
+
compareGroupsFn,
|
|
126
|
+
isExpandedGroup,
|
|
127
|
+
isHiddenRow,
|
|
128
|
+
onToggleExpandGroup,
|
|
129
|
+
onUngroup,
|
|
130
|
+
onCopyGroup
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
export {
|
|
134
|
+
useTableGrouping
|
|
135
|
+
};
|
|
136
|
+
//# sourceMappingURL=grouping.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grouping.js","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"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ComputedRef, Ref } from 'vue';
|
|
2
|
+
import type { TableSortData } from '../../../components/tables/RuiTableHead.vue.js';
|
|
3
|
+
import type { TablePaginationData } from '../../../components/tables/RuiTablePagination.vue.js';
|
|
4
|
+
import type { TableOptions as TableDefaultOptions } from '../../../composables/defaults/table.js';
|
|
5
|
+
import { type GroupedTableRow } from '../../../composables/tables/data-table/types.js';
|
|
6
|
+
export interface UseTablePaginationOptions {
|
|
7
|
+
/** The default number of items displayed per page. */
|
|
8
|
+
itemsPerPage: number;
|
|
9
|
+
/** Whether pagination is managed externally (e.g. server-side). */
|
|
10
|
+
paginationModifiersExternal: boolean | undefined;
|
|
11
|
+
/** Whether to share the items-per-page setting across all tables. */
|
|
12
|
+
globalItemsPerPage: boolean | undefined;
|
|
13
|
+
}
|
|
14
|
+
export interface UseTablePaginationDeps<T extends object> {
|
|
15
|
+
pagination: Ref<TablePaginationData | undefined>;
|
|
16
|
+
grouped: ComputedRef<GroupedTableRow<T>[]>;
|
|
17
|
+
isHiddenRow: (row: GroupedTableRow<T>) => boolean;
|
|
18
|
+
sort: Ref<TableSortData<T>>;
|
|
19
|
+
emitUpdateOptions: (options: {
|
|
20
|
+
sort?: TableSortData<T>;
|
|
21
|
+
pagination?: TablePaginationData;
|
|
22
|
+
}) => void;
|
|
23
|
+
tableDefaults: TableDefaultOptions;
|
|
24
|
+
}
|
|
25
|
+
export interface UseTablePaginationReturn<T extends object> {
|
|
26
|
+
paginationData: Ref<TablePaginationData>;
|
|
27
|
+
filtered: ComputedRef<GroupedTableRow<T>[]>;
|
|
28
|
+
itemsLength: Ref<number>;
|
|
29
|
+
globalItemsPerPageSettings: ComputedRef<boolean>;
|
|
30
|
+
setInternalTotal: (items: GroupedTableRow<T>[]) => void;
|
|
31
|
+
resetPagination: () => void;
|
|
32
|
+
}
|
|
33
|
+
export declare function useTablePagination<T extends object>(options: UseTablePaginationOptions, deps: UseTablePaginationDeps<T>): UseTablePaginationReturn<T>;
|