Rendering Snippets


Useful Links

Table Demo


NameAgeEmailPhone
Tracy Ondricka59Cody.Hahn46@hotmail.com(270) 685-2088
Dr. Delores Greenholt86Jermain22@gmail.com(670) 634-8446
Lena Hagenes90Rosalind.Bins55@hotmail.com(388) 742-7727
Dr. Dallas Bogisich67Will_Orn@yahoo.com(987) 878-2091
Frances Hackett-Ullrich30Morton.Reichert4@hotmail.com(398) 339-5972
Miss Katherine Strosin47Josh_Dare@yahoo.com(522) 311-0039
Kim Ziemann II41Jacquelyn.Zemlak@yahoo.com(442) 360-5473
Al Krajcik63Georgiana.Howe21@yahoo.com(717) 941-5844
Lucille Sporer67Bernard.Purdy12@hotmail.com(706) 648-9699
Elizabeth White88Benny_OKeefe69@yahoo.com(884) 678-5353

Explanation


When you don't want to make an entire component for a small piece of reusable code, snippets are a great way to encapsulate and reuse logic. In this example, we'll create snippets for rendering text in a <strong> tag and email addresses as clickable mailto links.

You should already know how to make a basic table before proceeding.

Defining Snippets

Snippets can be defined in Svelte either directly in the markup or in the script tag. Here, we use two methods to define our snippets:

🗒️ NOTE: The implementation of snippets within this repo only works with snippets that take one argument.

Markup Snippet

Using Svelte's {#snippet ...} block, you can define a reusable snippet directly in your component's markup. For example, the snippet strongSnippet is defined to render its content in a <strong> tag:

{#snippet strongSnippet(content: string)}
    <strong>{content}</strong>
{/snippet}

Script (Raw) Snippet

Snippets can also be created programmatically in the script tag using the createRawSnippet function. This approach is useful when you do not need to use a Svelte component in your snippet.

<script lang="ts">
  import { createRawSnippet } from 'svelte';

  const mailtoSnippet = createRawSnippet<[string]>((email) => {
    const emailAddress = email();
    return {
      render: () => `<a href="mailto:${emailAddress}">${emailAddress}</a>`,
      // Optional - Setup function to run when the snippet is first rendered
      setup: () => {
        // Example of using a Svelte effect to implement reactivity
        $effect(() => {
          node.textContent = email();
        });
      }
    };
  });
</script>

This mailtoSnippet generates a clickable email link, using the provided email address.

Column Definitions

Next, we define a set of columns for our table. The column definition array specifies how each cell should be rendered, and this is where renderSnippet comes in. This function allows you to use the snippets defined earlier to customize the cell content.

Here's an example of how we use renderSnippet with our snippets in the column definitions:

<script lang="ts">
  import { createRawSnippet } from 'svelte';
  import { createColumnHelper } from '$lib/table'; 
  import { type UserProfile } from '$lib/services/user-profile'; 

  const mailtoSnippet = createRawSnippet<[string]>((email) => { 
    const emailAddress = email(); 
    return { 
      render: () => `<a href="mailto:${emailAddress}">${emailAddress}</a>` 
    }; 
  }); 

  const colHelp = createColumnHelper<UserProfile>(); 

  const columnDefs = [ 
    // Column def using snippet from markup 
    colHelp.accessor('name', { 
      header: 'Name', 
      cell: ({ cell }) => renderSnippet(strongSnippet, cell.getValue()) 
    }), 
    colHelp.accessor('age', { header: 'Age' }), 
    // Column def using snippet from above 
    colHelp.accessor('email', { 
      header: 'Email', 
      cell: ({ cell }) => renderSnippet(mailtoSnippet, cell.getValue()) 
    }), 
    colHelp.accessor('phone', { header: 'Phone' }) 
  ]; 
</script>

{#snippet strongSnippet(content: string)}
  <strong>{content}</strong>
{/snippet}

🗒️ NOTE: You can also use renderSnippet with the header field of each column.

Setting Up the Table

After defining the columns, the next step is to set up the table using the createSvelteTable function. This function initializes the table with the specified data, columns, and core row model.

<script lang="ts">
  import { createRawSnippet } from 'svelte'; 
  import { createColumnHelper } from '$lib/table'; 
  import { createColumnHelper, createSvelteTable, getCoreRowModel } from '$lib/table'; 
  import { type UserProfile } from '$lib/services/user-profile'; 
  import { type UserProfile, userProfiles } from '$lib/services/user-profile'; 

  const mailtoSnippet = createRawSnippet<[string]>((email) => {
    const emailAddress = email();
    return {
      render: () => `<a href="mailto:${emailAddress}">${emailAddress}</a>`
    };
  });

  const colHelp = createColumnHelper<UserProfile>();

  const columnDefs = [
    colHelp.accessor('name', {
      header: 'Name',
      cell: ({ cell }) => renderSnippet(strongSnippet, cell.getValue())
    }),
    colHelp.accessor('age', { header: 'Age' }),
    colHelp.accessor('email', {
      header: 'Email',
      cell: ({ cell }) => renderSnippet(mailtoSnippet, cell.getValue())
    }),
    colHelp.accessor('phone', { header: 'Phone' })
  ];

  const table = createSvelteTable({ 
    data: userProfiles, 
    columns: columnDefs, 
    getCoreRowModel: getCoreRowModel() 
  }); 
</script>

{#snippet strongSnippet(content: string)}
  <strong>{content}</strong>
{/snippet}

Rendering the Table

Finally, to render the table itself, we use the FlexRender component. FlexRender is responsible for dynamically rendering the table's cells based on the content and context provided.

<table>
  <thead>
    <tr>
      {#each table.getHeaderGroups() as headerGroup}
        {#each headerGroup.headers as header}
          <th>
            <FlexRender content={header.column.columnDef.header} context={header.getContext()} />
          </th>
        {/each}
      {/each}
    </tr>
  </thead>
  <tbody>
    {#each table.getRowModel().rows as row}
      <tr>
        {#each row.getVisibleCells() as cell}
          <td>
            <FlexRender content={cell.column.columnDef.cell} context={cell.getContext()} />
          </td>
        {/each}
      </tr>
    {/each}
  </tbody>
</table>