├── .gitignore ├── README.md ├── backup ├── index.html ├── package.json ├── src ├── components │ ├── container │ │ ├── index.tsx │ │ └── styles.css │ ├── node │ │ ├── index.tsx │ │ └── styles.css │ └── template │ │ ├── index.tsx │ │ └── styles.css ├── constants.ts ├── index.tsx ├── pages │ ├── example-page │ │ ├── index.tsx │ │ └── styles.css │ └── root │ │ ├── index.tsx │ │ ├── reset.css │ │ └── styles.css └── routes.tsx ├── tsconfig.json └── webpack ├── dev.config.js └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Inferno Typescript Template 2 | This is a lightweight template for getting started with the awesome InfernoJS library using Typescript. Those of you coming from React should find the project structure familiar. 3 | 4 | 5 | ### Usage 6 | This project uses Webpack for managing the build pipeline 7 | 8 | #### Debug 9 | This starts a Webpack development server on `http://localhost:8080` Changes made to the source will be automatically reloaded 10 | ``` 11 | npm run debug 12 | ``` 13 | 14 | #### Build 15 | Builds the project to `./build` 16 | ``` 17 | npm run build 18 | ``` 19 | -------------------------------------------------------------------------------- /backup: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "sourceMap": true, 5 | "noImplicitAny": true, 6 | "module": "commonjs", 7 | "target": "es5" 8 | }, 9 | "files": [ 10 | "./typings/inferno.d.ts" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Inferno TypeScript example 4 | 5 | 6 |
7 | 8 | 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "inferno-typescript-template", 3 | "version": "1.0.0", 4 | "description": "A basic example of Inferno with TypeScript", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "webpack -p --config=./webpack/webpack.config.js", 9 | "debug": "webpack-dev-server --config=./webpack/dev.config.js --hot" 10 | }, 11 | "keywords": [ 12 | "inferno", 13 | "typescript" 14 | ], 15 | "author": "Dominic Gannaway", 16 | "license": "MIT", 17 | "dependencies": { 18 | "classnames": "^2.2.5", 19 | "history": "^4.4.1", 20 | "inferno": "^1.5.0", 21 | "inferno-component": "^1.5.0", 22 | "inferno-create-element": "^1.5.0", 23 | "inferno-router": "^1.5.0" 24 | }, 25 | "devDependencies": { 26 | "@types/classnames": "0.0.32", 27 | "awesome-typescript-loader": "^3.0.0-beta.17", 28 | "clean-webpack-plugin": "^0.1.14", 29 | "css-loader": "^0.26.1", 30 | "extract-text-webpack-plugin": "^1.0.1", 31 | "html-webpack-plugin": "^2.24.1", 32 | "postcss": "^5.2.6", 33 | "postcss-cssnext": "^2.9.0", 34 | "postcss-loader": "^1.2.1", 35 | "source-map-loader": "^0.1.5", 36 | "style-loader": "^0.13.1", 37 | "ts-loader": "^2.0.0", 38 | "typescript": "^2.1.5", 39 | "webpack": "^1.14.0", 40 | "webpack-dev-server": "^1.16.2" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/components/container/index.tsx: -------------------------------------------------------------------------------- 1 | import './styles.css' 2 | import createElement from 'inferno-create-element' 3 | import Component from 'inferno-component' 4 | 5 | interface IProps { 6 | } 7 | 8 | interface IState { 9 | 10 | } 11 | 12 | export default class Container extends Component { 13 | constructor() { 14 | super() 15 | } 16 | render() { 17 | const { direction, stretch, styles, ...rest } = this.props 18 | const style = { 19 | display: 'flex', 20 | direction: direction || 'row', 21 | flexGrow: stretch, 22 | ...styles, 23 | } 24 | return ( 25 |
26 |
27 | ) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/components/container/styles.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironbay/inferno-typescript-template/ccab78124ce52d0ace85584a07610624182694f6/src/components/container/styles.css -------------------------------------------------------------------------------- /src/components/node/index.tsx: -------------------------------------------------------------------------------- 1 | import './styles.css' 2 | import createElement from 'inferno-create-element' 3 | import Component from 'inferno-component' 4 | 5 | interface IProps { 6 | data: Object 7 | label: string 8 | path: Array 9 | onEdit: (path: Array, value: any) => void 10 | } 11 | 12 | interface IState { 13 | hidden: boolean 14 | } 15 | 16 | export default class Node extends Component { 17 | 18 | constructor() { 19 | super() 20 | this.state = { 21 | hidden: false 22 | } 23 | } 24 | render() { 25 | const { data, label, path, onEdit } = this.props 26 | const { hidden } = this.state 27 | const count = Object.keys(data).length 28 | return ( 29 |
30 | this.toggle(hidden)} className='node-label'>"{label}": {'{'} 31 | { 32 | !hidden && count > 0 && ( 33 |
34 | { 35 | Object.keys(data).map(key => { 36 | const value = data[key] 37 | if (value === Object(value)) 38 | return ( 39 | 40 | ) 41 | return ( 42 |
43 | {JSON.stringify(key)}: 44 | this.edit([...path, key], value)} 46 | className={`node-value ${typeof(value)}`}> 47 | {JSON.stringify(value)} 48 | 49 |
50 | ) 51 | }) 52 | } 53 |
54 | ) 55 | } 56 | { 57 | hidden && count > 0 && ... 58 | } 59 | {'}'} 60 |
61 | ) 62 | } 63 | toggle(val: boolean) { 64 | this.setState({ 65 | hidden: !val, 66 | }) 67 | } 68 | edit(path: Array, value: any) { 69 | const { onEdit } = this.props 70 | if (!onEdit) 71 | return 72 | const next = prompt(`Edit ${path.join('.')}`, value) 73 | if (!next) 74 | return 75 | let parsed = next 76 | try { 77 | parsed = JSON.parse(next) 78 | } catch (e) { 79 | } 80 | onEdit(path, parsed) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/components/node/styles.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironbay/inferno-typescript-template/ccab78124ce52d0ace85584a07610624182694f6/src/components/node/styles.css -------------------------------------------------------------------------------- /src/components/template/index.tsx: -------------------------------------------------------------------------------- 1 | import './styles.css' 2 | import createElement from 'inferno-create-element' 3 | import Component from 'inferno-component' 4 | 5 | interface IProps { 6 | } 7 | 8 | interface IState { 9 | 10 | } 11 | 12 | export default class Template extends Component { 13 | constructor() { 14 | super() 15 | } 16 | render() { 17 | return ( 18 | false 19 | ) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/components/template/styles.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironbay/inferno-typescript-template/ccab78124ce52d0ace85584a07610624182694f6/src/components/template/styles.css -------------------------------------------------------------------------------- /src/constants.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ironbay/inferno-typescript-template/ccab78124ce52d0ace85584a07610624182694f6/src/constants.ts -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import Inferno from 'inferno' 2 | import { routes } from './routes' 3 | 4 | Inferno.render(routes, document.getElementById('inferno')) 5 | -------------------------------------------------------------------------------- /src/pages/example-page/index.tsx: -------------------------------------------------------------------------------- 1 | import './styles.css' 2 | import createElement from 'inferno-create-element' 3 | import Component from 'inferno-component' 4 | 5 | import Node from '../../components/node' 6 | 7 | interface IProps { 8 | } 9 | 10 | const SAMPLE_DATA = { 11 | hello: "world", 12 | welcome: { 13 | to: { 14 | typescript: "!", 15 | it: { 16 | is: "pretty", 17 | great: "!" 18 | } 19 | } 20 | } 21 | } 22 | 23 | export default class ExamplePage extends Component { 24 | constructor() { 25 | super() 26 | this.state = SAMPLE_DATA 27 | } 28 | render() { 29 | const { state } = this 30 | return 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/pages/example-page/styles.css: -------------------------------------------------------------------------------- 1 | .node { 2 | font-family: monospace; 3 | line-height: 1.2rem; 4 | } 5 | .node-children { 6 | margin-left: 2rem; 7 | } 8 | 9 | .node-value.number { 10 | font-weight: bold; 11 | color: #1A01CC; 12 | } 13 | 14 | .node-value.string { 15 | color: #0B7500; 16 | } 17 | 18 | .node-value.boolean { 19 | font-weight: bold; 20 | color: #1A01CC; 21 | } 22 | 23 | .node-label { 24 | cursor: pointer; 25 | } 26 | -------------------------------------------------------------------------------- /src/pages/root/index.tsx: -------------------------------------------------------------------------------- 1 | import './reset.css' 2 | import './styles.css' 3 | import createElement from 'inferno-create-element' 4 | import Component from 'inferno-component' 5 | import Inferno from 'inferno' 6 | import Container from '../../components/container' 7 | 8 | interface IProps { 9 | children: any 10 | params: any 11 | } 12 | 13 | export default class Root extends Component { 14 | constructor() { 15 | super() 16 | this.state = {} 17 | } 18 | componentWillMount() { 19 | } 20 | componentDidMount() { 21 | } 22 | componentWillReceiveProps(next: IProps) { 23 | } 24 | render() { 25 | const { children} = this.props 26 | return ( 27 | 28 | {children} 29 | 30 | ) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/pages/root/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, menu, nav, section { 29 | display: block; 30 | } 31 | body { 32 | line-height: 1; 33 | } 34 | ol, ul { 35 | list-style: none; 36 | } 37 | blockquote, q { 38 | quotes: none; 39 | } 40 | blockquote:before, blockquote:after, 41 | q:before, q:after { 42 | content: ''; 43 | content: none; 44 | } 45 | table { 46 | border-collapse: collapse; 47 | border-spacing: 0; 48 | } 49 | -------------------------------------------------------------------------------- /src/pages/root/styles.css: -------------------------------------------------------------------------------- 1 | pre { 2 | font-size: 1rem; 3 | } 4 | -------------------------------------------------------------------------------- /src/routes.tsx: -------------------------------------------------------------------------------- 1 | import createElement from 'inferno-create-element' 2 | import { Router, Route } from 'inferno-router' 3 | import { createBrowserHistory } from 'history' 4 | const browserHistory = createBrowserHistory() 5 | 6 | export const history = browserHistory 7 | 8 | import Root from './pages/root' 9 | import ExamplePage from './pages/example-page' 10 | 11 | export const routes = ( 12 | 13 | 14 | 15 | 16 | 17 | 18 | ) 19 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.1.5", 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "target": "es5", 6 | "module": "commonjs", 7 | "moduleResolution": "node", 8 | "allowJs": false, 9 | "allowSyntheticDefaultImports": true, 10 | "sourceMap": true, 11 | "lib": ["dom","es5","scripthost", "es2015.promise", "es2015.collection", "es2017.object"], 12 | "types": [ 13 | "inferno" 14 | ], 15 | "jsx": "react", 16 | "jsxFactory": "createElement", 17 | "noUnusedLocals": false, 18 | "strictNullChecks": false, 19 | "removeComments": false 20 | }, 21 | "include": [ 22 | "src", 23 | "node_modules/@types" 24 | ], 25 | "exclude": [ 26 | "node_modules" 27 | ] 28 | } 29 | 30 | -------------------------------------------------------------------------------- /webpack/dev.config.js: -------------------------------------------------------------------------------- 1 | var config = require('./webpack.config.js') 2 | var webpack = require('webpack') 3 | 4 | config.devtool = 'cheap-module-source-map' 5 | config.module.loaders[1].loader = "style-loader!css-loader?importLoaders=1!postcss-loader" 6 | 7 | 8 | module.exports = config 9 | -------------------------------------------------------------------------------- /webpack/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require("path") 2 | const ExtractTextPlugin = require("extract-text-webpack-plugin"); 3 | const CleanWebpackPlugin = require('clean-webpack-plugin'); 4 | const HtmlWebpackPlugin = require("html-webpack-plugin"); 5 | const webpack = require('webpack'); 6 | const output = path.join(__dirname, '../build'); 7 | 8 | module.exports = { 9 | context: path.resolve(__dirname, '..'), 10 | devServer: { 11 | inline: true, 12 | hot: true, 13 | historyApiFallback: true, 14 | }, 15 | resolve: { 16 | extensions : ["", ".js", ".jsx", ".ts", ".tsx"] 17 | }, 18 | entry: [ 19 | './src/index.tsx' 20 | ], 21 | output: { 22 | path: output, 23 | filename: 'bundle.js', 24 | publicPath: '/', 25 | }, 26 | plugins: [], 27 | progress: true, 28 | module: { 29 | loaders: [ 30 | // All files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'. 31 | { test: /\.tsx?$/, loader: "awesome-typescript-loader" }, 32 | { 33 | test: /\.css$/, 34 | loader: ExtractTextPlugin.extract("style-loader", "css-loader?importLoaders=1", "postcss-loader") 35 | } 36 | ], 37 | 38 | preLoaders: [ 39 | // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'. 40 | { test: /\.js$/, loader: "source-map-loader" } 41 | ] 42 | }, 43 | plugins: [ 44 | new HtmlWebpackPlugin({ 45 | template: path.resolve(__dirname, '../index.html'), 46 | inject : 'body', 47 | hash : true, 48 | }), 49 | new ExtractTextPlugin("bundle.css"), 50 | new CleanWebpackPlugin( 51 | ["build"], { 52 | verbose: true 53 | } 54 | ) 55 | ], 56 | postcss: function () { 57 | return [require('postcss-cssnext')]; 58 | } 59 | }; 60 | --------------------------------------------------------------------------------