---
components: ["DataTable", "Pagination","Toolbar", "ToolbarContent", "ToolbarSearch", "ToolbarMenu", "ToolbarMenuItem", "ToolbarBatchActions"]
---

<script>
  import { InlineNotification, DataTable, DataTableSkeleton, Pagination, Toolbar, ToolbarContent, ToolbarSearch, ToolbarMenu, ToolbarMenuItem, Button, Link } from "carbon-components-svelte";
  import Launch from "carbon-icons-svelte/lib/Launch.svelte";
  import Preview from "../../components/Preview.svelte";
</script>

`DataTable` displays structured data in a tabular format. Use it to present large datasets with features like sorting, filtering, pagination, and row selection.

<InlineNotification svx-ignore lowContrast title="Note:" kind="info" hideCloseButton>
  <div class="body-short-01">
    This component is keyed for performance.
    
    Every <strong>headers</strong> object must have a unique "key" property.
    <div class="body-short-01">Every <strong>rows</strong> object must have a unique "id" property.</div>
  </div>
</InlineNotification>

## Default

Create a basic table by providing `headers` and `rows` data. Match the `key` in headers with the corresponding property in rows.

<DataTable
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
/>

## Slotted cells

Use the `"cell"` slot to customize cell content. Access row and cell data through `let:row` and `let:cell` directives. Use `"cell-header"` slot for header cells.

<DataTable
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
>
 <svelte:fragment slot="cell-header" let:header>
    {#if header.key === 'port'}
      {header.value} (network)
    {:else}
      {header.value}
    {/if}
  </svelte:fragment>
  <svelte:fragment slot="cell" let:row let:cell>
    {#if cell.key === 'rule' && cell.value === 'Round robin'}
      <Link icon={Launch} href="https://en.wikipedia.org/wiki/Round-robin_DNS" target="_blank">{cell.value}</Link>
    {:else}
      {cell.value}
    {/if}
  </svelte:fragment>
</DataTable>

## With title, description

Add a title and description to provide context for the table data.

<DataTable title="Load balancers" description="Your organization's active load balancers."
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
/>

## Slottable title, description

Use slots to customize the title and description content.

<DataTable
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
>
    <strong slot="title">Load balancers</strong>
    <span slot="description" style="font-size: 1rem">
      Your organization's active load balancers.
    </span>
</DataTable>

## Static width

Set `useStaticWidth` to `true` to render the table with an auto width instead of 100%.

<DataTable useStaticWidth
title="Load balancers" description="Your organization's active load balancers."
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
/>

## Custom column widths

Specify `width` or `minWidth` in the `headers` object to set column dimensions. This applies a fixed table layout.

<InlineNotification svx-ignore lowContrast kind="warning" title="Note:" hideCloseButton>
  <div class="body-short-01">Custom column widths do not work with a <a class="bx--link" href="#sticky-header">sticky header</a>.</div>
</InlineNotification>

<FileSource src="/framed/DataTable/DataTableHeaderWidth" />

## Sticky header

Set `stickyHeader` to `true` to fix the header in place. This adds a maximum height to force scrolling.

<DataTable
  stickyHeader
  headers={[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" },
  ]}
  rows={Array.from({ length: 20 }).map((_, i) => ({
    id: i,
    name: "Load Balancer " + (i + 1),
    protocol: "HTTP",
    port: i % 3 ? (i % 2 ? 3000 : 80) : 443,
    rule: i % 3 ? "Round robin" : "DNS delegation",
  }))}
/>

## With toolbar

Add a toolbar with search, menu, and actions above the table.

<DataTable title="Load balancers" description="Your organization's active load balancers."
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
>
  <Toolbar>
    <ToolbarContent>
      <ToolbarSearch />
      <ToolbarMenu>
        <ToolbarMenuItem primaryFocus>Restart all</ToolbarMenuItem>
        <ToolbarMenuItem href="https://cloud.ibm.com/docs/loadbalancer-service">
          API documentation
        </ToolbarMenuItem>
        <ToolbarMenuItem hasDivider danger>Stop all</ToolbarMenuItem>
      </ToolbarMenu>
      <Button>Create balancer</Button>
    </ToolbarContent>
  </Toolbar>
</DataTable>

## With toolbar (small size)

Use `size="short"` to create a more compact table with a small toolbar.

<DataTable size="short" title="Load balancers" description="Your organization's active load balancers."
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
>
  <Toolbar size="sm">
    <ToolbarContent>
      <ToolbarSearch />
      <ToolbarMenu>
        <ToolbarMenuItem primaryFocus>Restart all</ToolbarMenuItem>
        <ToolbarMenuItem href="https://cloud.ibm.com/docs/loadbalancer-service">API documentation</ToolbarMenuItem>
        <ToolbarMenuItem hasDivider danger>Stop all</ToolbarMenuItem>
      </ToolbarMenu>
      <Button>Create balancer</Button>
    </ToolbarContent>
  </Toolbar>
</DataTable>

## Filterable

Set `shouldFilterRows` to `true` to enable client-side filtering. The default filter performs string comparisons on cell values.

For pagination with filtering, bind to `filteredRowIds` and pass its length to `Pagination`'s `totalItems`.

<FileSource src="/framed/DataTable/DataTableFilterable" />

## Filterable (custom)

Pass a function to `shouldFilterRows` to implement custom filtering logic.

<FileSource src="/framed/DataTable/DataTableFilterCustom" />

## Zebra stripes

Set `zebra` to `true` to add alternating row colors.

<DataTable zebra
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
/>

## Tall rows

Set `size="tall"` for increased row height.

<DataTable size="tall"
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
/>

## Medium rows

Set `size="medium"` for standard row height.

<DataTable size="medium"
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
/>

## Short rows

Set `size="short"` for compact row height.

<DataTable size="short"
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
/>

## Compact rows

Set `size="compact"` for minimal row height.

<DataTable size="compact"
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
/>

## Sortable

Set `sortable` to `true` to enable column sorting. Disable sorting on specific columns by setting `sort: false` in the header object.

<DataTable sortable
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol", sort: false },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
/>

## Sortable with pagination

Bind to `pageSize` and `page` props of `Pagination` and pass them to `DataTable`.

<FileSource src="/framed/DataTable/DataTablePagination" />

## Sortable with custom display and sort methods

Use `display` and `sort` functions in header objects to customize cell rendering and sorting.

<DataTable sortable title="Load balancers" description="Your organization's active load balancers."
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "cost", value: "Cost", display: (cost) => cost + " €" },
    {
      key: "expireDate",
      value: "Expire date",
      display: (date) => new Date(date).toLocaleString(),
      sort: (a, b) => new Date(a) - new Date(b),
    },
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      cost: 100,
      expireDate: "2020-10-21",
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      cost: 200,
      expireDate: "2020-09-10",
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      cost: 150,
      expireDate: "2020-11-24",
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      cost: 250,
      expireDate: "2020-12-01",
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      cost: 550,
      expireDate: "2021-03-21",
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      cost: 400,
      expireDate: "2020-11-14",
    },
  ]}"
/>

## Sortable with nested object values

Access nested object properties using dot notation in the header key.

<DataTable sortable title="Load balancers" description="Your organization's active load balancers."
           headers="{[
    { key: "name", value: "Name" },
    { key: "network.protocol", value: "Protocol" },
    { key: "network.port", value: "Port" },
    { key: "cost", value: "Cost", display: (cost) => cost + " €" },
    {
      key: "expireDate",
      value: "Expire date",
      display: (date) => new Date(date).toLocaleString(),
      sort: (a, b) => new Date(a) - new Date(b),
    },
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      network: {
        protocol: "HTTP",
        port: 3000,
      },
      cost: 100,
      expireDate: "2020-10-21",
    },
    {
      id: "b",
      name: "Load Balancer 1",
      network: {
        protocol: "HTTP",
        port: 443,
      },
      cost: 200,
      expireDate: "2020-09-10",
    },
    {
      id: "c",
      name: "Load Balancer 2",
      network: {
        protocol: "HTTP",
        port: 80,
      },
      cost: 150,
      expireDate: "2020-11-24",
    },
    {
      id: "d",
      name: "Load Balancer 6",
      network: {
        protocol: "HTTP",
        port: 3000,
      },
      cost: 250,
      expireDate: "2020-12-01",
    },
    {
      id: "e",
      name: "Load Balancer 4",
      network: {
        protocol: "HTTP",
        port: 443,
      },
      cost: 550,
      expireDate: "2021-03-21",
    },
    {
      id: "f",
      name: "Load Balancer 5",
      network: {
        protocol: "HTTP",
        port: 80,
      },
      cost: 400,
      expireDate: "2020-11-14",
    },
  ]}"
/>

## Programmatic sorting

Use `sortKey` and `sortDirection` props to control sorting programmatically. Set `sortKey` to a valid header key and `sortDirection` to "none", "ascending", or "descending".

<FileSource src="/framed/DataTable/DataTableProgrammaticSorting" />

## Empty column with overflow menu

Set `empty: true` in a header object to create an empty column. Use this for overflow menus without a header.

<FileSource src="/framed/DataTable/DataTableAppendColumns" />

## Selectable rows (checkbox)

Set `selectable` to `true` for multi-select functionality. Bind to `selectedRowIds` to track selections. Use `inputName` to customize checkbox names.

<FileSource src="/framed/DataTable/SelectableDataTable" />

## Batch selection

Set `batchSelection` to `true` to add a checkbox for selecting all rows. The checkbox shows an indeterminate state when some rows are selected.

<FileSource src="/framed/DataTable/DataTableBatchSelection" />

## Batch selection with initial selected rows

Use `selectedRowIds` to specify initially selected rows.

<FileSource src="/framed/DataTable/DataTableBatchSelectionInitial" />

## Batch selection with batch actions toolbar

Add a toolbar for batch actions when rows are selected.

<FileSource src="/framed/DataTable/DataTableBatchSelectionToolbar" />

## Batch selection with controlled toolbar

Control the batch actions toolbar with the `active` prop. Prevent default cancel behavior in the `on:cancel` event.

<FileSource src="/framed/DataTable/DataTableBatchSelectionToolbarControlled" />

## Selectable rows (radio)

Set `radio` to `true` for single-row selection. Bind to `selectedRowIds` to track the selected row. Use `inputName` to customize radio button names.

<FileSource src="/framed/DataTable/RadioSelectableDataTable" />

## Non-selectable rows

Use `nonSelectableRowIds` to prevent selection of specific rows.

<FileSource src="/framed/DataTable/DataTableNonSelectableRows" />

## Expandable rows

Set `expandable` to `true` to make rows expandable. Use the `expanded-row` slot to customize expanded content.

<DataTable expandable
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
>
  <svelte:fragment slot="expanded-row" let:row>
    <pre>{JSON.stringify(row, null, 2)}</pre>
  </svelte:fragment>
</DataTable>

## Non-expandable rows

Use `nonExpandableRowIds` to prevent expansion of specific rows.

<FileSource src="/framed/DataTable/DataTableNonExpandableRows" />

## Expandable (zebra styles)

Combine expandable rows with zebra striping.

<FileSource src="/framed/DataTable/DataTableExpandableZebra" />

## Expandable (compact size)

Set `size="compact"` for expandable rows with minimal height.

<DataTable size="compact" expandable
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
>
  <svelte:fragment slot="expanded-row" let:row>
    <pre>{JSON.stringify(row, null, 2)}</pre>
  </svelte:fragment>
</DataTable>

## Expandable (short size)

Set `size="short"` for expandable rows with compact height.

<DataTable size="short" expandable
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
>
  <svelte:fragment slot="expanded-row" let:row>
    <pre>{JSON.stringify(row, null, 2)}</pre>
  </svelte:fragment>
</DataTable>

## Expandable (tall size)

Set `size="tall"` for expandable rows with increased height.

<DataTable size="tall" expandable
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
>
  <svelte:fragment slot="expanded-row" let:row>
    <pre>{JSON.stringify(row, null, 2)}</pre>
  </svelte:fragment>
</DataTable>

## Batch expansion

Set `batchExpansion` to `true` to expand and collapse all rows at once.

<DataTable batchExpansion
  headers="{[
    { key: "name", value: "Name" },
    { key: "protocol", value: "Protocol" },
    { key: "port", value: "Port" },
    { key: "rule", value: "Rule" }
  ]}"
  rows="{[
    {
      id: "a",
      name: "Load Balancer 3",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "b",
      name: "Load Balancer 1",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "c",
      name: "Load Balancer 2",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
    {
      id: "d",
      name: "Load Balancer 6",
      protocol: "HTTP",
      port: 3000,
      rule: "Round robin"
    },
    {
      id: "e",
      name: "Load Balancer 4",
      protocol: "HTTP",
      port: 443,
      rule: "Round robin"
    },
    {
      id: "f",
      name: "Load Balancer 5",
      protocol: "HTTP",
      port: 80,
      rule: "DNS delegation"
    },
  ]}"
>
  <svelte:fragment slot="expanded-row" let:row>
    <pre>{JSON.stringify(row, null, 2)}</pre>
  </svelte:fragment>
</DataTable>

## Expandable and selectable rows

Combine `batchExpansion` and `batchSelection` for tables with both expandable and selectable rows.

<FileSource src="/framed/DataTable/DataTableExpandableSelectable" />

## Skeleton

Use `DataTableSkeleton` to show a loading state.

<DataTableSkeleton />

## Skeleton with headers, row count

Specify headers and row count for the skeleton.

<DataTableSkeleton headers={["Name", "Protocol", "Port", "Rule"]} rows={10} />

## Skeleton with object headers

Pass header objects to customize the skeleton.

<DataTableSkeleton headers={[{ value: "Name" }, {value: "Protocol"}, {value:"Port"}, { value: "Rule"}]} rows={10} />

## Skeleton with empty header

Add an empty header column with `empty: true`.

<DataTableSkeleton headers={[{ value: "Name" }, {value: "Protocol"}, {value:"Port"}, { value: "Rule"}, { empty: true }]} rows={10} />

## Skeleton without header, toolbar

Hide the header and toolbar in the skeleton.

<DataTableSkeleton showHeader={false} showToolbar={false} />

## Skeleton (tall size)

Set `size="tall"` for a taller skeleton.

<DataTableSkeleton showHeader={false} showToolbar={false} size="tall" />

## Skeleton (short size)

Set `size="short"` for a shorter skeleton.

<DataTableSkeleton showHeader={false} showToolbar={false} size="short" />

## Skeleton (compact size)

Set `size="compact"` for a minimal skeleton.

<DataTableSkeleton showHeader={false} showToolbar={false} size="compact" />