@walltowall/map-to-components
TypeScript icon, indicating that this package has built-in type declarations

2.0.0 • Public • Published

Map to Components

React component to map a list of data to specified React components. Useful when rendering data from external sources such as block content from a CMS.

Install

npm i @walltowall/map-to-components

Usage

MapToComponents takes a list of data and renders a list of components using a provided map. See below for an example:

import { MapToComponents } from "@walltowall/map-to-components"

import { HeroBlock } from "blocks/hero"
import { CallToActionBlock } from "blocks/CallToAction"

// List of blocks that probably comes from a CMS
const list = [
  { id: 1, type: "Hero", text: "Text for a Hero component" },
  { id: 2, type: "CallToAction", text: "Hey", buttonText: "Call Me" },
]

// For each item in the list, get a unique key using `getKey`. `getKey`
// should return a unique value for each item in the list such as an ID
// or UUID. This value will be used as the `key` prop when rendering the
// component.
function getKey(data) {
  return data.id
}

// For each item in the list, get a unique type using `getType`. `getType`
// should return a string that corresponds to a React component defined in the
// `map` prop.
function getType(data) {
  return data.type
}

// Provide a map whose keys map to React components.
const map = {
  Hero: HeroBlock,
  CallToAction: (props) => <CallToActionBlock text="Hello World!" {...props} />,
}

const App = () => (
  <MapToComponents getKey={getKey} getType={getType} list={list} map={map} />
)

Providing props to components

In the previous example, notice that an item with type CallToAction would render <CallToActionBlock> with the prop text="Hello World". By creating a new function component in map, you can provide default props to your components. This is in contrast to just passing a reference to a component, as is done with <HeroBlock>.

By default, no props except key are passed to components.

To pass props to the components using data derived from the object in the list, you can provide a mapDataToProps prop to MapToComponents.

<MapToComponents
  map={{
    Hero: HeroBlock,
    CallToAction: CallToActionBlock,
  }}
  mapDataToProps={{
    Hero: ({ data }) => ({ text: data.text }),
    CallToAction: ({ data }) => ({ buttonText: data.buttonText }),
  }}
/>

In the above exmaple, the <HeroBlock> component receives a text prop with the value data.text, where data is the element in the list that maps to the Hero type.

Each functoin in mapDataToProps has access to the current element, data about the element such as index, and data about sibling elements. See the mapDataToProps API for reference.

mapDataToContext

There may be times where you need to reference data from other elements in the list, such as the previous or next element, that influences the data you pass to your component.

Using just mapDataToProps, the only way to access a sibiling's derived data (i.e. data that is dynamically created, not statically available on the element) is to set it on mapDataToProp's return object. Since all values returned from mapDataToProps are passed to the element's component, this forces the contextual data to be passed to the component, which may be unwanted.

Data about the next element is also not available yet as the list is mapped synchronously.

Instead, you can provide a mapDataToContext prop to create contextual data about an element. This works exactly like mapDataToProps. The objects returned from the mapDataToContext functions are available to the mapDataToProps functions under the context properties.

Unlike mapDataToProps, data returned from mapDataToContext is not passed to the component automatically.

Each function in mapDataToProps has access to the current element, data about the element such as index, and data about sibling elements. See the mapDataToContext API for reference.

API

MapToComponents

  • getKey: (Function) Function that returns a unique key for an element in the list. Required.
  • getType: (Function) Function that returns the type for an element in the list. Required.
  • list: (Array): List of data. This can be an array containing mixed types.
  • map: (Object): Object mapping a data type to a React component to be rendered.
  • mapDataToProps: (Object) Object mapping a data type to a function returning props for the component to be rendered.
  • mapDataToContext: (Object) Object mapping a data type to a function returning contextual data for the element.
  • meta: (Any) Arbitrary data that is made available to functions in mapDataToProps and mapDataToContext.
  • default: (Component) Component to be rendered if an element type is not defined in map. This component always receives type as a prop.
  • defaultMapDataToProps: (Function) Function used to determine props for a type not defined in mapDataToProps.
  • defaultMapDataToContext: (Function) Function used to determine context for a type not defined in mapDataToContext.

mapDataToProps

Functions in the object passed to mapDataToProps and defaultMapDataToProps are provided an object as their only argument with the following properties:

General

  • list: (Array) List of elements.
  • keys: (Array) List of keys for each element in list.
  • types: (Array) List of types for each element in list.
  • comps: (Array) List of components for each element in list.
  • contexts: (Array) List of context values for each element in list.
  • map: (Object) Mapping of types to React components.
  • meta: (Any) Data provided to the meta prop.

Element

  • data: (Any) The current element.
  • index: (Integer) The index for the current element.
  • context: (Object) The context for the current element.
  • key: (Any) The key for the current element.
  • type: (String) The type for the current element.
  • Comp: (Component) The component for the current element.

Previous element

  • previousData: (Any) The previous element.
  • previousContext: (Object) The context for the previous element.
  • previousKey: (Any) The key for the previous element.
  • previousType: (String) The type for the previous element.
    • PreviousComp: (Component) The component for the previous element.

Next element

  • nextData: (Any) The next element.
  • nextContext: (Object) The context for the next element.
  • nextKey: (Any) The key for the next element.
  • nextType: (String) The type for the next element.
  • NextComp: (Component) The component for the next element.

mapDataToContext

Same signature as mapDataToProps. All context properties will be undefined and should not be used.

Development and Publishing

Tools

Publishing

This library uses GitHub Actions to automate publishing when changes are made to the main branch. To skip CI (GitHub action), add skip-ci to a commit message. To skip release a release, add skip-release to a commit message.

Ensure that the NPM_TOKEN secret in the GitHub repository is set with an appropriate token from npm.

License

MIT © Wall-to-Wall Studios

Readme

Keywords

none

Package Sidebar

Install

npm i @walltowall/map-to-components

Weekly Downloads

0

Version

2.0.0

License

MIT

Unpacked Size

21.6 kB

Total Files

6

Last publish

Collaborators

  • kalamak
  • walltowall-dev
  • angeloashmore
  • asyarb
  • kangken