Back to Mantine

Polymorphic In Polymorphic

apps/help.mantine.dev/src/pages/q/polymorphic-in-polymorphic.mdx

9.5.22.1 KB
Original Source

import { Layout } from '@/layout';

export const meta = { title: 'Why can I not use one polymorphic component in the component prop of another polymorphic component?', description: 'Learn how polymorphic components types work', slug: 'polymorphic-in-polymorphic', category: 'components', tags: ['component', 'renderRoot'], created_at: 'July 25, 2024', last_updated_at: 'July 25, 2024', };

export default Layout(meta);

What is polymorphic component?

A polymorphic component is a component which root element can be changed with component prop. All polymorphic components have a default element which is used when component prop is not provided. For example, the Button component default element is button and it can be changed to a or any other element or component:

tsx
import { Button } from '@mantine/core';

function Demo() {
  return (
    <Button component="a" href="https://mantine.dev/" target="_blank">
      Mantine website
    </Button>
  );
}

Polymorphic components types

Polymorphic components types are defined by the type of the root element which is not known until the component is used.

Example:

tsx
import { Box } from '@mantine/core';

// MyBox component props types are now known
// Types will be assigned only when MyBox is used
const MyBox = Box;

function Demo() {
  // MyBox props type can be determined based on
  // `component` prop or its absence
  // In this case MyBox props type contain
  // React.ComponentProps<'div'>
  return <MyBox>Hello</MyBox>;
}

function Demo2() {
  // In this case MyBox props type contain
  // React.ComponentProps<'a'>
  return <MyBox component="a" href="https://mantine.dev/" />;
}

Why I cannot use one polymorphic component in component prop of another polymorphic component?

When you use one polymorphic component in component prop of another polymorphic component, types cannot be inferred correctly because the type of the root element is not known until the component is used.

tsx
import { Box, Button } from '@mantine/core';

function Demo() {
  // Types cannot be inferred correctly
  return <Box component={Button} />;
}