JSPM

  • Created
  • Published
  • Downloads 32744
  • Score
    100M100P100Q149152F
  • License MIT

Utils to manage your React Children; find and filter children by type or custom function, enforce child content, and more!

Package Exports

  • react-nanny

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (react-nanny) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

react-nanny

Utils to manage your React Children; find and filter children by type or custom function, enforce child content, and more!

Hello friend. Have you ever had the need to:

  • ...query a set of React Children by type or otherwise?
  • ...reject and remove some of your children for whatever [judgement free] reason?
  • ...ensure that your children return content at some level?

If you answered yes to any of those questions, then it sounds like your children could use a nanny to help bring order to the chaos...

Version: 2.2.0

Installation

$ npm install react-nanny --save

Summary of Utils

For detailed information on each util, see below this table.

function Description
getChildGets first child by specified predicate
getChildDeepGets first child by specified predicate (deep search)
getChildByTypeGets first child by specified type
getChildByTypeDeepGets first child by specified type (deep search)
getChildrenGets all children by specified predicate
getChildrenDeepGets first child by specified predicate (deep search)
getChildrenByTypeGets all children by specified type
getChildrenByTypeDeepGets all children by specified type (deep search)
noEmptyChildrenDeepEnsure that there is some level of content and not just a bunch of empty divs, spans, etc (deep search)
removeChildrenRemoves all children by specified predicate
removeChildrenDeepRemoves all children by specified predicate (deep search)
removeChildrenByTypeRemoves all children by specified type
removeChildrenByTypeDeepRemoves all children by specified type (deep search)
typeOfComponentGets the string type of the component's {customTypeKey}, string type of the core html (JSX intrinsic) element, or the function type

What can I use to derive types for a comparison?

You can use an imported type, a React.ReactNode, value from typeOfComponent, a string type for an HTML (JSX Intrinsic) element, or a string representation of the type by using the customTypeKey feature.

Imported Type

import { getChildByType } from 'react-nanny';
import MyComponent from './MyComponent';

getChildByType(children, [MyComponent]);

React.ReactNode

import { getChildByType, removeChildrenByType } from 'react-nanny';
import MyComponent from './MyComponent';

const child = getChildByType(children, [MyComponent]);
...
removeChildrenByType(children, [child]);

typeOfComponent

import { getChildByType, removeChildrenByType, typeOfComponent } from 'react-nanny';
import MyComponent from './MyComponent';

const child = getChildByType(children, [MyComponent]);
...
removeChildrenByType(children, [typeOfComponent(child)]);

String type for HTML (JSX Intrinsic) Elements

import { getChildByType } from 'react-nanny';

getChildByType(children, ['div']);

customTypeKey

What the heck is a customTypeKey?

One simple way to be able to define and identify a type on a component and ensure that it is the same in development builds and production builds is to add a constant prop that contains the string type. Consider the following hypothetical component:

import React from 'react';

const Hello = ({ __TYPE }) => <div>Hello World!</div>;

Hello.defaultProps = {
  __TYPE: 'Hello',
};

The Hello has a prop __TYPE that has a value of 'Hello'. We can query against this value and know that it's reliable regardless of environment.

The customTypeKey in react-nanny defines what the name of this prop is. In our example, customTypeKey would be '__TYPE' to query using this technique

import { getChildByType } from 'react-nanny';

getChildByType(children, ['Hello']);

Let's say you don't like __TYPE and what to use your own value such as: CUSTOM. You can accomplish this by providing the name for the customTypeKey:

import { getChildByType } from 'react-nanny';

getChildByType(children, ['Hello'], { customTypeKey: 'CUSTOM' });

For more information on how to enforce the integrity of the customTypeKey, check out my Medium article: Find & Filter React Children By Type

Now, without further ado, the utils...


getChild<T=React.ReactNode>

Gets first child by specified predicate

Since v1.0.0

Param Type

children

JSX children
T

predicate

The predicate to determine if the given child is a match
(child: T) => boolean

Returns: {T} - The first matching child

Import

import { getChild } from 'react-nanny';

Examples

// Finds the first occurrence of a child that has a prop of 'active' set to true
getChild(children, child => child.props.active);

getChildDeep<T=React.ReactNode>

Gets first child by specified predicate (deep search)

Since v1.0.0

Param Type

children

JSX children
T

predicate

The predicate to determine if the given child is a match
(child: T) => boolean

Returns: {T} - The first matching child

Import

import { getChildDeep } from 'react-nanny';

Examples

// Finds the first occurrence of a child that has a prop of 'active' set to true
getChildDeep(children, child => child.props.active);

getChildByType<T=React.ReactNode>

Gets first child by specified type

Since v1.0.0 (modified v2.0.0)

Param Type

children

JSX children
T

types

Types of children to match
any[]

{ customTypeKey: '__TYPE', prioritized: false } (optional)

The configuration params
GetChildByTypeConfig

Returns: {T} - The first matching child

This function will check the prop {customTypeKey} first and then component.type to match core html (JSX intrinsic) elements or component functions. To find a React Fragment, search for 'react.fragment'.

Supporting Types

// The configuration type for the util:
//   customTypeKey?: string = '__TYPE' - The custom component prop key to check the type
//   prioritized?: boolean = false - Whether or not the order of types is prioritized
export type GetChildByTypeConfig = { customTypeKey?: string, prioritized?: boolean };

Import

import { getChildByType, GetChildByTypeConfig } from 'react-nanny';

Examples

// Finds the first occurrence of either a ToDo (custom component w/defined type as prop), a div, or a React Fragment
getChildByType(children, ['ToDo', 'div', 'react.fragment']);

// Finds the first occurrence of either a MyComponent (custom component - full component passed in), a div, or a React Fragment
import MyComponent from './MyComponent';
getChildByType(children, [MyComponent, 'div', 'react.fragment']);

// Finds the first occurrence of either a ToDo, a div, or a React Fragment with a preference for that order. If ToDo exists, it will return that first. If not, then div, etc.
getChildByType(children, ['ToDo', 'div', 'react.fragment'], { prioritized: true });

getChildByTypeDeep<T=React.ReactNode>

Gets first child by specified type (deep search)

Since v1.0.0 (modified v2.0.0)

Param Type

children

JSX children
T

types

Types of children to match
any[]

{ customTypeKey: '__TYPE', prioritized: false } (optional)

The configuration params
GetChildByTypeConfig

Returns: {T} - The first matching child

This function will check the prop {customTypeKey} first and then component.type to match core html (JSX intrinsic) elements or component functions. To find a React Fragment, search for 'react.fragment'.

Supporting Types

// The configuration type for the util:
//   customTypeKey?: string = '__TYPE' - The custom component prop key to check the type
//   prioritized?: boolean = false - Whether or not the order of types is prioritized

export type GetChildByTypeConfig = { customTypeKey?: string, prioritized?: boolean };

Import

import { getChildByTypeDeep, GetChildByTypeConfig } from 'react-nanny';

Examples

// Finds the first occurrence of either a ToDo (custom component w/defined type as prop), a div, or a React Fragment
getChildByTypeDeep(children, ['ToDo', 'div', 'react.fragment']);

// Finds the first occurrence of either a MyComponent (custom component - full component passed in), a div, or a React Fragment
import MyComponent from './MyComponent';
getChildByTypeDeep(children, [MyComponent, 'div', 'react.fragment']);

// Finds the first occurrence of either a ToDo, a div, or a React Fragment with a preference for that order. If ToDo exists, it will return that first. If not, then div, etc.
getChildByTypeDeep(children, ['ToDo', 'div', 'react.fragment'], { prioritized: true });

getChildren<T=React.ReactNode>

Gets all children by specified predicate

Since v1.0.0

Param Type

children

JSX children
T

predicate

The predicate to determine if the given child is a match
(child: T) => boolean

Returns: {T[]} - Array of matching children

Import

import { getChildren } from 'react-nanny';

Examples

// Finds all children that have an 'active' prop set to true
getChildren(children, child => child.props.active);

getChildrenDeep<T=React.ReactNode>

Gets first child by specified predicate (deep search)

Since v1.0.0

Param Type

children

JSX children
T

predicate

The predicate to determine if the given child is a match
(child: T) => boolean

Returns: {T} - The first matching child

Import

import { getChildrenDeep } from 'react-nanny';

Examples

// Finds the first occurrence of a child that has a prop of 'active' set to true
getChildrenDeep(children, child => child.props.active);

getChildrenByType<T=React.ReactNode>

Gets all children by specified type

Since v1.0.0 (modified v2.0.0)

Param Type

children

JSX children
T

types

Types of children to match
any[]

{ customTypeKey: '__TYPE' } (optional)

The configuration params
GetChildrenByTypeConfig

Returns: {T[]} - Array of matching children

This function will check the prop {customTypeKey} first and then component.type to match core html (JSX intrinsic) elements or component functions. To find a React Fragment, search for 'react.fragment'.

Supporting Types

// The configuration type for the util:
//   customTypeKey?: string = '__TYPE' - The custom component prop key to check the type

export type GetChildrenByTypeConfig = { customTypeKey?: string };

Import

import { getChildrenByType, GetChildrenByTypeConfig } from 'react-nanny';

Examples

// Finds all occurrences of ToDo (custom component), div, and React Fragment
getChildrenByType(children, ['ToDo', 'div', 'react.fragment']);

// Finds all occurrences of MyComponent (custom component - full component passed in), a div, and React Fragment
import MyComponent from './MyComponent';
getChildrenByType(children, [MyComponent, 'div', 'react.fragment']);

// Finds all occurrences of ToDo (custom component) with a customized {customTypeKey}
getChildrenByType(children, ['ToDo'], { customTypeKey: 'myTypeKey' });

getChildrenByTypeDeep<T=React.ReactNode>

Gets all children by specified type (deep search)

Since v1.0.0 (modified v2.0.0)

Param Type

children

JSX children
T

types

Types of children to match
any[]

{ customTypeKey: '__TYPE' } (optional)

The configuration params
GetChildrenByTypeConfig

Returns: {T[]} - Array of matching children

This function will check the prop {customTypeKey} first and then component.type to match core html (JSX intrinsic) elements or component functions. To find a React Fragment, search for 'react.fragment'.

Supporting Types

// The configuration type for the util:
//   customTypeKey?: string = '__TYPE' - The custom component prop key to check the type

export type GetChildrenByTypeConfig = { customTypeKey?: string };

Import

import { getChildrenByTypeDeep, GetChildrenByTypeConfig } from 'react-nanny';

Examples

// Finds all occurrences of ToDo (custom component), div, and React Fragment
getChildrenByTypeDeep(children, ['ToDo', 'div', 'react.fragment']);

// Finds all occurrences of MyComponent (custom component - full component passed in), a div, and React Fragment
import MyComponent from './MyComponent';
getChildrenByTypeDeep(children, [MyComponent, 'div', 'react.fragment']);

// Finds all occurrences of ToDo (custom component) with a customized {customTypeKey}
getChildrenByTypeDeep(children, ['ToDo'], { customTypeKey: 'myTypeKey' });

noEmptyChildrenDeep

Ensure that there is some level of content and not just a bunch of empty divs, spans, etc (deep search)

Since v1.0.0

Param TypeDefault

component

A component, array of components, or content of a component
any

config (optional)

Configuration options for custom components
NoEmptyConfigconfig

Returns: {boolean} - Whether or not there is content provided. true = content is provided as children at some depth; false = no content is provided as children at any depth

Supporting Types

// The configuration type for the util:
//   ignore?: string[] = [] - A list of components to ignore; Components in this list will be considered as valid content
//   rejectCustom?: boolean = true - Whether or not custom components should be rejected as content
//   rejectEmptyCustom?: boolean = false - Whether or not custom components require children to be considered valid content; Note: {rejectCustom} must be set to false in order for this setting to be considered

export type NoEmptyConfig = { ignore?: string[], rejectCustom?: boolean, rejectEmptyCustom?: boolean };

Import

import { noEmptyChildrenDeep } from 'react-nanny';

Examples

// Ensure that one of the following is true at some level of depth for the children: 
//   * There is markup with content
//   * A 'CustomComponent' is provided
//   * A different custom component that has children
noEmptyChildrenDeep(component, { ignore: ['CustomComponent'], rejectCustom: false, rejectEmptyCustom: true })

removeChildren<T=React.ReactNode>

Removes all children by specified predicate

Since v1.0.0

Param Type

children

JSX children
T

predicate

The predicate to determine if the given child is a match
(child: T) => boolean

Returns: {T[]} - All non-matching children

Import

import { removeChildren } from 'react-nanny';

Examples

// Removes all children that have an 'active' prop set to false
removeChildren(children, child => !child.props.active);

removeChildrenDeep<T=React.ReactNode>

Removes all children by specified predicate (deep search)

Since v1.0.0

Param Type

children

JSX children
T

predicate

The predicate to determine if the given child is a match
(child: T) => boolean

Returns: {T[]} - All non-matching children

Import

import { removeChildrenDeep } from 'react-nanny';

Examples

// Removes all children that have an 'active' prop set to false
removeChildrenDeep(children, child => !child.props.active);

removeChildrenByType<T=React.ReactNode>

Removes all children by specified type

Since v1.0.0 (modified v2.0.0)

Param Type

children

JSX children
T

types

Types of children to match
any[]

{ customTypeKey: '__TYPE' } (optional)

The configuration params
RemoveChildrenByTypeConfig

Returns: {T[]} - All non-matching children

This function will check the prop {customTypeKey} first and then component.type to match core html (JSX intrinsic) elements or component functions. To remove a React Fragment, search for 'react.fragment'.

Import

import { removeChildrenByType, RemoveChildrenByTypeConfig } from 'react-nanny';

Examples

// Removes all occurrences of ToDo (custom component), div, and React Fragment
removeChildrenByType(children, ['ToDo', 'div', 'react.fragment']);

// Removes all occurrences of MyComponent (custom component - from import), a div, and React Fragment
import MyComponent from './MyComponent';
removeChildrenByType(children, [MyComponent, 'div', 'react.fragment']);

// Removes all occurrences of MyComponent (custom component - as React.ReactNode), a div, and React Fragment
const component = getChildByType(['MyComponent']);
removeChildrenByType(children, [component, 'div', 'react.fragment']);

// Removes all occurrences of ToDo (custom component) with a customized {customTypeKey}
removeChildrenByType(children, ['ToDo'], { customTypeKey: 'myTypeKey' });

removeChildrenByTypeDeep<T=React.ReactNode>

Removes all children by specified type (deep search)

Since v1.0.0 (modified v2.0.0)

Param Type

children

JSX children
T

types

Types of children to match
any[]

{ customTypeKey: '__TYPE' } (optional)

The configuration params
RemoveChildrenByTypeConfig

Returns: {T[]} - All non-matching children

This function will check the prop {customTypeKey} first and then component.type to match core html (JSX intrinsic) elements or component functions. To remove a React Fragment, search for 'react.fragment'.

Import

import { removeChildrenByTypeDeep, RemoveChildrenByTypeConfig } from 'react-nanny';

Examples

// Removes all occurrences of ToDo (custom component), div, and React Fragment
removeChildrenByTypeDeep(children, ['ToDo', 'div', 'react.fragment']);

// Removes all occurrences of MyComponent (custom component - full component passed in), a div, and React Fragment
import MyComponent from './MyComponent';
removeChildrenByTypeDeep(children, [MyComponent, 'div', 'react.fragment']);

// Removes all occurrences of MyComponent (custom component - as React.ReactNode), a div, and React Fragment
const component = getChildByType(['MyComponent']);
removeChildrenByTypeDeep(children, [component, 'div', 'react.fragment']);

// Removes all occurrences of ToDo (custom component) with a customized {customTypeKey}
removeChildrenByTypeDeep(children, ['ToDo'], { customTypeKey: 'myTypeKey' });

typeOfComponent

Gets the string type of the component's {customTypeKey}, string type of the core html (JSX intrinsic) element, or the function type

Since v1.0.0

Param TypeDefault

component

The component to type check
any

customTypeKey (optional)

The custom component prop key to check the type
string'__TYPE'

Returns: {string} - The string representation of the type

React Fragments will return type 'react.fragment'. Priority will be given to the {customTypeKey} if one exists

Import

import { typeOfComponent } from 'react-nanny';

Package Contents

Within the module you'll find the following directories and files:

package.json
CHANGELOG.md -- history of changes to the module
README.md -- this file
/lib
  └───/es5
    └───/getChild
      └───index.d.ts - 1.1 KB
      └───index.js - 1.78 KB
    └───/getChildByType
      └───index.d.ts - 3.82 KB
      └───index.js - 5.71 KB
    └───/getChildren
      └───index.d.ts - 1.1 KB
      └───index.js - 2.16 KB
    └───/getChildrenByType
      └───index.d.ts - 3.27 KB
      └───index.js - 4.83 KB
      └───index.d.ts - 634 Bytes
      └───index.js - 2.78 KB
    └───/noEmptyChildren
      └───index.d.ts - 1.69 KB
      └───index.js - 3.35 KB
    └───/removeChildren
      └───index.d.ts - 1.11 KB
      └───index.js - 3.01 KB
    └───/removeChildrenByType
      └───index.d.ts - 3.36 KB
      └───index.js - 5.75 KB
    └───/typeOfComponent
      └───index.d.ts - 614 Bytes
      └───index.js - 1.53 KB
    └───/_private
      └───utils.d.ts - 61 Bytes
      └───utils.js - 575 Bytes
  └───/es6
    └───/getChild
      └───index.d.ts - 1.1 KB
      └───index.js - 1.6 KB
    └───/getChildByType
      └───index.d.ts - 3.82 KB
      └───index.js - 5.42 KB
    └───/getChildren
      └───index.d.ts - 1.1 KB
      └───index.js - 1.96 KB
    └───/getChildrenByType
      └───index.d.ts - 3.27 KB
      └───index.js - 4.55 KB
      └───index.d.ts - 634 Bytes
      └───index.js - 544 Bytes
    └───/noEmptyChildren
      └───index.d.ts - 1.69 KB
      └───index.js - 3.12 KB
    └───/removeChildren
      └───index.d.ts - 1.11 KB
      └───index.js - 2.78 KB
    └───/removeChildrenByType
      └───index.d.ts - 3.36 KB
      └───index.js - 5.44 KB
    └───/typeOfComponent
      └───index.d.ts - 614 Bytes
      └───index.js - 1.39 KB
    └───/_private
      └───utils.d.ts - 61 Bytes
      └───utils.js - 398 Bytes

License

MIT

Author

Michael Paravano

Dependencies

None