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-component-catalog

v2.1.1

Published

Manage a catalog (registry) of react-components easily.

Downloads

434

Readme

React-Component-Catalog

npm version Build Status Coverage Status GitHub license

Dependencies Known Vulnerabilities Commitizen friendly lerna

React-Component-Catalog is a library for individually registering, retrieving, and rendering React components based on your own conditions (eg. different component for various clients, sites, ...).

Getting started

npm i react-component-catalog --save

# or
yarn add react-component-catalog

Then install the correct versions of each peerDependency package, which are listed by the command:

npm info "react-component-catalog@latest" peerDependencies

If using npm 5+, use this shortcut:

npx install-peerdeps --dev react-component-catalog

# or
yarn add react-component-catalog -D --peer

Upgrade from 1.x.x to 2.0.0

Catalog Data Structure changes

When upgrading to 2.0.0, one needs to change the Catalog's data structure.

// catalog.js
- import { Catalog } from 'react-component-catalog'
import Button from './button'

-const catalog = new Catalog({
-  components: {
-    Button,
-  },
-})
+const catalog = {
+  Button,
+)

export default catalog

CatalogProvider changes

Previously, CatalogProvider rendered it's children with an empty catalog, when none was provided. In 2.x it renders null instead. Same happens, when no child component is provided.

import { CatalogProvider } from 'react-component-catalog'
import catalog from './catalog' // your apps catalog

const App = () => (
- <CatalogProvider catalog={new Catalog({ components: catalog })}>
+ <CatalogProvider catalog={catalog}>
    <div>Hello</div>
  </CatalogProvider>
)

CatalogProvider accepts an object and no instance of Catalog anymore.

useCatalog and catalog changes

getComponent does not return null anymore when a component is not found, instead it returns undefined.

import React from 'react'
import CatalogComponent, { useCatalog } from 'react-component-catalog'

const App = () => {
- const { catalog } = useCatalog()
+ const catalog = useCatalog()

- console.log('available components', catalog._components)
+ console.log('available components', catalog._catalog)

  const Button = catalog.getComponent('Button')

  // ...
}

Catalog changes

Catalog is not exported anymore, so code like does not work anymore:

- import { Catalog } from 'react-catalog-component'

CatalogComponent and Module Augmentation

The CatalogComponents interface can be augmented to add more typing support.

// react-component-catalog.d.ts
declare module 'react-component-catalog' {
  export interface CatalogComponents {
    Title: React.FunctionComponent<{}>
  }
}

Whenever you use the CatalogComponent now you can do the following to get full typing support (opt-in feature). When you do not provide the interface, any string, string[] or Record<string, any> value for component is allowed.

const App = () => (
  <CatalogComponent<CatalogComponents> component="Title">
    Hello World
  </CatalogComponent>
)

// this works too, but `component` has no typing support
const App = () => (
  <CatalogComponent component="Title">Hello Base</CatalogComponent>
)

Attention: it is recommended to use CatalogComponents only when it was augmented. Because it represents an empty interface and without adding your own custom properties it will match everything.

Basic Usage

Create a Catalog

// button.js
import React from 'react'

const Button = props => <button>{props.children}</button>

export default Button
// catalog.js
import Button from './button'

const catalog = {
  Button,
}

export default catalog

Create a nested Catalog

It is also possible to add a nested components-object to the Catalog. This allows registering variations of a component. Take an article for instance. You might want to register different types of the component. There might be a AudioArticle, VideoArticle and a BaseArticle component you want to use. You can add them to the catalog like this:

// catalog.js
// different types of articles
import AudioArticle from './audio-article'
import BaseArticle from './base-article'
import VideoArticle from './video-article'

const catalog = {
  ArticlePage: {
    AudioArticle,
    BaseArticle,
    VideoArticle,
  },
}

export default catalog

And you could later use it like this:

// app.js
import React from 'react'
import CatalogComponent, { useCatalog } from 'react-component-catalog'

const App = props => {
  const { isAudioArticle, isVideoArticle } = props
  const catalog = useCatalog()

  // get the ArticlePage object from the catalog
  const ArticlePage = catalog.getComponent('ArticlePage')

  // or get them one by one with one of the following methods
  // const BaseArticle = catalog.getComponent('ArticlePage.BaseArticle')
  // <CatalogComponent component="ArticlePage.BaseArticle" />

  if (isAudioArticle) {
    return <ArticlePage.AudioArticle {...props} />
  }

  if (isVideoArticle) {
    return <ArticlePage.VideoArticle {...props} />
  }

  return <ArticlePage.BaseArticle {...props} />
}

export default App

Create a CatalogProvider

// index.js
import React from 'react'
import ReactDOM from 'react-dom'

import { CatalogProvider } from 'react-component-catalog'
import catalog from './catalog'
import App from './app'

ReactDOM.render(
  <CatalogProvider catalog={catalog}>
    <App />
  </CatalogProvider>,
  document.getElementById('_root'),
)

Nesting CatalogProvider

<CatalogProvider /> can be nested, whereas the inner provider will extend and overwrite the parent provider.

// setup catalogs
const catalog = {
  OuterComponent: () => <div>OuterComponent</div>,
  Title: ({ children }) => <h1>OuterTitle - {children}</h1>,
}

const innerCatalog = {
  InnerComponent: () => <div>InnerComponent</div>,
  Title: ({ children }) => <h2>InnerTitle - {children}</h2>, // inner CatalogProvider overwrites Title of the outer catalog
}

// usage
const App = () => (
  <CatalogProvider catalog={catalog}>
    <CatalogProvider catalog={innerCatalog}>
      <Content />
    </CatalogProvider>
  </CatalogProvider>
)

<Content /> can access components inside the catalog and innerCatalog. If the innerCatalog contains a component with the same name than in the catalog it will overwrite it. In this case <Title /> gets overwritten in the inner provider.

Import and use the catalog (with react-hooks)

// app.js
import React from 'react'
// useCatalog is a react-hook
import CatalogComponent, { useCatalog } from 'react-component-catalog'

const App = () => {
  const catalog = useCatalog()
  const Button = catalog.getComponent('Button')

  // you can also first check if it exists
  const hasButton = catalog.hasComponent('Button')

  // or you use them with the <CatalogComponent /> component
  return (
    <div>
      <CatalogComponent component="Title">Hello Client1</CatalogComponent>
      <CatalogComponent
        component="Card"
        {/* the fallbackComponent can either be a new component, or a component
          from the catalog */}
        fallbackComponent={() => <div>Component not found</div>}
        { /* fallbackComponent="FallbackComponent" */ }
      >
        Hello Card
      </CatalogComponent>
      {Button && <Button />}
    </div>
  )
}

export default App

Use catalog with ref

Refs provide a way to access DOM nodes or React elements created in the render method. (Source: reactjs.org)

It is possible to use react-component-catalog with ref as well. It would look similar to (works also with <CatalogComponent />):

const TestComponent = withCatalog(props => (
  <button {...props} type="button">
    Hello Button
  </button>
))

/* eslint-disable react/no-multi-comp */
class App extends React.Component {
  constructor(props) {
    super(props)
    this.setRef = React.createRef()
  }

  render() {
    // or <CatalogComponent component="TestComponent" ref={this.setRef} />
    return (
      <CatalogProvider catalog={{ TestComponent }}>
        <TestComponent ref={this.setRef} />
      </CatalogProvider>
    )
  }
}

How to build and test this package

# -- build the package --
yarn
yarn build
# -- test the package in an example app --
# run the example in watch-mode
yarn watch

# or run the example in production mode
cd packages/example
yarn build
yarn start

How to release and publish the package

This package uses standard-version and commitizen for standardizing commit messages, release tags and the changelog.

When you're ready to release, execute the following commands in the given order:

  1. git checkout master
  2. git pull origin master
  3. yarn release:prepare: select the proper version
  4. yarn release --release-as <version>: use the version selected before (e.g. beta releases: yarn release --prerelease beta --release-as major)
  5. git push --tags
  6. cd packages/react-component-catalog && yarn publish: do not select a new version.

TODO: automate and optimize scripts, see 3ba95ec and 2eb2a8b

Links

Credits

Inspired by Building a Component Registry in React by Erasmo Marín. I did not find a package implementing his thoughts and ideas in such a straightforward way. That is why, I decided to create it.

Licence

Apache 2.0

Maintainers