Skip to content

Commit

Permalink
Merge pull request #66 from Lemoncode/#61-suspense-samples
Browse files Browse the repository at this point in the history
#61 suspense samples
  • Loading branch information
brauliodiez authored May 15, 2019
2 parents b502af5 + 0a256c9 commit 662eb26
Show file tree
Hide file tree
Showing 21 changed files with 672 additions and 0 deletions.
16 changes: 16 additions & 0 deletions examples/06-suspense-like/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage"
}
],
"@babel/preset-typescript",
"@babel/preset-react"
],
"plugins": [
"@babel/proposal-class-properties",
"@babel/proposal-object-rest-spread"
]
}
49 changes: 49 additions & 0 deletions examples/06-suspense-like/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "06-suspense-like",
"version": "1.0.0",
"description": "React Promise Tracker sample with suspense-like component",
"keywords": [
"react",
"promise",
"tracker",
"hook",
"hooks",
"typescript"
],
"author": "Javier Calzado ([email protected])",
"license": "MIT",
"main": "src/index.tsx",
"scripts": {
"start": "webpack-dev-server --mode development --inline --hot --open",
"typecheck": "tsc --pretty --noEmit",
"build": "npm run typecheck && webpack --mode development"
},
"dependencies": {
"@babel/polyfill": "^7.2.5",
"@material-ui/core": "3.9.3",
"react": "16.8.4",
"react-dom": "16.8.4",
"react-promise-tracker": "2.0.2"
},
"devDependencies": {
"@babel/cli": "^7.2.3",
"@babel/core": "^7.2.2",
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/preset-env": "^7.3.1",
"@babel/preset-react": "^7.0.0",
"@babel/preset-typescript": "^7.3.3",
"@types/node": "11.13.4",
"@types/react": "16.8.8",
"@types/react-dom": "16.8.2",
"babel-loader": "^8.0.6",
"core-js": "^2.6.5",
"html-webpack-plugin": "^3.2.0",
"tslint": "^5.16.0",
"tslint-react": "^4.0.0",
"typescript": "^3.4.5",
"webpack": "^4.29.3",
"webpack-cli": "^3.2.3",
"webpack-dev-server": "^3.1.14"
}
}
24 changes: 24 additions & 0 deletions examples/06-suspense-like/src/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const fetchWithDelay = (url: string, delay: number): Promise<Response> =>
new Promise(resolve => setTimeout(() => resolve(fetch(url, { method: "GET" })), delay));

export interface Quote {
body: string;
author: string;
}

export const getQuote = () =>
fetchWithDelay("https://favqs.com/api/qotd", Math.random() * 3000)
.then(result => result.json())
.then<{ quote: Quote }>(result => result.quote);

const arrayBufferToBase64 = buffer => {
let binary = "";
const bytes = [].slice.call(new Uint8Array(buffer));
bytes.forEach(b => (binary += String.fromCharCode(b)));
return window.btoa(binary);
};

export const getPicture = (width: number, height: number) =>
fetchWithDelay(`https://picsum.photos/${width}/${height}`, Math.random() * 3000).then(res =>
res.arrayBuffer().then(buffer => "data:image/jpeg;base64," + arrayBufferToBase64(buffer))
);
40 changes: 40 additions & 0 deletions examples/06-suspense-like/src/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as React from "react";
import CircularProgress from "@material-ui/core/CircularProgress";
import Typography from "@material-ui/core/Typography";
import Button from "@material-ui/core/Button";
import { WithStyles, withStyles } from "@material-ui/core/styles";
import { trackPromise, usePromiseTracker } from "react-promise-tracker";
import { Quote, getQuote, getPicture } from "./api";
import { styles } from "./styles";


const Suspense: React.FC<{ tag: string, className?: string }> = ({ tag, className, children }) => {
const { promiseInProgress } = usePromiseTracker({ area: tag });
return promiseInProgress ? <CircularProgress className={className} size={60}/> : <>{children}</>;
};

const AppInner: React.FC<WithStyles<typeof styles>> = ({classes}) => {
const [quote, setQuote] = React.useState<Quote>({ body: "", author: "" });
const [picture, setPicture] = React.useState();
const loadData = React.useCallback(() => {
trackPromise(getQuote(), "quote").then(setQuote);
trackPromise(getPicture(500, 200), "picture").then(setPicture);
}, []);

React.useEffect(() => loadData(), []);

return (
<div className={classes.container}>
<Button variant="outlined" onClick={loadData} className={classes.button}>Refresh</Button>
<Suspense tag="picture" className={classes.progress}>
<img src={picture} className={classes.pic}/>
</Suspense>
<Suspense tag="quote" className={classes.progress}>
<Typography variant="h4" align="center" className={classes.text}>{quote.body}</Typography>
<Typography variant="h5" className={classes.text}>{quote.author}</Typography>
</Suspense>
</div>
);
};

export const App = withStyles(styles)(AppInner);
14 changes: 14 additions & 0 deletions examples/06-suspense-like/src/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>React Promise Tracker - Suspense</title>
</head>

<body>
<div id="root"></div>
</body>

</html>
12 changes: 12 additions & 0 deletions examples/06-suspense-like/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as React from "react";
import * as ReactDOM from "react-dom";
import CssBaseline from "@material-ui/core/CssBaseline";
import { App } from "./app";

ReactDOM.render(
<>
<CssBaseline />
<App />
</>,
document.getElementById("root")
);
25 changes: 25 additions & 0 deletions examples/06-suspense-like/src/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { createStyles } from "@material-ui/core/styles";

export const styles = () => createStyles({
progress: {
margin: "1rem",
},
container: {
display: "flex",
flexDirection: "column",
alignItems: "center",
padding: "2rem",
},
button: {
marginBottom: "2rem",
},
pic: {
marginBottom: "1.25rem",
borderRadius: "8px",
},
text: {
marginBottom: "0.75rem",
}
});


16 changes: 16 additions & 0 deletions examples/06-suspense-like/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"target": "es6",
"module": "es6",
"moduleResolution": "node",
"declaration": false,
"noImplicitAny": false,
"jsx": "react",
"sourceMap": true,
"noLib": false,
"suppressImplicitAnyIndexErrors": true,
"allowSyntheticDefaultImports": true,
},
"compileOnSave": false,
"exclude": ["node_modules"]
}
92 changes: 92 additions & 0 deletions examples/06-suspense-like/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
{
"extends": ["tslint:recommended", "tslint-react", "tslint-config-prettier"],
"defaultSeverity": "warning",
"rules": {
"align": [true, "parameters", "statements"],
"array-type": false,
"arrow-parens": false,
"class-name": true,
"comment-format": [true, "check-space"],
"curly": false,
"eofline": true,
"forin": false,
"import-spacing": true,
"indent": [true, "spaces"],
"interface-name": [true, "never-prefix"],
"jsdoc-format": true,
"jsx-no-lambda": false,
"jsx-no-multiline-js": false,
"label-position": true,
"max-line-length": [true, 120],
"member-ordering": false,
"member-access": false,
"no-any": false,
"no-arg": true,
"no-bitwise": true,
"no-console": false,
"no-consecutive-blank-lines": [true, 2],
"no-construct": true,
"no-debugger": true,
"no-default-export": false,
"no-duplicate-variable": true,
"no-empty": true,
"no-empty-interface": false,
"no-eval": true,
"no-implicit-dependencies": false,
"no-internal-module": true,
"no-object-literal-type-assertion": false,
"no-shadowed-variable": true,
"no-string-literal": false,
"no-submodule-imports": false,
"no-trailing-whitespace": true,
"no-unsafe-finally": true,
"no-unused-expression": true,
"no-var-keyword": true,
"no-var-requires": false,
"object-literal-key-quotes": [true, "as-needed"],
"object-literal-sort-keys": false,
"one-line": [true, "check-catch", "check-else", "check-open-brace", "check-whitespace"],
"only-arrow-functions": false,
"ordered-imports": false,
"quotemark": [true, "double", "jsx-double"],
"radix": false,
"semicolon": [true, "always", "strict-bound-class-methods"],
"trailing-comma": [
true,
{
"multiline": {
"objects": "always",
"arrays": "always",
"imports": "always",
"exports": "always",
"typeLiterals": "always"
},
"singleline": "never",
"esSpecCompliant": true
}
],
"triple-equals": [true, "allow-null-check"],
"typedef": [true, "parameter", "property-declaration"],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore", "allow-pascal-case"],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-module",
"check-operator",
"check-separator",
"check-type",
"check-typecast"
]
}
}
41 changes: 41 additions & 0 deletions examples/06-suspense-like/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");

const basePath = __dirname;

module.exports = {
context: path.join(basePath, "src"),
resolve: {
extensions: [".js", ".ts", ".tsx"],
},
entry: ["./index.tsx"],
output: {
path: path.join(basePath, "dist"),
filename: "bundle.js"
},
devtool: "source-map",
devServer: {
contentBase: "./dist", // Content base
inline: true, // Enable watch and live reload
host: "localhost",
port: 8080,
stats: "errors-only"
},
module: {
rules: [
{
test: /\.(tsx?)|(js)$/,
exclude: /node_modules/,
loader: "babel-loader",
},
]
},
plugins: [
//Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: "index.html", //Name of file in ./dist/
template: "index.html", //Name of template in ./src
hash: true
})
]
};
16 changes: 16 additions & 0 deletions examples/07-suspense-custom/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage"
}
],
"@babel/preset-typescript",
"@babel/preset-react"
],
"plugins": [
"@babel/proposal-class-properties",
"@babel/proposal-object-rest-spread"
]
}
Loading

0 comments on commit 662eb26

Please sign in to comment.