123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- import type { BasicTableProps, TableRowSelection } from '../types/table';
- import type { Ref, ComputedRef } from 'vue';
- import { computed, unref, ref, nextTick, watch } from 'vue';
- import { getViewportOffset } from '/@/utils/domUtils';
- import { isBoolean } from '/@/utils/is';
- import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
- import { useModalContext } from '/@/components/Modal';
- import { useDebounce } from '/@/hooks/core/useDebounce';
- import type { BasicColumn } from '/@/components/Table';
- export function useTableScroll(
- propsRef: ComputedRef<BasicTableProps>,
- tableElRef: Ref<ComponentRef>,
- columnsRef: ComputedRef<BasicColumn[]>,
- rowSelectionRef: ComputedRef<TableRowSelection<any> | null>
- ) {
- const tableHeightRef: Ref<Nullable<number>> = ref(null);
- const modalFn = useModalContext();
- // const [debounceCalcTableHeight] = useDebounce(calcTableHeight, 80);
- const [debounceRedoHeight] = useDebounce(redoHeight, 250);
- const getCanResize = computed(() => {
- const { canResize, scroll } = unref(propsRef);
- return canResize && !(scroll || {}).y;
- });
- watch(
- () => unref(getCanResize),
- () => {
- debounceRedoHeight();
- },
- {
- immediate: true,
- }
- );
- function redoHeight() {
- if (unref(getCanResize)) {
- nextTick(() => {
- calcTableHeight();
- });
- }
- }
- function setHeight(heigh: number) {
- tableHeightRef.value = heigh;
- // Solve the problem of modal adaptive height calculation when the form is placed in the modal
- modalFn?.redoModalHeight?.();
- }
- // No need to repeat queries
- let paginationEl: HTMLElement | null;
- let footerEl: HTMLElement | null;
- let bodyEl: HTMLElement | null;
- async function calcTableHeight() {
- const { resizeHeightOffset, pagination, maxHeight } = unref(propsRef);
- if (!unref(getCanResize)) return;
- await nextTick();
- //Add a delay to get the correct bottomIncludeBody paginationHeight footerHeight headerHeight
- setTimeout(() => {
- const table = unref(tableElRef);
- if (!table) return;
- const tableEl: Element = table.$el;
- if (!tableEl) return;
- const headEl = tableEl.querySelector('.ant-table-thead ');
- if (!headEl) return;
- // Table height from bottom
- const { bottomIncludeBody } = getViewportOffset(headEl);
- // Table height from bottom height-custom offset
- const paddingHeight = 32;
- const borderHeight = 0;
- // Pager height
- let paginationHeight = 2;
- if (!isBoolean(pagination)) {
- if (!paginationEl) {
- paginationEl = tableEl.querySelector('.ant-pagination') as HTMLElement;
- }
- if (paginationEl) {
- const offsetHeight = paginationEl.offsetHeight;
- paginationHeight += offsetHeight || 0;
- } else {
- // TODO First fix 24
- paginationHeight += 24;
- }
- }
- let footerHeight = 0;
- if (!isBoolean(pagination)) {
- if (!footerEl) {
- footerEl = tableEl.querySelector('.ant-table-footer') as HTMLElement;
- } else {
- const offsetHeight = footerEl.offsetHeight;
- footerHeight += offsetHeight || 0;
- }
- }
- let headerHeight = 0;
- if (headEl) {
- headerHeight = (headEl as HTMLElement).offsetHeight;
- }
- let height =
- bottomIncludeBody -
- (resizeHeightOffset || 0) -
- paddingHeight -
- borderHeight -
- paginationHeight -
- footerHeight -
- headerHeight;
- height = (height > maxHeight! ? (maxHeight as number) : height) ?? height;
- setHeight(height);
- if (!bodyEl) {
- bodyEl = tableEl.querySelector('.ant-table-body');
- }
- bodyEl!.style.height = `${height}px`;
- }, 200);
- }
- useWindowSizeFn(calcTableHeight, 200);
- const getScrollX = computed(() => {
- let width = 0;
- if (unref(rowSelectionRef)) {
- width += 60;
- }
- // TODO props ?? 0;
- const NORMAL_WIDTH = 150;
- const columns = unref(columnsRef).filter((item) => !item.defaultHidden);
- columns.forEach((item) => {
- width += Number.parseInt(item.width as string) || 0;
- });
- const unsetWidthColumns = columns.filter((item) => !Reflect.has(item, 'width'));
- const len = unsetWidthColumns.length;
- if (len !== 0) {
- width += len * NORMAL_WIDTH;
- }
- const table = unref(tableElRef);
- const tableWidth = table?.$el?.offsetWidth ?? 0;
- return tableWidth > width ? '100%' : width;
- });
- const getScrollRef = computed(() => {
- const tableHeight = unref(tableHeightRef);
- const { canResize, scroll } = unref(propsRef);
- return {
- x: unref(getScrollX),
- y: canResize ? tableHeight : null,
- scrollToFirstRowOnChange: false,
- ...scroll,
- };
- });
- return { getScrollRef, redoHeight };
- }
|