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 |
---|---|
getChild | Gets first child by specified predicate |
getChildDeep | Gets first child by specified predicate (deep search) |
getChildByType | Gets first child by specified type |
getChildByTypeDeep | Gets first child by specified type (deep search) |
getChildren | Gets all children by specified predicate |
getChildrenDeep | Gets first child by specified predicate (deep search) |
getChildrenByType | Gets all children by specified type |
getChildrenByTypeDeep | Gets all children by specified type (deep search) |
noEmptyChildrenDeep | Ensure that there is some level of content and not just a bunch of empty divs, spans, etc (deep search) |
removeChildren | Removes all children by specified predicate |
removeChildrenDeep | Removes all children by specified predicate (deep search) |
removeChildrenByType | Removes all children by specified type |
removeChildrenByTypeDeep | Removes all children by specified type (deep search) |
typeOfComponent | Gets 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 | Type | Default |
---|---|---|
component A component, array of components, or content of a component | any | |
config (optional) Configuration options for custom components | NoEmptyConfig | config |
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 | Type | Default |
---|---|---|
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 ParavanoDependencies
None