Skip to content

Commit e700457

Browse files
committed
* Moved Bootstrap and jQuery to external dependencies.
* Changed to a fork of sequence-viewer repository to remove need for Handlebars.js. It isn't used by sequence-viewer, but it is still included in the source. Including it causes build errors when trying to use it as a component. * Upgraded a few other dependencies.
1 parent f60923e commit e700457

File tree

6 files changed

+151
-120
lines changed

6 files changed

+151
-120
lines changed

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,22 @@ component.
1515
npm install --save react-sequence-viewer
1616
```
1717

18+
## Dependencies
19+
20+
The following are dependencies required by the `sequence-viewer` module that is wrapped
21+
by this React component.
22+
23+
* jQuery
24+
* Bootstrap CSS
25+
26+
You can either include these into your HTML page or add them to your
27+
own application build (see usage below).
28+
29+
````html
30+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
31+
<link type="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"></link>
32+
```
33+
1834
## Usage
1935

2036
The following code renders a sequence-viewer component in the HTML
@@ -25,6 +41,16 @@ element with an ID of 'sequence-viewer1'.
2541
```jsx
2642
import React from 'react';
2743
import {render} from 'react-dom';
44+
45+
// Either uncomment these lines or pull
46+
// in jQuery and Bootstrap into the HTML page of your application.
47+
// The below requires that jQuery/Bootstrap be installed as a dependency
48+
// in your package.json file.
49+
//import jquery from 'jquery';
50+
//window.jQuery = jquery;
51+
52+
//import 'bootstrap/dist/css/bootstrap.min.css';
53+
2854
import ReactSequenceViewer from 'react-sequence-viewer';
2955

3056
const mySeq = 'CAGTCGATCGTAGCTAGCTAGCTGATCGATGC';
@@ -41,6 +67,16 @@ render(React.createClass({
4167
```jsx
4268
import React from 'react';
4369
import {render} from 'react-dom';
70+
71+
// Either uncomment these lines or pull
72+
// in jQuery and Bootstrap into the HTML page of your application.
73+
// The below requires that jQuery/Bootstrap be installed as a dependency
74+
// in your package.json file.
75+
//import jquery from 'jquery';
76+
//window.jQuery = jquery;
77+
78+
//import 'bootstrap/dist/css/bootstrap.min.css';
79+
4480
import ReactSequenceViewer from 'react-sequence-viewer';
4581

4682
const mySeq = 'CAGTCGATCGTAGCTAGCTAGCTGATCGATGC';

demo/src/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ import React from 'react'
22
import {render} from 'react-dom'
33

44
import Component from '../../src'
5+
import jquery from 'jquery';
6+
window.jQuery = jquery;
7+
8+
import 'bootstrap/dist/css/bootstrap.min.css';
59

610
//const seq = 'MALWMRLLPLLALLALWGPGPGAGSLQPLALEGSLQKRGIVEQCCTSICSLYQLENYCN';
711
const seq = 'MALWMRLLPLLALLALWGPDPAAAFVNQHLCGSHLVEALYLVCGERGFFYTPKTRREAEDLQVGQVELGGGPGAGSLQPLALEGSLQKRGIVEQCCTSICSLYQLENYCN';
@@ -43,7 +47,7 @@ let Demo = React.createClass({
4347
render() {
4448
return <div>
4549
<h1>react-sequence-viewer Demo</h1>
46-
<Component onSubpartSelected={subPart} onMouseSelection={mouseClick} legend={exampleLegend} coverage={exampleSequenceCoverage} sequence={seq} showLineNumbers={true} toolbar={true} search={true} badge={false} title="" />
50+
<Component onSubpartSelected={subPart} onMouseSelection={mouseClick} legend={exampleLegend} coverage={exampleSequenceCoverage} sequence={seq} showLineNumbers={true} toolbar={true} search={true} badge={true} title="My Protein" />
4751
</div>
4852
}
4953
})

nwb.config.js

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,9 @@ module.exports = {
1111
}
1212
}
1313
},
14-
// Override require('handlebars') in sequence-viewer.js
15-
// Without this, the sequence-viewer package will require
16-
// the main Handlebar.js bundle, which causes problems with webpack.
17-
//
18-
// To avoid these problems, you can also import the Handlebars.js
19-
// runtime only package, but that requires the use of external templates
20-
// and a webpack loader to precompile them. The sequence-viewer component
21-
// uses inline Handlebars.js templates currently.
2214
webpack: {
2315
compat: {
2416
enzyme: true
25-
},
26-
aliases: {
27-
'handlebars': path.resolve("node_modules/handlebars/dist/handlebars.min.js"),
28-
'jQuery': path.resolve("node_modules/jquery/dist/jquery.min.js")
2917
}
3018
}
3119
};

package.json

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-sequence-viewer",
3-
"version": "0.1.2",
3+
"version": "0.1.3",
44
"description": "A React wrapper around the BioJS sequence-viewer component",
55
"main": "lib/index.js",
66
"jsnext:main": "es/index.js",
@@ -20,18 +20,17 @@
2020
"test:watch": "nwb test --server"
2121
},
2222
"dependencies": {
23-
"bootstrap": "^3.3.7",
24-
"handlebars": "3.0.2",
25-
"jquery": "^3.1.0",
26-
"sequence-viewer": "^0.2.18",
27-
"uuid": "^3.0.0"
23+
"sequence-viewer": "github:FlyBase/sequence-viewer",
24+
"uuid": "^3.0.1"
2825
},
2926
"peerDependencies": {
3027
"react": "15.x"
3128
},
3229
"devDependencies": {
30+
"bootstrap": "^3.3.7",
3331
"enzyme": "^2.4.1",
34-
"nwb": "0.12.x",
32+
"jquery": "^3.1.1",
33+
"nwb": "0.13.x",
3534
"react": "^15.3.1",
3635
"react-addons-test-utils": "^15.3.1",
3736
"react-dom": "^15.3.1"

src/index.js

Lines changed: 98 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,124 +1,122 @@
11
import React, {PropTypes, Component} from 'react';
22
import { v4 } from 'uuid';
33

4-
import Bootstrap from 'bootstrap/dist/css/bootstrap.min.css';
5-
// See nwb.config.js for some webpack magic that allows this to work.
64
import Sequence from 'sequence-viewer';
75

86
export default class ReactSequenceViewer extends Component {
9-
constructor(props) {
10-
super(props);
11-
this.handleChange = this.handleChange.bind(this);
7+
constructor(props) {
8+
super(props);
9+
this.handleChange = this.handleChange.bind(this);
1210

13-
if (props.selection && props.selection.length > 0 && props.coverage && props.coverage.length > 0) {
14-
console.warn("The selection and coverage options are not compatible with each other.");
15-
}
16-
// Initialize the sequence-viewer object.
17-
this._seqObj = new Sequence(this.props.sequence);
18-
this._div = null;
11+
if (props.selection && props.selection.length > 0 && props.coverage && props.coverage.length > 0) {
12+
console.warn("The selection and coverage options are not compatible with each other.");
1913
}
14+
// Initialize the sequence-viewer object.
15+
this._seqObj = new Sequence(this.props.sequence);
16+
this._div = null;
17+
}
2018

21-
// Function to call the render function of sequence-viewer.
22-
// You can override existing props by passing an object with key value
23-
// pairs to override existing props.
24-
// e.g.
25-
// callRender({toolbar: false})
26-
// would override the existing toolbar setting.
27-
callRender(newProps = {}) {
28-
const { selection, ...props} = this.props;
19+
// Function to call the render function of sequence-viewer.
20+
// You can override existing props by passing an object with key value
21+
// pairs to override existing props.
22+
// e.g.
23+
// callRender({toolbar: false})
24+
// would override the existing toolbar setting.
25+
callRender(newProps = {}) {
26+
const { selection, ...props} = this.props;
2927

30-
// Read in div from private variable.
31-
const div = this._div;
28+
// Read in div from private variable.
29+
const div = this._div;
3230

33-
//Render div if it is not null.
34-
if (div !== null) {
35-
this._seqObj.render('#' + div.id,{...props,...newProps});
36-
this._seqObj.coverage(this.props.coverage);
37-
this._seqObj.addLegend(this.props.legend);
38-
if (selection.length > 0) this._seqObj.selection(...selection);
39-
}
31+
//Render div if it is not null.
32+
if (div !== null) {
33+
this._seqObj.render('#' + div.id,{...props,...newProps});
34+
this._seqObj.coverage(this.props.coverage);
35+
this._seqObj.addLegend(this.props.legend);
36+
if (selection.length > 0) this._seqObj.selection(...selection);
4037
}
38+
}
4139

42-
// When the component mounts, add a change listenver to the document
43-
// and call render. We attach the change listener here becuase
44-
// jQuery events don't see to bubble up through React properly.
45-
// Thus, when a user toggles the charsPerLine drop down menu.
46-
// the event is handled by jQuery, but not seen by React when the
47-
// listener is attached at the component div level.
48-
// Attaching it to the document seems to work.
49-
componentDidMount() {
50-
document.addEventListener('change', this.handleChange);
51-
this.callRender();
52-
this._seqObj.onSubpartSelected(this.props.onSubpartSelected);
53-
this._seqObj.onMouseSelection(this.props.onMouseSelection);
54-
}
40+
// When the component mounts, add a change listenver to the document
41+
// and call render. We attach the change listener here becuase
42+
// jQuery events don't see to bubble up through React properly.
43+
// Thus, when a user toggles the charsPerLine drop down menu.
44+
// the event is handled by jQuery, but not seen by React when the
45+
// listener is attached at the component div level.
46+
// Attaching it to the document seems to work.
47+
componentDidMount() {
48+
document.addEventListener('change', this.handleChange);
49+
this.callRender();
50+
this._seqObj.onSubpartSelected(this.props.onSubpartSelected);
51+
this._seqObj.onMouseSelection(this.props.onMouseSelection);
52+
}
5553

56-
// Remove the event listener when the component is unmounted.
57-
componentWillUnmount() {
58-
document.removeEventListener('change', this.handleChange);
59-
}
54+
// Remove the event listener when the component is unmounted.
55+
componentWillUnmount() {
56+
document.removeEventListener('change', this.handleChange);
57+
}
6058

61-
// Function called when the user changes the charsPerLine setting via the toolbar.
62-
handleChange(e) {
63-
const elem = e.target;
64-
// Check that the event was triggered by the right <select> button.
65-
if ((" " + elem.className + " " ).indexOf( " " + this.props.seqLenClass + " " ) > -1) {
66-
// Call render and override the charsPerLine setting with whatever the user specified.
67-
this.callRender({charsPerLine: elem.value});
68-
}
59+
// Function called when the user changes the charsPerLine setting via the toolbar.
60+
handleChange(e) {
61+
const elem = e.target;
62+
// Check that the event was triggered by the right <select> button.
63+
if ((" " + elem.className + " " ).indexOf( " " + this.props.seqLenClass + " " ) > -1) {
64+
// Call render and override the charsPerLine setting with whatever the user specified.
65+
this.callRender({charsPerLine: elem.value});
6966
}
67+
}
7068

71-
// Render a div with the sequence-viwer widget in it.
72-
render() {
73-
const { id, sequence, className } = this.props;
74-
// Create the container div and store a reference to it once it is mounted
75-
// in the DOM. The componentDidMount function above will then get called
76-
// and render the widget.
77-
return (
78-
<div className={className} id={this.props.id} ref={(div) => this._div = div}></div>
79-
);
80-
}
69+
// Render a div with the sequence-viwer widget in it.
70+
render() {
71+
const { id, sequence, className } = this.props;
72+
// Create the container div and store a reference to it once it is mounted
73+
// in the DOM. The componentDidMount function above will then get called
74+
// and render the widget.
75+
return (
76+
<div className={className} id={this.props.id} ref={(div) => this._div = div}></div>
77+
);
78+
}
8179
}
8280

8381
ReactSequenceViewer.propTypes = {
84-
id: PropTypes.string,
85-
sequence: PropTypes.string.isRequired,
86-
className: PropTypes.string,
87-
selection: PropTypes.arrayOf((arr, key, compName, location, propFullName) => {
88-
if (arr.length !== 3) {
89-
return new Error(
90-
'Invalid prop `selection` supplied to `' + compName + '`. Validation failed.'
91-
);
92-
}
93-
}),
94-
coverage: PropTypes.arrayOf(
95-
PropTypes.shape({
96-
start: PropTypes.number.isRequired,
97-
end: PropTypes.number.isRequired,
98-
color : PropTypes.string,
99-
bgcolor : PropTypes.string,
100-
underscore : PropTypes.bool,
101-
tooltip : PropTypes.string,
102-
onclick : PropTypes.func,
103-
})),
104-
legend: PropTypes.arrayOf(
105-
PropTypes.shape({
106-
name: PropTypes.string,
107-
color: PropTypes.string,
108-
underscore: PropTypes.bool,
109-
})),
110-
seqLenClass: PropTypes.string,
111-
onMouseSelection: PropTypes.func,
112-
onSubpartSelected: PropTypes.func,
82+
id: PropTypes.string,
83+
sequence: PropTypes.string.isRequired,
84+
className: PropTypes.string,
85+
selection: PropTypes.arrayOf((arr, key, compName, location, propFullName) => {
86+
if (arr.length !== 3) {
87+
return new Error(
88+
'Invalid prop `selection` supplied to `' + compName + '`. Validation failed.'
89+
);
90+
}
91+
}),
92+
coverage: PropTypes.arrayOf(
93+
PropTypes.shape({
94+
start: PropTypes.number.isRequired,
95+
end: PropTypes.number.isRequired,
96+
color : PropTypes.string,
97+
bgcolor : PropTypes.string,
98+
underscore : PropTypes.bool,
99+
tooltip : PropTypes.string,
100+
onclick : PropTypes.func,
101+
})),
102+
legend: PropTypes.arrayOf(
103+
PropTypes.shape({
104+
name: PropTypes.string,
105+
color: PropTypes.string,
106+
underscore: PropTypes.bool,
107+
})),
108+
seqLenClass: PropTypes.string,
109+
onMouseSelection: PropTypes.func,
110+
onSubpartSelected: PropTypes.func,
113111
};
114112

115113
ReactSequenceViewer.defaultProps = {
116-
id: v4(),
117-
coverage: [],
118-
legend: [],
119-
selection: [],
120-
seqLenClass: "CPLChoice",
121-
onMouseSelection: (elem) => {},
122-
onSubpartSelected: (elem) => {},
123-
className: '',
114+
id: v4(),
115+
coverage: [],
116+
legend: [],
117+
selection: [],
118+
seqLenClass: "CPLChoice",
119+
onMouseSelection: (elem) => {},
120+
onSubpartSelected: (elem) => {},
121+
className: '',
124122
}

tests/index-test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ import React from 'react';
22
import expect, {spyOn, createSpy} from 'expect';
33
import { mount, shallow } from 'enzyme';
44

5+
import jquery from 'jquery';
6+
7+
window.jQuery = jquery;
8+
9+
import 'bootstrap/dist/css/bootstrap.min.css';
10+
511
import Component from 'src/';
612

713
describe('<Component />', () => {

0 commit comments

Comments
 (0)