Custom header components

The header field on a ColumnDef accepts a function that returns either a renderSnippet(...) or renderComponent(...). The function receives a HeaderContext so it can access the column, header, and grid.

With a snippet

<script lang="ts">
  import { renderSnippet, type ColumnDef } from 'sv-grid-community'

  const columns: ColumnDef<{}, Person>[] = [
    {
      field: 'salary',
      header: (ctx) => renderSnippet(SalaryHeader, { sorted: ctx.column.getIsSorted() }),
      format: { type: 'currency', currency: 'USD' },
    },
  ]
</script>

{#snippet SalaryHeader(p: { sorted: false | 'asc' | 'desc' })}
  <span class="inline-flex items-center gap-1">
    <span>💰 Salary</span>
    {#if p.sorted === 'asc'}↑{:else if p.sorted === 'desc'}↓{/if}
  </span>
{/snippet}

With a component

import HeaderWithIcon from './HeaderWithIcon.svelte'
import { renderComponent } from 'sv-grid-community'

const columns = [
  {
    field: 'status',
    header: () => renderComponent(HeaderWithIcon, { icon: 'flag', label: 'Status' }),
  },
]

HeaderContext

The argument passed to your header callback exposes:

type HeaderContext<TData> = {
  header: Header<TData>
  column: Column<TData>
  table: SvGrid<TData>
}

// Column gives you sort state, filter capability, and the toggle handler:
ctx.column.getCanSort()
ctx.column.getIsSorted()                    // false | 'asc' | 'desc'
ctx.column.getToggleSortingHandler()        // () => void

When to use it

Anything that needs more than a string belongs here - multi-line headers, filter icons inside the header, units, tooltips, custom sort indicators, a "select all" checkbox in a leading column.

Gotchas

See also