Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6775529

Browse files
Deprecate withRef for innerRef (#46)
1 parent 4e5f234 commit 6775529

File tree

4 files changed

+22
-73
lines changed

4 files changed

+22
-73
lines changed

‎README.md‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,12 @@ Makes available a `theme` context to use in styled components. The shape of the
158158
159159
Returns a `function` to wrap a component and make it themeable.
160160

161-
The returned component accepts a `theme`and `composeTheme` apart from the props of the original component. They are used to provide a `theme` to the component and to configure the style composition, which can be configured via options too. The function arguments are:
161+
The returned component accepts a `theme`, `composeTheme` and `innerRef` props apart from the props of the original component. They former two are used to provide a `theme` to the component and to configure the style composition, which can be configured via options too, while the latter is used to pass a ref callback to the decorated component. The function arguments are:
162162

163163
- `Identifier` *(String)* used to provide a unique identifier to the component that will be used to get a theme from context.
164164
- `[defaultTheme]` (*Object*) is classname object resolved from CSS modules. It will be used as the default theme to calculate a new theme that will be passed to the component.
165165
- `[options]` (*Object*) If specified it allows to customize the behavior:
166166
- [`composeTheme = 'deeply'`] *(String)* allows to customize the way themes are merged or to disable merging completely. The accepted values are `deeply` to deeply merge themes, `softly` to softly merge themes and `false` to disable theme merging.
167-
- [`withRef = false`] *(Boolean)* if true, stores a ref to the wrapped component instance and makes it available via `getWrappedInstance()` method. Defaults to false.
168167

169168
## About
170169

‎index.d.ts‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@ declare module "react-css-themr"
66
{
77
/** @default "deeply" */
88
composeTheme?: "deeply" | "softly" | false,
9-
/** @default false */
10-
withRef?: boolean
119
}
1210

1311
export interface ThemeProviderProps
1412
{
13+
innerRef?: Function,
1514
theme: {}
1615
}
1716

@@ -22,7 +21,7 @@ declare module "react-css-themr"
2221

2322
interface ThemedComponent<P, S> extends React.Component<P, S>
2423
{
25-
getWrappedInstance(): React.Component<P,S>;
24+
2625
}
2726

2827
interface ThemedComponentClass<P, S> extends React.ComponentClass<P>

‎src/components/themr.js‎

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,14 @@ import invariant from 'invariant'
88
/**
99
* @typedef {{}} TReactCSSThemrOptions
1010
* @property {String|Boolean} [composeTheme=COMPOSE_DEEPLY]
11-
* @property {Boolean} [withRef=false]
1211
*/
1312

1413
const COMPOSE_DEEPLY = 'deeply'
1514
const COMPOSE_SOFTLY = 'softly'
1615
const DONT_COMPOSE = false
1716

1817
const DEFAULT_OPTIONS = {
19-
composeTheme: COMPOSE_DEEPLY,
20-
withRef: false
18+
composeTheme: COMPOSE_DEEPLY
2119
}
2220

2321
const THEMR_CONFIG = typeof Symbol !== 'undefined' ?
@@ -32,7 +30,7 @@ const THEMR_CONFIG = typeof Symbol !== 'undefined' ?
3230
* @returns {function(ThemedComponent:Function):Function} - ThemedComponent
3331
*/
3432
export default (componentName, localTheme, options = {}) => (ThemedComponent) => {
35-
const { composeTheme: optionComposeTheme,withRef: optionWithRef } = { ...DEFAULT_OPTIONS, ...options }
33+
const { composeTheme: optionComposeTheme } = { ...DEFAULT_OPTIONS, ...options }
3634
validateComposeOption(optionComposeTheme)
3735

3836
let config = ThemedComponent[THEMR_CONFIG]
@@ -59,6 +57,7 @@ export default (componentName, localTheme, options = {}) => (ThemedComponent) =>
5957
static propTypes = {
6058
...ThemedComponent.propTypes,
6159
composeTheme: PropTypes.oneOf([ COMPOSE_DEEPLY, COMPOSE_SOFTLY, DONT_COMPOSE ]),
60+
innerRef: PropTypes.func,
6261
theme: PropTypes.object,
6362
themeNamespace: PropTypes.string
6463
}
@@ -74,9 +73,9 @@ export default (componentName, localTheme, options = {}) => (ThemedComponent) =>
7473
}
7574

7675
getWrappedInstance() {
77-
invariant(optionWithRef,
78-
'To access the wrapped instance, you need to specify ' +
79-
'{ withRef: true } as the third argument of the themr() call.'
76+
invariant(true,
77+
'DEPRECATED: To access the wrapped instance, you have to pass ' +
78+
'{ innerRef: fn } and retrieve with a callback ref style.'
8079
)
8180

8281
return this.refs.wrappedInstance
@@ -136,25 +135,15 @@ export default (componentName, localTheme, options = {}) => (ThemedComponent) =>
136135
}
137136

138137
render() {
139-
let renderedElement
140138
//exclude themr-only props
141139
//noinspection JSUnusedLocalSymbols
142-
const { composeTheme, themeNamespace, ...props } = this.props //eslint-disable-line no-unused-vars
143-
144-
if (optionWithRef) {
145-
renderedElement = React.createElement(ThemedComponent, {
146-
...props,
147-
ref: 'wrappedInstance',
148-
theme: this.theme_
149-
})
150-
} else {
151-
renderedElement = React.createElement(ThemedComponent, {
152-
...props,
153-
theme: this.theme_
154-
})
155-
}
140+
const { composeTheme, innerRef, themeNamespace, ...props } = this.props //eslint-disable-line no-unused-vars
156141

157-
return renderedElement
142+
return React.createElement(ThemedComponent, {
143+
...props,
144+
ref: innerRef,
145+
theme: this.theme_
146+
})
158147
}
159148
}
160149

‎test/components/themr.spec.js‎

Lines changed: 7 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ describe('Themr decorator function', () => {
1010
class Passthrough extends Component {
1111
render() {
1212
const { theme, ...props } = this.props //eslint-disable-line no-unused-vars
13-
return <div {...props} />
13+
return <div ref={(node)=>{this.rootNode=node}}{...props} />
1414
}
1515
}
1616

@@ -278,55 +278,18 @@ describe('Themr decorator function', () => {
278278
expect(stub.props.theme).toEqual({})
279279
})
280280

281-
it('should throw when trying to access the wrapped instance if withRef is not specified', () => {
282-
const theme = { Container: { foo: 'foo_1234' } }
283-
284-
@themr('Container')
281+
it('gets the reference to a decorated component using innerRef prop', () => {
285282
class Container extends Component {
286283
render() {
287284
return <Passthrough {...this.props} />
288285
}
289286
}
290287

291-
const tree = TestUtils.renderIntoDocument(
292-
<ProviderMock theme={theme}>
293-
<Container />
294-
</ProviderMock>
295-
)
296-
297-
const container = TestUtils.findRenderedComponentWithType(tree, Container)
298-
expect(() => container.getWrappedInstance()).toThrow(
299-
/Toaccessthewrappedinstance,youneedtospecify\{withRef:true\}asthethirdargumentofthethemr\(\)call\./
300-
)
301-
})
302-
303-
it('should return the instance of the wrapped component for use in calling child methods', () => {
304-
const someData = {
305-
some: 'data'
306-
}
307-
308-
class Container extends Component {
309-
someInstanceMethod() {
310-
return someData
311-
}
312-
313-
render() {
314-
return <Passthrough />
315-
}
316-
}
317-
318-
const decorator = themr('Component', null, { withRef: true })
319-
const Decorated = decorator(Container)
320-
321-
const tree = TestUtils.renderIntoDocument(
322-
<Decorated />
323-
)
324-
325-
const decorated = TestUtils.findRenderedComponentWithType(tree, Decorated)
326-
327-
expect(() => decorated.someInstanceMethod()).toThrow()
328-
expect(decorated.getWrappedInstance().someInstanceMethod()).toBe(someData)
329-
expect(decorated.refs.wrappedInstance.someInstanceMethod()).toBe(someData)
288+
const spy = sinon.stub()
289+
const ThemedContainer = themr('Container')(Container)
290+
const tree = TestUtils.renderIntoDocument(<ThemedContainer innerRef={spy} />)
291+
const stub = TestUtils.findRenderedComponentWithType(tree, Container)
292+
expect(spy.withArgs(stub).calledOnce).toBe(true)
330293
})
331294

332295
it('should throw if themeNamespace passed without theme', () => {
@@ -510,7 +473,6 @@ describe('Themr decorator function', () => {
510473
)
511474

512475
const stub = TestUtils.findRenderedComponentWithType(tree, Passthrough)
513-
// expect(stub.props.theme).toEqual(containerTheme)
514476
expect(stub.props.themeNamespace).toNotExist()
515477
expect(stub.props.composeTheme).toNotExist()
516478
expect(stub.props.theme).toExist()

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /