Skip to content

Commit

Permalink
feat: allow filterProps to be a function (#417)
Browse files Browse the repository at this point in the history
  • Loading branch information
bschlenk authored and armandabric committed Jan 17, 2020
1 parent 7c92d58 commit c4908bb
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 4 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,13 @@ console.log(reactElementToJSXString(<div a="1" b="2">Hello, world!</div>));

Just return the name you want for the provided ReactElement, as a string.

**options.filterProps: array, default []**
**options.filterProps: string[] | (val: any, key: string) => boolean, default []**

Provide an array of props to filter for every component. For example ['key'] will suppress the key="" prop from being added.
If an array of strings is passed, filter out any prop who's name is in
the array. For example ['key'] will suppress the key="" prop from being added.

If a function is passed, it will be called for each prop with two arguments,
the prop value and key, and will filter out any that return false.

**options.showDefaultProps: boolean, default true**

Expand Down
12 changes: 12 additions & 0 deletions src/formatter/createPropFilter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* @flow */

export default function createPropFilter(
props: {},
filter: string[] | ((any, string) => boolean)
) {
if (Array.isArray(filter)) {
return (key: string) => filter.indexOf(key) === -1;
} else {
return (key: string) => filter(props[key], key);
}
}
26 changes: 26 additions & 0 deletions src/formatter/createPropFilter.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* @flow */

import createPropFilter from './createPropFilter';

describe('createPropFilter', () => {
it('should filter based on an array of keys', () => {
const props = { a: 1, b: 2, c: 3 };
const filter = createPropFilter(props, ['b']);

const filteredPropKeys = Object.keys(props).filter(filter);

expect(filteredPropKeys).toEqual(['a', 'c']);
});

it('should filter based on a callback', () => {
const props = { a: 1, b: 2, c: 3 };
const filter = createPropFilter(
props,
(val, key) => key !== 'b' && val < 3
);

const filteredPropKeys = Object.keys(props).filter(filter);

expect(filteredPropKeys).toEqual(['a']);
});
});
7 changes: 5 additions & 2 deletions src/formatter/formatReactElementNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import formatTreeNode from './formatTreeNode';
import formatProp from './formatProp';
import mergeSiblingPlainStringChildrenReducer from './mergeSiblingPlainStringChildrenReducer';
import sortPropsByNames from './sortPropsByNames';
import createPropFilter from './createPropFilter';
import type { Options } from './../options';
import type { ReactElementTreeNode } from './../tree';

Expand Down Expand Up @@ -126,13 +127,15 @@ export default (

const visibleAttributeNames = [];

const propFilter = createPropFilter(props, filterProps);

Object.keys(props)
.filter(propName => filterProps.indexOf(propName) === -1)
.filter(propFilter)
.filter(onlyPropsWithOriginalValue(defaultProps, props))
.forEach(propName => visibleAttributeNames.push(propName));

Object.keys(defaultProps)
.filter(defaultPropName => filterProps.indexOf(defaultPropName) === -1)
.filter(propFilter)
.filter(() => showDefaultProps)
.filter(defaultPropName => !visibleAttributeNames.includes(defaultPropName))
.forEach(defaultPropName => visibleAttributeNames.push(defaultPropName));
Expand Down
26 changes: 26 additions & 0 deletions src/formatter/formatReactElementNode.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,30 @@ describe('formatReactElementNode', () => {
</div>`
);
});

it('should allow filtering props by function', () => {
const tree = {
type: 'ReactElement',
displayName: 'h1',
defaultProps: {},
props: { className: 'myClass', onClick: () => {} },
childrens: [
{
value: 'Hello world',
type: 'string',
},
],
};

const options = {
...defaultOptions,
filterProps: (val, key) => !key.startsWith('on'),
};

expect(formatReactElementNode(tree, false, 0, options)).toEqual(
`<h1 className="myClass">
Hello world
</h1>`
);
});
});
11 changes: 11 additions & 0 deletions src/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,17 @@ describe('reactElementToJSXString(ReactElement)', () => {
).toEqual('<TestComponent a="b" />');
});

it("reactElementToJSXString(<TestComponent />, { filterProps: () => !key.startsWith('some')) })", () => {
expect(
reactElementToJSXString(
<TestComponent a="b" someProp="foo" someOtherProp={false} />,
{
filterProps: (val, key) => !key.startsWith('some'),
}
)
).toEqual('<TestComponent a="b" />');
});

it('reactElementToJSXString(<TestComponent />, { useBooleanShorthandSyntax: false })', () => {
expect(
reactElementToJSXString(
Expand Down

0 comments on commit c4908bb

Please sign in to comment.