Skip to content
This repository was archived by the owner on Dec 13, 2018. It is now read-only.

Commit a94d620

Browse files
bjoernricksKent C. Dodds
authored andcommitted
feat(filterProps): add option to filter props (#315)
* feat(filterProps): add option to filter props (#314) Allow to filter specific props of a glamorous component to be not forwarded to its children. Sometimes it may not be possible to set the rooEl option to filter unknown properties for the leaf elements. This is especially the case when glamorous is being used within a HOC. This commit adds a new filterProps option. The option expects an array of prop names which shouldn't be passed to child components. * docs: add me to contributors * Update split-props.js closes #314
1 parent a027e20 commit a94d620

File tree

5 files changed

+136
-11
lines changed

5 files changed

+136
-11
lines changed

.all-contributorsrc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,18 @@
478478
"code",
479479
"test"
480480
]
481+
},
482+
{
483+
"login": "bjoernricks",
484+
"name": "Björn Ricks",
485+
"avatar_url": "https://avatars2.githubusercontent.com/u/897575?v=4",
486+
"profile": "https://twitter.com/bjoernricks",
487+
"contributions": [
488+
"bug",
489+
"code",
490+
"doc",
491+
"test"
492+
]
481493
}
482494
]
483495
}

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
[![downloads][downloads-badge]][npmcharts]
1515
[![MIT License][license-badge]][LICENSE]
1616

17-
[![All Contributors](https://img.shields.io/badge/all_contributors-50-orange.svg?style=flat-square)](#contributors)
17+
[![All Contributors](https://img.shields.io/badge/all_contributors-51-orange.svg?style=flat-square)](#contributors)
1818
[![PRs Welcome][prs-badge]][prs]
1919
[![Chat][chat-badge]][chat]
2020
[![Code of Conduct][coc-badge]][coc]
@@ -121,7 +121,7 @@ Thanks goes to these people ([emoji key][emojis]):
121121
| [<img src="https://avatars2.githubusercontent.com/u/4118089?v=3" width="100px;"/><br /><sub>FredericH</sub>](http://fr.linkedin.com/in/fredericheem)<br />[💡](#example-FredericHeem "Examples") | [<img src="https://avatars3.githubusercontent.com/u/656630?v=3" width="100px;"/><br /><sub>Atticus White</sub>](https://atticuswhite.com)<br />[📖](https://github.com/paypal/glamorous/commits?author=ajwhite "Documentation") [🔌](#plugin-ajwhite "Plugin/utility libraries") | [<img src="https://avatars0.githubusercontent.com/u/13483453?v=3" width="100px;"/><br /><sub>marzelin</sub>](https://github.com/marzelin)<br />[💻](https://github.com/paypal/glamorous/commits?author=marzelin "Code") | [<img src="https://avatars2.githubusercontent.com/u/4074973?v=3" width="100px;"/><br /><sub>iwantmyname</sub>](https://iwantmyname.com/)<br />[🚇](#infra-iwantmyname "Infrastructure (Hosting, Build-Tools, etc)") | [<img src="https://avatars1.githubusercontent.com/u/11809142?v=3" width="100px;"/><br /><sub>Ethan Godt</sub>](http://ethangodt.com)<br /> | [<img src="https://avatars3.githubusercontent.com/u/2175447?v=3" width="100px;"/><br /><sub>Zill Ding</sub>](https://github.com/zillding)<br />[💻](https://github.com/paypal/glamorous/commits?author=zillding "Code") | [<img src="https://avatars3.githubusercontent.com/u/411643?v=3" width="100px;"/><br /><sub>Dan Bradley</sub>](https://github.com/debradley)<br />[💻](https://github.com/paypal/glamorous/commits?author=debradley "Code") |
122122
| [<img src="https://avatars3.githubusercontent.com/u/22868432?v=3" width="100px;"/><br /><sub>Lufty Wiranda</sub>](http://instagram.com/luftywiranda13)<br />[💻](https://github.com/paypal/glamorous/commits?author=luftywiranda13 "Code") | [<img src="https://avatars3.githubusercontent.com/u/3208863?v=3" width="100px;"/><br /><sub>Ansuman Shah</sub>](https://github.com/ansumanshah)<br />[💻](https://github.com/paypal/glamorous/commits?author=ansumanshah "Code") [📖](https://github.com/paypal/glamorous/commits?author=ansumanshah "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/11598?v=3" width="100px;"/><br /><sub>Travis LaDuke</sub>](http://-)<br />[💡](#example-laduke "Examples") | [<img src="https://avatars2.githubusercontent.com/u/11290953?v=3" width="100px;"/><br /><sub>Aydın Çağrı Dumlu</sub>](https://github.com/acgrdumlu)<br />[🐛](https://github.com/paypal/glamorous/issues?q=author%3Aacgrdumlu "Bug reports") [💻](https://github.com/paypal/glamorous/commits?author=acgrdumlu "Code") | [<img src="https://avatars2.githubusercontent.com/u/1383861?v=3" width="100px;"/><br /><sub>Maja Wichrowska</sub>](https://github.com/majapw)<br />[🐛](https://github.com/paypal/glamorous/issues?q=author%3Amajapw "Bug reports") | [<img src="https://avatars3.githubusercontent.com/u/6845263?v=3" width="100px;"/><br /><sub>Tom Liu</sub>](https://github.com/gt3240)<br />[📖](https://github.com/paypal/glamorous/commits?author=gt3240 "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/1863771?v=3" width="100px;"/><br /><sub>Siddharth Kshetrapal</sub>](https://github.com/siddharthkp)<br />[⚠️](https://github.com/paypal/glamorous/commits?author=siddharthkp "Tests") [🔧](#tool-siddharthkp "Tools") |
123123
| [<img src="https://avatars2.githubusercontent.com/u/5257243?v=3" width="100px;"/><br /><sub>WillowHQ</sub>](https://github.com/WillowHQ)<br />[📖](https://github.com/paypal/glamorous/commits?author=WillowHQ "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/12202757?v=4" width="100px;"/><br /><sub>Mohammad Rajabifard</sub>](https://tarino.ir)<br />[🐛](https://github.com/paypal/glamorous/issues?q=author%3Amorajabi "Bug reports") [📖](https://github.com/paypal/glamorous/commits?author=morajabi "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/17005317?v=3" width="100px;"/><br /><sub>Omar Albacha</sub>](https://github.com/Oalbacha)<br />[💻](https://github.com/paypal/glamorous/commits?author=Oalbacha "Code") [📖](https://github.com/paypal/glamorous/commits?author=Oalbacha "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/28659384?v=3" width="100px;"/><br /><sub>tdeschryver</sub>](https://github.com/tdeschryver)<br />[💻](https://github.com/paypal/glamorous/commits?author=tdeschryver "Code") [⚠️](https://github.com/paypal/glamorous/commits?author=tdeschryver "Tests") | [<img src="https://avatars0.githubusercontent.com/u/4955191?v=4" width="100px;"/><br /><sub>Dylan Mozlowski</sub>](https://github.com/DylanMoz)<br />[💻](https://github.com/paypal/glamorous/commits?author=DylanMoz "Code") | [<img src="https://avatars2.githubusercontent.com/u/3275424?v=4" width="100px;"/><br /><sub>andretshurotshka</sub>](https://github.com/goodmind)<br />[💻](https://github.com/paypal/glamorous/commits?author=goodmind "Code") [⚠️](https://github.com/paypal/glamorous/commits?author=goodmind "Tests") | [<img src="https://avatars3.githubusercontent.com/u/12836237?v=4" width="100px;"/><br /><sub>Danila</sub>](https://github.com/O4epegb)<br />[⚠️](https://github.com/paypal/glamorous/commits?author=O4epegb "Tests") |
124-
| [<img src="https://avatars3.githubusercontent.com/u/12473268?v=4" width="100px;"/><br /><sub>Junyoung Clare Jang</sub>](http://ailrun.github.io/)<br />[💻](https://github.com/paypal/glamorous/commits?author=Ailrun "Code") [⚠️](https://github.com/paypal/glamorous/commits?author=Ailrun "Tests") |
124+
| [<img src="https://avatars3.githubusercontent.com/u/12473268?v=4" width="100px;"/><br /><sub>Junyoung Clare Jang</sub>](http://ailrun.github.io/)<br />[💻](https://github.com/paypal/glamorous/commits?author=Ailrun "Code") [⚠️](https://github.com/paypal/glamorous/commits?author=Ailrun "Tests") | [<img src="https://avatars2.githubusercontent.com/u/897575?v=4" width="100px;"/><br /><sub>Björn Ricks</sub>](https://twitter.com/bjoernricks)<br />[🐛](https://github.com/paypal/glamorous/issues?q=author%3Abjoernricks "Bug reports") [💻](https://github.com/paypal/glamorous/commits?author=bjoernricks "Code") [📖](https://github.com/paypal/glamorous/commits?author=bjoernricks "Documentation") [⚠️](https://github.com/paypal/glamorous/commits?author=bjoernricks "Tests") |
125125
<!-- ALL-CONTRIBUTORS-LIST:END -->
126126

127127
This project follows the [all-contributors][all-contributors] specification.

src/__tests__/index.filter-props.js

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/* eslint func-style:0, react/prop-types:0 */
2+
import React from 'react'
3+
import {mount as render} from 'enzyme'
4+
import glamorous from '../'
5+
6+
test('filterProps are not passed to child component', () => {
7+
const filterProps = ['bold']
8+
const Child = props => <div {...props} />
9+
const Text = glamorous(Child, {filterProps})(
10+
{
11+
fontSize: 20,
12+
},
13+
({bold}) => ({
14+
fontWeight: bold ? 'bold' : undefined,
15+
}),
16+
)
17+
const rendered = render(<Text bold id="1" />)
18+
const child = rendered.find(Child)
19+
20+
expect(rendered.prop('bold')).toBe(true)
21+
expect(rendered.prop('id')).toBe('1')
22+
expect(child.prop('bold')).toBeUndefined()
23+
expect(child.prop('id')).toBe('1')
24+
})
25+
26+
test('filterProps takes precedence over built in props', () => {
27+
const filterProps = ['id']
28+
const Text = glamorous('div', {filterProps})()
29+
30+
const rendered = render(<Text bar="foo" id="1" lang="en" />)
31+
const child = rendered.find('div')
32+
33+
expect(rendered.prop('bar')).toBe('foo')
34+
expect(rendered.prop('id')).toBe('1')
35+
expect(rendered.prop('lang')).toBe('en')
36+
expect(child.prop('bar')).toBeUndefined()
37+
expect(child.prop('id')).toBeUndefined()
38+
expect(child.prop('lang')).toBe('en')
39+
})
40+
41+
test('filterProps takes precedence over forwardProps', () => {
42+
const filterProps = ['foo']
43+
const forwardProps = ['foo', 'bar']
44+
const Child = ({bar}) => <div id={bar} />
45+
const Text = glamorous(Child, {
46+
rootEl: 'div',
47+
filterProps,
48+
forwardProps,
49+
})()
50+
51+
const rendered = render(<Text foo="bar" bar="foo" />)
52+
const child = rendered.find(Child)
53+
54+
expect(rendered.prop('bar')).toBe('foo')
55+
expect(rendered.prop('foo')).toBe('bar')
56+
expect(child.prop('foo')).toBeUndefined()
57+
expect(child.prop('bar')).toBe('foo')
58+
expect(child.find('div').prop('id')).toBe('foo')
59+
})
60+
61+
test('filterProps takes precedence over cssOverrides', () => {
62+
const filterProps = ['foo']
63+
const Text = glamorous('div', {
64+
filterProps,
65+
propsAreCssOverrides: true,
66+
})(({foo}) => (foo ? {padding: '1'} : undefined))
67+
68+
const rendered = render(<Text margin={1} foo="bar" />)
69+
const child = rendered.find('div')
70+
71+
expect(rendered.prop('margin')).toBe(1)
72+
expect(rendered.prop('foo')).toBe('bar')
73+
expect(child.prop('foo')).toBeUndefined()
74+
expect(child.prop('margin')).toBeUndefined()
75+
})
76+
77+
test('filterProps are applied to new component', () => {
78+
const filterProps = ['shoulRender']
79+
const Child = props => <div {...props} />
80+
const Text = glamorous(Child, {filterProps})({
81+
color: 'red',
82+
fontSize: 20,
83+
})
84+
const View = Text.withComponent('div')
85+
86+
expect(View.filterProps).toEqual(filterProps)
87+
})
88+
89+
test('filterProps can be overridden for the new component', () => {
90+
const Child = props => <div {...props} />
91+
const Text = glamorous(Child, {filterProps: ['shouldRender']})({
92+
color: 'red',
93+
fontSize: 20,
94+
})
95+
const filterProps = ['other-thing']
96+
const View = Text.withComponent('div', {filterProps})
97+
98+
expect(View.filterProps).toEqual(filterProps)
99+
})
100+
101+
// vim: set ts=2 sw=2 tw=80:

src/create-glamorous.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ function createGlamorous(splitProps) {
2828
rootEl,
2929
displayName,
3030
shouldClassNameUpdate,
31+
filterProps = [],
3132
forwardProps = [],
3233
propsAreCssOverrides = comp.propsAreCssOverrides,
3334
withProps: basePropsToApply,
@@ -101,15 +102,20 @@ function createGlamorous(splitProps) {
101102
}
102103

103104
function withComponent(newComp, options = {}) {
104-
const {forwardProps: fp, ...componentProperties} = GlamorousComponent
105+
const {
106+
forwardProps: fwp,
107+
filterProps: flp,
108+
...componentProperties
109+
} = GlamorousComponent
105110
return glamorous(
106111
{
107112
...componentProperties,
108113
comp: newComp,
109114
},
110115
{
111-
// allows the forwardProps to be overridden
112-
forwardProps: fp,
116+
// allows the forwardProps and filterProps to be overridden
117+
forwardProps: fwp,
118+
filterProps: flp,
113119
...options,
114120
},
115121
)()
@@ -149,6 +155,7 @@ function createGlamorous(splitProps) {
149155
comp,
150156
styles,
151157
rootEl,
158+
filterProps,
152159
forwardProps,
153160
displayName,
154161
propsToApply: basePropsToApply,
@@ -169,6 +176,7 @@ function createGlamorous(splitProps) {
169176
comp,
170177
styles,
171178
rootEl,
179+
filterProps,
172180
forwardProps,
173181
displayName,
174182
propsToApply: basePropsToApply,
@@ -186,8 +194,10 @@ function createGlamorous(splitProps) {
186194
// component in glamorous
187195
comp: componentsComp,
188196
rootEl: rootEl || componentsComp,
189-
// join forwardProps (for anyone doing: glamorous(glamorous.a({}), {}))
197+
// join forwardProps and filterProps
198+
// (for anyone doing: glamorous(glamorous.a({}), {}))
190199
forwardProps: when(comp.forwardProps, forwardProps),
200+
filterProps: when(comp.filterProps, filterProps),
191201
// set the displayName to something that's slightly more
192202
// helpful than `GlamorousComponent` :)
193203
displayName: displayName || `glamorous(${getDisplayName(comp)})`,

src/split-props.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,21 @@ export default function splitProps(
1111
// component ever
1212
...rest
1313
},
14-
{propsAreCssOverrides, rootEl, forwardProps},
14+
{propsAreCssOverrides, rootEl, filterProps, forwardProps},
1515
) {
1616
const returnValue = {toForward: {}, cssProp, cssOverrides: {}}
1717
if (!propsAreCssOverrides) {
18-
if (typeof rootEl !== 'string') {
19-
// if it's not a string, then we can forward everything
20-
// (because it's a component)
18+
if (typeof rootEl !== 'string' && filterProps.length === 0) {
19+
// if it's not a string and filterProps is empty,
20+
// then we can forward everything (because it's a component)
2121
returnValue.toForward = rest
2222
return returnValue
2323
}
2424
}
2525
return Object.keys(rest).reduce((split, propName) => {
26-
if (
26+
if (filterProps.indexOf(propName) !== -1) {
27+
return split
28+
} else if (
2729
forwardProps.indexOf(propName) !== -1 ||
2830
shouldForwardProperty(rootEl, propName)
2931
) {

0 commit comments

Comments
 (0)