Homelogologo
Sponsor

Composition

Create adaptable user interfaces using component composition techniques.

Elemnts UI components are built with flexibility in mind, giving you two powerful ways to customize how components render: the as prop and the asChild prop. Both are powered by Ark UI.

Changing the HTML Element

The as prop lets you swap out the default HTML element while keeping all the component's styles and functionality intact.

import { Text } from "@elemnts-ui/react"; <Text as="h1">This renders as an H1 tag</Text> <Text as="span">This renders as a span</Text>

When to use as:

  • Need a different semantic HTML element (e.g., turning a p into a span)
  • Want to maintain styling while changing the underlying tag

Composing Components

The asChild prop is perfect when you want to wrap Elemnts UI components around custom components—like framework-specific links (TanStack Router, Next.js Link) or your own UI elements.

When enabled, asChild passes all props and behavior to its direct child, effectively making the Elemnts UI component invisible in the DOM.

import { Button } from "@elemnts-ui/react"; import { Link } from "@tanstack/react-router"; <Button asChild> <Link to="/about">About Us</Link> </Button>

Key Rules for asChild

RuleDescription
Single ChildOnly one child element is allowed inside the component.
Prop MergingIf both parent and child define the same prop (e.g., onClick), both functions will execute.
Ref ForwardingThe child component must support ref forwarding to ensure compatibility with Ark UI.

Building Your Own Components

Elemnts UI provides factory and styled to help you create polymorphic, styled components.

Using factory (Ark UI)

The factory (aliased from ark) lets you generate HTML elements that natively support the asChild prop.

import { factory } from "@elemnts-ui/react"; const MyComponent = factory.div; <MyComponent asChild> <button>Click me</button> </MyComponent>

Using styled

The styled function combines an element (or factory element) with a Panda CSS recipe or styles.

import { styled, factory } from "@elemnts-ui/react"; import { myRecipe } from "../styled-system/recipes"; const MyStyledComponent = styled(factory.div, myRecipe);

Custom Prop Filtering

By default, styled excludes style-related props from the DOM. You can override this with shouldForwardProp.

import { styled } from "@elemnts-ui/react"; const CustomBox = styled("div", {}, { shouldForwardProp: (prop) => !prop.startsWith("$"), });

Best Practices

Use CasePropWhy?
Swapping HTML elements (e.g., p → span)asSimple and effective for semantic changes
Wrapping framework-specific components (e.g., Router Link)asChildEnsures compatibility with custom logic
Maintaining accessibilityBothAlways verify ARIA roles and keyboard interactions when changing elements (e.g., as="button" on a div)