Skip to content

Commit fdb727e

Browse files
authored
fix(explorer): editable cells keep focus (#3664)
1 parent d83a0fd commit fdb727e

4 files changed

Lines changed: 51 additions & 23 deletions

File tree

.changeset/big-feet-give.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@latticexyz/explorer": patch
3+
---
4+
5+
Editable table cells no longer lose focus during editing when the query is set to "live".

packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/EditableTableCell.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ export function EditableTableCell({ name, table, keyTuple, value: defaultValue }
3535
const { worldAddress } = useParams();
3636
const { id: chainId } = useChain();
3737
const account = useAccount();
38-
3938
const valueSchema = getValueSchema(table);
4039
const fieldType = valueSchema?.[name as never]?.type;
4140

@@ -54,7 +53,6 @@ export function EditableTableCell({ name, table, keyTuple, value: defaultValue }
5453
});
5554

5655
const receipt = await waitForTransactionReceipt(wagmiConfig, { hash: txHash });
57-
5856
return { txHash, receipt };
5957
},
6058
onMutate: () => {

packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/explore/TablesViewer.tsx

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ import {
1010
import { parseAsJson, parseAsString, useQueryState } from "nuqs";
1111
import { useCallback, useMemo } from "react";
1212
import { Table as TableType } from "@latticexyz/config";
13-
import { getKeySchema, getKeyTuple } from "@latticexyz/protocol-parser/internal";
13+
import { getKeySchema } from "@latticexyz/protocol-parser/internal";
1414
import {
1515
ColumnDef,
1616
OnChangeFn,
1717
PaginationState,
18+
RowData,
1819
SortingState,
1920
flexRender,
2021
getCoreRowModel,
@@ -31,9 +32,9 @@ import { cn } from "../../../../../../utils";
3132
import { useChain } from "../../../../hooks/useChain";
3233
import { TData, TDataRow, useTableDataQuery } from "../../../../queries/useTableDataQuery";
3334
import { indexerForChainId } from "../../../../utils/indexerForChainId";
34-
import { EditableTableCell } from "./EditableTableCell";
3535
import { ExportButton } from "./ExportButton";
3636
import { PAGE_SIZE_OPTIONS } from "./consts";
37+
import { defaultColumn } from "./defaultColumn";
3738
import { usePaginationState } from "./hooks/usePaginationState";
3839
import { useSQLQueryState } from "./hooks/useSQLQueryState";
3940
import { getLimitOffset } from "./utils/getLimitOffset";
@@ -42,6 +43,13 @@ import { typeSortingFn } from "./utils/typeSortingFn";
4243
const initialSortingState: SortingState = [];
4344
const initialRows: TData["rows"] = [];
4445

46+
declare module "@tanstack/react-table" {
47+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
48+
interface TableMeta<TData extends RowData> {
49+
tableConfig?: TableType;
50+
}
51+
}
52+
4553
type Props = {
4654
table?: TableType;
4755
query?: string;
@@ -83,7 +91,6 @@ export function TablesViewer({ table, isLiveQuery }: Props) {
8391
const schema = table?.schema[name];
8492
const type = schema?.type;
8593
const keySchema = getKeySchema(table);
86-
8794
return {
8895
accessorKey: name,
8996
header: ({ column }) => {
@@ -101,27 +108,14 @@ export function TablesViewer({ table, isLiveQuery }: Props) {
101108
);
102109
},
103110
sortingFn: (rowA, rowB, columnId) => typeSortingFn(rowA, rowB, columnId, type),
104-
cell: ({ row }) => {
105-
const keySchema = getKeySchema(table);
106-
const value = row.getValue(name);
107-
if (!table || Object.keys(keySchema).includes(name)) {
108-
return value;
109-
}
110-
111-
try {
112-
const keyTuple = getKeyTuple(table, row.original as never);
113-
return <EditableTableCell name={name} table={table} value={value} keyTuple={keyTuple} />;
114-
} catch (e) {
115-
return value;
116-
}
117-
},
118111
};
119112
});
120113
}, [table, tableData]);
121114

122115
const reactTable = useReactTable({
123116
data: tableData?.rows ?? initialRows,
124117
columns: tableColumns,
118+
defaultColumn,
125119
initialState: {
126120
pagination: {
127121
pageSize: pagination.pageSize,
@@ -142,6 +136,9 @@ export function TablesViewer({ table, isLiveQuery }: Props) {
142136
globalFilter,
143137
pagination,
144138
},
139+
meta: {
140+
tableConfig: table,
141+
},
145142
});
146143

147144
// Pagination is only enabled if the query has a LIMIT and OFFSET that are divisible by the page size
@@ -196,6 +193,7 @@ export function TablesViewer({ table, isLiveQuery }: Props) {
196193
</TableRow>
197194
))}
198195
</TableHeader>
196+
199197
<TableBody className="relative">
200198
{isLoading && (
201199
<div className="absolute inset-0 z-10 flex items-center justify-center bg-background/50 backdrop-blur-sm">
@@ -204,10 +202,12 @@ export function TablesViewer({ table, isLiveQuery }: Props) {
204202
)}
205203
{!isError && reactTable.getRowModel().rows?.length ? (
206204
reactTable.getRowModel().rows.map((row) => (
207-
<TableRow key={row.id} data-state={row.getIsSelected() && "selected"}>
208-
{row.getVisibleCells().map((cell) => (
209-
<TableCell key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</TableCell>
210-
))}
205+
<TableRow key={row.id}>
206+
{row.getVisibleCells().map((cell) => {
207+
return (
208+
<TableCell key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</TableCell>
209+
);
210+
})}
211211
</TableRow>
212212
))
213213
) : (
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { getKeySchema, getKeyTuple } from "@latticexyz/protocol-parser/internal";
2+
import { CellContext, ColumnDef } from "@tanstack/react-table";
3+
import { TDataRow } from "../../../../queries/useTableDataQuery";
4+
import { EditableTableCell } from "./EditableTableCell";
5+
6+
export const defaultColumn: Partial<ColumnDef<TDataRow>> = {
7+
cell: ({ getValue, row, column, table }: CellContext<TDataRow, unknown>) => {
8+
const value = getValue();
9+
const tableConfig = table.options.meta?.tableConfig;
10+
11+
if (!tableConfig) return value;
12+
try {
13+
const name = column.id;
14+
const keySchema = getKeySchema(tableConfig);
15+
if (!table || Object.keys(keySchema).includes(name)) {
16+
return value;
17+
}
18+
19+
const keyTuple = getKeyTuple(tableConfig, row.original as never);
20+
return <EditableTableCell name={name} table={tableConfig} value={value} keyTuple={keyTuple} />;
21+
} catch (e) {
22+
return value;
23+
}
24+
},
25+
};

0 commit comments

Comments
 (0)