# Composability Every Rokkit component exposes named **snippet slots**. Pass a snippet to replace any part of the component's rendering — item content, group headers, empty states — without forking the component or fighting with CSS overrides. ## Why snippets, not slots Svelte 5 snippets are the clean equivalent of render props or named slots from earlier eras. They keep your customization logic co-located with your usage, not inside the library, and they receive **strongly-typed arguments** (the item proxy, the index, etc.) so customization is type-safe. The library handles data logic, keyboard navigation, and ARIA; you control the pixels. ## itemContent — replace the inside of a row The most common snippet is `itemContent`. Every selection component (`List`, `Menu`, `Tree`, `Select`, `Grid`) accepts it. The snippet receives a `ProxyItem` you can read fields off: ```svelte {#snippet itemContent(proxy)} {proxy.label} {proxy.get('role')} {/snippet} ``` The component still renders the row wrapper (the ` {/snippet} ``` Per-item snippets fall back to `itemContent` if the named snippet isn't defined, so you can introduce them progressively. ## Layout-level snippets Some components expose snippets for chrome around the rows: | Snippet | Component | Purpose | | --- | --- | --- | | `crumb` | BreadCrumbs | Replace each crumb's content | | `slide` | Carousel | Render slide `i` of `count` | | `tag` | SearchFilter | Custom filter chip styling | | `content` | UploadTarget / Timeline | Drop-zone body / per-step extra | | `header` / `footer` | Card | Top + bottom zones inside the card | | `tooltipContent` | Tooltip | Rich bubble body | ## Snippets receive ProxyItem, not your raw data The `proxy` argument is a thin reactive wrapper around your row. Use `proxy.label`, `proxy.value`, `proxy.get('field')` — those resolve via your `fields` mapping, so the snippet keeps working when you rename source keys.