mirror of https://github.com/buster-so/buster.git
additional context provider logic
This commit is contained in:
parent
f9b41bc6de
commit
16fadc1b5c
|
@ -6,16 +6,18 @@ import { cn } from '@/lib/classMerge';
|
|||
import { CaretDown, CaretUp } from '../../../icons/NucleoIconFilled';
|
||||
import { HEADER_HEIGHT } from './constants';
|
||||
import { useSortColumnContext } from './SortColumnWrapper';
|
||||
import { Virtualizer } from '@tanstack/react-virtual';
|
||||
import { useMount } from '@/hooks';
|
||||
|
||||
interface DraggableHeaderProps {
|
||||
header: Header<Record<string, string | number | Date | null>, unknown>;
|
||||
resizable: boolean;
|
||||
sortable: boolean;
|
||||
overTargetId: string | null;
|
||||
isOverTarget: boolean;
|
||||
}
|
||||
|
||||
const DraggableHeader: React.FC<DraggableHeaderProps> = React.memo(
|
||||
({ header, sortable, resizable, overTargetId }) => {
|
||||
({ header, sortable, resizable, isOverTarget }) => {
|
||||
// Set up dnd-kit's useDraggable for this header cell
|
||||
const {
|
||||
attributes,
|
||||
|
@ -35,8 +37,6 @@ const DraggableHeader: React.FC<DraggableHeaderProps> = React.memo(
|
|||
id: `droppable-${header.id}`
|
||||
});
|
||||
|
||||
const isOverTarget = overTargetId === header.id;
|
||||
|
||||
const style: CSSProperties = {
|
||||
position: 'relative',
|
||||
whiteSpace: 'nowrap',
|
||||
|
@ -53,8 +53,7 @@ const DraggableHeader: React.FC<DraggableHeaderProps> = React.memo(
|
|||
className={cn(
|
||||
'group bg-background relative border-r select-none last:border-r-0',
|
||||
header.column.getIsResizing() ? 'bg-primary/8' : 'hover:bg-item-hover',
|
||||
isOverTarget &&
|
||||
'bg-primary/10 border-primary inset rounded-sm border border-r border-dashed'
|
||||
isOverTarget && 'bg-primary/10 border-primary inset border border-r border-dashed'
|
||||
)}
|
||||
// onClick toggles sorting if enabled
|
||||
onClick={header.column.getCanSort() ? header.column.getToggleSortingHandler() : undefined}>
|
||||
|
@ -101,65 +100,47 @@ const DraggableHeader: React.FC<DraggableHeaderProps> = React.memo(
|
|||
|
||||
DraggableHeader.displayName = 'DraggableHeader';
|
||||
|
||||
// Header content component to use in the DragOverlay
|
||||
const HeaderDragOverlay = ({
|
||||
header
|
||||
}: {
|
||||
header: Header<Record<string, string | number | Date | null>, unknown>;
|
||||
}) => {
|
||||
return (
|
||||
<div
|
||||
className="flex items-center rounded-sm border bg-white p-2 shadow-lg"
|
||||
style={{
|
||||
width: header.column.getSize(),
|
||||
height: `${HEADER_HEIGHT}px`,
|
||||
opacity: 0.85,
|
||||
transform: 'translate3d(0, 0, 0)', // Ensure no unexpected transforms are applied
|
||||
pointerEvents: 'none' // Prevent the overlay from intercepting pointer events
|
||||
}}>
|
||||
{flexRender(header.column.columnDef.header, header.getContext())}
|
||||
{header.column.getIsSorted() === 'asc' && <span> 🔼</span>}
|
||||
{header.column.getIsSorted() === 'desc' && <span> 🔽</span>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
interface DataGridHeaderProps {
|
||||
table: Table<Record<string, string | number | Date | null>>;
|
||||
sortable: boolean;
|
||||
resizable: boolean;
|
||||
rowVirtualizer: Virtualizer<HTMLDivElement, Element>;
|
||||
}
|
||||
|
||||
export const DataGridHeader: React.FC<DataGridHeaderProps> = ({ table, sortable, resizable }) => {
|
||||
const { activeId, overTargetId, activeHeader } = useSortColumnContext((x) => x);
|
||||
export const DataGridHeader: React.FC<DataGridHeaderProps> = ({
|
||||
rowVirtualizer,
|
||||
table,
|
||||
sortable,
|
||||
resizable
|
||||
}) => {
|
||||
const overTargetId = useSortColumnContext((x) => x.overTargetId);
|
||||
|
||||
const showScrollShadow = (rowVirtualizer?.scrollOffset || 0) > 10;
|
||||
|
||||
return (
|
||||
<thead className="bg-background sticky top-0 z-10 w-full" suppressHydrationWarning>
|
||||
<tr className="flex border-b shadow">
|
||||
{table
|
||||
.getHeaderGroups()[0]
|
||||
?.headers.map(
|
||||
(header: Header<Record<string, string | number | Date | null>, unknown>) => (
|
||||
<DraggableHeader
|
||||
key={header.id}
|
||||
header={header}
|
||||
sortable={sortable}
|
||||
resizable={resizable}
|
||||
overTargetId={overTargetId}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</tr>
|
||||
|
||||
{/* Drag Overlay */}
|
||||
<DragOverlay
|
||||
wrapperElement="span"
|
||||
adjustScale={false}
|
||||
dropAnimation={null} // Using null to completely disable animation
|
||||
zIndex={1000}>
|
||||
{activeId && activeHeader && <HeaderDragOverlay header={activeHeader} />}
|
||||
</DragOverlay>
|
||||
</thead>
|
||||
<>
|
||||
<thead className="bg-background sticky top-0 z-10 w-full" suppressHydrationWarning>
|
||||
<tr
|
||||
className={cn(
|
||||
'flex border-b transition-all duration-200',
|
||||
showScrollShadow && 'shadow-sm'
|
||||
)}>
|
||||
{table
|
||||
.getHeaderGroups()[0]
|
||||
?.headers.map(
|
||||
(header: Header<Record<string, string | number | Date | null>, unknown>) => (
|
||||
<DraggableHeader
|
||||
key={header.id}
|
||||
header={header}
|
||||
sortable={sortable}
|
||||
resizable={resizable}
|
||||
isOverTarget={overTargetId === header.id}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</tr>
|
||||
</thead>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -9,13 +9,15 @@ import {
|
|||
DragOverEvent,
|
||||
DragEndEvent,
|
||||
DndContext,
|
||||
pointerWithin
|
||||
pointerWithin,
|
||||
DragOverlay
|
||||
} from '@dnd-kit/core';
|
||||
import { restrictToHorizontalAxis } from '@dnd-kit/modifiers';
|
||||
import { arrayMove } from '@dnd-kit/sortable';
|
||||
import { Header, Table } from '@tanstack/react-table';
|
||||
import { flexRender, Header, Table } from '@tanstack/react-table';
|
||||
import { useState, useRef, useMemo, useEffect } from 'react';
|
||||
import { useContextSelector, createContext } from 'use-context-selector';
|
||||
import { HEADER_HEIGHT } from './constants';
|
||||
|
||||
export const SortColumnWrapper: React.FC<{
|
||||
table: Table<Record<string, string | number | Date | null>>;
|
||||
|
@ -136,24 +138,51 @@ export const SortColumnWrapper: React.FC<{
|
|||
onDragStart={onDragStart}
|
||||
onDragOver={onDragOver}
|
||||
onDragEnd={onDragEnd}>
|
||||
<SortColumnContext.Provider value={{ activeId, overTargetId, activeHeader }}>
|
||||
<SortColumnContext.Provider value={{ overTargetId }}>
|
||||
{children}
|
||||
|
||||
<DragOverlay
|
||||
wrapperElement="span"
|
||||
adjustScale={false}
|
||||
dropAnimation={null} // Using null to completely disable animation
|
||||
zIndex={1000}>
|
||||
{activeId && activeHeader && <HeaderDragOverlay header={activeHeader} />}
|
||||
</DragOverlay>
|
||||
</SortColumnContext.Provider>
|
||||
</DndContext>
|
||||
);
|
||||
};
|
||||
|
||||
type SortColumnContextType = {
|
||||
activeId: string | null;
|
||||
overTargetId: string | null;
|
||||
activeHeader: Header<Record<string, string | number | Date | null>, unknown> | null;
|
||||
};
|
||||
|
||||
export const SortColumnContext = createContext<SortColumnContextType>({
|
||||
activeId: null,
|
||||
overTargetId: null,
|
||||
activeHeader: null
|
||||
overTargetId: null
|
||||
});
|
||||
|
||||
export const useSortColumnContext = <T,>(selector: (ctx: SortColumnContextType) => T) =>
|
||||
useContextSelector(SortColumnContext, selector);
|
||||
|
||||
// Header content component to use in the DragOverlay
|
||||
const HeaderDragOverlay = ({
|
||||
header
|
||||
}: {
|
||||
header: Header<Record<string, string | number | Date | null>, unknown>;
|
||||
}) => {
|
||||
return (
|
||||
<div
|
||||
className="flex items-center rounded-sm border bg-white p-2 shadow-lg"
|
||||
style={{
|
||||
width: header.column.getSize(),
|
||||
height: `${HEADER_HEIGHT}px`,
|
||||
opacity: 0.85,
|
||||
transform: 'translate3d(0, 0, 0)', // Ensure no unexpected transforms are applied
|
||||
pointerEvents: 'none' // Prevent the overlay from intercepting pointer events
|
||||
}}>
|
||||
{flexRender(header.column.columnDef.header, header.getContext())}
|
||||
{header.column.getIsSorted() === 'asc' && <span> 🔼</span>}
|
||||
{header.column.getIsSorted() === 'desc' && <span> 🔽</span>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -126,7 +126,12 @@ export const TanStackDataGrid: React.FC<TanStackDataGridProps> = React.memo(
|
|||
setColOrder={setColOrder}
|
||||
onReorderColumns={onReorderColumns}>
|
||||
<table className="bg-background w-full">
|
||||
<DataGridHeader table={table} sortable={sortable} resizable={resizable} />
|
||||
<DataGridHeader
|
||||
table={table}
|
||||
sortable={sortable}
|
||||
resizable={resizable}
|
||||
rowVirtualizer={rowVirtualizer}
|
||||
/>
|
||||
|
||||
<tbody
|
||||
className="relative"
|
||||
|
|
Loading…
Reference in New Issue