Skip to content

Commit

Permalink
fix: sticky table header, remove badge when value is 0
Browse files Browse the repository at this point in the history
  • Loading branch information
tewshi committed Jan 12, 2024
1 parent 64561ba commit 567a0d1
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 34 deletions.
9 changes: 9 additions & 0 deletions example/cypress/support/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,12 @@

// Import commands.js using ES2015 syntax:
import './commands';

Cypress.on('uncaught:exception', (e) => {
if (
/ResizeObserver loop completed/.test(e.message) ||
/ResizeObserver loop limit exceeded/.test(e.message)
) {
return false;
}
});
6 changes: 3 additions & 3 deletions src/components/tables/TableHead.vue
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,14 @@ const onToggleAll = (checked: boolean) => emit('select:all', checked);
const isSortedBy = (key: TableColumn<T>['key']) => key in props.sortedMap;
const getSortIndex = (key: TableColumn<T>['key']) => {
const getSortIndex = (key: TableColumn<T>['key']): number => {
const sortBy = props.sortData;
if (!sortBy || !Array.isArray(sortBy) || !isSortedBy(key)) {
return -1;
}
return sortBy.findIndex((sort) => sort.column === key) ?? -1;
return sortBy.findIndex((sort) => sort.column === key);
};
const getSortDirection = (key: TableColumn<T>['key']) =>
Expand Down Expand Up @@ -182,7 +182,7 @@ const getSortDirection = (key: TableColumn<T>['key']) =>
<slot :column="column" :name="`header.${column.key.toString()}`">
<Badge
v-if="column.sortable"
:value="getSortIndex(column.key) >= 0"
:model-value="getSortIndex(column.key) >= 0"
:text="`${getSortIndex(column.key) + 1}`"
color="secondary"
size="sm"
Expand Down
54 changes: 23 additions & 31 deletions src/composables/sticky-header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { type Ref } from 'vue';
/**
* Setup sticky table header
*/
export const useStickyTableHeader = (offsetTop: Ref<number> = ref(0)) => {
export const useStickyTableHeader = (
offsetTop: Ref<number> = ref(0),
sticky: Ref<boolean> = ref(false),
) => {
const table: Ref<HTMLTableElement | null> = ref(null);
const tableScroller: Ref<HTMLElement | null> = ref(null);
const stick: Ref<boolean> = ref(false);
Expand All @@ -15,10 +18,10 @@ export const useStickyTableHeader = (offsetTop: Ref<number> = ref(0)) => {
row: ':scope > tbody > tr:not([hidden])',
};

const updateHeaderCellWidth = () => {
const watchCellWidth = () => {
const root = get(table);

if (!root) {
if (!get(sticky) || !root) {
return;
}

Expand All @@ -28,22 +31,29 @@ export const useStickyTableHeader = (offsetTop: Ref<number> = ref(0)) => {

const head: HTMLHeadElement | null =
root.querySelector(selectors.head) ?? null;

const columns: NodeListOf<HTMLElement> | undefined = head?.querySelectorAll(
selectors.th,
);

const clonedColumns: NodeListOf<HTMLElement> | undefined =
theadClone?.querySelectorAll(selectors.th);

columns?.forEach((column: HTMLElement, i: number) => {
const cellRect = clonedColumns?.item(i)?.getBoundingClientRect();
column.style.width = `${cellRect?.width ?? 0}px`;
clonedColumns?.forEach((th: HTMLElement, i: number) => {
useResizeObserver(th, (entries) => {
const cellRect = entries[0].target.getBoundingClientRect();
const column = columns?.item(i);
if (column) {
column.style.width = `${cellRect.width}px`;
}
});
});
};

const addStickyClass = () => {
const toggleStickyClass = () => {
const root = get(table);

if (!root) {
if (!get(sticky) || !root) {
return;
}

Expand Down Expand Up @@ -73,7 +83,6 @@ export const useStickyTableHeader = (offsetTop: Ref<number> = ref(0)) => {
const top = get(offsetTop) ?? 0;

head.style.width = `${theadWidth}px`;
theadClone.style.height = `${headRect.height}px`;

const rows = root.querySelectorAll(selectors.row);

Expand All @@ -98,29 +107,12 @@ export const useStickyTableHeader = (offsetTop: Ref<number> = ref(0)) => {
}
};

const updateHeader = () => {
addStickyClass();
updateHeaderCellWidth();
};

watchEffect(() => {
if (!get(table)?.querySelector(selectors.head)) {
return;
}

updateHeader();

const scroller = get(tableScroller);

if (scroller) {
useResizeObserver(get(tableScroller), updateHeader);
}
});

onMounted(() => {
useEventListener(window, 'scroll', addStickyClass);
useEventListener(window, 'resize', updateHeader);
useEventListener(tableScroller, 'scroll', updateHeader);
toggleStickyClass();
useEventListener(tableScroller, 'scroll', toggleStickyClass);
useEventListener(document.body, 'scroll', toggleStickyClass);
useEventListener(window, 'resize', toggleStickyClass);
watchCellWidth();
});

return {
Expand Down

0 comments on commit 567a0d1

Please sign in to comment.