Skip to content

Calico v0.4: Polymorphic Components

Calico v0.4 introduces true typed polymorphic components with the help of react-polymorphic-box.

Senior Developer
Oct 2, 2020

Calico is our atomic CSS-in-JS library built on top of treat and, now, @kripod’s react-polymorphic-box. If you’re not familiar with Calico, check out its introduction post for a background on why it exists and its benefits.

Calico v0.4.0 was just published with the new ability to define the component rendered by the <Box> component. While <Box> always supported setting the HTML element to render using the component prop, and technically did support providing a React component, it did not properly update the component’s TypeScript props.

import * as React from 'react' import { Box } from '@walltowall/calico' type FooProps = { bar: string } const Foo = ({ bar }: FooProps) => <span>{bar}</span> // Before v0.4.0 const App = () => <Box as={Foo} /> // No error // v0.4.0 const App = () => <Box as={Foo} /> // Type error: missing prop `bar`

In this example, we want TypeScript to tell us we forgot to add the required bar prop. We now have that capability thanks to some clever typing done by react-polymorphic-box.

You may have noticed we’re using the as prop now instead of component. This change was made to align with the as prop convention popularized by styled-components and is more likely to be what users expect.

Deprecating the component prop

The component prop is now deprecated. You will get a console warning only during development to update your components to the as prop. This is just a prop rename and should not require any logic changes. With the new typing capabilities, however, you may see additional TypeScript errors that were previously hidden.

# Replace instances of `component` with `as`: <Box - as={Foo} + as={Foo} {...props} />

Reporting bugs

If you encounter any bugs while using Calico, be sure to open an issue or submit a pull request on GitHub. We’re also happy to review any ideas or feedback you have to make Calico even better.