Replies: 3 comments 7 replies
-
So you can build the Quik adapter for us? Someone made this before, but it sounded like it was buggy. |
Beta Was this translation helpful? Give feedback.
-
To the future visitors of this page, I know the struggle to adapt tanstack with qwik, import type { NoSerialize } from "@builder.io/qwik";
import { noSerialize, useStore, useVisibleTask$ } from "@builder.io/qwik";
import type {
ColumnPinningState,
PaginationState,
RowSelectionState,
SortingState,
Table,
} from "@tanstack/table-core";
import {
createTable,
getCoreRowModel,
getPaginationRowModel,
getSortedRowModel,
} from "@tanstack/table-core";
import type { TableHookColumns, TableHookData } from "../../../types";
type TableState = {
sorting: SortingState;
pagination: PaginationState;
columnPinning: ColumnPinningState;
globalFilter: string;
rowSelection: RowSelectionState;
};
const createUnSeralizedTable = <T>(
data: TableHookData<T>,
columns: TableHookColumns<T>,
state: TableState,
) =>
noSerialize(
createTable({
columns,
data: data.value,
state: state,
renderFallbackValue: "fallback",
onStateChange: (newState) => {
// @ts-ignore
const updated = newState(state);
console.log("onStateChange updated", updated);
state.sorting = updated.sorting;
state.pagination = updated.pagination;
state.columnPinning = updated.columnPinning;
state.globalFilter = updated.globalFilter;
state.rowSelection = updated.rowSelection;
},
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
getPaginationRowModel: getPaginationRowModel(),
enableGlobalFilter: true,
onGlobalFilterChange: (value) => {
state.globalFilter = value;
console.log("onGlobalFilterChange");
},
onRowSelectionChange: (newSelection) => {
// @ts-ignore
const updated = newSelection(state.rowSelection);
console.log("onRowSelectionChange updated", updated);
state.rowSelection = updated;
},
}),
);
const initialState: TableState = {
sorting: [],
pagination: { pageIndex: 0, pageSize: 5 },
columnPinning: { left: [], right: [] },
globalFilter: "",
rowSelection: {},
};
export const useTable = <T>(
data: TableHookData<T>,
columns: TableHookColumns<T>,
) => {
const table = useStore<{
instance: NoSerialize<Table<T>>;
state: TableState;
}>({
instance: createUnSeralizedTable<T>(data, columns, initialState),
state: initialState,
});
useVisibleTask$(({ track }) => {
track(data);
table.instance = createUnSeralizedTable<T>(data, columns, table.state);
});
return table;
}; Below is my table base which is used to render the table. import type { NoSerialize } from "@builder.io/qwik";
import { component$ } from "@builder.io/qwik";
import { tableFlexRender } from "~/utils/table";
import { TableRowActions } from "./actions/base";
import type { AvailableTables, Entity } from "../../../types";
import { TableHeaderCheckBox, TableRowCheckBox } from "./selection";
import { TableFooter } from "./footer/base";
import { ArrowDropDownIcon, ArrowDropUpIcon } from "../icons";
type Props = {
table: NoSerialize<AvailableTables>;
entity: Entity;
onDelete$: (entityId: string) => void;
onDeleteConfirm$: (entityId: string) => void;
showConfirmDialogOnDelete?: boolean;
};
export const TableBase = component$<Props>(
({
table,
entity,
onDelete$,
onDeleteConfirm$,
showConfirmDialogOnDelete = true,
}) => {
return (
<table class="table">
<thead>
{table?.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
<TableHeaderCheckBox entity={entity} table={table} />
{headerGroup.headers.map(({ column }) => {
const id = column.id;
return (
<th
key={id}
onClick$={() => {
const thisCol = table.getColumn(id)!;
thisCol.toggleSorting();
}}
>
<div class="flex">
{column.columnDef.header}
{column.getIsSorted() ? (
<ArrowDropUpIcon />
) : (
<ArrowDropDownIcon />
)}
</div>
</th>
);
})}
</tr>
))}
</thead>
<tbody>
{table?.getRowModel().rows.map((row) => {
return (
<tr key={row.id} class="hover">
<TableRowCheckBox
table={table}
entity={entity}
entityId={row.original.id}
rowId={row.id}
/>
{row.getAllCells().map((cell) => (
<td key={cell.id}>
{tableFlexRender(
cell.column.columnDef.cell,
cell.getContext(),
)}
</td>
))}
<TableRowActions
entity={entity}
entityId={row.original.id}
onDelete$={onDelete$}
onDeleteConfirm$={onDeleteConfirm$}
showConfirmDialogOnDelete={showConfirmDialogOnDelete}
/>
</tr>
);
})}
</tbody>
<TableFooter table={table} />
</table>
);
},
); Finally, this is how it can be used all together export default component$(() => {
const data = useLoader();
const table = useOrderTable(data);
return (
<>
<TableBase
table={table.instance}
entity="ORDER"
onDelete$={(id) => {
console.log("id", id);
}}
onDeleteConfirm$={(id) => {
// removed for sharing purposes
}}
/>
</>
);
}); I hope you guys find this usefull . Apologies for some extra/redundant code that my code blocks might have, I just copy pasted from my project. |
Beta Was this translation helpful? Give feedback.
-
Hello, in my search for an example of how to implement a table, I came across the TanStack Table library and its implementation for Qwik and one of the funny things is that they are selling us the idea of this, without specifying the environment where Qwik runs. , the examples that are in the official documentation are only running in a project generated by VITE.js and setting the boot mode to "csr:true", this causes a big problem when wanting to use an official implementation of Qwik + Qwik City.. since this is 100% SSR and that half of the qualities if not all the advantages that the library offers as CSR are lost due to this POC. Look this example using Implement TanStack Table Core in Qwik City. https://stackblitz.com/edit/qwik-tanstack-table-solution?file=src%2Froutes%2Findex.tsx |
Beta Was this translation helpful? Give feedback.
-
TranStack Table for Qwik!
With the growing adoption and blazing fast speed of the Qwik framework, it would be fantastic broaden TranStack/Table reach with a Qwik adapter. The adapters and an infinite scroll example seems less than trivial, but would be of great mutual value to both TranStack and Qwik.
NOTE: As I am uncertain if TranStack/Virtual is the infinite-scroll aspect for TranStack/Table, I've opened a companion discussion here, but please feel free to close either if appropriate.
Cc: @tannerlinsley, @KevinVandy, @mhevery, @gioboa
Beta Was this translation helpful? Give feedback.
All reactions