Skip to content

Commit

Permalink
Adds getDOMElement() to createComponent.js (#22)
Browse files Browse the repository at this point in the history
* Added a new method to the createComponent, called 'getDOMElement', to retrieve the root DOM element of the component

* Added a test to cover the new method getDOMElement(). For that I imported ReactDOM and added an expectedRender with a JSX to be rendered and be asserted with

* Fixed typo in JSDoc

* Added documentation about the getDOMElement() in the createComponent.js

* Changed the createComponent.spec.js to remove the created/rendered component in the afterEach() spec's lifecycle
  • Loading branch information
mAiNiNfEcTiOn authored Aug 15, 2016
1 parent 2324cf9 commit 28518cc
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 6 deletions.
28 changes: 28 additions & 0 deletions docs/api/createComponent.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,34 @@ const MyComponent = createComponent({
});
```

## Custom methods

The `createComponent` function also adds some custom methods to the object passed to it. These can be called directly
by the instance of the component.

```js
import { createComponent } from 'frint';

const MyComponent = createComponent({
handleSubmit(e) {
const rootElement = this.getDOMElement();

/** Adds the class .hide to the component's root DOM element */
rootElement.classList.add('hide');
},

render() {
return <div><button onClick={this.handleSubmit}>Click me to hide</button></div>;
}
});
```

### getDOMElement

This method returns the topmost HTMLElement of your component's DOM tree. In case you don't have any DOM tree rendered,
it will return `null`.


## Lifecycle events

On the object passed to `createComponent`, certain lifecycle events can be defined. These will be called by the framework automatically.
Expand Down
15 changes: 14 additions & 1 deletion src/createComponent.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import ReactDOM from 'react-dom';

/**
* Module that specifies the createComponent function for creating Components.
Expand All @@ -18,6 +19,7 @@ import React from 'react';
export default function createComponent(options = {}) {
return React.createClass({
...options,

componentDidMount() {
if (typeof options.afterMount === 'function') {
return options.afterMount.call(this);
Expand All @@ -32,6 +34,17 @@ export default function createComponent(options = {}) {
}

return null;
}
},

/**
* Returns the root HTML element of the component.
*
* @method getDOMElement
* @return {HTMLElement|null} Returns the component's root HTML Node.
* @public
*/
getDOMElement() {
return ReactDOM.findDOMNode(this);
},
});
}
19 changes: 14 additions & 5 deletions test/createComponent.spec.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
/* global describe, it */
import chai, { expect } from 'chai';
import createComponent from '../src/createComponent';
import React from 'react';
import ReactDOM from 'react-dom';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import createComponent from '../src/createComponent';

const sandbox = sinon.sandbox.create();
chai.use(sinonChai);

describe('createComponent', () => {
const expectedRender = <div className="test"></div>;
const mySpec = {
myCustomFunction() { return 'foo'; },
render() { return null; }
render() { return expectedRender; }
};
let MyComponent;
let myComponentInstance;

beforeEach(() => {
sandbox.spy(React, 'createClass');
MyComponent = createComponent(mySpec);
myComponentInstance = new MyComponent();
myComponentInstance = ReactDOM.render(React.createElement(MyComponent), document.getElementById('root'));
});

afterEach(() => {
const element = document.querySelector('#root .test');
element.parentNode.removeChild(element);
sandbox.restore();
});

Expand All @@ -33,7 +37,8 @@ describe('createComponent', () => {
myCustomFunction: mySpec.myCustomFunction,
render: mySpec.render,
componentDidMount: sinon.match.func,
componentWillUnmount: sinon.match.func
componentWillUnmount: sinon.match.func,
getDOMElement: sinon.match.func
});
});

Expand All @@ -42,8 +47,12 @@ describe('createComponent', () => {
expect(myComponentInstance).to.be.instanceof(MyComponent);
});

it('gets the DOM Node when executing getDOMElement()', () => {
expect(myComponentInstance.getDOMElement()).to.be.equal(document.querySelector('#root .test'));
});

it('has the spec\'s functions', () => {
expect(myComponentInstance.myCustomFunction()).to.be.equal('foo');
expect(myComponentInstance.render()).to.be.equal(null);
expect(myComponentInstance.render()).to.be.equal(expectedRender);
});
});

0 comments on commit 28518cc

Please sign in to comment.