bryanmylee / svelte-headless-table

Unopinionated and extensible data tables for Svelte
https://svelte-headless-table.bryanmylee.com/
471 stars 29 forks source link

Row animations #65

Open FluffyDiscord opened 1 year ago

FluffyDiscord commented 1 year ago

Hello, I would like to add animations to my rows so that for example the sorting is nicely animated.

Right now I would need to remove <Subscribe> component hosting the table row tr

<tbody {...$tableBodyAttrs}>
    {#each $rows as row (row.id)}
//  <Subscribe rowAttrs={row.attrs()} let:rowAttrs> 
        <tr animate:flip={{delay: 0, duration: 200, easing: quintInOut}} class="group text-sm" {...row.attrs()}>
            {#each row.cells as cell (cell.id)}
                <Subscribe attrs={cell.attrs()} let:attrs>
                    <td class="group-hover:bg-neutral-100 px-4 first:pl-8 last:pr-4 py-2.5" {...attrs}>
                        <Render of={cell.render()}/>
                    </td>
                </Subscribe>
            {/each}
        </tr>
//   </Subscribe>
    {/each}
</tbody>

Is it even possible to achieve animations with the Subscribe component wrapping our tr row ?

On the other hand what exactly are we losing (and how critical it is) when we remove the Subscribe component ?

bryanmylee commented 1 year ago

What Subscribe does

The Subscribe component lets us subscribe to Svelte stores within the template itself. If you unsubscribe from it, then your table cells will lose reactivity to changes in the table component e.g. selected prop set on the addSelectedRows plugin.

I made the decision to compose the table from multiple nested stores instead of one giant store because it lets us selectively update parts of the table. As far as I'm aware, Svelte does not diff a virtual DOM to get the smallest changes required like in React, so it's not performant to take the approach that something like react-table takes.

Correct me if I'm wrong, but react-table stores the table as a single state object and relies on the diffing algorithm to update the DOM efficiently.

animate

I've clearly forgotten that Svelte's animate directive requires the element to be a direct child of a keyed block. I'm not sure what the right move is here, but I'll look into solutions to either make the Subscribe component transparent or unnecessary.

bryanmylee commented 1 year ago

Seems like there's an existing issue to work on the animate directive: https://github.com/sveltejs/svelte/issues/7209.

This is definitely one of Svelte's limitations; it tries to handle so many things and ends up having to compromise on many of them.

risalfajar commented 1 year ago

Can we replace Subscribe with the use directive?

bryanmylee commented 1 year ago

@risalfajar Unfortunately not as they don't really solve the same issue.

The biggest limitation is that the use directive only works after mount, so any solution we come up with will not work in SSR.

Furthermore, there's no way to provide data as needed with use.

However, I'm currently exploring the ability to flatten nested stores into a single global store, which would get rid of the need for Subscribe.