Slot
Merges its props onto a single child element, the Blazor approximation of asChild.
Forwarded onclick fired 0 times (the same props land on either element)
@* The consumer splats the merged dictionary onto ONE element they own. *@
<NaviusSlot Attributes="_forwarded">
@(attrs =>
@<a href="/home" @attributes="attrs">Home</a>)
</NaviusSlot>
@code {
// class + style merge; on* handlers compose with the child's own.
private IReadOnlyDictionary<string, object> _forwarded => new Dictionary<string, object>
{
["class"] = "text-primary underline",
["onclick"] = EventCallback.Factory.Create<MouseEventArgs>(this, OnNavigate),
};
}Features
- Renders no element of its own; the forwarded props land on the consumer's single child element.
- Merges
class/className(concatenated) andstyle(per CSS property) instead of overwriting. - Composes colliding
on*event handlers: the child handler runs first, then the forwarded one. Neither is dropped. - Used internally by primitives that need to project behaviour onto an arbitrary element you control.
Installation
Install the brain, or copy just this primitive in with the CLI.
navius add slotAnatomy
Pass the props to forward via Attributes, then splat the merged dictionary onto exactly one root element.
@using Navius.Primitives.Components.Slot
<NaviusSlot Attributes="@props">
@(attrs =>
@<button @attributes="attrs">Click me</button>)
</NaviusSlot>API Reference
Root
Renders no element of its own. It merges Attributes (plus any attributes splatted directly onto it) and invokes ChildContent with the resulting read-only dictionary.
| Prop | Type | Default |
|---|---|---|
| Attributes | IReadOnlyDictionary<string, object>? | - |
| UnmatchedAttributes | IDictionary<string, object>? | - |
| ChildContent | RenderFragment<IReadOnlyDictionary<string, object>>? | - |
Slot has no element to mark, so it renders no data attributes. The merge it performs is summarized below:
| Data attribute | Values |
|---|---|
| class / className | Normalized to one class attribute and concatenated (space separated). |
| style | Merged per CSS property; the child's value wins per property, no duplicate declarations. |
| on* handlers | Composed: the child handler runs first, then the forwarded handler. Never dropped. |
| everything else | Last-wins: attributes splatted onto <NaviusSlot> override the forwarded Attributes. |
Limitation
A true 1:1 port of the spec's Slot is not possible in Blazor: a RenderFragment does not expose its child element's props, so Slot cannot reach in and rewrite them. Instead, the consumer is handed the merged dictionary and must splat it onto a single root element with @attributes. Splatting onto more than one element, or forgetting to splat, means the forwarded props are silently lost.
Accessibility
Slot is a composition utility with no semantics or keyboard behaviour of its own; it adds nothing and removes nothing. Accessibility is governed entirely by the element you splat onto and the props you forward: keep ARIA roles, tabindex, and event handlers on the rendered element, and Slot will merge rather than clobber them.