npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-as

v1.0.3

Published

Render react components as other components.

Downloads

8

Readme

Alt text

Why?

While developing with react I've experienced the need to adjust the tag or element type of my components. This was especially needed if I wanted the appearance of one component but the functionality of an other. Like rendering a Link as a Button, the link should have the functionality (and markup) of the Link component but the appearance of the Button component.

How was this solved until now?

The solution was to introduce an component, tag or as property to the components which had the appearance but not the functionality. In the Link and Button example the Button would receive such an property. Many popular libraries are doing like this: MUI, Ant Design, react-bootstrap. The problem is that if more components should receive the functionality of the Link component, the property needs to be re-implement over and over again for each component. And this is where react-as comes in! Not only can react-as replicate the current solution without re-implementing it over and over again, its also possible to give the Link component the as prop instead of the Button.

Usage

The package comes with the As react component and the transform function. Both are exactly the same, but you can choose when to use what.

import As, { transform } from "react-as";
import { Link } from "react-router-dom";
import Button from "./Button";

// with <As /> component
const MyComponent = () => (
  <As
    component={<Button theme="primary">Button</Button>}
    as={<Link to="/home" />}
  />
);

// with transform function
const MyComponent = () =>
  transform(<Button theme="primary">Button</Button>, <Link to="/home" />);

How does it work?

JSX elements have a type called ElementType or ComponentType. This type is required and is always defined. This type can be split into 3 categories:

  1. intrinsic type for elements like div, p, a etc.
  2. exotic type for special react elements like Fragment, Context, Memo etc.
  3. custom type for your own Components

Simply put the library traverses the root elements of your components until it encounters a intrinsic element, because this means this is the element which most likely should be transformed. It creates a new custom render function where it changes the type of this element to your desired as component type.

If during the traversal no intrinsic element type could be found, the transformation is considered unsuccessful and you can decide with the strategy option how to handle the case.

API

As already mentioned, the package has two main functions:

  1. The As react component. (default and named export)
  2. The transform function. (named export only)

Both are doing exactly the same. The As component is just a wrapper for the transform function.

As Component Props

All props are optional and can be null or undefined as well.

Options

The options object gives you more control of the transformation process.

OverwriteProps

This functions allows you to control which properties are passed to the transformed component. The function takes the componentProps as its first argument, the "as" component props as its second argument and should return an tuple which represents the overwritten props.

The simplified typescript type declaration is:

type OverwriteProps<CompProps, AsProps> = (
  compProps: CompProps,
  asProps: AsProps
) => [CompProps, AsProps];

Types

The package comes with the InputComponentProps helper type which is here to help you write a correctly typed OverwriteProps function. Because typescript can't interfere the type of a JSX.Element you have to do it yourself, For all other cases the OverwriteProps can interfere the correct props type for you automatically.

import As, { InputComponentProps }  from 'react-as';

<As
  component={<div>Div as Paragraph</div>}
  as={<MyComponent />}
  options={{
    overwriteProps: (componentProps: InputComponentProps<'div'>, asProps: InputComponentProps<typeof MyComponent>) => [componentProps, asProps],
  }}
/>

In the example above I'm using the InputComponentProps helper type to get the correct props type for the two components I'm transforming.

License

MIT