# Child Snippet Documentation

Learn how to use the `child` snippet to render your own elements.

This is a documentation section that potentially contains examples, demos, and other useful information related to a specific part of Bits UI. When helping users with this documentation, you can ignore the classnames applied to the demos unless they are relevant to the user's issue.

The `child` snippet is a powerful feature that gives you complete control over the rendered elements in Bits UI components, allowing for customization while maintaining accessibility and functionality.

## When to Use It

You should use the `child` snippet when you need:

- Svelte-specific features like transitions, animations, actions, or scoped styles  
- Integration with custom components in your application  
- Precise control over the DOM structure  
- Advanced composition of components ## Basic Usage

Many Bits UI components have default HTML elements that wrap their content. For example, `Accordion.Trigger` renders a `<button>` element by default:

```svelte
<button {...props}>
 {@render children()}
</button>
```

When you need to customize this element, the `child` snippet lets you take control:

```svelte
<script lang="ts">
 import MyCustomButton from "$lib/components";
 import { Accordion } from "bits-ui";
</script>
<Accordion.Trigger>
 {#snippet child({ props })}
  <MyCustomButton {...props}>Toggle Item</MyCustomButton>
 {/snippet}
</Accordion.Trigger>

<Accordion.Trigger>
 {#snippet child({ props })}
  <button {...props} class="scoped-button">Toggle Item</button>
 {/snippet}
</Accordion.Trigger>
<style>
 .scoped-button {
  background-color: #3182ce;
  color: #fff;
 }
</style>
```

In this example:

- The `props` parameter contains all necessary attributes and event handlers
- The `{...props}` spread applies these to your custom element/component
- You can add scoped styles, transitions, actions, etc. directly to the element ## How It Works

When you use the `child` snippet:

1. 
   The component passes all internal props and your custom props passed to the component via the `props` snippet parameter
2. 
   You decide which element receives these props
3. 
   The component's internal logic continues to work correctly

### Behind the Scenes

Components that support the `child` snippet typically implement logic similar to:

```svelte
<script lang="ts">
 // Bits UI component internal logic
 let { child, children, ...restProps } = $props();
 const trigger = makeTrigger();
 // Merge internal props with user props
 const mergedProps = $derived(mergeProps(restProps, trigger.props));
</script>
{#if child}
 {@render child({ props: mergedProps })}
{:else}
 <button {...mergedProps}>
  {@render children?.()}
 </button>
{/if}
```

## Working with Props

### Custom IDs & Attributes

To use custom IDs, event handlers, or other attributes, pass them to the component first:

```svelte
<Accordion.Trigger
 id="my-custom-id"
 data-testid="accordion-trigger"
 onclick={() => console.log("clicked")}
>
 {#snippet child({ props })}
  <button {...props}>Open accordion item</button>
 {/snippet}
</Accordion.Trigger>
```

The `props` object will now include:

- Your custom ID ( `id="my-custom-id"` )
- Your data attribute ( `data-testid="accordion-trigger"` )
- Your click event handler, properly merged with internal handlers  
- All required ARIA attributes and internal event handlers ## Combining with Svelte Features

You can apply Svelte-specific features to your custom elements, such as transitions, actions, and scoped styles:

```svelte
<Accordion.Trigger>
 {#snippet child({ props })}
  <div {...props} use:myCustomAction class="my-custom-trigger">
  </div>
 {/snippet}
</Accordion.Trigger>
<style>
 .my-custom-trigger {
  background-color: #3182ce;
  color: #fff;
 }
</style>
```

## Floating Components

Floating content components (tooltips, popovers, dropdowns, etc.) require special handling due to their positioning requirements.

### Required Structure

For floating components, you must use a two-level structure:

1. 
   An **outer wrapper element** with `{...wrapperProps}` 2. 
   An **inner content element** with `{...props}` ```svelte
<Popover.Content>
 {#snippet child({ wrapperProps, props, open })}
  {#if open}
   <div {...wrapperProps}>
    <div {...props}>
    </div>
   </div>
  {/if}
 {/snippet}
</Popover.Content>
```

### Important Rules for Floating Content

- The wrapper element with `{...wrapperProps}` must remain **unstyled**
- Positioning is handled by the wrapper element; styling goes on the inner content element  
- The `open` parameter lets you conditionally render the content, triggering Svelte transitions
- Always maintain this two-level structure to ensure proper positioning and behavior ### Components Requiring Wrapper Elements

The following components require a wrapper element:

- `Combobox.Content` - `DatePicker.Content` - `DateRangePicker.Content` - `DropdownMenu.Content` - `LinkPreview.Content` - `Menubar.Content` - `Popover.Content` - `Select.Content` - `Tooltip.Content` ## Examples

### Basic Custom Element

```svelte
<Collapsible.Trigger>
 {#snippet child({ props })}
  <button {...props}>
   <Icon name="star" />
   <span>Favorite</span>
  </button>
 {/snippet}
</Collapsible.Trigger>
```

### With Svelte Transitions

```svelte
<Dialog.Content>
 {#snippet child({ props, open })}
  {#if open}
   <div {...props} transition:scale={{ start: 0.95 }}>
    Dialog content with a scale transition
   </div>
  {/if}
 {/snippet}
</Dialog.Content>
```

### Floating Element Example

```svelte
<Tooltip.Content>
 {#snippet child({ wrapperProps, props, open })}
  {#if open}
   <div {...wrapperProps}>
    <div {...props} transition:fade>Custom tooltip content</div>
   </div>
  {/if}
 {/snippet}
</Tooltip.Content>
```

## Common Pitfalls

- **Missing props spread**: Always include `{...props}` on your custom element
- **Styling the wrapper**: Never style the wrapper element in floating components  
- **Direct children**: When using child, other children outside the snippet are ignored  
- **Missing structure**: For floating elements, forgetting the two-level structure will break positioning ## Related Resources

- [mergeProps](/docs/utilities/merge-props) Utility
- [Styling Guide](/docs/styling)  
- [Transitions Guide](/docs/transitions)