# Design: Content Patterns
## DataTable Component
### `src/lib/components/common/DataTable.svelte`
```svelte
{#if loading}
{:else if isEmpty}
{:else}
{#each $table.getHeaderGroups() as headerGroup}
{#each headerGroup.headers as header}
|
{header.column.columnDef.header}
{#if header.column.getCanSort()}
{#if $sorting.find(s => s.id === header.column.id)?.desc === true}
{:else if $sorting.find(s => s.id === header.column.id)?.desc === false}
{:else}
{/if}
{/if}
|
{/each}
{/each}
{#each rows as row}
onRowClick?.(row.original)}
>
{#each row.getVisibleCells() as cell}
|
{@html cell.renderCell()}
|
{/each}
{/each}
{/if}
```
---
## FilterBar Component
### `src/lib/components/common/FilterBar.svelte`
```svelte
onSearchChange?.(e.currentTarget.value)}
/>
{#if children}
{@render children()}
{/if}
{#if hasFilters}
{/if}
```
---
## EmptyState Component
### `src/lib/components/common/EmptyState.svelte`
```svelte
{title}
{description}
{#if children}
{@render children()}
{/if}
```
---
## LoadingState Component
### `src/lib/components/common/LoadingState.svelte`
```svelte
{#if type === 'table'}
{#each Array(columns) as _}
{/each}
{#each Array(rows) as _}
{#each Array(columns) as _}
{/each}
{/each}
{:else if type === 'card'}
{:else if type === 'list'}
{#each Array(rows) as _}
{/each}
{:else}
{/if}
```
---
## File Structure
```
src/lib/components/common/
├── DataTable.svelte # NEW
├── FilterBar.svelte # NEW
├── EmptyState.svelte # NEW
├── LoadingState.svelte # NEW
└── StatCard.svelte # (from p03)
```
---
## Usage Examples
### DataTable Usage
```svelte
navigate(`/team-members/${row.id}`)}
/>
```
### FilterBar Usage
```svelte
search = v}
>
```