Skip to content

Commit 9ef3b34

Browse files
committed
complete viewer core
1 parent 457aaa8 commit 9ef3b34

14 files changed

+419
-271
lines changed

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
node_modules/
1+
node_modules/
2+
dist/
3+
lib/

demo/index.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from 'react';
22
import * as ReactDOM from 'react-dom';
3-
import ViewerWrap from '../src/ViewerWrap';
3+
import Viewer from '../src/Viewer';
44
const img2 = require('./images/landscape2.jpg');
55
const img = require('./images/landscape.jpg');
66
const img3 = require('./images/tibet-6.jpg');
@@ -18,7 +18,7 @@ class App extends React.Component<any, any> {
1818
return (
1919
<div>
2020
<button onClick={() => { this.setState({ visible: !this.state.visible }); } }>show</button>
21-
<ViewerWrap
21+
<Viewer
2222
visible={this.state.visible}
2323
onClose={() => { this.setState({ visible: false }); } }
2424
images={[img2, img, img3]}

getBabelCommonConfig.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = function getBabelCommonConfig() {
2+
const babelConfig = require('atool-build/lib/getBabelCommonConfig')();
3+
babelConfig.plugins.push([require.resolve('babel-plugin-transform-runtime'),
4+
{ polyfill: false }]);
5+
return babelConfig;
6+
};

getTSCommonConfig.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use strict';
2+
3+
module.exports = function () {
4+
return {
5+
target: 'es6',
6+
jsx: 'preserve',
7+
moduleResolution: 'node',
8+
declaration: true,
9+
allowSyntheticDefaultImports: true,
10+
};
11+
};

gulpfile.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
const gulp = require('gulp');
2+
const ts = require('gulp-typescript');
3+
const tsConfig = require('./getTSCommonConfig')();
4+
const babelConfig = require('./getBabelCommonConfig')();
5+
delete babelConfig.cacheDirectory;
6+
const babel = require('gulp-babel');
7+
const transformLess = require('atool-build/lib/transformLess');
8+
const through2 = require('through2');
9+
const merge2 = require('merge2');
10+
11+
function babelify(js) {
12+
return js.pipe(babel(babelConfig))
13+
.pipe(gulp.dest('lib'));
14+
}
15+
16+
gulp.task('default', () => {
17+
const less = gulp.src(['src/' + '**/' + '*.less'])
18+
.pipe(through2.obj(function (file, encoding, next) {
19+
this.push(file.clone());
20+
if (file.path.match(/\/style\/index\.less$/)) {
21+
transformLess(file.path).then((css) => {
22+
file.contents = new Buffer(css);
23+
file.path = file.path.replace(/\.less$/, '.css');
24+
this.push(file);
25+
next();
26+
}).catch((e) => {
27+
console.error(e);
28+
});
29+
} else {
30+
next();
31+
}
32+
}))
33+
.pipe(gulp.dest('lib'));
34+
const img = gulp.src(['src/' + '**/' + '*.png']).pipe(gulp.dest('lib'));
35+
const tsResult = gulp.src([
36+
'src/' + '**/' + '*.tsx',
37+
]).pipe(ts(tsConfig));
38+
const tsFiles = babelify(tsResult.js);
39+
const tsd = tsResult.dts.pipe(gulp.dest('lib'));
40+
return merge2([tsFiles, tsd]);
41+
});

package.json

+15-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
"name": "react-viewer",
33
"version": "0.0.1",
44
"description": "react image viewer",
5-
"main": "dist/ViewerWrap",
5+
"main": "dist/index",
66
"scripts": {
77
"test": "echo \"Error: no test specified\" && exit 1",
88
"start": "dora --port 8001 --plugins \"webpack,webpack-hmr,browser-history?index=/demo/index.html\"",
9-
"lint": "tslint -c tslint.json src/**/*.ts src/**/*.tsx"
9+
"lint": "tslint -c tslint.json src/**/*.ts src/**/*.tsx",
10+
"build": "atool-build --config webpack.config.prop.js && gulp"
1011
},
1112
"repository": {
1213
"type": "git",
@@ -22,21 +23,33 @@
2223
"bugs": {
2324
"url": "https://github.com/infeng/react-viewer/issues"
2425
},
26+
"files": [
27+
"dist",
28+
"lib"
29+
],
30+
"typings": "lib/index.d.ts",
2531
"homepage": "https://github.com/infeng/react-viewer#readme",
2632
"devDependencies": {
2733
"@types/node": "^6.0.45",
2834
"@types/react": "^0.14.39",
2935
"@types/react-dom": "^0.14.17",
3036
"atool-build": "^0.8.1",
37+
"babel-plugin-transform-runtime": "^6.15.0",
38+
"babel-runtime": "^6.11.6",
3139
"dora": "^0.4.3",
3240
"dora-plugin-browser-history": "^0.2.0",
3341
"dora-plugin-webpack": "^0.8.1",
3442
"dora-plugin-webpack-hmr": "^0.2.1",
43+
"gulp": "^3.9.1",
44+
"gulp-babel": "^6.1.2",
45+
"gulp-typescript": "^3.0.2",
3546
"html-loader": "^0.4.4",
3647
"html-webpack-plugin": "^2.22.0",
48+
"merge2": "^1.0.2",
3749
"pre-commit": "^1.1.3",
3850
"react": "^15.3.2",
3951
"react-dom": "^15.3.2",
52+
"through2": "^2.0.1",
4053
"tslint": "^3.15.1",
4154
"typescript": "^2.0.3",
4255
"webpack": "^1.13.2"

src/Viewer.tsx

+49-60
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,67 @@
11
import * as React from 'react';
2-
import './style/index.less';
2+
import * as ReactDOM from 'react-dom';
33
import ViewerCore from './ViewerCore';
4-
import ViewerNav from './ViewerNav';
4+
import ViewerProps from './ViewerProps';
55

6-
function noop() {}
6+
export default class Viewer extends React.Component<ViewerProps, any> {
7+
private container: HTMLDivElement;
8+
private component: React.ReactNode;
79

8-
interface ViewerState {
9-
activeIndex?: number;
10-
}
11-
12-
export default class Viewer extends React.Component<ViewerProps, ViewerState> {
13-
static defaultProps = {
14-
visible: false,
15-
onClose: noop,
16-
images: [],
17-
activeIndex: 0,
18-
};
19-
20-
private prefixCls: string;
21-
22-
constructor(props) {
23-
super(props);
10+
constructor() {
11+
super();
2412

25-
this.prefixCls = 'react-viewer';
13+
this.container = null;
14+
this.component = null;
15+
}
2616

27-
this.state = {
28-
activeIndex: this.props.activeIndex,
29-
};
17+
renderViewer() {
18+
if (this.props.visible || this.component) {
19+
if (!this.container) {
20+
this.container = document.createElement('div');
21+
}
22+
document.body.appendChild(this.container);
23+
let instance = this;
24+
ReactDOM.unstable_renderSubtreeIntoContainer(
25+
this,
26+
<ViewerCore
27+
{...this.props}
28+
/>,
29+
this.container,
30+
function () {
31+
instance.component = this;
32+
},
33+
);
34+
}
35+
}
3036

31-
this.handleChangeImg = this.handleChangeImg.bind(this);
37+
removeViewer() {
38+
if (this.container) {
39+
const container = this.container;
40+
ReactDOM.unmountComponentAtNode(container);
41+
container.parentNode.removeChild(container);
42+
this.container = null;
43+
this.component = null;
44+
}
3245
}
3346

34-
handleClose(e) {
35-
this.props.onClose();
47+
componentWillUnmount() {
48+
if (this.props.visible) {
49+
this.props.onClose();
50+
this.removeViewer();
51+
} else {
52+
this.removeViewer();
53+
}
3654
}
3755

38-
handleChangeImg(newIndex: number) {
39-
let newState = this.state;
40-
newState.activeIndex = newIndex;
41-
this.setState(newState);
56+
componentDidMount() {
57+
this.renderViewer();
4258
}
4359

44-
componentWillReceiveProps(nextProps: ViewerProps) {
45-
if (this.state.activeIndex !== nextProps.activeIndex) {
46-
this.setState({
47-
activeIndex: nextProps.activeIndex,
48-
});
49-
}
60+
componentDidUpdate() {
61+
this.renderViewer();
5062
}
5163

5264
render() {
53-
let activeImgSrc = '';
54-
if (this.props.images.length > 0) {
55-
activeImgSrc = this.props.images[this.state.activeIndex];
56-
}
57-
58-
return (
59-
<div style={{display: this.props.visible ? 'block' : 'none'}}>
60-
<div className={`${this.prefixCls}-mask`}></div>
61-
<div className={`${this.prefixCls}-close`} onClick={this.handleClose.bind(this)}></div>
62-
<ViewerCore
63-
prefixCls={this.prefixCls}
64-
imgSrc={activeImgSrc}
65-
visible={this.props.visible}
66-
/>
67-
<div className={`${this.prefixCls}-footer`}>
68-
<ViewerNav
69-
prefixCls={this.prefixCls}
70-
images={this.props.images}
71-
activeIndex={this.state.activeIndex}
72-
onChangeImg={this.handleChangeImg}
73-
/>
74-
</div>
75-
</div>
76-
);
65+
return null;
7766
}
7867
}

0 commit comments

Comments
 (0)