Skip to content

Commit 0b1241a

Browse files
committed
first commit
0 parents  commit 0b1241a

24 files changed

+412
-0
lines changed

.editorconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# top-most EditorConfig file
2+
root = true
3+
4+
# Unix-style newlines with a newline ending every file
5+
[*]
6+
end_of_line = lf
7+
charset = utf-8
8+
indent_style = space
9+
indent_size = 4

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.idea
2+
node_modules
3+
coverage
4+
npm-debug.log

.npmignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
__mocks__
3+
coverage
4+
tslint.json

README.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
## About
2+
This project is an example for using Typescript, React to build UI components module, which could be used by other client
3+
typescript project.
4+
5+
This project will generate TypeDefinitions(*.d.ts) files for the UI components, thus providing code completion and type
6+
checking.
7+
8+
Libraries which used inside this project:
9+
* React
10+
* Typescript
11+
* Bootstrap@3
12+
* Storybook
13+
* Standard-version
14+
15+
### Usage
16+
* Install dependencies
17+
```bash
18+
$ npm install -S bootstrap@3
19+
$ npm i -S NPM-path/ui-widgets-ts
20+
```
21+
22+
* Import
23+
```js
24+
// CSS Assets
25+
import "bootstrap/dist/css/bootstrap.min.css";
26+
27+
// JS Assets
28+
import "jquery";
29+
import "bootstrap/dist/js/bootstrap.js";
30+
31+
```
32+
33+
* Use components, e.g. Button
34+
```js
35+
36+
import { Button as MyTestBtn } from "ui-widgets-ts";
37+
or
38+
import { Button as MyTestBtn } from "ui-widgets-ts/dist/Button";
39+
40+
...
41+
<MyTestBtn type="danger">My Test Button</MyTestBtn>
42+
...
43+
```
44+
45+
### Development
46+
47+
* Open first terminal
48+
```
49+
$ npm install
50+
$ npm run watch
51+
```
52+
53+
* open second terminal
54+
§```
55+
$ npm run build
56+
$ npm run storybook
57+
```
58+
visit: http://localhost:9001/
59+
60+
Folder `src` is all the place we write our components
61+
62+
Folder `storybook` is the place we view/test our components. New component
63+
should always be added as stories in the [react-storybook](https://storybooks.js.org/).
64+
65+
#### Test
66+
[JEST](https://facebook.github.io/jest/) framework.
67+
68+
Create files `*.(test|spec).tsx` under `src` folder and then write test code. Code coverage must be fulfilled.
69+
70+
```
71+
$ npm run test
72+
```
73+
74+
#### Production build
75+
* `npm run build`
76+
This `/dist` folder could be used as the module dependency such as in NPM, or in Github Repo

__mocks__/fileMock.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// __mocks__/fileMock.js
2+
3+
module.exports = 'test-file-stub';

__mocks__/styleMock.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// __mocks__/styleMock.js
2+
3+
module.exports = {};

dist/Button/index.d.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/// <reference types="react" />
2+
import * as React from "react";
3+
export declare type BtnType = "danger" | "info" | "warning" | "success" | "primary";
4+
export interface IBtnProps {
5+
type: BtnType;
6+
onClick?: any;
7+
}
8+
export declare class Button extends React.Component<IBtnProps, any> {
9+
render(): JSX.Element;
10+
}

dist/Button/index.js

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/Button/index.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { Button } from "./Button";

dist/index.js

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
{
2+
"name": "ui-react-module-typescript-storybook-jest",
3+
"version": "1.0.0",
4+
"description": "Module by React Typescript",
5+
"author": "caitengjiao1987@gmail.com",
6+
"keywords": [
7+
"Component",
8+
"Typescript",
9+
"Module",
10+
"React",
11+
"Storybook",
12+
"JEST"
13+
],
14+
"main": "./dist/index.js",
15+
"typings": "./dist/index.d.ts",
16+
"scripts": {
17+
"clean": "rimraf dist/*",
18+
"copy": "cpx 'src/app/**/*.{png,jpg,css}' dist",
19+
"build:ts": "tsc -p src",
20+
"test": "jest --notify --coverage --bail",
21+
"watch": "tsc -p src -w",
22+
"prebuild": "npm run clean && npm run test && npm run copy",
23+
"build": "npm run build:ts",
24+
"storybook": "start-storybook -p 9001 -c storybook/.config"
25+
},
26+
"jest": {
27+
"globals": {
28+
"__TS_CONFIG__": "src/tsconfig.json"
29+
},
30+
"moduleFileExtensions": [
31+
"ts",
32+
"tsx",
33+
"js"
34+
],
35+
"moduleNameMapper": {
36+
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
37+
"\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js"
38+
},
39+
"transform": {
40+
".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
41+
},
42+
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx)$",
43+
"coverageThreshold": {
44+
"global": {
45+
"lines": 75
46+
}
47+
}
48+
},
49+
"devDependencies": {
50+
"@kadira/react-storybook-addon-info": "^3.4.0",
51+
"@kadira/storybook": "^2.35.3",
52+
"@kadira/storybook-addon-knobs": "^1.7.1",
53+
"@types/enzyme": "^2.7.9",
54+
"@types/jest": "^19.2.2",
55+
"@types/node": "^7.0.13",
56+
"@types/react": "^15.0.22",
57+
"@types/react-dom": "^0.14.23",
58+
"bootstrap": "^3.3.7",
59+
"cpx": "^1.5.0",
60+
"cross-env": "^4.0.0",
61+
"css-loader": "^0.28.0",
62+
"enzyme": "^2.8.2",
63+
"expose-loader": "^0.7.3",
64+
"file-loader": "^0.11.1",
65+
"imports-loader": "^0.7.1",
66+
"jest": "^19.0.2",
67+
"jquery": "^2.2.4",
68+
"react": "^15.5.4",
69+
"react-dom": "^15.5.4",
70+
"react-test-renderer": "^15.5.4",
71+
"rimraf": "^2.6.1",
72+
"source-map-loader": "^0.2.1",
73+
"ts-jest": "^19.0.10",
74+
"ts-loader": "^2.0.3",
75+
"tslint": "^5.1.0",
76+
"tslint-loader": "^3.5.2",
77+
"typescript": "^2.3.0",
78+
"url-loader": "^0.5.8",
79+
"webpack": "^2.4.1",
80+
"webpack-merge": "^4.1.0"
81+
}
82+
}

src/app/Button/button.test.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import {shallow} from "enzyme";
2+
import * as React from "react";
3+
import {Button} from "./index";
4+
5+
test("Button should work", () => {
6+
// Render a button with type
7+
const btn = shallow(
8+
<Button type="danger">Test</Button>,
9+
);
10+
11+
expect(btn.text()).toEqual("Test");
12+
});

src/app/Button/index.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import * as React from "react";
2+
3+
export type ButtonType = "danger" | "info" | "warning" | "success" | "primary" ;
4+
5+
export interface IBtnProps {
6+
type: ButtonType;
7+
onClick?: () => {};
8+
}
9+
10+
/**
11+
* Implement Bootstrap button react component by Typescript.
12+
* For the client project who used this, just add bootstrap CSS thus will work.
13+
*/
14+
export class Button extends React.Component<IBtnProps, any> {
15+
16+
public render() {
17+
const {type, onClick, children} = this.props;
18+
return (
19+
<button onClick={onClick} type="button" className={`btn btn-${type}`}>{children}</button>
20+
);
21+
}
22+
}

src/app/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { Button } from "./Button";

src/tsconfig.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"compilerOptions": {
3+
"sourceMap": true,
4+
"noImplicitAny": false,
5+
"suppressImplicitAnyIndexErrors": true,
6+
"removeComments": true,
7+
"pretty": false,
8+
"module": "commonjs",
9+
"target": "es6",
10+
"jsx": "react",
11+
"strictNullChecks": true,
12+
"declaration": true,
13+
"experimentalDecorators": true,
14+
"emitDecoratorMetadata":true,
15+
"lib": [
16+
"es2015",
17+
"es2016",
18+
"es2017",
19+
"dom"
20+
],
21+
"outDir": "../dist"
22+
},
23+
"exclude": [
24+
"node_modules",
25+
"**/*.test.tsx",
26+
"**/*.test.ts"
27+
]
28+
}

storybook/.config/addons.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import '@kadira/storybook/addons';
2+
3+
// To add the knobs addon
4+
import '@kadira/storybook-addon-knobs/register'

storybook/.config/config.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { configure, setAddon } from '@kadira/storybook';
2+
import infoAddon from '@kadira/react-storybook-addon-info';
3+
4+
setAddon(infoAddon);
5+
6+
const req = require.context('../stories', true, /.stories.tsx$/)
7+
8+
function loadStories() {
9+
req.keys().forEach((filename) => req(filename))
10+
}
11+
12+
configure(loadStories, module);

storybook/.config/webpack.config.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// load the default config generator.
2+
const genDefaultConfig = require('@kadira/storybook/dist/server/config/defaults/webpack.config.js');
3+
const path = require('path');
4+
const webpack = require('webpack');
5+
const webpackMerge = require('webpack-merge');
6+
7+
/**
8+
* Webpack config for Storybook
9+
* In reality, most project will use Webpack2, TS, React to bundle the build
10+
* So the configuration here is also a mimic/prove for the client projects who use ui-widgets-ts package.
11+
*/
12+
module.exports = function (config, env) {
13+
const default_config = genDefaultConfig(config, env);
14+
15+
// Extend it as you need.
16+
const final_config = webpackMerge.smart(default_config, {
17+
module: {
18+
loaders: [
19+
{
20+
test: /\.ts(x)?$/,
21+
loaders: ['ts-loader']
22+
},
23+
{ test: require.resolve("jquery"), loader: "expose-loader?$!expose-loader?jQuery" }
24+
]
25+
},
26+
27+
resolve: {
28+
// Resolve alias so as to make import { Button } from "ui-widgets" works
29+
alias: {
30+
"ui-widgets-ts": path.resolve(__dirname, "../../dist")
31+
}
32+
}
33+
});
34+
35+
return final_config;
36+
};
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import {action, storiesOf} from "@kadira/storybook";
2+
import {text, withKnobs} from "@kadira/storybook-addon-knobs";
3+
4+
import {Button} from "ui-widgets-ts";
5+
import * as React from "react";
6+
7+
const stories: any = storiesOf("Bootstrap", module);
8+
stories.addDecorator(withKnobs);
9+
10+
stories.addWithInfo("Button", "Demo bootstrap buttons", () => (
11+
<div>
12+
<Button type="danger"
13+
onClick={action("clicked")}>
14+
{text("Label", "danger Button")}
15+
</Button>
16+
<Button type="info"
17+
onClick={action("clicked")}>
18+
{text("Label", "info Button")}
19+
</Button>
20+
</div>
21+
));
22+

storybook/stories/global.stories.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// CSS Assets
2+
import "bootstrap/dist/css/bootstrap.min.css";
3+
4+
// JS Assets
5+
import "jquery";
6+
import "bootstrap/dist/js/bootstrap.js";

0 commit comments

Comments
 (0)