Composition
Learn how to compose default components with custom elements
The asChild Prop
In Ark Ripple, asChild lets you integrate custom components, ensuring consistent styling and behavior while
promoting flexibility and reusability. All Ark components that render a DOM element accept asChild.
Here's an example using asChild to integrate a custom Button component within a Popover:
import { Popover } from 'ark-ripple/popover';
export component AsChild() {
<Popover.Root>
<Popover.Trigger
asChild={component(propsFn) {
<button {...propsFn()}>{'Open Popover'}</button>
}}
/>
<Popover.Positioner>
<Popover.Content>{'Content'}</Popover.Content>
</Popover.Positioner>
</Popover.Root>
}In this example, asChild allows the Button to be used as the trigger for the Popover, inheriting its
behaviors from Popover.Trigger.
The Ark Factory
You can use the ark factory to create your own elements that work just like Ark Ripple components.
import { ark } from 'ark-ripple/factory';
export component Factory() {
<ark.span
asChild={component(propsFn) {
<a {...propsFn()} href="#">{'Ark UI'}</a>
}}
/>
}This will produce the following HTML:
<span id="child" class="parent child" style="background: red; color: blue;">Ark UI</span>
ID Composition
When composing components that need to work together, share IDs between them using the ids prop for proper
accessibility and interaction.
import { Avatar } from 'ark-ripple/avatar'
import { Tooltip } from 'ark-ripple/tooltip'
export component TooltipWithAvatar() {
const id = ':ark-avatar'
<Tooltip.Root ids={{ trigger: id }}>
<Tooltip.Trigger>
component asChild({ propsFn }){
<Avatar.Root {...propsFn({ ids: { root: id } })}>
<Avatar.Image src="https://bit.ly/sage-adebayo" />
<Avatar.Fallback>{"SA"}</Avatar.Fallback>
</Avatar.Root>
}
</Tooltip.Trigger>
<Tooltip.Positioner>
<Tooltip.Content>{"Abraham Aremu is online"}</Tooltip.Content>
</Tooltip.Positioner>
</Tooltip.Root>
}
Both components share the same id through their ids props, creating proper accessibility bindings, aria-*
attributes and interaction behavior.
Limitations
Certain components, such as Checkbox.Root or RadioGroup.Item, have specific requirements for their child elements.
For instance, they may require a label element as a child. If you change the underlying element type, ensure it remains
accessible and functional.