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

Commit

Permalink
feat(forwardProps): allow to forward innerRef (#351)
Browse files Browse the repository at this point in the history
* Allow to forward innerRef for both normal glamorous and tiny glamorous

* Add danielberndt to contributors

* Fix url in danielberndt’s contributor profile

* apply innerRef-forwarding logic to all cases

* moved above now-irrelevant comment section

* Move ref tests into its own refs.js file 

Also renamed nodeType to node within these tests
  • Loading branch information
danielberndt authored and Kent C. Dodds committed Oct 26, 2017
1 parent 0cc1006 commit 73cbc5f
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 27 deletions.
10 changes: 10 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,16 @@
"contributions": [
"code"
]
},
{
"login": "danielberndt",
"name": "Daniel",
"avatar_url": "https://avatars3.githubusercontent.com/u/856386?v=4",
"profile": "https://www.danielberndt.net",
"contributions": [
"code",
"test"
]
}
]
}
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
[![downloads][downloads-badge]][npmcharts]
[![MIT License][license-badge]][LICENSE]

[![All Contributors](https://img.shields.io/badge/all_contributors-54-orange.svg?style=flat-square)](#contributors)
[![All Contributors](https://img.shields.io/badge/all_contributors-55-orange.svg?style=flat-square)](#contributors)
[![PRs Welcome][prs-badge]][prs]
[![Chat][chat-badge]][chat]
[![Code of Conduct][coc-badge]][coc]
Expand Down Expand Up @@ -155,7 +155,7 @@ Thanks goes to these people ([emoji key][emojis]):
| [<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") |
| [<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") |
| [<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") |
| [<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") | [<img src="https://avatars0.githubusercontent.com/u/4934193?v=4" width="100px;"/><br /><sub>Tyler Deitz</sub>](http://tylerdeitz.com)<br />[💻](https://github.com/paypal/glamorous/commits?author=tvler "Code") | [<img src="https://avatars2.githubusercontent.com/u/16104985?v=4" width="100px;"/><br /><sub>Shovan Chatterjee</sub>](https://twitter.com/shovan_ch)<br />[📖](https://github.com/paypal/glamorous/commits?author=shovanch "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/6839660?v=4" width="100px;"/><br /><sub>johnjessewood</sub>](https://github.com/johnjesse)<br />[💻](https://github.com/paypal/glamorous/commits?author=johnjesse "Code") |
| [<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") | [<img src="https://avatars0.githubusercontent.com/u/4934193?v=4" width="100px;"/><br /><sub>Tyler Deitz</sub>](http://tylerdeitz.com)<br />[💻](https://github.com/paypal/glamorous/commits?author=tvler "Code") | [<img src="https://avatars2.githubusercontent.com/u/16104985?v=4" width="100px;"/><br /><sub>Shovan Chatterjee</sub>](https://twitter.com/shovan_ch)<br />[📖](https://github.com/paypal/glamorous/commits?author=shovanch "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/6839660?v=4" width="100px;"/><br /><sub>johnjessewood</sub>](https://github.com/johnjesse)<br />[💻](https://github.com/paypal/glamorous/commits?author=johnjesse "Code") | [<img src="https://avatars3.githubusercontent.com/u/856386?v=4" width="100px;"/><br /><sub>Daniel</sub>](https://www.danielberndt.net)<br />[💻](https://github.com/paypal/glamorous/commits?author=danielberndt "Code") [⚠️](https://github.com/paypal/glamorous/commits?author=danielberndt "Tests") |
<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors][all-contributors] specification.
Expand Down
11 changes: 0 additions & 11 deletions src/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -361,17 +361,6 @@ test('allows you to pass custom props that are allowed', () => {
)
})

test('should receive inner ref if specified', () => {
const getRef = jest.fn()
const Comp = glamorous.div({
marginLeft: '24px',
})

mount(<Comp innerRef={getRef} />)

expect(getRef).toHaveBeenCalled()
})

test('can accept classNames instead of style objects', () => {
// this is to support a babel plugin to pre-compile static styles
const className1 = glamor.css({paddingTop: 1, paddingRight: 1}).toString()
Expand Down
124 changes: 124 additions & 0 deletions src/__tests__/refs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/* eslint func-style:0, react/prop-types:0 */
import React from 'react'
import {mount} from 'enzyme'
import glamorous from '../'

const nodeEnv = process.env.NODE_ENV

jest.mock('../constants')

afterEach(() => {
process.env.NODE_ENV = nodeEnv
})

test('should receive inner ref if specified', () => {
const getRef = jest.fn()
const Comp = glamorous.div({
marginLeft: '24px',
})

mount(<Comp innerRef={getRef} />)

expect(getRef).toHaveBeenCalled()
})

test('should pass inner ref to underlying component if forwarded', () => {
let node = null
const getRef = n => (node = n)

class InnerComp extends React.Component {
render() {
return (
<div>
<span ref={this.props.innerRef} />
</div>
)
}
}

const Comp = glamorous(InnerComp, {forwardProps: ['innerRef']})({
marginLeft: '24px',
})

mount(<Comp innerRef={getRef} />)

expect(node).toBeInstanceOf(HTMLElement)
expect(node.tagName).toBe('SPAN')
})

test('should not pass inner ref to underlying component if not forwarded', () => {
let node = null
const getRef = n => (node = n)

class InnerComp extends React.Component {
render() {
return (
<div>
<span ref={this.props.innerRef} />
</div>
)
}
}

const Comp = glamorous(InnerComp)({
marginLeft: '24px',
})

mount(<Comp innerRef={getRef} />)

expect(node).toBeInstanceOf(InnerComp)
})

test('should pass inner ref to underlying component if forwarded and rootEl is set', () => {
let node = null
const getRef = n => (node = n)

class InnerComp extends React.Component {
render() {
return (
<div>
<span ref={this.props.innerRef} />
</div>
)
}
}

const Comp = glamorous(InnerComp, {
rootEl: 'div',
forwardProps: ['innerRef'],
})({
marginLeft: '24px',
})

mount(<Comp innerRef={getRef} />)

expect(node).toBeInstanceOf(HTMLElement)
expect(node.tagName).toBe('SPAN')
})

test('should pass inner ref to underlying component if forwarded and filterProps are specified', () => {
let node = null
const getRef = n => (node = n)

class InnerComp extends React.Component {
render() {
return (
<div>
<span ref={this.props.innerRef} />
</div>
)
}
}

const Comp = glamorous(InnerComp, {
filterProps: ['noname'],
forwardProps: ['innerRef'],
})({
marginLeft: '24px',
})

mount(<Comp innerRef={getRef} />)

expect(node).toBeInstanceOf(HTMLElement)
expect(node.tagName).toBe('SPAN')
})
49 changes: 48 additions & 1 deletion src/__tests__/tiny.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint func-style:0, react/prop-types:0 */
import React from 'react'
import {render} from 'enzyme'
import {render, mount} from 'enzyme'

import glamorousTiny from '../tiny'

Expand Down Expand Up @@ -31,3 +31,50 @@ test('should pass glam object prop', () => {
const context = expect.any(Object) // the context
expect(dynamicStyles).toHaveBeenCalledWith(props, context)
})

test('should pass inner ref to underlying component if forwarded', () => {
let node = null
const getRef = n => (node = n)

class InnerComp extends React.Component {
render() {
return (
<div>
<span ref={this.props.innerRef} />
</div>
)
}
}

const Comp = glamorousTiny(InnerComp, {forwardProps: ['innerRef']})({
marginLeft: '24px',
})

mount(<Comp innerRef={getRef} />)

expect(node).toBeInstanceOf(HTMLElement)
expect(node.tagName).toBe('SPAN')
})

test('should not pass inner ref to underlying component if not forwarded', () => {
let node = null
const getRef = n => (node = n)

class InnerComp extends React.Component {
render() {
return (
<div>
<span ref={this.props.innerRef} />
</div>
)
}
}

const Comp = glamorousTiny(InnerComp)({
marginLeft: '24px',
})

mount(<Comp innerRef={getRef} />)

expect(node).toBeInstanceOf(InnerComp)
})
3 changes: 2 additions & 1 deletion src/create-glamorous.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ function createGlamorous(splitProps) {
: this.className

return React.createElement(GlamorousComponent.comp, {
ref: props.innerRef,
// if innerRef is forwarded we don't want to apply it here
ref: 'innerRef' in toForward ? undefined : props.innerRef,
...toForward,
className: this.className,
})
Expand Down
9 changes: 7 additions & 2 deletions src/split-props.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,21 @@ import shouldForwardProperty from './should-forward-property'
export default function splitProps(
{
css: cssProp,
innerRef,
// these are plucked off
theme, // because they
className, // should never
innerRef, // be forwarded
glam, // to the lower
glam, // be forwarded
// to the lower
// component ever
...rest
},
{propsAreCssOverrides, rootEl, filterProps, forwardProps},
) {
// forward innerRef if user wishes to do so
if (innerRef !== undefined && forwardProps.indexOf('innerRef') !== -1) {
rest.innerRef = innerRef
}
const returnValue = {toForward: {}, cssProp, cssOverrides: {}}
if (!propsAreCssOverrides) {
if (typeof rootEl !== 'string' && filterProps.length === 0) {
Expand Down
28 changes: 18 additions & 10 deletions src/tiny.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
/* eslint no-unused-vars:0 */
import createGlamorous from './create-glamorous'

function splitProps({
css: cssProp,
// these are plucked off
theme, // because they
className, // should never
innerRef, // be forwarded
glam, // to the lower
// component ever
...rest
}) {
function splitProps(
{
css: cssProp,
innerRef,
// these are plucked off
theme, // because they
className, // should never
glam, // be forwarded
// to the lower
// component ever
...rest
},
{forwardProps},
) {
// forward innerRef if user wishes to do so
if (innerRef !== undefined && forwardProps.indexOf('innerRef') !== -1) {
rest.innerRef = innerRef
}
return {toForward: rest, cssProp}
}

Expand Down

0 comments on commit 73cbc5f

Please sign in to comment.