Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Switch to TanStack Table #1260

Closed
wants to merge 9 commits into from

Conversation

shyakadavis
Copy link
Contributor

@shyakadavis shyakadavis commented Sep 2, 2024

Closes: #1189

I wonder if we should wait for the Svelte 5 version, though? If that's the case, happy to close this and wait for it. 🙂

TODO:

  • If/when greet lit, I can try my hand at overhauling the docs for the datable, because this P.R only switches the Tasks example
  • Center text when no search result(s)
  • Fix faceted filters
  • Clean-up change functions (onRowSelectionChange, onSortingChange, onColumnFiltersChange, onColumnVisibilityChange), preferably to separate function definitions
  • When you select all, and then deselect at least one row, the header's checkbox remains checked. This is because checked isn't reacting to changes to table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'). Will keep investigating.
  • Figure how generics play into this - I forewent using them because I kept running into weird TS errors, and used the Task type instead.
  • Move from the /tasks-2 route to /tasks
  • Changed the file names to shorter/clear ones, because I often find it hard to locate a file (I know cmd+p is the way to go), but you know, 🤷 I can revert to the old way, though 🙂

Before submitting the PR, please make sure you do the following

  • If your PR isn't addressing a small fix (like a typo), it references an issue where it is discussed ahead of time and assigned to you. In many cases, features are absent for a reason.
  • Prefix your PR title with feat:, fix:, chore:, or docs:.
  • This message body should clearly illustrate what problems it solves.
  • Format & lint the code with pnpm format and pnpm lint

Copy link

changeset-bot bot commented Sep 2, 2024

⚠️ No Changeset found

Latest commit: 86b5fd6

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

github-actions bot commented Sep 2, 2024

built with Refined Cloudflare Pages Action

⚡ Cloudflare Pages Deployment

Name Status Preview Last Commit
shadcn-svelte ✅ Ready (View Log) Visit Preview 86b5fd6

…header to indeterminate, otherwise, checked or not)
@kaechele
Copy link

kaechele commented Sep 2, 2024

Nice! I started working on this in parallel but you beat me to it. My solution is very close to what you have.

Generics should technically be straightforward. Here's what works for me.
You'd add generics="TData, TValue" to your <script lang="ts"> and:

  • your data is now TData[] instead of Task[]
  • Table<Task> becomes a Table<TData>
  • your ColumnDef<Task> become a ColumnDef<TData, TValue>
  • a Column<Task> is now a Column<TData, TValue>

One could think about pulling the column definition out of the components. This is what I ended up doing.
Composing the Task table specific cells into the table happens in the column definitions anyway. That way the base components become more reusable.

EDIT: I'm actually working on this using @tanstack/svelte-table@alpha and Svelte 5, so a few things are a bit different to account for the Svelte 5 changes. In hindsight, I should have probably added a YMMV to the generics part. Haven't tested it with the older versions.

@shyakadavis
Copy link
Contributor Author

Hey, @kaechele

It's my first time working with TanStack-anything, so glad I wasn't far off with how others are doing it. 😅

You'd add generics="TData, TValue" to your <script lang="ts">

Yup. This is what I was doing, but when it came to passing props in the column defs, weird errors came up. Which leads me to:

One could think about pulling the column definition out of the components.

Sure. I could look into this. Thanks.

Composing the Task table specific cells into the table happens in the column definitions anyway. That way the base components become more reusable.

Hmm... can I trouble you with a snippet of this? Can't get my head around what you mean, yet.

EDIT: I'm actually working on this using @tanstack/svelte-table@alpha and Svelte 5, so a few things are a bit different to account for the Svelte 5 changes. In hindsight, I should have probably added a YMMV to the generics part. Haven't tested it with the older versions.

I'm actually wondering if I should just wait for Svelte 5 as well. I guess I'm doing it now in case it's easier when migrating to S5. 🤷

@c-kirkeby
Copy link

In the TanStack docs they recommend using column helpers for building column definitions which are quite similar to the API from svelte-headless-table. I believe the rationale is that they provide a higher type safety.

@shyakadavis
Copy link
Contributor Author

In the TanStack docs they recommend using column helpers for building column definitions

Ah. Thanks a lot, @c-kirkeby Will change this in a few.

@shyakadavis
Copy link
Contributor Author

@kaechele

Before I commit my interpretation of this:

One could think about pulling the column definition out of the components.

Did you mean doing something like this:

header.svelte

	type $$Props = HTMLAttributes<HTMLDivElement> & {
		title: string;
		canSort: boolean;
		isSorted: boolean | 'asc' | 'desc' | boolean;
		toggleSorting: (desc?: boolean, isMulti?: boolean) => void;
		toggleVisibility: (v: boolean) => void;
	};

and in columns.ts

columnHelper.accessor('id', {
		id: 'task',
		header: ({ column }) => {
			return renderComponent(ColumnHeader, {
				title: 'Task',
				canSort: column.getCanSort(),
				isSorted: column.getIsSorted(),
				toggleSorting: column.toggleSorting,
				toggleVisibility: column.toggleVisibility
			});
		},
		enableSorting: false,
		enableHiding: false
	}),

@kaechele
Copy link

kaechele commented Sep 3, 2024

Yes, this is partially what I had in mind.

The other part, I just saw, you already had in your initial PR submission. Namely the creation of columns.ts.
I'm thinking that should live closer to the content part of the application (i.e. in the route with the +page.svelte as it is specific to the rendering of that particular set of data. In my view that is dependent on whether we want to treat the data table as generic and configurable for the purposes of documenting best practices.

Not that it would be necessary for this example app, since it's pretty specific and self-contained. But that's how I would handle it in an application where I keep my data table more generic. I feel this may make the documentation a bit more useful.

@shyakadavis
Copy link
Contributor Author

Closing as this has been shipped in the next branch. 🎉 (PR: #1318)

@shyakadavis shyakadavis deleted the feat/tanstack branch October 16, 2024 08:31
@shyakadavis shyakadavis restored the feat/tanstack branch November 4, 2024 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Enhancement: TanStack Table
4 participants