Kobalte.v0.12.5

Polymorphism

All component parts that render a DOM element have an as and a asChild prop.

The as prop

For simple use cases the as prop can be used, either with native HTML elements or custom Solid components:

tsx
import { Tabs as KTabs } from "@kobalte/core";
import { MyCustomButton } from "./components";
function App() {
return (
<KTabs.Root>
<KTabs.List>
{/* Render an anchor tag instead of the default button */}
<KTabs.Trigger value="one" as="a">
A Trigger
</KTabs.Trigger>
{/* Render MyCustomButton instead of the default button */}
<KTabs.Trigger value="one" as={MyCustomButton}>
Custom Button Trigger
</KTabs.Trigger>
</KTabs.List>
<KTabs.Content value="one">Content one</KTabs.Content>
</KTabs.Root>
);
}
tsx
import { Tabs as KTabs } from "@kobalte/core";
import { MyCustomButton } from "./components";
function App() {
return (
<KTabs.Root>
<KTabs.List>
{/* Render an anchor tag instead of the default button */}
<KTabs.Trigger value="one" as="a">
A Trigger
</KTabs.Trigger>
{/* Render MyCustomButton instead of the default button */}
<KTabs.Trigger value="one" as={MyCustomButton}>
Custom Button Trigger
</KTabs.Trigger>
</KTabs.List>
<KTabs.Content value="one">Content one</KTabs.Content>
</KTabs.Root>
);
}

The asChild prop

For more advanced use cases the asChild prop and the <As> component can be used. The main reason to use asChild over the as prop is being able to set props without interfering with Kobalte.

When using this pattern the following rules apply to the component with the asChild prop, and it's child <As> component:

  • CSS classes are combined.
  • Props are combined, if same attribute exists the one from <As> win.
  • Event handlers are chained, the one from <As> get called first.
tsx
import { As, Tabs as KTabs } from "@kobalte/core";
import { MyCustomButton } from "./components";
function App() {
return (
<KTabs.Root>
<KTabs.List>
{/* The `value` prop is used by Kobalte and not passed to MyCustomButton */}
<KTabs.Trigger value="one" as={MyCustomButton}>
A Trigger
</KTabs.Trigger>
{/* The `value` prop is used by Kobalte and not passed to MyCustomButton */}
<KTabs.Trigger value="one" asChild>
{/* The `value` prop is directly passed to MyCustomButton */}
<As component={MyCustomButton} value="custom">
Custom Button Trigger
</As>
</KTabs.Trigger>
</KTabs.List>
<KTabs.Content value="one">Content one</KTabs.Content>
</KTabs.Root>
);
}
tsx
import { As, Tabs as KTabs } from "@kobalte/core";
import { MyCustomButton } from "./components";
function App() {
return (
<KTabs.Root>
<KTabs.List>
{/* The `value` prop is used by Kobalte and not passed to MyCustomButton */}
<KTabs.Trigger value="one" as={MyCustomButton}>
A Trigger
</KTabs.Trigger>
{/* The `value` prop is used by Kobalte and not passed to MyCustomButton */}
<KTabs.Trigger value="one" asChild>
{/* The `value` prop is directly passed to MyCustomButton */}
<As component={MyCustomButton} value="custom">
Custom Button Trigger
</As>
</KTabs.Trigger>
</KTabs.List>
<KTabs.Content value="one">Content one</KTabs.Content>
</KTabs.Root>
);
}