This commit is contained in:
Philipinho
2026-03-09 01:08:15 +00:00
parent 4ff13cef62
commit 084746e65a
12 changed files with 667 additions and 105 deletions
@@ -33,7 +33,7 @@ type GridContainerProps = {
table: Table<IBaseRow>;
onCellUpdate: (rowId: string, propertyId: string, value: unknown) => void;
onAddRow?: () => void;
onAddColumn?: () => void;
baseId?: string;
onColumnReorder?: (columnId: string, overColumnId: string) => void;
onResizeEnd?: () => void;
onRowReorder?: (rowId: string, targetRowId: string, position: "above" | "below") => void;
@@ -46,7 +46,7 @@ export function GridContainer({
table,
onCellUpdate,
onAddRow,
onAddColumn,
baseId,
onColumnReorder,
onResizeEnd,
onRowReorder,
@@ -115,8 +115,8 @@ export function GridContainer({
const gridTemplateColumns = useMemo(() => {
const visibleColumns = table.getVisibleLeafColumns();
const columnWidths = visibleColumns.map((col) => `${col.getSize()}px`);
return columnWidths.join(" ") + (onAddColumn ? " 40px" : "");
}, [table, table.getState().columnSizing, table.getState().columnVisibility, onAddColumn]);
return columnWidths.join(" ") + (baseId ? " 40px" : "");
}, [table, table.getState().columnSizing, table.getState().columnVisibility, table.getState().columnOrder, baseId]);
const totalHeight = virtualizer.getTotalSize();
@@ -148,6 +148,18 @@ export function GridContainer({
onAddRow?.();
}, [onAddRow]);
const handlePropertyCreated = useCallback(() => {
// Wait for React to re-render with the new column, then scroll to it
requestAnimationFrame(() => {
requestAnimationFrame(() => {
scrollRef.current?.scrollTo({
left: scrollRef.current.scrollWidth,
behavior: "smooth",
});
});
});
}, []);
const sensors = useSensors(
useSensor(PointerSensor, {
activationConstraint: { distance: 8 },
@@ -194,7 +206,12 @@ export function GridContainer({
items={sortableColumnIds}
strategy={horizontalListSortingStrategy}
>
<GridHeader table={table} onAddColumn={onAddColumn} />
<GridHeader
table={table}
baseId={baseId}
columnOrder={table.getState().columnOrder}
onPropertyCreated={handlePropertyCreated}
/>
</SortableContext>
{paddingTop > 0 && (
@@ -1,39 +1,38 @@
import { memo, useCallback } from "react";
import { Table } from "@tanstack/react-table";
import { memo } from "react";
import { Table, ColumnOrderState } from "@tanstack/react-table";
import { IBaseRow } from "@/features/base/types/base.types";
import { GridHeaderCell } from "./grid-header-cell";
import { IconPlus } from "@tabler/icons-react";
import { CreatePropertyPopover } from "@/features/base/components/property/create-property-popover";
import classes from "@/features/base/styles/grid.module.css";
type GridHeaderProps = {
table: Table<IBaseRow>;
onAddColumn?: () => void;
baseId?: string;
// Passed explicitly to break memo when columns change
// (table ref is stable from useReactTable, so memo won't fire without this)
columnOrder: ColumnOrderState;
onPropertyCreated?: () => void;
};
export const GridHeader = memo(function GridHeader({
table,
onAddColumn,
baseId,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
columnOrder: _columnOrder,
onPropertyCreated,
}: GridHeaderProps) {
const headerGroups = table.getHeaderGroups();
const handleAddColumn = useCallback(() => {
onAddColumn?.();
}, [onAddColumn]);
return (
<div className={classes.headerRow} role="row">
{headerGroups[0]?.headers.map((header) => (
<GridHeaderCell key={header.id} header={header} />
))}
{onAddColumn && (
<div
className={classes.addColumnButton}
onClick={handleAddColumn}
role="button"
tabIndex={0}
>
<IconPlus size={16} />
</div>
{baseId && (
<CreatePropertyPopover
baseId={baseId}
onPropertyCreated={onPropertyCreated}
/>
)}
</div>
);