From 07b6d19df3f5f30e0170f4ad7996a26ebf1dd7f8 Mon Sep 17 00:00:00 2001 From: Uchan Date: Fri, 10 Mar 2023 08:06:54 +0900 Subject: [PATCH 01/36] init test --- readme.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 9036f07..250ce3c 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,7 @@ # React Typescript by sample +git init test !! + [🇪🇸 Versión Español](./readme_es.md) The goal of this project is to provide a set of simple samples, providing and step by step guide to @@ -122,7 +124,7 @@ Starting from sample 03,start using React-Router (SPA navigation). ### [13 Login Form](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/13_LoginForm) -Starting from sample 12, implement a basic login page, that will redirect the user to another page whenever the login has completed successfully. +Starting from sample 12, implement a basic login page, that will redirect the user to another page whenever the login has completed successfully. ### [14 Form Validation](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/14_FormValidation) From 0f49686162048e0e0a7b9423d7bfa878fe553248 Mon Sep 17 00:00:00 2001 From: Uchan Date: Fri, 10 Mar 2023 08:14:07 +0900 Subject: [PATCH 02/36] init commit --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 250ce3c..3a0f253 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ # React Typescript by sample -git init test !! +git init test [🇪🇸 Versión Español](./readme_es.md) From 316ee2db8d870fe4c452797cf57fd20a0df56bd3 Mon Sep 17 00:00:00 2001 From: Uchan Date: Sat, 11 Mar 2023 10:12:59 +0900 Subject: [PATCH 03/36] init --- hooks/00_BoilerPlate/.babelrc | 10 ---- hooks/00_BoilerPlate/package.json | 35 -------------- hooks/00_BoilerPlate/src/index.html | 12 ----- hooks/00_BoilerPlate/src/main.ts | 1 - hooks/00_BoilerPlate/tsconfig.json | 15 ------ hooks/00_BoilerPlate/webpack.config.js | 63 -------------------------- 6 files changed, 136 deletions(-) delete mode 100644 hooks/00_BoilerPlate/.babelrc delete mode 100644 hooks/00_BoilerPlate/package.json delete mode 100644 hooks/00_BoilerPlate/src/index.html delete mode 100644 hooks/00_BoilerPlate/src/main.ts delete mode 100644 hooks/00_BoilerPlate/tsconfig.json delete mode 100644 hooks/00_BoilerPlate/webpack.config.js diff --git a/hooks/00_BoilerPlate/.babelrc b/hooks/00_BoilerPlate/.babelrc deleted file mode 100644 index 957cae3..0000000 --- a/hooks/00_BoilerPlate/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "entry" - } - ] - ] -} diff --git a/hooks/00_BoilerPlate/package.json b/hooks/00_BoilerPlate/package.json deleted file mode 100644 index 12b2f5b..0000000 --- a/hooks/00_BoilerPlate/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "react-typescript-by-sample", - "version": "1.0.0", - "description": "React Typescript examples", - "main": "index.js", - "scripts": { - "start": "webpack-dev-server --mode development --inline --hot --open", - "build": "webpack --mode development" - }, - "keywords": [ - "react", - "typescript", - "hooks" - ], - "author": "Braulio Diez Botella", - "license": "MIT", - "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.10.5", - "@babel/polyfill": "^7.10.4", - "@babel/preset-env": "^7.10.4", - "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.1.0", - "css-loader": "^3.6.0", - "file-loader": "^6.0.0", - "html-webpack-plugin": "^4.3.0", - "mini-css-extract-plugin": "^0.9.0", - "style-loader": "^1.2.1", - "typescript": "^3.9.7", - "url-loader": "^4.1.0", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.0" - } -} diff --git a/hooks/00_BoilerPlate/src/index.html b/hooks/00_BoilerPlate/src/index.html deleted file mode 100644 index d493ac4..0000000 --- a/hooks/00_BoilerPlate/src/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - -
-

Sample app

-
- - diff --git a/hooks/00_BoilerPlate/src/main.ts b/hooks/00_BoilerPlate/src/main.ts deleted file mode 100644 index 03acc28..0000000 --- a/hooks/00_BoilerPlate/src/main.ts +++ /dev/null @@ -1 +0,0 @@ -document.write("Hello from main.ts !"); diff --git a/hooks/00_BoilerPlate/tsconfig.json b/hooks/00_BoilerPlate/tsconfig.json deleted file mode 100644 index f90a3f0..0000000 --- a/hooks/00_BoilerPlate/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "compilerOptions": { - "target": "es6", - "module": "es6", - "moduleResolution": "node", - "declaration": false, - "noImplicitAny": false, - "jsx": "react", - "sourceMap": true, - "noLib": false, - "suppressImplicitAnyIndexErrors": true - }, - "compileOnSave": false, - "exclude": ["node_modules"] -} diff --git a/hooks/00_BoilerPlate/webpack.config.js b/hooks/00_BoilerPlate/webpack.config.js deleted file mode 100644 index 3771572..0000000 --- a/hooks/00_BoilerPlate/webpack.config.js +++ /dev/null @@ -1,63 +0,0 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const webpack = require("webpack"); -const path = require("path"); - -const basePath = __dirname; - -module.exports = { - context: path.join(basePath, "src"), - resolve: { - extensions: [".js", ".ts", ".tsx"], - }, - entry: ["@babel/polyfill", "./main.ts"], - 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: /\.(ts|tsx)$/, - exclude: /node_modules/, - loader: "awesome-typescript-loader", - options: { - useBabel: true, - babelCore: "@babel/core", // needed for Babel v7 - }, - }, - { - test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"], - }, - { - test: /\.(png|jpg|gif|svg)$/, - loader: "file-loader", - options: { - name: "assets/img/[name].[ext]?[hash]", - esModule: false, - }, - }, - ], - }, - 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, - }), - new MiniCssExtractPlugin({ - filename: "[name].css", - chunkFilename: "[id].css", - }), - ], -}; From 794e198506363a9df30fb8a962b937d861c3a9fc Mon Sep 17 00:00:00 2001 From: Uchan Date: Sat, 11 Mar 2023 10:49:26 +0900 Subject: [PATCH 04/36] mm --- hooks/00_BoilerPlate/.babelrc | 10 +++++ hooks/00_BoilerPlate/package.json | 30 +++++++++++++ hooks/00_BoilerPlate/src/index.html | 15 +++++++ hooks/00_BoilerPlate/src/main.ts | 1 + hooks/00_BoilerPlate/tsconfig.json | 15 +++++++ hooks/00_BoilerPlate/webpack.config.js | 60 ++++++++++++++++++++++++++ 6 files changed, 131 insertions(+) create mode 100644 hooks/00_BoilerPlate/.babelrc create mode 100644 hooks/00_BoilerPlate/package.json create mode 100644 hooks/00_BoilerPlate/src/index.html create mode 100644 hooks/00_BoilerPlate/src/main.ts create mode 100644 hooks/00_BoilerPlate/tsconfig.json create mode 100644 hooks/00_BoilerPlate/webpack.config.js diff --git a/hooks/00_BoilerPlate/.babelrc b/hooks/00_BoilerPlate/.babelrc new file mode 100644 index 0000000..957cae3 --- /dev/null +++ b/hooks/00_BoilerPlate/.babelrc @@ -0,0 +1,10 @@ +{ + "presets": [ + [ + "@babel/preset-env", + { + "useBuiltIns": "entry" + } + ] + ] +} diff --git a/hooks/00_BoilerPlate/package.json b/hooks/00_BoilerPlate/package.json new file mode 100644 index 0000000..1150364 --- /dev/null +++ b/hooks/00_BoilerPlate/package.json @@ -0,0 +1,30 @@ +{ + "name": "00_boilerplate", + "version": "1.0.0", + "description": "In this sample we setup the basic plumbing to \"build\" our project and launch it in a dev server.", + "main": "index.js", + "scripts": { + "start": "webpack-dev-server --mode development --hot --open", + "build": "webpack --mode development" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.20.2", + "babel-loader": "^9.1.2", + "css-loader": "^6.7.3", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "mini-css-extract-plugin": "^2.7.3", + "style-loader": "^3.3.1", + "ts-loader": "^9.4.2", + "typescript": "^4.9.5", + "url-loader": "^4.1.1", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" + } +} diff --git a/hooks/00_BoilerPlate/src/index.html b/hooks/00_BoilerPlate/src/index.html new file mode 100644 index 0000000..50d0c9c --- /dev/null +++ b/hooks/00_BoilerPlate/src/index.html @@ -0,0 +1,15 @@ + + + + + + + + + +
+

Sample app

+
+ + + \ No newline at end of file diff --git a/hooks/00_BoilerPlate/src/main.ts b/hooks/00_BoilerPlate/src/main.ts new file mode 100644 index 0000000..03acc28 --- /dev/null +++ b/hooks/00_BoilerPlate/src/main.ts @@ -0,0 +1 @@ +document.write("Hello from main.ts !"); diff --git a/hooks/00_BoilerPlate/tsconfig.json b/hooks/00_BoilerPlate/tsconfig.json new file mode 100644 index 0000000..f90a3f0 --- /dev/null +++ b/hooks/00_BoilerPlate/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "es6", + "moduleResolution": "node", + "declaration": false, + "noImplicitAny": false, + "jsx": "react", + "sourceMap": true, + "noLib": false, + "suppressImplicitAnyIndexErrors": true + }, + "compileOnSave": false, + "exclude": ["node_modules"] +} diff --git a/hooks/00_BoilerPlate/webpack.config.js b/hooks/00_BoilerPlate/webpack.config.js new file mode 100644 index 0000000..6774736 --- /dev/null +++ b/hooks/00_BoilerPlate/webpack.config.js @@ -0,0 +1,60 @@ +var HtmlWebpackPlugin = require("html-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var webpack = require("webpack"); +var path = require("path"); + +var basePath = __dirname; + +module.exports = { + context: path.join(basePath, "src"), + resolve: { + extensions: [".js", ".ts", ".tsx"] + }, + entry: ["@babel/polyfill", "./main.ts"], + output: { + path: path.join(basePath, "dist"), + filename: "bundle.js" + }, + devtool: "source-map", + devServer: { + // inline: true, // Enable watch and live reload + // host: "localhost", + // port: 8080, + // stats: "errors-only", + static: { + directory: "./dist", + } + }, + module: { + rules: [ + { + test: /\.(ts|tsx)$/, + exclude: /node_modules/, + loader: "ts-loader", + }, + { + test: /\.css$/, + use: [MiniCssExtractPlugin.loader, "css-loader"] + }, + { + test: /\.(png|jpg|gif|svg)$/, + loader: "file-loader", + options: { + name: "assets/img/[name].[ext]?[hash]" + } + } + ] + }, + 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 + }), + new MiniCssExtractPlugin({ + filename: "[name].css", + chunkFilename: "[id].css" + }) + ] +}; \ No newline at end of file From f4e5eddba03d626c1bc50a979e879cc94cde81ef Mon Sep 17 00:00:00 2001 From: Uchan Date: Sun, 12 Mar 2023 20:25:49 +0900 Subject: [PATCH 05/36] HelloReact --- hooks/01_HelloReact/.babelrc | 10 ----- hooks/01_HelloReact/package.json | 42 ++++++++++----------- hooks/01_HelloReact/webpack.config.js | 53 +++++++++++++-------------- 3 files changed, 45 insertions(+), 60 deletions(-) delete mode 100644 hooks/01_HelloReact/.babelrc diff --git a/hooks/01_HelloReact/.babelrc b/hooks/01_HelloReact/.babelrc deleted file mode 100644 index 957cae3..0000000 --- a/hooks/01_HelloReact/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "entry" - } - ] - ] -} diff --git a/hooks/01_HelloReact/package.json b/hooks/01_HelloReact/package.json index 264e71d..2e688fe 100644 --- a/hooks/01_HelloReact/package.json +++ b/hooks/01_HelloReact/package.json @@ -4,7 +4,7 @@ "description": "React Typescript examples", "main": "index.js", "scripts": { - "start": "webpack-dev-server --mode development --inline --hot --open", + "start": "webpack-dev-server --mode development --hot --open", "build": "webpack --mode development" }, "keywords": [ @@ -15,27 +15,25 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.10.5", - "@babel/polyfill": "^7.10.4", - "@babel/preset-env": "^7.10.4", - "@types/react": "^16.9.43", - "@types/react-dom": "^16.9.8", - "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.1.0", - "css-loader": "^3.6.0", - "file-loader": "^6.0.0", - "html-webpack-plugin": "^4.3.0", - "mini-css-extract-plugin": "^0.9.0", - "style-loader": "^1.2.1", - "typescript": "^3.9.7", - "url-loader": "^4.1.0", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.0" + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.20.2", + "babel-loader": "^9.1.2", + "css-loader": "^6.7.3", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "mini-css-extract-plugin": "^2.7.3", + "style-loader": "^3.3.1", + "ts-loader": "^9.4.2", + "typescript": "^4.9.5", + "url-loader": "^4.1.1", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" }, "dependencies": { - "react": "^16.13.1", - "react-dom": "^16.13.1" + "react": "^18.2.0", + "react-dom": "^18.2.0" } -} +} \ No newline at end of file diff --git a/hooks/01_HelloReact/webpack.config.js b/hooks/01_HelloReact/webpack.config.js index 32eff84..1d6fce3 100644 --- a/hooks/01_HelloReact/webpack.config.js +++ b/hooks/01_HelloReact/webpack.config.js @@ -1,63 +1,60 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const webpack = require("webpack"); -const path = require("path"); +var HtmlWebpackPlugin = require("html-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var webpack = require("webpack"); +var path = require("path"); -const basePath = __dirname; +var basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"], + extensions: [".js", ".ts", ".tsx"] }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js", + 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", + // inline: true, // Enable watch and live reload + // host: "localhost", + // port: 8080, + // stats: "errors-only", + static: { + directory: "./dist", + } }, module: { rules: [ { test: /\.(ts|tsx)$/, exclude: /node_modules/, - loader: "awesome-typescript-loader", - options: { - useBabel: true, - babelCore: "@babel/core", // needed for Babel v7 - }, + loader: "ts-loader", }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"], + use: [MiniCssExtractPlugin.loader, "css-loader"] }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]", - esModule: false, - }, - }, - ], + name: "assets/img/[name].[ext]?[hash]" + } + } + ] }, 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, + hash: true }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css", - }), - ], -}; + chunkFilename: "[id].css" + }) + ] +}; \ No newline at end of file From f615b05c82a9741c1ddd3a8d525f0c4569d61681 Mon Sep 17 00:00:00 2001 From: Uchan Date: Mon, 13 Mar 2023 07:57:33 +0900 Subject: [PATCH 06/36] properties --- hooks/02_Properties/.babelrc | 10 ----- hooks/02_Properties/package.json | 44 +++++++++++----------- hooks/02_Properties/webpack.config.js | 53 +++++++++++++-------------- 3 files changed, 47 insertions(+), 60 deletions(-) delete mode 100644 hooks/02_Properties/.babelrc diff --git a/hooks/02_Properties/.babelrc b/hooks/02_Properties/.babelrc deleted file mode 100644 index 957cae3..0000000 --- a/hooks/02_Properties/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "entry" - } - ] - ] -} diff --git a/hooks/02_Properties/package.json b/hooks/02_Properties/package.json index 264e71d..6c2b1b9 100644 --- a/hooks/02_Properties/package.json +++ b/hooks/02_Properties/package.json @@ -4,7 +4,7 @@ "description": "React Typescript examples", "main": "index.js", "scripts": { - "start": "webpack-dev-server --mode development --inline --hot --open", + "start": "webpack-dev-server --mode development --hot --open", "build": "webpack --mode development" }, "keywords": [ @@ -15,27 +15,27 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.10.5", - "@babel/polyfill": "^7.10.4", - "@babel/preset-env": "^7.10.4", - "@types/react": "^16.9.43", - "@types/react-dom": "^16.9.8", - "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.1.0", - "css-loader": "^3.6.0", - "file-loader": "^6.0.0", - "html-webpack-plugin": "^4.3.0", - "mini-css-extract-plugin": "^0.9.0", - "style-loader": "^1.2.1", - "typescript": "^3.9.7", - "url-loader": "^4.1.0", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.0" + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.20.2", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "babel-loader": "^9.1.2", + "css-loader": "^6.7.3", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "mini-css-extract-plugin": "^2.7.3", + "style-loader": "^3.3.1", + "ts-loader": "^9.4.2", + "typescript": "^4.9.5", + "url-loader": "^4.1.1", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" }, "dependencies": { - "react": "^16.13.1", - "react-dom": "^16.13.1" + "react": "^18.2.0", + "react-dom": "^18.2.0" } -} +} \ No newline at end of file diff --git a/hooks/02_Properties/webpack.config.js b/hooks/02_Properties/webpack.config.js index 32eff84..1d6fce3 100644 --- a/hooks/02_Properties/webpack.config.js +++ b/hooks/02_Properties/webpack.config.js @@ -1,63 +1,60 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const webpack = require("webpack"); -const path = require("path"); +var HtmlWebpackPlugin = require("html-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var webpack = require("webpack"); +var path = require("path"); -const basePath = __dirname; +var basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"], + extensions: [".js", ".ts", ".tsx"] }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js", + 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", + // inline: true, // Enable watch and live reload + // host: "localhost", + // port: 8080, + // stats: "errors-only", + static: { + directory: "./dist", + } }, module: { rules: [ { test: /\.(ts|tsx)$/, exclude: /node_modules/, - loader: "awesome-typescript-loader", - options: { - useBabel: true, - babelCore: "@babel/core", // needed for Babel v7 - }, + loader: "ts-loader", }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"], + use: [MiniCssExtractPlugin.loader, "css-loader"] }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]", - esModule: false, - }, - }, - ], + name: "assets/img/[name].[ext]?[hash]" + } + } + ] }, 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, + hash: true }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css", - }), - ], -}; + chunkFilename: "[id].css" + }) + ] +}; \ No newline at end of file From e63d9493a0cf73e110a596d848ec0cf71ec0ae4b Mon Sep 17 00:00:00 2001 From: Uchan Date: Mon, 13 Mar 2023 08:10:33 +0900 Subject: [PATCH 07/36] state --- hooks/03_State/.babelrc | 10 ------ hooks/03_State/package.json | 44 +++++++++++++------------- hooks/03_State/src/app.tsx | 24 +++++++-------- hooks/03_State/src/hello.tsx | 6 ++-- hooks/03_State/src/index.tsx | 12 +++++--- hooks/03_State/src/nameEdit.tsx | 16 +++++----- hooks/03_State/webpack.config.js | 53 +++++++++++++++----------------- 7 files changed, 76 insertions(+), 89 deletions(-) delete mode 100644 hooks/03_State/.babelrc diff --git a/hooks/03_State/.babelrc b/hooks/03_State/.babelrc deleted file mode 100644 index 957cae3..0000000 --- a/hooks/03_State/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "entry" - } - ] - ] -} diff --git a/hooks/03_State/package.json b/hooks/03_State/package.json index 264e71d..6c2b1b9 100644 --- a/hooks/03_State/package.json +++ b/hooks/03_State/package.json @@ -4,7 +4,7 @@ "description": "React Typescript examples", "main": "index.js", "scripts": { - "start": "webpack-dev-server --mode development --inline --hot --open", + "start": "webpack-dev-server --mode development --hot --open", "build": "webpack --mode development" }, "keywords": [ @@ -15,27 +15,27 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.10.5", - "@babel/polyfill": "^7.10.4", - "@babel/preset-env": "^7.10.4", - "@types/react": "^16.9.43", - "@types/react-dom": "^16.9.8", - "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.1.0", - "css-loader": "^3.6.0", - "file-loader": "^6.0.0", - "html-webpack-plugin": "^4.3.0", - "mini-css-extract-plugin": "^0.9.0", - "style-loader": "^1.2.1", - "typescript": "^3.9.7", - "url-loader": "^4.1.0", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.0" + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.20.2", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "babel-loader": "^9.1.2", + "css-loader": "^6.7.3", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "mini-css-extract-plugin": "^2.7.3", + "style-loader": "^3.3.1", + "ts-loader": "^9.4.2", + "typescript": "^4.9.5", + "url-loader": "^4.1.1", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" }, "dependencies": { - "react": "^16.13.1", - "react-dom": "^16.13.1" + "react": "^18.2.0", + "react-dom": "^18.2.0" } -} +} \ No newline at end of file diff --git a/hooks/03_State/src/app.tsx b/hooks/03_State/src/app.tsx index f7d1429..d188387 100644 --- a/hooks/03_State/src/app.tsx +++ b/hooks/03_State/src/app.tsx @@ -3,16 +3,14 @@ import { HelloComponent } from "./hello"; import { NameEditComponent } from "./nameEdit"; export const App = () => { - const [name, setName] = React.useState("initialName"); - - const setUsernameState = (event: React.ChangeEvent) => { - setName(event.target.value); - }; - - return ( - <> - - - - ); -}; + const [name, setName] = React.useState('defaultUserName') + const setUsernameState = (event: React.ChangeEvent) => { + setName(event.target.value) + } + return ( + <> + + + + ); +}; \ No newline at end of file diff --git a/hooks/03_State/src/hello.tsx b/hooks/03_State/src/hello.tsx index b6b7aca..b9b1d81 100644 --- a/hooks/03_State/src/hello.tsx +++ b/hooks/03_State/src/hello.tsx @@ -4,6 +4,6 @@ interface Props { userName: string; } -export const HelloComponent: React.FC = (props) => { - return

Hello user: {props.userName} !

; -}; +export const HelloComponent: React.FC = (props) => ( +

Hello user: {props.userName} !

+); diff --git a/hooks/03_State/src/index.tsx b/hooks/03_State/src/index.tsx index 26ed977..0f847e1 100644 --- a/hooks/03_State/src/index.tsx +++ b/hooks/03_State/src/index.tsx @@ -1,6 +1,8 @@ -import * as React from "react"; -import * as ReactDOM from "react-dom"; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { App } from './app'; -import { App } from "./app"; - -ReactDOM.render(, document.getElementById("root")); +ReactDOM.render( + , + document.getElementById('root') +); diff --git a/hooks/03_State/src/nameEdit.tsx b/hooks/03_State/src/nameEdit.tsx index 02f7e36..a6ef1ef 100644 --- a/hooks/03_State/src/nameEdit.tsx +++ b/hooks/03_State/src/nameEdit.tsx @@ -1,13 +1,13 @@ import * as React from "react"; interface Props { - userName: string; - onChange: (e: React.ChangeEvent) => void; + userName: string; + onChange: (e: React.ChangeEvent) => void; } -export const NameEditComponent: React.FC = (props) => ( - <> - - - -); +export const NameEditComponent = (props: Props) => ( + <> + + + +) \ No newline at end of file diff --git a/hooks/03_State/webpack.config.js b/hooks/03_State/webpack.config.js index 32eff84..1d6fce3 100644 --- a/hooks/03_State/webpack.config.js +++ b/hooks/03_State/webpack.config.js @@ -1,63 +1,60 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const webpack = require("webpack"); -const path = require("path"); +var HtmlWebpackPlugin = require("html-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var webpack = require("webpack"); +var path = require("path"); -const basePath = __dirname; +var basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"], + extensions: [".js", ".ts", ".tsx"] }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js", + 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", + // inline: true, // Enable watch and live reload + // host: "localhost", + // port: 8080, + // stats: "errors-only", + static: { + directory: "./dist", + } }, module: { rules: [ { test: /\.(ts|tsx)$/, exclude: /node_modules/, - loader: "awesome-typescript-loader", - options: { - useBabel: true, - babelCore: "@babel/core", // needed for Babel v7 - }, + loader: "ts-loader", }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"], + use: [MiniCssExtractPlugin.loader, "css-loader"] }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]", - esModule: false, - }, - }, - ], + name: "assets/img/[name].[ext]?[hash]" + } + } + ] }, 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, + hash: true }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css", - }), - ], -}; + chunkFilename: "[id].css" + }) + ] +}; \ No newline at end of file From 6bb418512827646cfb90d311fbd6afc71f63cf83 Mon Sep 17 00:00:00 2001 From: Uchan Date: Mon, 13 Mar 2023 22:05:49 +0900 Subject: [PATCH 08/36] init --- hooks/04_Callback/.babelrc | 10 ----- hooks/04_Callback/package.json | 41 ------------------- hooks/04_Callback/src/app.tsx | 18 --------- hooks/04_Callback/src/hello.tsx | 9 ----- hooks/04_Callback/src/index.html | 13 ------ hooks/04_Callback/src/index.tsx | 6 --- hooks/04_Callback/src/nameEdit.tsx | 26 ------------ hooks/04_Callback/tsconfig.json | 15 ------- hooks/04_Callback/webpack.config.js | 63 ----------------------------- 9 files changed, 201 deletions(-) delete mode 100644 hooks/04_Callback/.babelrc delete mode 100644 hooks/04_Callback/package.json delete mode 100644 hooks/04_Callback/src/app.tsx delete mode 100644 hooks/04_Callback/src/hello.tsx delete mode 100644 hooks/04_Callback/src/index.html delete mode 100644 hooks/04_Callback/src/index.tsx delete mode 100644 hooks/04_Callback/src/nameEdit.tsx delete mode 100644 hooks/04_Callback/tsconfig.json delete mode 100644 hooks/04_Callback/webpack.config.js diff --git a/hooks/04_Callback/.babelrc b/hooks/04_Callback/.babelrc deleted file mode 100644 index 957cae3..0000000 --- a/hooks/04_Callback/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "entry" - } - ] - ] -} diff --git a/hooks/04_Callback/package.json b/hooks/04_Callback/package.json deleted file mode 100644 index 264e71d..0000000 --- a/hooks/04_Callback/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "react-typescript-by-sample", - "version": "1.0.0", - "description": "React Typescript examples", - "main": "index.js", - "scripts": { - "start": "webpack-dev-server --mode development --inline --hot --open", - "build": "webpack --mode development" - }, - "keywords": [ - "react", - "typescript", - "hooks" - ], - "author": "Braulio Diez Botella", - "license": "MIT", - "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.10.5", - "@babel/polyfill": "^7.10.4", - "@babel/preset-env": "^7.10.4", - "@types/react": "^16.9.43", - "@types/react-dom": "^16.9.8", - "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.1.0", - "css-loader": "^3.6.0", - "file-loader": "^6.0.0", - "html-webpack-plugin": "^4.3.0", - "mini-css-extract-plugin": "^0.9.0", - "style-loader": "^1.2.1", - "typescript": "^3.9.7", - "url-loader": "^4.1.0", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.0" - }, - "dependencies": { - "react": "^16.13.1", - "react-dom": "^16.13.1" - } -} diff --git a/hooks/04_Callback/src/app.tsx b/hooks/04_Callback/src/app.tsx deleted file mode 100644 index 84c22a8..0000000 --- a/hooks/04_Callback/src/app.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import * as React from "react"; -import { HelloComponent } from "./hello"; -import { NameEditComponent } from "./nameEdit"; - -export const App = () => { - const [name, setName] = React.useState("defaultUserName"); - - const setUsernameState = (newName : string) => { - setName(newName); - }; - - return ( - <> - - - - ); -}; diff --git a/hooks/04_Callback/src/hello.tsx b/hooks/04_Callback/src/hello.tsx deleted file mode 100644 index b6b7aca..0000000 --- a/hooks/04_Callback/src/hello.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import * as React from "react"; - -interface Props { - userName: string; -} - -export const HelloComponent: React.FC = (props) => { - return

Hello user: {props.userName} !

; -}; diff --git a/hooks/04_Callback/src/index.html b/hooks/04_Callback/src/index.html deleted file mode 100644 index cef0845..0000000 --- a/hooks/04_Callback/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - -
-

Sample app

-
-
- - diff --git a/hooks/04_Callback/src/index.tsx b/hooks/04_Callback/src/index.tsx deleted file mode 100644 index 26ed977..0000000 --- a/hooks/04_Callback/src/index.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import * as React from "react"; -import * as ReactDOM from "react-dom"; - -import { App } from "./app"; - -ReactDOM.render(, document.getElementById("root")); diff --git a/hooks/04_Callback/src/nameEdit.tsx b/hooks/04_Callback/src/nameEdit.tsx deleted file mode 100644 index 8b1a5ca..0000000 --- a/hooks/04_Callback/src/nameEdit.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import * as React from "react"; - -interface Props { - initialUserName: string; - onNameUpdated: (newName: string) => any; -} - -export const NameEditComponent: React.FC = (props) => { - const [editingName, setEditingName] = React.useState(props.initialUserName); - - const onChange = (e: React.ChangeEvent) => { - setEditingName(e.target.value); - }; - - const onNameSubmit = (event: any): any => { - props.onNameUpdated(editingName); - }; - - return ( - <> - - - - - ); -}; diff --git a/hooks/04_Callback/tsconfig.json b/hooks/04_Callback/tsconfig.json deleted file mode 100644 index f90a3f0..0000000 --- a/hooks/04_Callback/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "compilerOptions": { - "target": "es6", - "module": "es6", - "moduleResolution": "node", - "declaration": false, - "noImplicitAny": false, - "jsx": "react", - "sourceMap": true, - "noLib": false, - "suppressImplicitAnyIndexErrors": true - }, - "compileOnSave": false, - "exclude": ["node_modules"] -} diff --git a/hooks/04_Callback/webpack.config.js b/hooks/04_Callback/webpack.config.js deleted file mode 100644 index 32eff84..0000000 --- a/hooks/04_Callback/webpack.config.js +++ /dev/null @@ -1,63 +0,0 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const webpack = require("webpack"); -const path = require("path"); - -const basePath = __dirname; - -module.exports = { - context: path.join(basePath, "src"), - resolve: { - extensions: [".js", ".ts", ".tsx"], - }, - entry: ["@babel/polyfill", "./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: /\.(ts|tsx)$/, - exclude: /node_modules/, - loader: "awesome-typescript-loader", - options: { - useBabel: true, - babelCore: "@babel/core", // needed for Babel v7 - }, - }, - { - test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"], - }, - { - test: /\.(png|jpg|gif|svg)$/, - loader: "file-loader", - options: { - name: "assets/img/[name].[ext]?[hash]", - esModule: false, - }, - }, - ], - }, - 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, - }), - new MiniCssExtractPlugin({ - filename: "[name].css", - chunkFilename: "[id].css", - }), - ], -}; From afd361c07d369a2fb57a4674b99c2e548821b90f Mon Sep 17 00:00:00 2001 From: Uchan Date: Mon, 13 Mar 2023 22:16:07 +0900 Subject: [PATCH 09/36] callback --- hooks/04_Callback/package.json | 41 ++++++++++++++++++++ hooks/04_Callback/src/app.tsx | 16 ++++++++ hooks/04_Callback/src/hello.tsx | 9 +++++ hooks/04_Callback/src/index.html | 13 +++++++ hooks/04_Callback/src/index.tsx | 8 ++++ hooks/04_Callback/src/nameEdit.tsx | 25 ++++++++++++ hooks/04_Callback/tsconfig.json | 15 ++++++++ hooks/04_Callback/webpack.config.js | 60 +++++++++++++++++++++++++++++ 8 files changed, 187 insertions(+) create mode 100644 hooks/04_Callback/package.json create mode 100644 hooks/04_Callback/src/app.tsx create mode 100644 hooks/04_Callback/src/hello.tsx create mode 100644 hooks/04_Callback/src/index.html create mode 100644 hooks/04_Callback/src/index.tsx create mode 100644 hooks/04_Callback/src/nameEdit.tsx create mode 100644 hooks/04_Callback/tsconfig.json create mode 100644 hooks/04_Callback/webpack.config.js diff --git a/hooks/04_Callback/package.json b/hooks/04_Callback/package.json new file mode 100644 index 0000000..6c2b1b9 --- /dev/null +++ b/hooks/04_Callback/package.json @@ -0,0 +1,41 @@ +{ + "name": "react-typescript-by-sample", + "version": "1.0.0", + "description": "React Typescript examples", + "main": "index.js", + "scripts": { + "start": "webpack-dev-server --mode development --hot --open", + "build": "webpack --mode development" + }, + "keywords": [ + "react", + "typescript", + "hooks" + ], + "author": "Braulio Diez Botella", + "license": "MIT", + "devDependencies": { + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.20.2", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "babel-loader": "^9.1.2", + "css-loader": "^6.7.3", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "mini-css-extract-plugin": "^2.7.3", + "style-loader": "^3.3.1", + "ts-loader": "^9.4.2", + "typescript": "^4.9.5", + "url-loader": "^4.1.1", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" + }, + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0" + } +} \ No newline at end of file diff --git a/hooks/04_Callback/src/app.tsx b/hooks/04_Callback/src/app.tsx new file mode 100644 index 0000000..870f4a8 --- /dev/null +++ b/hooks/04_Callback/src/app.tsx @@ -0,0 +1,16 @@ +import * as React from "react"; +import { HelloComponent } from "./hello"; +import { NameEditComponent } from "./nameEdit"; + +export const App = () => { + const [name, setName] = React.useState('defaultUserName') + const setUsernameState = (newName: string) => { + setName(newName) + } + return ( + <> + + + + ); +}; \ No newline at end of file diff --git a/hooks/04_Callback/src/hello.tsx b/hooks/04_Callback/src/hello.tsx new file mode 100644 index 0000000..b9b1d81 --- /dev/null +++ b/hooks/04_Callback/src/hello.tsx @@ -0,0 +1,9 @@ +import * as React from "react"; + +interface Props { + userName: string; +} + +export const HelloComponent: React.FC = (props) => ( +

Hello user: {props.userName} !

+); diff --git a/hooks/04_Callback/src/index.html b/hooks/04_Callback/src/index.html new file mode 100644 index 0000000..cef0845 --- /dev/null +++ b/hooks/04_Callback/src/index.html @@ -0,0 +1,13 @@ + + + + + + + +
+

Sample app

+
+
+ + diff --git a/hooks/04_Callback/src/index.tsx b/hooks/04_Callback/src/index.tsx new file mode 100644 index 0000000..0f847e1 --- /dev/null +++ b/hooks/04_Callback/src/index.tsx @@ -0,0 +1,8 @@ +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { App } from './app'; + +ReactDOM.render( + , + document.getElementById('root') +); diff --git a/hooks/04_Callback/src/nameEdit.tsx b/hooks/04_Callback/src/nameEdit.tsx new file mode 100644 index 0000000..0e203ea --- /dev/null +++ b/hooks/04_Callback/src/nameEdit.tsx @@ -0,0 +1,25 @@ +import * as React from "react"; + +interface Props { + initialUserName: string, + onNameUpdated: (newName: string) => any; +} + +export const NameEditComponent = (props: Props) => { + const [editingName, setEditingName] = React.useState(props.initialUserName); + + const onChange = (e: React.ChangeEvent) => { + setEditingName(e.target.value); + } + + const onNameSubmit = (event: any): any => { + props.onNameUpdated(editingName); + } + return ( + <> + + + + + ) +} \ No newline at end of file diff --git a/hooks/04_Callback/tsconfig.json b/hooks/04_Callback/tsconfig.json new file mode 100644 index 0000000..f90a3f0 --- /dev/null +++ b/hooks/04_Callback/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "es6", + "moduleResolution": "node", + "declaration": false, + "noImplicitAny": false, + "jsx": "react", + "sourceMap": true, + "noLib": false, + "suppressImplicitAnyIndexErrors": true + }, + "compileOnSave": false, + "exclude": ["node_modules"] +} diff --git a/hooks/04_Callback/webpack.config.js b/hooks/04_Callback/webpack.config.js new file mode 100644 index 0000000..1d6fce3 --- /dev/null +++ b/hooks/04_Callback/webpack.config.js @@ -0,0 +1,60 @@ +var HtmlWebpackPlugin = require("html-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var webpack = require("webpack"); +var path = require("path"); + +var basePath = __dirname; + +module.exports = { + context: path.join(basePath, "src"), + resolve: { + extensions: [".js", ".ts", ".tsx"] + }, + entry: ["@babel/polyfill", "./index.tsx"], + output: { + path: path.join(basePath, "dist"), + filename: "bundle.js" + }, + devtool: "source-map", + devServer: { + // inline: true, // Enable watch and live reload + // host: "localhost", + // port: 8080, + // stats: "errors-only", + static: { + directory: "./dist", + } + }, + module: { + rules: [ + { + test: /\.(ts|tsx)$/, + exclude: /node_modules/, + loader: "ts-loader", + }, + { + test: /\.css$/, + use: [MiniCssExtractPlugin.loader, "css-loader"] + }, + { + test: /\.(png|jpg|gif|svg)$/, + loader: "file-loader", + options: { + name: "assets/img/[name].[ext]?[hash]" + } + } + ] + }, + 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 + }), + new MiniCssExtractPlugin({ + filename: "[name].css", + chunkFilename: "[id].css" + }) + ] +}; \ No newline at end of file From 7152efd97a59c6fc346199a1b716a109d47f0850 Mon Sep 17 00:00:00 2001 From: Uchan Date: Tue, 14 Mar 2023 08:10:42 +0900 Subject: [PATCH 10/36] refactor --- hooks/05_Refactor/.babelrc | 10 ------ hooks/05_Refactor/package.json | 44 ++++++++++++------------ hooks/05_Refactor/src/app.tsx | 49 ++++++++++++-------------- hooks/05_Refactor/src/hello.tsx | 6 ++-- hooks/05_Refactor/src/index.tsx | 12 ++++--- hooks/05_Refactor/src/nameEdit.tsx | 47 ++++++++++++++----------- hooks/05_Refactor/webpack.config.js | 53 ++++++++++++++--------------- 7 files changed, 106 insertions(+), 115 deletions(-) delete mode 100644 hooks/05_Refactor/.babelrc diff --git a/hooks/05_Refactor/.babelrc b/hooks/05_Refactor/.babelrc deleted file mode 100644 index 957cae3..0000000 --- a/hooks/05_Refactor/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "entry" - } - ] - ] -} diff --git a/hooks/05_Refactor/package.json b/hooks/05_Refactor/package.json index 264e71d..6c2b1b9 100644 --- a/hooks/05_Refactor/package.json +++ b/hooks/05_Refactor/package.json @@ -4,7 +4,7 @@ "description": "React Typescript examples", "main": "index.js", "scripts": { - "start": "webpack-dev-server --mode development --inline --hot --open", + "start": "webpack-dev-server --mode development --hot --open", "build": "webpack --mode development" }, "keywords": [ @@ -15,27 +15,27 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.10.5", - "@babel/polyfill": "^7.10.4", - "@babel/preset-env": "^7.10.4", - "@types/react": "^16.9.43", - "@types/react-dom": "^16.9.8", - "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.1.0", - "css-loader": "^3.6.0", - "file-loader": "^6.0.0", - "html-webpack-plugin": "^4.3.0", - "mini-css-extract-plugin": "^0.9.0", - "style-loader": "^1.2.1", - "typescript": "^3.9.7", - "url-loader": "^4.1.0", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.0" + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.20.2", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "babel-loader": "^9.1.2", + "css-loader": "^6.7.3", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "mini-css-extract-plugin": "^2.7.3", + "style-loader": "^3.3.1", + "ts-loader": "^9.4.2", + "typescript": "^4.9.5", + "url-loader": "^4.1.1", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" }, "dependencies": { - "react": "^16.13.1", - "react-dom": "^16.13.1" + "react": "^18.2.0", + "react-dom": "^18.2.0" } -} +} \ No newline at end of file diff --git a/hooks/05_Refactor/src/app.tsx b/hooks/05_Refactor/src/app.tsx index e02695f..854dc0f 100644 --- a/hooks/05_Refactor/src/app.tsx +++ b/hooks/05_Refactor/src/app.tsx @@ -3,33 +3,26 @@ import { HelloComponent } from "./hello"; import { NameEditComponent } from "./nameEdit"; export const App = () => { - const [name, setName] = React.useState("defaultUserName"); - const [editingName, setEditingName] = React.useState("defaultUserName"); + const [name, setName] = React.useState('defaultUserName') + const [editingName, setEditingName] = React.useState("defaultUserName"); + const setUsernameState = () => { + setName(editingName) + } - const loadUsername = () => { - setTimeout(() => { - setName("name from async call"); - setEditingName("name from async call"); - }, 500); - }; + const loadUsername = () => { + setTimeout(() => { + setName("name from async call"); + setEditingName("name from async call"); + }, 500); + }; - React.useEffect(() => { - loadUsername(); - }, []); - - const setUsernameState = () => { - setName(editingName); - }; - - return ( - <> - - - - ); -}; + React.useEffect(() => { + loadUsername() + }, []); + return ( + <> + + + + ); +}; \ No newline at end of file diff --git a/hooks/05_Refactor/src/hello.tsx b/hooks/05_Refactor/src/hello.tsx index b6b7aca..b9b1d81 100644 --- a/hooks/05_Refactor/src/hello.tsx +++ b/hooks/05_Refactor/src/hello.tsx @@ -4,6 +4,6 @@ interface Props { userName: string; } -export const HelloComponent: React.FC = (props) => { - return

Hello user: {props.userName} !

; -}; +export const HelloComponent: React.FC = (props) => ( +

Hello user: {props.userName} !

+); diff --git a/hooks/05_Refactor/src/index.tsx b/hooks/05_Refactor/src/index.tsx index 26ed977..0f847e1 100644 --- a/hooks/05_Refactor/src/index.tsx +++ b/hooks/05_Refactor/src/index.tsx @@ -1,6 +1,8 @@ -import * as React from "react"; -import * as ReactDOM from "react-dom"; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { App } from './app'; -import { App } from "./app"; - -ReactDOM.render(, document.getElementById("root")); +ReactDOM.render( + , + document.getElementById('root') +); diff --git a/hooks/05_Refactor/src/nameEdit.tsx b/hooks/05_Refactor/src/nameEdit.tsx index c2eebf3..2a40ec7 100644 --- a/hooks/05_Refactor/src/nameEdit.tsx +++ b/hooks/05_Refactor/src/nameEdit.tsx @@ -1,26 +1,35 @@ import * as React from "react"; interface Props { - initialUserName: string; - editingName: string; - onNameUpdated: () => any; - onEditingNameUpdated: (newEditingName: string) => any; + initialUserName: string; + onNameUpdated: () => any; + editingName: string; + onEditingNameUpdated: (newEditingName: string) => any; } -export const NameEditComponent: React.FC = (props) => { - const onChange = (e: React.ChangeEvent) => { - props.onEditingNameUpdated(e.target.value); - }; +export const NameEditComponent = (props: Props) => { + // const [editingName, setEditingName] = React.useState(props.initialUserName); + const [lastInitialName, setLastInitialName] = React.useState(props.initialUserName); - const onNameSubmit = (event: any): any => { - props.onNameUpdated(); - }; + const onChange = (e: React.ChangeEvent) => { + // setEditingName(e.target.value); + props.onNameUpdated(); + } - return ( - <> - - - - - ); -}; + const onNameSubmit = (event: any): any => { + // props.onNameUpdated(editingName); + props.onNameUpdated(); + } + + // if (props.initialUserName !== lastInitialName) { + // setLastInitialName(props.initialUserName); + // setEditingName(props.initialUserName); + // } + return ( + <> + + + + + ) +} \ No newline at end of file diff --git a/hooks/05_Refactor/webpack.config.js b/hooks/05_Refactor/webpack.config.js index 32eff84..1d6fce3 100644 --- a/hooks/05_Refactor/webpack.config.js +++ b/hooks/05_Refactor/webpack.config.js @@ -1,63 +1,60 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const webpack = require("webpack"); -const path = require("path"); +var HtmlWebpackPlugin = require("html-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var webpack = require("webpack"); +var path = require("path"); -const basePath = __dirname; +var basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"], + extensions: [".js", ".ts", ".tsx"] }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js", + 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", + // inline: true, // Enable watch and live reload + // host: "localhost", + // port: 8080, + // stats: "errors-only", + static: { + directory: "./dist", + } }, module: { rules: [ { test: /\.(ts|tsx)$/, exclude: /node_modules/, - loader: "awesome-typescript-loader", - options: { - useBabel: true, - babelCore: "@babel/core", // needed for Babel v7 - }, + loader: "ts-loader", }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"], + use: [MiniCssExtractPlugin.loader, "css-loader"] }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]", - esModule: false, - }, - }, - ], + name: "assets/img/[name].[ext]?[hash]" + } + } + ] }, 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, + hash: true }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css", - }), - ], -}; + chunkFilename: "[id].css" + }) + ] +}; \ No newline at end of file From fda92e3661c255f068e09ff142d214f7c16daa48 Mon Sep 17 00:00:00 2001 From: Uchan Date: Tue, 14 Mar 2023 08:11:54 +0900 Subject: [PATCH 11/36] init --- hooks/06_Enable/.babelrc | 10 ------ hooks/06_Enable/package.json | 44 ++++++++++++------------- hooks/06_Enable/src/app.tsx | 50 ++++++++++++----------------- hooks/06_Enable/src/hello.tsx | 6 ++-- hooks/06_Enable/src/index.tsx | 12 ++++--- hooks/06_Enable/src/nameEdit.tsx | 50 ++++++++++++++++------------- hooks/06_Enable/webpack.config.js | 53 +++++++++++++++---------------- 7 files changed, 106 insertions(+), 119 deletions(-) delete mode 100644 hooks/06_Enable/.babelrc diff --git a/hooks/06_Enable/.babelrc b/hooks/06_Enable/.babelrc deleted file mode 100644 index 957cae3..0000000 --- a/hooks/06_Enable/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "entry" - } - ] - ] -} diff --git a/hooks/06_Enable/package.json b/hooks/06_Enable/package.json index 264e71d..6c2b1b9 100644 --- a/hooks/06_Enable/package.json +++ b/hooks/06_Enable/package.json @@ -4,7 +4,7 @@ "description": "React Typescript examples", "main": "index.js", "scripts": { - "start": "webpack-dev-server --mode development --inline --hot --open", + "start": "webpack-dev-server --mode development --hot --open", "build": "webpack --mode development" }, "keywords": [ @@ -15,27 +15,27 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.10.5", - "@babel/polyfill": "^7.10.4", - "@babel/preset-env": "^7.10.4", - "@types/react": "^16.9.43", - "@types/react-dom": "^16.9.8", - "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.1.0", - "css-loader": "^3.6.0", - "file-loader": "^6.0.0", - "html-webpack-plugin": "^4.3.0", - "mini-css-extract-plugin": "^0.9.0", - "style-loader": "^1.2.1", - "typescript": "^3.9.7", - "url-loader": "^4.1.0", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.0" + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.20.2", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "babel-loader": "^9.1.2", + "css-loader": "^6.7.3", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "mini-css-extract-plugin": "^2.7.3", + "style-loader": "^3.3.1", + "ts-loader": "^9.4.2", + "typescript": "^4.9.5", + "url-loader": "^4.1.1", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" }, "dependencies": { - "react": "^16.13.1", - "react-dom": "^16.13.1" + "react": "^18.2.0", + "react-dom": "^18.2.0" } -} +} \ No newline at end of file diff --git a/hooks/06_Enable/src/app.tsx b/hooks/06_Enable/src/app.tsx index 8a834bf..854dc0f 100644 --- a/hooks/06_Enable/src/app.tsx +++ b/hooks/06_Enable/src/app.tsx @@ -3,34 +3,26 @@ import { HelloComponent } from "./hello"; import { NameEditComponent } from "./nameEdit"; export const App = () => { - const [name, setName] = React.useState("defaultUserName"); - const [editingName, setEditingName] = React.useState("defaultUserName"); + const [name, setName] = React.useState('defaultUserName') + const [editingName, setEditingName] = React.useState("defaultUserName"); + const setUsernameState = () => { + setName(editingName) + } - const loadUsername = () => { - setTimeout(() => { - setName("name from async call"); - setEditingName("name from async call"); - }, 500); - }; + const loadUsername = () => { + setTimeout(() => { + setName("name from async call"); + setEditingName("name from async call"); + }, 500); + }; - React.useEffect(() => { - loadUsername(); - }, []); - - const setUsernameState = () => { - setName(editingName); - }; - - return ( - <> - - - - ); -}; + React.useEffect(() => { + loadUsername() + }, []); + return ( + <> + + + + ); +}; \ No newline at end of file diff --git a/hooks/06_Enable/src/hello.tsx b/hooks/06_Enable/src/hello.tsx index b6b7aca..b9b1d81 100644 --- a/hooks/06_Enable/src/hello.tsx +++ b/hooks/06_Enable/src/hello.tsx @@ -4,6 +4,6 @@ interface Props { userName: string; } -export const HelloComponent: React.FC = (props) => { - return

Hello user: {props.userName} !

; -}; +export const HelloComponent: React.FC = (props) => ( +

Hello user: {props.userName} !

+); diff --git a/hooks/06_Enable/src/index.tsx b/hooks/06_Enable/src/index.tsx index 26ed977..0f847e1 100644 --- a/hooks/06_Enable/src/index.tsx +++ b/hooks/06_Enable/src/index.tsx @@ -1,6 +1,8 @@ -import * as React from "react"; -import * as ReactDOM from "react-dom"; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { App } from './app'; -import { App } from "./app"; - -ReactDOM.render(, document.getElementById("root")); +ReactDOM.render( + , + document.getElementById('root') +); diff --git a/hooks/06_Enable/src/nameEdit.tsx b/hooks/06_Enable/src/nameEdit.tsx index 7f9091e..2a40ec7 100644 --- a/hooks/06_Enable/src/nameEdit.tsx +++ b/hooks/06_Enable/src/nameEdit.tsx @@ -1,29 +1,35 @@ import * as React from "react"; interface Props { - initialUserName: string; - editingName: string; - onNameUpdated: () => any; - onEditingNameUpdated: (newEditingName: string) => any; - disabled: boolean; + initialUserName: string; + onNameUpdated: () => any; + editingName: string; + onEditingNameUpdated: (newEditingName: string) => any; } -export const NameEditComponent: React.FC = (props) => { - const onChange = (e: React.ChangeEvent) => { - props.onEditingNameUpdated(e.target.value); - }; +export const NameEditComponent = (props: Props) => { + // const [editingName, setEditingName] = React.useState(props.initialUserName); + const [lastInitialName, setLastInitialName] = React.useState(props.initialUserName); - const onNameSubmit = (event: any): any => { - props.onNameUpdated(); - }; + const onChange = (e: React.ChangeEvent) => { + // setEditingName(e.target.value); + props.onNameUpdated(); + } - return ( - <> - - - - - ); -}; + const onNameSubmit = (event: any): any => { + // props.onNameUpdated(editingName); + props.onNameUpdated(); + } + + // if (props.initialUserName !== lastInitialName) { + // setLastInitialName(props.initialUserName); + // setEditingName(props.initialUserName); + // } + return ( + <> + + + + + ) +} \ No newline at end of file diff --git a/hooks/06_Enable/webpack.config.js b/hooks/06_Enable/webpack.config.js index 32eff84..1d6fce3 100644 --- a/hooks/06_Enable/webpack.config.js +++ b/hooks/06_Enable/webpack.config.js @@ -1,63 +1,60 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const webpack = require("webpack"); -const path = require("path"); +var HtmlWebpackPlugin = require("html-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var webpack = require("webpack"); +var path = require("path"); -const basePath = __dirname; +var basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"], + extensions: [".js", ".ts", ".tsx"] }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js", + 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", + // inline: true, // Enable watch and live reload + // host: "localhost", + // port: 8080, + // stats: "errors-only", + static: { + directory: "./dist", + } }, module: { rules: [ { test: /\.(ts|tsx)$/, exclude: /node_modules/, - loader: "awesome-typescript-loader", - options: { - useBabel: true, - babelCore: "@babel/core", // needed for Babel v7 - }, + loader: "ts-loader", }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"], + use: [MiniCssExtractPlugin.loader, "css-loader"] }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]", - esModule: false, - }, - }, - ], + name: "assets/img/[name].[ext]?[hash]" + } + } + ] }, 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, + hash: true }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css", - }), - ], -}; + chunkFilename: "[id].css" + }) + ] +}; \ No newline at end of file From a1bb304199c3f8b7b0b6ab3eb6c622e76bbf97c9 Mon Sep 17 00:00:00 2001 From: Uchan Date: Tue, 14 Mar 2023 08:21:05 +0900 Subject: [PATCH 12/36] enable --- hooks/06_Enable/src/app.tsx | 6 +++++- hooks/06_Enable/src/nameEdit.tsx | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/hooks/06_Enable/src/app.tsx b/hooks/06_Enable/src/app.tsx index 854dc0f..3e5fc01 100644 --- a/hooks/06_Enable/src/app.tsx +++ b/hooks/06_Enable/src/app.tsx @@ -22,7 +22,11 @@ export const App = () => { return ( <> - + ); }; \ No newline at end of file diff --git a/hooks/06_Enable/src/nameEdit.tsx b/hooks/06_Enable/src/nameEdit.tsx index 2a40ec7..d764808 100644 --- a/hooks/06_Enable/src/nameEdit.tsx +++ b/hooks/06_Enable/src/nameEdit.tsx @@ -5,6 +5,7 @@ interface Props { onNameUpdated: () => any; editingName: string; onEditingNameUpdated: (newEditingName: string) => any; + disabled: boolean; } export const NameEditComponent = (props: Props) => { @@ -13,7 +14,7 @@ export const NameEditComponent = (props: Props) => { const onChange = (e: React.ChangeEvent) => { // setEditingName(e.target.value); - props.onNameUpdated(); + props.onEditingNameUpdated(e.target.value); } const onNameSubmit = (event: any): any => { @@ -29,7 +30,7 @@ export const NameEditComponent = (props: Props) => { <> - + ) } \ No newline at end of file From 9788921630760469c1af6aa50f3b8e4f47a0eb5c Mon Sep 17 00:00:00 2001 From: Uchan Date: Wed, 15 Mar 2023 08:00:02 +0900 Subject: [PATCH 13/36] init --- hooks/07_ColorPicker/.babelrc | 10 --- hooks/07_ColorPicker/package.json | 44 ++++++------- hooks/07_ColorPicker/src/app.tsx | 65 ++++++++----------- .../src/components/colorBrowser.tsx | 16 ----- .../src/components/colorPicker.tsx | 57 ---------------- hooks/07_ColorPicker/src/components/hello.tsx | 9 --- hooks/07_ColorPicker/src/components/index.tsx | 4 -- .../src/components/nameEdit.tsx | 30 --------- hooks/07_ColorPicker/src/hello.tsx | 9 +++ hooks/07_ColorPicker/src/index.tsx | 12 ++-- hooks/07_ColorPicker/src/model/color.ts | 5 -- hooks/07_ColorPicker/src/nameEdit.tsx | 36 ++++++++++ hooks/07_ColorPicker/webpack.config.js | 53 +++++++-------- 13 files changed, 126 insertions(+), 224 deletions(-) delete mode 100644 hooks/07_ColorPicker/.babelrc delete mode 100644 hooks/07_ColorPicker/src/components/colorBrowser.tsx delete mode 100644 hooks/07_ColorPicker/src/components/colorPicker.tsx delete mode 100644 hooks/07_ColorPicker/src/components/hello.tsx delete mode 100644 hooks/07_ColorPicker/src/components/index.tsx delete mode 100644 hooks/07_ColorPicker/src/components/nameEdit.tsx create mode 100644 hooks/07_ColorPicker/src/hello.tsx delete mode 100644 hooks/07_ColorPicker/src/model/color.ts create mode 100644 hooks/07_ColorPicker/src/nameEdit.tsx diff --git a/hooks/07_ColorPicker/.babelrc b/hooks/07_ColorPicker/.babelrc deleted file mode 100644 index 957cae3..0000000 --- a/hooks/07_ColorPicker/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "entry" - } - ] - ] -} diff --git a/hooks/07_ColorPicker/package.json b/hooks/07_ColorPicker/package.json index 264e71d..6c2b1b9 100644 --- a/hooks/07_ColorPicker/package.json +++ b/hooks/07_ColorPicker/package.json @@ -4,7 +4,7 @@ "description": "React Typescript examples", "main": "index.js", "scripts": { - "start": "webpack-dev-server --mode development --inline --hot --open", + "start": "webpack-dev-server --mode development --hot --open", "build": "webpack --mode development" }, "keywords": [ @@ -15,27 +15,27 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.10.5", - "@babel/polyfill": "^7.10.4", - "@babel/preset-env": "^7.10.4", - "@types/react": "^16.9.43", - "@types/react-dom": "^16.9.8", - "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.1.0", - "css-loader": "^3.6.0", - "file-loader": "^6.0.0", - "html-webpack-plugin": "^4.3.0", - "mini-css-extract-plugin": "^0.9.0", - "style-loader": "^1.2.1", - "typescript": "^3.9.7", - "url-loader": "^4.1.0", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.0" + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.20.2", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "babel-loader": "^9.1.2", + "css-loader": "^6.7.3", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "mini-css-extract-plugin": "^2.7.3", + "style-loader": "^3.3.1", + "ts-loader": "^9.4.2", + "typescript": "^4.9.5", + "url-loader": "^4.1.1", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" }, "dependencies": { - "react": "^16.13.1", - "react-dom": "^16.13.1" + "react": "^18.2.0", + "react-dom": "^18.2.0" } -} +} \ No newline at end of file diff --git a/hooks/07_ColorPicker/src/app.tsx b/hooks/07_ColorPicker/src/app.tsx index b629405..3e5fc01 100644 --- a/hooks/07_ColorPicker/src/app.tsx +++ b/hooks/07_ColorPicker/src/app.tsx @@ -1,43 +1,32 @@ import * as React from "react"; -import { HelloComponent, NameEditComponent, ColorBrowser, ColorPicker } from "./components"; -import { Color } from "./model/color"; +import { HelloComponent } from "./hello"; +import { NameEditComponent } from "./nameEdit"; export const App = () => { - const [name, setName] = React.useState("defaultUserName"); - const [editingName, setEditingName] = React.useState("defaultUserName"); - const [color, setColor] = React.useState({ - red: 20, - green: 40, - blue: 180 - }); + const [name, setName] = React.useState('defaultUserName') + const [editingName, setEditingName] = React.useState("defaultUserName"); + const setUsernameState = () => { + setName(editingName) + } - const loadUsername = () => { - setTimeout(() => { - setName("name from async call"); - setEditingName("name from async call"); - }, 500); - }; + const loadUsername = () => { + setTimeout(() => { + setName("name from async call"); + setEditingName("name from async call"); + }, 500); + }; - React.useEffect(() => { - loadUsername(); - }, []); - - const setUsernameState = () => { - setName(editingName); - }; - - return ( - <> - - - - - - ); -}; + React.useEffect(() => { + loadUsername() + }, []); + return ( + <> + + + + ); +}; \ No newline at end of file diff --git a/hooks/07_ColorPicker/src/components/colorBrowser.tsx b/hooks/07_ColorPicker/src/components/colorBrowser.tsx deleted file mode 100644 index 813746c..0000000 --- a/hooks/07_ColorPicker/src/components/colorBrowser.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from "react"; -import { Color } from "../model/color"; - -interface Props { - color: Color; -} - -export const ColorBrowser: React.FC = (props) => { - const divStyle: React.CSSProperties = { - width: "11rem", - height: "7rem", - backgroundColor: `rgb(${props.color.red},${props.color.green}, ${props.color.blue})`, - }; - - return
; -}; diff --git a/hooks/07_ColorPicker/src/components/colorPicker.tsx b/hooks/07_ColorPicker/src/components/colorPicker.tsx deleted file mode 100644 index 23bdca3..0000000 --- a/hooks/07_ColorPicker/src/components/colorPicker.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import * as React from "react"; -import { Color } from "../model/color"; - -interface Props { - color: Color; - onColorUpdated: (color: Color) => void; -} - -export const ColorPicker: React.FC = (props) => ( -
- - props.onColorUpdated({ - red: +event.target.value, - green: props.color.green, - blue: props.color.blue - }) - } - /> - {props.color.red} -
- - props.onColorUpdated({ - red: props.color.red, - green: event.target.value, - blue: props.color.blue - }) - } - /> - {props.color.green} -
- - props.onColorUpdated({ - red: props.color.red, - green: props.color.green, - blue: event.target.value - }) - } - /> - {props.color.blue} -
-
-); diff --git a/hooks/07_ColorPicker/src/components/hello.tsx b/hooks/07_ColorPicker/src/components/hello.tsx deleted file mode 100644 index b6b7aca..0000000 --- a/hooks/07_ColorPicker/src/components/hello.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import * as React from "react"; - -interface Props { - userName: string; -} - -export const HelloComponent: React.FC = (props) => { - return

Hello user: {props.userName} !

; -}; diff --git a/hooks/07_ColorPicker/src/components/index.tsx b/hooks/07_ColorPicker/src/components/index.tsx deleted file mode 100644 index 7d9f725..0000000 --- a/hooks/07_ColorPicker/src/components/index.tsx +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./hello"; -export * from "./nameEdit"; -export * from "./colorBrowser"; -export * from "./colorPicker"; diff --git a/hooks/07_ColorPicker/src/components/nameEdit.tsx b/hooks/07_ColorPicker/src/components/nameEdit.tsx deleted file mode 100644 index 5461073..0000000 --- a/hooks/07_ColorPicker/src/components/nameEdit.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import * as React from "react"; - -interface Props { - initialUserName: string; - editingName: string; - onNameUpdated: () => any; - onEditingNameUpdated: (newEditingName: string) => any; - disabled : boolean; -} - -export const NameEditComponent: React.FC = (props) => { - const onChange = (e: React.ChangeEvent) => { - props.onEditingNameUpdated(e.target.value); - }; - - const onNameSubmit = (event: any): any => { - props.onNameUpdated(); - }; - - return ( - <> - - - - - ); -}; diff --git a/hooks/07_ColorPicker/src/hello.tsx b/hooks/07_ColorPicker/src/hello.tsx new file mode 100644 index 0000000..b9b1d81 --- /dev/null +++ b/hooks/07_ColorPicker/src/hello.tsx @@ -0,0 +1,9 @@ +import * as React from "react"; + +interface Props { + userName: string; +} + +export const HelloComponent: React.FC = (props) => ( +

Hello user: {props.userName} !

+); diff --git a/hooks/07_ColorPicker/src/index.tsx b/hooks/07_ColorPicker/src/index.tsx index 26ed977..0f847e1 100644 --- a/hooks/07_ColorPicker/src/index.tsx +++ b/hooks/07_ColorPicker/src/index.tsx @@ -1,6 +1,8 @@ -import * as React from "react"; -import * as ReactDOM from "react-dom"; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { App } from './app'; -import { App } from "./app"; - -ReactDOM.render(, document.getElementById("root")); +ReactDOM.render( + , + document.getElementById('root') +); diff --git a/hooks/07_ColorPicker/src/model/color.ts b/hooks/07_ColorPicker/src/model/color.ts deleted file mode 100644 index 17acfed..0000000 --- a/hooks/07_ColorPicker/src/model/color.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface Color { - red: number; - green: number; - blue: number; -} diff --git a/hooks/07_ColorPicker/src/nameEdit.tsx b/hooks/07_ColorPicker/src/nameEdit.tsx new file mode 100644 index 0000000..d764808 --- /dev/null +++ b/hooks/07_ColorPicker/src/nameEdit.tsx @@ -0,0 +1,36 @@ +import * as React from "react"; + +interface Props { + initialUserName: string; + onNameUpdated: () => any; + editingName: string; + onEditingNameUpdated: (newEditingName: string) => any; + disabled: boolean; +} + +export const NameEditComponent = (props: Props) => { + // const [editingName, setEditingName] = React.useState(props.initialUserName); + const [lastInitialName, setLastInitialName] = React.useState(props.initialUserName); + + const onChange = (e: React.ChangeEvent) => { + // setEditingName(e.target.value); + props.onEditingNameUpdated(e.target.value); + } + + const onNameSubmit = (event: any): any => { + // props.onNameUpdated(editingName); + props.onNameUpdated(); + } + + // if (props.initialUserName !== lastInitialName) { + // setLastInitialName(props.initialUserName); + // setEditingName(props.initialUserName); + // } + return ( + <> + + + + + ) +} \ No newline at end of file diff --git a/hooks/07_ColorPicker/webpack.config.js b/hooks/07_ColorPicker/webpack.config.js index 32eff84..1d6fce3 100644 --- a/hooks/07_ColorPicker/webpack.config.js +++ b/hooks/07_ColorPicker/webpack.config.js @@ -1,63 +1,60 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const webpack = require("webpack"); -const path = require("path"); +var HtmlWebpackPlugin = require("html-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var webpack = require("webpack"); +var path = require("path"); -const basePath = __dirname; +var basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"], + extensions: [".js", ".ts", ".tsx"] }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js", + 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", + // inline: true, // Enable watch and live reload + // host: "localhost", + // port: 8080, + // stats: "errors-only", + static: { + directory: "./dist", + } }, module: { rules: [ { test: /\.(ts|tsx)$/, exclude: /node_modules/, - loader: "awesome-typescript-loader", - options: { - useBabel: true, - babelCore: "@babel/core", // needed for Babel v7 - }, + loader: "ts-loader", }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"], + use: [MiniCssExtractPlugin.loader, "css-loader"] }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]", - esModule: false, - }, - }, - ], + name: "assets/img/[name].[ext]?[hash]" + } + } + ] }, 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, + hash: true }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css", - }), - ], -}; + chunkFilename: "[id].css" + }) + ] +}; \ No newline at end of file From 4bdf6bfb7618e8e28804dee6696e0b2ee06072f6 Mon Sep 17 00:00:00 2001 From: Uchan Date: Wed, 15 Mar 2023 08:21:01 +0900 Subject: [PATCH 14/36] colorpicker --- hooks/07_ColorPicker/src/app.tsx | 9 ++- .../src/components/colorBrowser.tsx | 16 +++++ .../src/components/colorpicker.tsx | 59 +++++++++++++++++++ .../src/{ => components}/hello.tsx | 0 hooks/07_ColorPicker/src/components/index.tsx | 14 +++++ .../src/{ => components}/nameEdit.tsx | 0 hooks/07_ColorPicker/src/index.tsx | 8 --- hooks/07_ColorPicker/src/model/color.tsx | 5 ++ hooks/07_ColorPicker/webpack.config.js | 2 +- 9 files changed, 102 insertions(+), 11 deletions(-) create mode 100644 hooks/07_ColorPicker/src/components/colorBrowser.tsx create mode 100644 hooks/07_ColorPicker/src/components/colorpicker.tsx rename hooks/07_ColorPicker/src/{ => components}/hello.tsx (100%) create mode 100644 hooks/07_ColorPicker/src/components/index.tsx rename hooks/07_ColorPicker/src/{ => components}/nameEdit.tsx (100%) delete mode 100644 hooks/07_ColorPicker/src/index.tsx create mode 100644 hooks/07_ColorPicker/src/model/color.tsx diff --git a/hooks/07_ColorPicker/src/app.tsx b/hooks/07_ColorPicker/src/app.tsx index 3e5fc01..ce3c949 100644 --- a/hooks/07_ColorPicker/src/app.tsx +++ b/hooks/07_ColorPicker/src/app.tsx @@ -1,10 +1,13 @@ import * as React from "react"; -import { HelloComponent } from "./hello"; -import { NameEditComponent } from "./nameEdit"; +import { ColorBrowser, HelloComponent, NameEditComponent, ColorPicker } from "./components"; +import { Color } from "./model/color"; +// import { HelloComponent } from "./components/hello"; +// import { NameEditComponent } from "./components/nameEdit"; export const App = () => { const [name, setName] = React.useState('defaultUserName') const [editingName, setEditingName] = React.useState("defaultUserName"); + const [color, setColor] = React.useState({ red: 20, green: 40, blue: 180 }) const setUsernameState = () => { setName(editingName) } @@ -21,6 +24,8 @@ export const App = () => { }, []); return ( <> + + { + const divStyle: React.CSSProperties = { + width: "11rem", + height: "7rem", + backgroundColor: `rgb(${props.color.red},${props.color.green},${props.color.blue})` + } + + return
; +} \ No newline at end of file diff --git a/hooks/07_ColorPicker/src/components/colorpicker.tsx b/hooks/07_ColorPicker/src/components/colorpicker.tsx new file mode 100644 index 0000000..4e9f680 --- /dev/null +++ b/hooks/07_ColorPicker/src/components/colorpicker.tsx @@ -0,0 +1,59 @@ +import * as React from "react"; +import { Color } from "../model/color"; + +interface Props { + color: Color; + onColorUpdated: (color: Color) => void; +} + +export const ColorPicker = (props: Props) => ( +
+ + props.onColorUpdated({ + red: +event.target.value, + green: props.color.green, + blue: props.color.blue + }) + } + /> + {props.color.red} + +
+ + props.onColorUpdated({ + red: props.color.red, + green: +event.target.value, + blue: props.color.blue + }) + } + /> + {props.color.green} +
+ + + props.onColorUpdated({ + red: props.color.red, + green: props.color.green, + blue: +event.target.value + }) + } + /> + {props.color.blue} +
+
+); \ No newline at end of file diff --git a/hooks/07_ColorPicker/src/hello.tsx b/hooks/07_ColorPicker/src/components/hello.tsx similarity index 100% rename from hooks/07_ColorPicker/src/hello.tsx rename to hooks/07_ColorPicker/src/components/hello.tsx diff --git a/hooks/07_ColorPicker/src/components/index.tsx b/hooks/07_ColorPicker/src/components/index.tsx new file mode 100644 index 0000000..c9937b6 --- /dev/null +++ b/hooks/07_ColorPicker/src/components/index.tsx @@ -0,0 +1,14 @@ +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { App } from '../app'; + +ReactDOM.render( + , + document.getElementById('root') +); + + +export * from "./hello" +export * from "./nameEdit" +export * from "./colorBrowser" +export * from './colorPicker' \ No newline at end of file diff --git a/hooks/07_ColorPicker/src/nameEdit.tsx b/hooks/07_ColorPicker/src/components/nameEdit.tsx similarity index 100% rename from hooks/07_ColorPicker/src/nameEdit.tsx rename to hooks/07_ColorPicker/src/components/nameEdit.tsx diff --git a/hooks/07_ColorPicker/src/index.tsx b/hooks/07_ColorPicker/src/index.tsx deleted file mode 100644 index 0f847e1..0000000 --- a/hooks/07_ColorPicker/src/index.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import * as React from 'react'; -import * as ReactDOM from 'react-dom'; -import { App } from './app'; - -ReactDOM.render( - , - document.getElementById('root') -); diff --git a/hooks/07_ColorPicker/src/model/color.tsx b/hooks/07_ColorPicker/src/model/color.tsx new file mode 100644 index 0000000..c1783c6 --- /dev/null +++ b/hooks/07_ColorPicker/src/model/color.tsx @@ -0,0 +1,5 @@ +export interface Color { + red: number; + green: number; + blue: number; +} \ No newline at end of file diff --git a/hooks/07_ColorPicker/webpack.config.js b/hooks/07_ColorPicker/webpack.config.js index 1d6fce3..c2fd5a1 100644 --- a/hooks/07_ColorPicker/webpack.config.js +++ b/hooks/07_ColorPicker/webpack.config.js @@ -10,7 +10,7 @@ module.exports = { resolve: { extensions: [".js", ".ts", ".tsx"] }, - entry: ["@babel/polyfill", "./index.tsx"], + entry: ["@babel/polyfill", "./components/index.tsx"], output: { path: path.join(basePath, "dist"), filename: "bundle.js" From 7a590b9ff64caaed8398738ee04d49959cad9469 Mon Sep 17 00:00:00 2001 From: Uchan Date: Thu, 16 Mar 2023 08:48:19 +0900 Subject: [PATCH 15/36] colorpickerrefactor --- hooks/08_ColorPickerRefactor/.babelrc | 10 --- hooks/08_ColorPickerRefactor/package.json | 44 +++++----- hooks/08_ColorPickerRefactor/src/app.tsx | 68 +++++++-------- .../src/components/colorBrowser.tsx | 22 +++-- .../src/components/colorPicker.tsx | 83 +++++++++---------- .../src/components/hello.tsx | 6 +- .../src/components/index.tsx | 18 +++- .../src/components/nameEdit.tsx | 51 +++++++----- hooks/08_ColorPickerRefactor/src/index.tsx | 6 -- .../08_ColorPickerRefactor/src/model/color.ts | 5 -- .../src/model/color.tsx | 5 ++ .../08_ColorPickerRefactor/webpack.config.js | 55 ++++++------ 12 files changed, 177 insertions(+), 196 deletions(-) delete mode 100644 hooks/08_ColorPickerRefactor/.babelrc delete mode 100644 hooks/08_ColorPickerRefactor/src/index.tsx delete mode 100644 hooks/08_ColorPickerRefactor/src/model/color.ts create mode 100644 hooks/08_ColorPickerRefactor/src/model/color.tsx diff --git a/hooks/08_ColorPickerRefactor/.babelrc b/hooks/08_ColorPickerRefactor/.babelrc deleted file mode 100644 index 957cae3..0000000 --- a/hooks/08_ColorPickerRefactor/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "entry" - } - ] - ] -} diff --git a/hooks/08_ColorPickerRefactor/package.json b/hooks/08_ColorPickerRefactor/package.json index 264e71d..6c2b1b9 100644 --- a/hooks/08_ColorPickerRefactor/package.json +++ b/hooks/08_ColorPickerRefactor/package.json @@ -4,7 +4,7 @@ "description": "React Typescript examples", "main": "index.js", "scripts": { - "start": "webpack-dev-server --mode development --inline --hot --open", + "start": "webpack-dev-server --mode development --hot --open", "build": "webpack --mode development" }, "keywords": [ @@ -15,27 +15,27 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.10.5", - "@babel/polyfill": "^7.10.4", - "@babel/preset-env": "^7.10.4", - "@types/react": "^16.9.43", - "@types/react-dom": "^16.9.8", - "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.1.0", - "css-loader": "^3.6.0", - "file-loader": "^6.0.0", - "html-webpack-plugin": "^4.3.0", - "mini-css-extract-plugin": "^0.9.0", - "style-loader": "^1.2.1", - "typescript": "^3.9.7", - "url-loader": "^4.1.0", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.0" + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.20.2", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "babel-loader": "^9.1.2", + "css-loader": "^6.7.3", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "mini-css-extract-plugin": "^2.7.3", + "style-loader": "^3.3.1", + "ts-loader": "^9.4.2", + "typescript": "^4.9.5", + "url-loader": "^4.1.1", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" }, "dependencies": { - "react": "^16.13.1", - "react-dom": "^16.13.1" + "react": "^18.2.0", + "react-dom": "^18.2.0" } -} +} \ No newline at end of file diff --git a/hooks/08_ColorPickerRefactor/src/app.tsx b/hooks/08_ColorPickerRefactor/src/app.tsx index b629405..ce3c949 100644 --- a/hooks/08_ColorPickerRefactor/src/app.tsx +++ b/hooks/08_ColorPickerRefactor/src/app.tsx @@ -1,43 +1,37 @@ import * as React from "react"; -import { HelloComponent, NameEditComponent, ColorBrowser, ColorPicker } from "./components"; +import { ColorBrowser, HelloComponent, NameEditComponent, ColorPicker } from "./components"; import { Color } from "./model/color"; +// import { HelloComponent } from "./components/hello"; +// import { NameEditComponent } from "./components/nameEdit"; export const App = () => { - const [name, setName] = React.useState("defaultUserName"); - const [editingName, setEditingName] = React.useState("defaultUserName"); - const [color, setColor] = React.useState({ - red: 20, - green: 40, - blue: 180 - }); + const [name, setName] = React.useState('defaultUserName') + const [editingName, setEditingName] = React.useState("defaultUserName"); + const [color, setColor] = React.useState({ red: 20, green: 40, blue: 180 }) + const setUsernameState = () => { + setName(editingName) + } - const loadUsername = () => { - setTimeout(() => { - setName("name from async call"); - setEditingName("name from async call"); - }, 500); - }; + const loadUsername = () => { + setTimeout(() => { + setName("name from async call"); + setEditingName("name from async call"); + }, 500); + }; - React.useEffect(() => { - loadUsername(); - }, []); - - const setUsernameState = () => { - setName(editingName); - }; - - return ( - <> - - - - - - ); -}; + React.useEffect(() => { + loadUsername() + }, []); + return ( + <> + + + + + + ); +}; \ No newline at end of file diff --git a/hooks/08_ColorPickerRefactor/src/components/colorBrowser.tsx b/hooks/08_ColorPickerRefactor/src/components/colorBrowser.tsx index a28e438..827ae71 100644 --- a/hooks/08_ColorPickerRefactor/src/components/colorBrowser.tsx +++ b/hooks/08_ColorPickerRefactor/src/components/colorBrowser.tsx @@ -1,18 +1,16 @@ import * as React from "react"; -import { Color } from "../model/color"; +import { Color } from "../model/color" interface Props { - color: Color; + color: Color; } -export const ColorBrowser: React.FC = (props) => { - const divStyle: React.CSSProperties = { - width: "11rem", - height: "7rem", - backgroundColor: `rgb(${props.color.red},${props.color.green}, ${ - props.color.blue - })` - }; +export const ColorBrowser = (props: Props) => { + const divStyle: React.CSSProperties = { + width: "11rem", + height: "7rem", + backgroundColor: `rgb(${props.color.red},${props.color.green},${props.color.blue})` + } - return
; -}; + return
; +} \ No newline at end of file diff --git a/hooks/08_ColorPickerRefactor/src/components/colorPicker.tsx b/hooks/08_ColorPickerRefactor/src/components/colorPicker.tsx index ff4cbcd..aaa5e54 100644 --- a/hooks/08_ColorPickerRefactor/src/components/colorPicker.tsx +++ b/hooks/08_ColorPickerRefactor/src/components/colorPicker.tsx @@ -2,55 +2,46 @@ import * as React from "react"; import { Color } from "../model/color"; interface Props { - color: Color; - onColorUpdated: (color: Color) => void; + color: Color; + onColorUpdated: (color: Color) => void; } -const updateColor = (props: Props, colorId: keyof Color) => (value: any) => { - // keyof Color ensures only 'red', 'blue' or 'green' can be passed in. - props.onColorUpdated({ - ...props.color, // this creates a clone of the current props.color object... - [colorId]: value, // ... which gets one of its properties (colorId) immediately replaced by a new value. - }); -}; +interface PropsColorSlider { + key: string; + value: number; + onValueUpdated: (newValue: number) => void; +} -export const ColorPicker: React.FC = (props) => ( -
- -
- -
- - {props.color.blue} -
-
-); +const ColorSliderComponent = (props: PropsColorSlider) => { + return ( +
+ props.onValueUpdated(+event.target.value)} + /> + {props.value} +
+ ) +} -interface PropsColorSlider { - value: number; - onValueUpdated: (newValue: number) => void; +const updateColor = (props: Props, colorId: keyof Color) => (value) => { + props.onColorUpdated({ + ...props.color, + [colorId]: value + }) } -const ColorSliderComponent: React.FC = (props: PropsColorSlider) => { - return ( -
- props.onValueUpdated(+event.target.value)} - /> - {props.value} -
- ); -}; +export const ColorPicker = (props: Props) => ( + <> + {Object.keys(props.color).map((field: keyof Color) => ( + + ))} + +); \ No newline at end of file diff --git a/hooks/08_ColorPickerRefactor/src/components/hello.tsx b/hooks/08_ColorPickerRefactor/src/components/hello.tsx index b6b7aca..b9b1d81 100644 --- a/hooks/08_ColorPickerRefactor/src/components/hello.tsx +++ b/hooks/08_ColorPickerRefactor/src/components/hello.tsx @@ -4,6 +4,6 @@ interface Props { userName: string; } -export const HelloComponent: React.FC = (props) => { - return

Hello user: {props.userName} !

; -}; +export const HelloComponent: React.FC = (props) => ( +

Hello user: {props.userName} !

+); diff --git a/hooks/08_ColorPickerRefactor/src/components/index.tsx b/hooks/08_ColorPickerRefactor/src/components/index.tsx index 7d9f725..c9937b6 100644 --- a/hooks/08_ColorPickerRefactor/src/components/index.tsx +++ b/hooks/08_ColorPickerRefactor/src/components/index.tsx @@ -1,4 +1,14 @@ -export * from "./hello"; -export * from "./nameEdit"; -export * from "./colorBrowser"; -export * from "./colorPicker"; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { App } from '../app'; + +ReactDOM.render( + , + document.getElementById('root') +); + + +export * from "./hello" +export * from "./nameEdit" +export * from "./colorBrowser" +export * from './colorPicker' \ No newline at end of file diff --git a/hooks/08_ColorPickerRefactor/src/components/nameEdit.tsx b/hooks/08_ColorPickerRefactor/src/components/nameEdit.tsx index 7f9091e..d764808 100644 --- a/hooks/08_ColorPickerRefactor/src/components/nameEdit.tsx +++ b/hooks/08_ColorPickerRefactor/src/components/nameEdit.tsx @@ -1,29 +1,36 @@ import * as React from "react"; interface Props { - initialUserName: string; - editingName: string; - onNameUpdated: () => any; - onEditingNameUpdated: (newEditingName: string) => any; - disabled: boolean; + initialUserName: string; + onNameUpdated: () => any; + editingName: string; + onEditingNameUpdated: (newEditingName: string) => any; + disabled: boolean; } -export const NameEditComponent: React.FC = (props) => { - const onChange = (e: React.ChangeEvent) => { - props.onEditingNameUpdated(e.target.value); - }; +export const NameEditComponent = (props: Props) => { + // const [editingName, setEditingName] = React.useState(props.initialUserName); + const [lastInitialName, setLastInitialName] = React.useState(props.initialUserName); - const onNameSubmit = (event: any): any => { - props.onNameUpdated(); - }; + const onChange = (e: React.ChangeEvent) => { + // setEditingName(e.target.value); + props.onEditingNameUpdated(e.target.value); + } - return ( - <> - - - - - ); -}; + const onNameSubmit = (event: any): any => { + // props.onNameUpdated(editingName); + props.onNameUpdated(); + } + + // if (props.initialUserName !== lastInitialName) { + // setLastInitialName(props.initialUserName); + // setEditingName(props.initialUserName); + // } + return ( + <> + + + + + ) +} \ No newline at end of file diff --git a/hooks/08_ColorPickerRefactor/src/index.tsx b/hooks/08_ColorPickerRefactor/src/index.tsx deleted file mode 100644 index 26ed977..0000000 --- a/hooks/08_ColorPickerRefactor/src/index.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import * as React from "react"; -import * as ReactDOM from "react-dom"; - -import { App } from "./app"; - -ReactDOM.render(, document.getElementById("root")); diff --git a/hooks/08_ColorPickerRefactor/src/model/color.ts b/hooks/08_ColorPickerRefactor/src/model/color.ts deleted file mode 100644 index 17acfed..0000000 --- a/hooks/08_ColorPickerRefactor/src/model/color.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface Color { - red: number; - green: number; - blue: number; -} diff --git a/hooks/08_ColorPickerRefactor/src/model/color.tsx b/hooks/08_ColorPickerRefactor/src/model/color.tsx new file mode 100644 index 0000000..c1783c6 --- /dev/null +++ b/hooks/08_ColorPickerRefactor/src/model/color.tsx @@ -0,0 +1,5 @@ +export interface Color { + red: number; + green: number; + blue: number; +} \ No newline at end of file diff --git a/hooks/08_ColorPickerRefactor/webpack.config.js b/hooks/08_ColorPickerRefactor/webpack.config.js index 32eff84..c2fd5a1 100644 --- a/hooks/08_ColorPickerRefactor/webpack.config.js +++ b/hooks/08_ColorPickerRefactor/webpack.config.js @@ -1,63 +1,60 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const webpack = require("webpack"); -const path = require("path"); +var HtmlWebpackPlugin = require("html-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var webpack = require("webpack"); +var path = require("path"); -const basePath = __dirname; +var basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"], + extensions: [".js", ".ts", ".tsx"] }, - entry: ["@babel/polyfill", "./index.tsx"], + entry: ["@babel/polyfill", "./components/index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js", + 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", + // inline: true, // Enable watch and live reload + // host: "localhost", + // port: 8080, + // stats: "errors-only", + static: { + directory: "./dist", + } }, module: { rules: [ { test: /\.(ts|tsx)$/, exclude: /node_modules/, - loader: "awesome-typescript-loader", - options: { - useBabel: true, - babelCore: "@babel/core", // needed for Babel v7 - }, + loader: "ts-loader", }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"], + use: [MiniCssExtractPlugin.loader, "css-loader"] }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]", - esModule: false, - }, - }, - ], + name: "assets/img/[name].[ext]?[hash]" + } + } + ] }, 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, + hash: true }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css", - }), - ], -}; + chunkFilename: "[id].css" + }) + ] +}; \ No newline at end of file From d026e49c754a9f42ba5b898199f768885d9baf62 Mon Sep 17 00:00:00 2001 From: Uchan Date: Fri, 17 Mar 2023 08:39:14 +0900 Subject: [PATCH 16/36] =?UTF-8?q?init=20=E9=80=94=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hooks/09_Sidebar/.babelrc | 10 -- hooks/09_Sidebar/package.json | 44 ++++---- hooks/09_Sidebar/src/app.tsx | 101 +++++++----------- .../src/components/colorBrowser.tsx | 20 ++-- .../09_Sidebar/src/components/colorPicker.tsx | 83 +++++++------- hooks/09_Sidebar/src/components/hello.tsx | 6 +- hooks/09_Sidebar/src/components/index.tsx | 20 +++- hooks/09_Sidebar/src/components/nameEdit.tsx | 51 +++++---- hooks/09_Sidebar/src/components/sidebar.css | 57 +++++----- hooks/09_Sidebar/src/components/sidebar.tsx | 16 +-- hooks/09_Sidebar/src/index.html | 25 +++-- hooks/09_Sidebar/src/index.tsx | 6 -- hooks/09_Sidebar/src/model/color.ts | 5 - hooks/09_Sidebar/src/model/color.tsx | 5 + hooks/09_Sidebar/webpack.config.js | 64 ++++++----- 15 files changed, 245 insertions(+), 268 deletions(-) delete mode 100644 hooks/09_Sidebar/.babelrc delete mode 100644 hooks/09_Sidebar/src/index.tsx delete mode 100644 hooks/09_Sidebar/src/model/color.ts create mode 100644 hooks/09_Sidebar/src/model/color.tsx diff --git a/hooks/09_Sidebar/.babelrc b/hooks/09_Sidebar/.babelrc deleted file mode 100644 index 957cae3..0000000 --- a/hooks/09_Sidebar/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "entry" - } - ] - ] -} diff --git a/hooks/09_Sidebar/package.json b/hooks/09_Sidebar/package.json index 40171b2..d413868 100644 --- a/hooks/09_Sidebar/package.json +++ b/hooks/09_Sidebar/package.json @@ -4,7 +4,7 @@ "description": "React Typescript examples", "main": "index.js", "scripts": { - "start": "webpack-dev-server --mode development --inline --hot --open", + "start": "webpack-dev-server --mode development --hot --open", "build": "webpack --mode development" }, "keywords": [ @@ -15,28 +15,28 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.10.5", - "@babel/polyfill": "^7.10.4", - "@babel/preset-env": "^7.10.4", - "@types/node": "^14.0.24", - "@types/react": "^16.9.43", - "@types/react-dom": "^16.9.8", - "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.1.0", - "css-loader": "^3.6.0", - "file-loader": "^6.0.0", - "html-webpack-plugin": "^4.3.0", - "mini-css-extract-plugin": "^0.9.0", - "style-loader": "^1.2.1", - "typescript": "^3.9.7", - "url-loader": "^4.1.0", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.0" + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.20.2", + "@types/node": "^18.15.3", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "babel-loader": "^9.1.2", + "css-loader": "^6.7.3", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "mini-css-extract-plugin": "^2.7.3", + "style-loader": "^3.3.1", + "ts-loader": "^9.4.2", + "typescript": "^4.9.5", + "url-loader": "^4.1.1", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" }, "dependencies": { - "react": "^16.13.1", - "react-dom": "^16.13.1" + "react": "^18.2.0", + "react-dom": "^18.2.0" } } diff --git a/hooks/09_Sidebar/src/app.tsx b/hooks/09_Sidebar/src/app.tsx index 6eed921..ba5a6f7 100644 --- a/hooks/09_Sidebar/src/app.tsx +++ b/hooks/09_Sidebar/src/app.tsx @@ -1,69 +1,44 @@ import * as React from "react"; -import { - HelloComponent, - NameEditComponent, - ColorBrowser, - ColorPicker, - SidebarComponent -} from "./components"; +import { ColorBrowser, HelloComponent, NameEditComponent, ColorPicker, SidebarComponent } from "./components"; import { Color } from "./model/color"; +// import { HelloComponent } from "./components/hello"; +// import { NameEditComponent } from "./components/nameEdit"; export const App = () => { - const [name, setName] = React.useState("defaultUserName"); - const [editingName, setEditingName] = React.useState("defaultUserName"); - const [color, setColor] = React.useState({ - red: 20, - green: 40, - blue: 180 - }); - const [isVisible, setVisible] = React.useState(false); + const [name, setName] = React.useState('defaultUserName') + const [editingName, setEditingName] = React.useState("defaultUserName"); + const [color, setColor] = React.useState({ red: 20, green: 40, blue: 180 }) + const [isVisible, setVisible] = React.useState(false) + const setUsernameState = () => { + setName(editingName) + } - const loadUsername = () => { - setTimeout(() => { - setName("name from async call"); - setEditingName("name from async call"); - }, 500); - }; + const loadUsername = () => { + setTimeout(() => { + setName("name from async call"); + setEditingName("name from async call"); + }, 500); + }; - React.useEffect(() => { - loadUsername(); - }, []); - - const setUsernameState = () => { - setName(editingName); - }; - - return ( - <> - -

Cool Scfi movies

- -
- - - - -
- -
- - ); -}; + React.useEffect(() => { + loadUsername() + }, []); + return ( + <> + + + + + +
+ +
+ + ); +}; \ No newline at end of file diff --git a/hooks/09_Sidebar/src/components/colorBrowser.tsx b/hooks/09_Sidebar/src/components/colorBrowser.tsx index 813746c..827ae71 100644 --- a/hooks/09_Sidebar/src/components/colorBrowser.tsx +++ b/hooks/09_Sidebar/src/components/colorBrowser.tsx @@ -1,16 +1,16 @@ import * as React from "react"; -import { Color } from "../model/color"; +import { Color } from "../model/color" interface Props { - color: Color; + color: Color; } -export const ColorBrowser: React.FC = (props) => { - const divStyle: React.CSSProperties = { - width: "11rem", - height: "7rem", - backgroundColor: `rgb(${props.color.red},${props.color.green}, ${props.color.blue})`, - }; +export const ColorBrowser = (props: Props) => { + const divStyle: React.CSSProperties = { + width: "11rem", + height: "7rem", + backgroundColor: `rgb(${props.color.red},${props.color.green},${props.color.blue})` + } - return
; -}; + return
; +} \ No newline at end of file diff --git a/hooks/09_Sidebar/src/components/colorPicker.tsx b/hooks/09_Sidebar/src/components/colorPicker.tsx index 4346cd4..aaa5e54 100644 --- a/hooks/09_Sidebar/src/components/colorPicker.tsx +++ b/hooks/09_Sidebar/src/components/colorPicker.tsx @@ -2,55 +2,46 @@ import * as React from "react"; import { Color } from "../model/color"; interface Props { - color: Color; - onColorUpdated: (color: Color) => void; + color: Color; + onColorUpdated: (color: Color) => void; } -const updateColor = (props: Props, colorId: keyof Color) => (value) => { - // keyof Color ensures only 'red', 'blue' or 'green' can be passed in. - props.onColorUpdated({ - ...props.color, // this creates a clone of the current props.color object... - [colorId]: value, // ... which gets one of its properties (colorId) immediately replaced by a new value. - }); -}; +interface PropsColorSlider { + key: string; + value: number; + onValueUpdated: (newValue: number) => void; +} -export const ColorPicker: React.FC = (props) => ( -
- -
- -
- - {props.color.blue} -
-
-); +const ColorSliderComponent = (props: PropsColorSlider) => { + return ( +
+ props.onValueUpdated(+event.target.value)} + /> + {props.value} +
+ ) +} -interface PropsColorSlider { - value: number; - onValueUpdated: (newValue: number) => void; +const updateColor = (props: Props, colorId: keyof Color) => (value) => { + props.onColorUpdated({ + ...props.color, + [colorId]: value + }) } -const ColorSliderComponent: React.FC = (props) => { - return ( -
- props.onValueUpdated(+event.target.value)} - /> - {props.value} -
- ); -}; +export const ColorPicker = (props: Props) => ( + <> + {Object.keys(props.color).map((field: keyof Color) => ( + + ))} + +); \ No newline at end of file diff --git a/hooks/09_Sidebar/src/components/hello.tsx b/hooks/09_Sidebar/src/components/hello.tsx index b6b7aca..b9b1d81 100644 --- a/hooks/09_Sidebar/src/components/hello.tsx +++ b/hooks/09_Sidebar/src/components/hello.tsx @@ -4,6 +4,6 @@ interface Props { userName: string; } -export const HelloComponent: React.FC = (props) => { - return

Hello user: {props.userName} !

; -}; +export const HelloComponent: React.FC = (props) => ( +

Hello user: {props.userName} !

+); diff --git a/hooks/09_Sidebar/src/components/index.tsx b/hooks/09_Sidebar/src/components/index.tsx index 6774259..045006f 100644 --- a/hooks/09_Sidebar/src/components/index.tsx +++ b/hooks/09_Sidebar/src/components/index.tsx @@ -1,5 +1,15 @@ -export * from "./hello"; -export * from "./nameEdit"; -export * from "./colorBrowser"; -export * from "./colorPicker"; -export * from "./sidebar"; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { App } from '../app'; + +ReactDOM.render( + , + document.getElementById('root') +); + + +export * from "./hello" +export * from "./nameEdit" +export * from "./colorBrowser" +export * from './colorPicker' +export * from './sidebar' \ No newline at end of file diff --git a/hooks/09_Sidebar/src/components/nameEdit.tsx b/hooks/09_Sidebar/src/components/nameEdit.tsx index 7f9091e..d764808 100644 --- a/hooks/09_Sidebar/src/components/nameEdit.tsx +++ b/hooks/09_Sidebar/src/components/nameEdit.tsx @@ -1,29 +1,36 @@ import * as React from "react"; interface Props { - initialUserName: string; - editingName: string; - onNameUpdated: () => any; - onEditingNameUpdated: (newEditingName: string) => any; - disabled: boolean; + initialUserName: string; + onNameUpdated: () => any; + editingName: string; + onEditingNameUpdated: (newEditingName: string) => any; + disabled: boolean; } -export const NameEditComponent: React.FC = (props) => { - const onChange = (e: React.ChangeEvent) => { - props.onEditingNameUpdated(e.target.value); - }; +export const NameEditComponent = (props: Props) => { + // const [editingName, setEditingName] = React.useState(props.initialUserName); + const [lastInitialName, setLastInitialName] = React.useState(props.initialUserName); - const onNameSubmit = (event: any): any => { - props.onNameUpdated(); - }; + const onChange = (e: React.ChangeEvent) => { + // setEditingName(e.target.value); + props.onEditingNameUpdated(e.target.value); + } - return ( - <> - - - - - ); -}; + const onNameSubmit = (event: any): any => { + // props.onNameUpdated(editingName); + props.onNameUpdated(); + } + + // if (props.initialUserName !== lastInitialName) { + // setLastInitialName(props.initialUserName); + // setEditingName(props.initialUserName); + // } + return ( + <> + + + + + ) +} \ No newline at end of file diff --git a/hooks/09_Sidebar/src/components/sidebar.css b/hooks/09_Sidebar/src/components/sidebar.css index 907d868..2a47251 100644 --- a/hooks/09_Sidebar/src/components/sidebar.css +++ b/hooks/09_Sidebar/src/components/sidebar.css @@ -1,38 +1,47 @@ /* The side navigation menu */ .sidenav { - height: 100%; /* 100% Full-height */ - width: 0; /* 0 width - change this with JavaScript */ - position: fixed; /* Stay in place */ - z-index: 1; /* Stay on top */ - top: 0; - left: 0; - background-color: #808080; /* Gray*/ - overflow-x: hidden; /* Disable horizontal scroll */ - padding-top: 60px; /* Place content 60px from the top */ - transition: 0.5s; /* 0.5 second transition effect to slide in the sidenav */ + height: 100%; + /* 100% Full-height */ + width: 0; + /* 0 width - change this with JavaScript */ + position: fixed; + /* Stay in place */ + z-index: 1; + /* Stay on top */ + top: 0; + left: 0; + background-color: #808080; + /* Gray*/ + overflow-x: hidden; + /* Disable horizontal scroll */ + padding-top: 60px; + /* Place content 60px from the top */ + transition: 0.5s; + /* 0.5 second transition effect to slide in the sidenav */ } /* Position and style the close button (top right corner) */ .sidenav .closebtn { - position: absolute; - top: 0; - right: 25px; - font-size: 36px; - margin-left: 50px; + position: absolute; + top: 0; + right: 25px; + font-size: 36px; + margin-left: 50px; } /* Style page content - use this if you want to push the page content to the right when you open the side navigation */ #main { - transition: margin-left 0.5s; - padding: 20px; + transition: margin-left 0.5s; + padding: 20px; } /* On smaller screens, where height is less than 450px, change the style of the sidenav (less padding and a smaller font size) */ @media screen and (max-height: 450px) { - .sidenav { - padding-top: 15px; - } - .sidenav a { - font-size: 18px; - } -} + .sidenav { + padding-top: 15px; + } + + .sidenav a { + font-size: 18px; + } +} \ No newline at end of file diff --git a/hooks/09_Sidebar/src/components/sidebar.tsx b/hooks/09_Sidebar/src/components/sidebar.tsx index 0847a55..12c28da 100644 --- a/hooks/09_Sidebar/src/components/sidebar.tsx +++ b/hooks/09_Sidebar/src/components/sidebar.tsx @@ -3,15 +3,15 @@ import * as React from "react"; const classNames = require("./sidebar.css"); interface Props { - isVisible: boolean; + isVisible: boolean; } const divStyle = (props: Props): React.CSSProperties => ({ - width: props.isVisible ? "23rem" : "0rem", -}); + width: (props.isVisible) ? '23rem' : '0rem' +}) -export const SidebarComponent: React.StatelessComponent = (props) => ( -
- {props.children} -
-); +export const SidebarComponent = (props: Props) => ( +
+ Basic side bar, first steps +
+); \ No newline at end of file diff --git a/hooks/09_Sidebar/src/index.html b/hooks/09_Sidebar/src/index.html index c57efef..ff56f8d 100644 --- a/hooks/09_Sidebar/src/index.html +++ b/hooks/09_Sidebar/src/index.html @@ -1,13 +1,16 @@ - - - - - -
-

Sample app

-
-
- - + + + + + + + +
+

Sample app

+
+
+ + + \ No newline at end of file diff --git a/hooks/09_Sidebar/src/index.tsx b/hooks/09_Sidebar/src/index.tsx deleted file mode 100644 index 26ed977..0000000 --- a/hooks/09_Sidebar/src/index.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import * as React from "react"; -import * as ReactDOM from "react-dom"; - -import { App } from "./app"; - -ReactDOM.render(, document.getElementById("root")); diff --git a/hooks/09_Sidebar/src/model/color.ts b/hooks/09_Sidebar/src/model/color.ts deleted file mode 100644 index 17acfed..0000000 --- a/hooks/09_Sidebar/src/model/color.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface Color { - red: number; - green: number; - blue: number; -} diff --git a/hooks/09_Sidebar/src/model/color.tsx b/hooks/09_Sidebar/src/model/color.tsx new file mode 100644 index 0000000..c1783c6 --- /dev/null +++ b/hooks/09_Sidebar/src/model/color.tsx @@ -0,0 +1,5 @@ +export interface Color { + red: number; + green: number; + blue: number; +} \ No newline at end of file diff --git a/hooks/09_Sidebar/webpack.config.js b/hooks/09_Sidebar/webpack.config.js index c999658..9860631 100644 --- a/hooks/09_Sidebar/webpack.config.js +++ b/hooks/09_Sidebar/webpack.config.js @@ -1,80 +1,78 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const webpack = require("webpack"); -const path = require("path"); +var HtmlWebpackPlugin = require("html-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var webpack = require("webpack"); +var path = require("path"); -const basePath = __dirname; +var basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx", ".css"], + extensions: [".js", ".ts", ".tsx", ".css"] }, - entry: ["@babel/polyfill", "./index.tsx"], + entry: ["@babel/polyfill", "./components/index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js", + 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", + // inline: true, // Enable watch and live reload + // host: "localhost", + // port: 8080, + // stats: "errors-only", + static: { + directory: "./dist", + } }, module: { rules: [ { test: /\.(ts|tsx)$/, exclude: /node_modules/, - loader: "awesome-typescript-loader", - options: { - useBabel: true, - babelCore: "@babel/core", // needed for Babel v7 - }, + loader: "ts-loader", }, { test: /\.css$/, include: /node_modules/, - use: [MiniCssExtractPlugin.loader, "css-loader"], + use: [MiniCssExtractPlugin.loader, "css-loader"] }, + // Use CSS modules for custom stylesheets { test: /\.css$/, exclude: /node_modules/, use: [ MiniCssExtractPlugin.loader, { - loader: "css-loader", + loader: 'css-loader', options: { + modules: true, modules: { localIdentName: "[name]__[local]___[hash:base64:5]", }, - localsConvention: "camelCase", }, - }, - ], + } + ] }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]", - esModule: false, - }, - }, - ], + name: "assets/img/[name].[ext]?[hash]" + } + } + ] }, 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, + hash: true }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css", - }), - ], -}; + chunkFilename: "[id].css" + }) + ] +}; \ No newline at end of file From 10f32b3ba300b598a666f7996d62a31447f515f0 Mon Sep 17 00:00:00 2001 From: Uchan Date: Sat, 18 Mar 2023 11:27:07 +0900 Subject: [PATCH 17/36] children is error --- hooks/09_Sidebar/src/app.tsx | 9 ++++++++- hooks/09_Sidebar/src/components/sidebar.tsx | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/hooks/09_Sidebar/src/app.tsx b/hooks/09_Sidebar/src/app.tsx index ba5a6f7..1f9e522 100644 --- a/hooks/09_Sidebar/src/app.tsx +++ b/hooks/09_Sidebar/src/app.tsx @@ -25,7 +25,14 @@ export const App = () => { }, []); return ( <> - + +

Cool Scfi movies

+ +
diff --git a/hooks/09_Sidebar/src/components/sidebar.tsx b/hooks/09_Sidebar/src/components/sidebar.tsx index 12c28da..6d1fe53 100644 --- a/hooks/09_Sidebar/src/components/sidebar.tsx +++ b/hooks/09_Sidebar/src/components/sidebar.tsx @@ -10,8 +10,8 @@ const divStyle = (props: Props): React.CSSProperties => ({ width: (props.isVisible) ? '23rem' : '0rem' }) -export const SidebarComponent = (props: Props) => ( +export const SidebarComponent: React.FC = (props) => (
- Basic side bar, first steps + {props.children}
); \ No newline at end of file From 5e80896f2feaec1920d0520131f3ddc2783cfa2b Mon Sep 17 00:00:00 2001 From: Uchan Date: Sat, 18 Mar 2023 11:58:19 +0900 Subject: [PATCH 18/36] tablemock --- hooks/10_TableMock/.babelrc | 10 - hooks/10_TableMock/Readme_es.md | 342 ++++++++++++++++++ hooks/10_TableMock/package.json | 44 +-- hooks/10_TableMock/src/api/memberApi.ts | 24 -- hooks/10_TableMock/src/api/memberApi.tsx | 24 ++ hooks/10_TableMock/src/app.tsx | 111 +++--- .../src/components/colorBrowser.tsx | 20 +- .../src/components/colorPicker.tsx | 83 ++--- hooks/10_TableMock/src/components/hello.tsx | 6 +- hooks/10_TableMock/src/components/index.tsx | 22 +- .../src/components/memberTable.tsx | 67 +--- .../10_TableMock/src/components/nameEdit.tsx | 51 +-- hooks/10_TableMock/src/components/sidebar.css | 57 +-- hooks/10_TableMock/src/components/sidebar.tsx | 19 +- hooks/10_TableMock/src/index.html | 25 +- hooks/10_TableMock/src/index.tsx | 6 - hooks/10_TableMock/src/model/color.ts | 5 - hooks/10_TableMock/src/model/color.tsx | 5 + .../src/model/{member.ts => member.tsx} | 0 hooks/10_TableMock/webpack.config.js | 64 ++-- 20 files changed, 640 insertions(+), 345 deletions(-) delete mode 100644 hooks/10_TableMock/.babelrc create mode 100644 hooks/10_TableMock/Readme_es.md delete mode 100644 hooks/10_TableMock/src/api/memberApi.ts create mode 100644 hooks/10_TableMock/src/api/memberApi.tsx delete mode 100644 hooks/10_TableMock/src/index.tsx delete mode 100644 hooks/10_TableMock/src/model/color.ts create mode 100644 hooks/10_TableMock/src/model/color.tsx rename hooks/10_TableMock/src/model/{member.ts => member.tsx} (100%) diff --git a/hooks/10_TableMock/.babelrc b/hooks/10_TableMock/.babelrc deleted file mode 100644 index 957cae3..0000000 --- a/hooks/10_TableMock/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "entry" - } - ] - ] -} diff --git a/hooks/10_TableMock/Readme_es.md b/hooks/10_TableMock/Readme_es.md new file mode 100644 index 0000000..109add7 --- /dev/null +++ b/hooks/10_TableMock/Readme_es.md @@ -0,0 +1,342 @@ +# 09 Sidebar + +En este ejemplo vamos a añadir una barra lateral a nuestra aplicación, empezaremos con una implementación específica, y luego la haremos genérica. + +# Pasos a seguir + +- Tomaremos como punto de partida el ejemplo _08 ColorPickerRefactor_, copiamos el contenido de ese archivo y ejecutamos _npm install_. + +```bash +npm install +``` + +- Cree un archivo llamado _src/components/sidebar.css_ y añada los siguientes estilos (http://www.w3schools.com/howto/howto_js_sidenav.asp): + +_./src/components/sidebar.css_ + +```css +/* The side navigation menu */ +.sidenav { + height: 100%; /* 100% Full-height */ + width: 0; /* 0 width - change this with JavaScript */ + position: fixed; /* Stay in place */ + z-index: 1; /* Stay on top */ + top: 0; + left: 0; + background-color: #808080; /* Gray*/ + overflow-x: hidden; /* Disable horizontal scroll */ + padding-top: 60px; /* Place content 60px from the top */ + transition: 0.5s; /* 0.5 second transition effect to slide in the sidenav */ +} + +/* Position and style the close button (top right corner) */ +.sidenav .closebtn { + position: absolute; + top: 0; + right: 25px; + font-size: 36px; + margin-left: 50px; +} + +/* Style page content - use this if you want to push the page content to the right when you open the side navigation */ +#main { + transition: margin-left 0.5s; + padding: 20px; +} + +/* On smaller screens, where height is less than 450px, change the style of the sidenav (less padding and a smaller font size) */ +@media screen and (max-height: 450px) { + .sidenav { + padding-top: 15px; + } + .sidenav a { + font-size: 18px; + } +} +``` + +- Vamos a usar módulos CSS, así que vamos a configurarlo. + +_./webpack.config.js_ + +```diff + module.exports = { + context: path.join(basePath, "src"), + resolve: { +- extensions: ['.js', '.ts', '.tsx'] ++ extensions: ['.js', '.ts', '.tsx', '.css'] + }, +``` + +- Sólo usaremos módulos CSS para hojas de estilo personalizadas. No usaremos Módulos CSS para otros archivos CSS, como Bootstrap (carpeta node_modules). + +_./webpack.config.js_ + +```diff + { + test: /\.css$/, ++ include: /node_modules/, + use: [MiniCssExtractPlugin.loader, "css-loader"] + }, ++ // Use CSS modules for custom stylesheets ++ { ++ test: /\.css$/, ++ exclude: /node_modules/, ++ use: [ ++ MiniCssExtractPlugin.loader, ++ { ++ loader: 'css-loader', ++ options: { ++ modules: true, ++ localIdentName: '[name]__[local]___[hash:base64:5]', ++ camelCase: true, ++ }, ++ }, ++ ] ++ }, ++ // Do not use CSS modules in node_modules folder + +``` + +- Vamos a crear el componente de la barra lateral, _src/components/sidebar.tsx_. Crearemos sólo + un rectángulo e interactuaremos con la animación. + +Necesitamos instalar los tipos para _node_, ya que usaremos _require_ a la hora de importar desde el _css_. + +```bash +npm install @types/node --save-dev +``` + +_./src/components/sidebar.tsx_ + +```jsx +import * as React from "react"; + +const classNames = require("./sidebar.css"); + +export const SidebarComponent = () => ( +
+ Basic side bar, first steps +
+); +``` + +- Añadimos este componente a nuestro barrel _index_ + +_./src/components/index.ts_ + +```diff +export * from "./hello"; +export * from "./nameEdit"; +export * from "./colorBrowser"; +export * from "./colorPicker"; ++ export * from "./sidebar"; +``` + +- Vamos a añadir un _id_ al elemento _body_ de la página _src/index.html_ + +_./src/index.html_ + +```diff +- ++ +``` + +- Colocamos el componente añadiéndolo en `app.tsx`: + +_./src/app.tsx_ + +```diff +import * as React from "react"; +- import { HelloComponent, NameEditComponent, ColorBrowser, ColorPicker } from "./components"; ++ import { HelloComponent, NameEditComponent, ColorBrowser, ColorPicker, SidebarComponent } from "./components"; +import { Color } from "./model/color"; +``` + +_./src/app.tsx_ + +```diff + return ( + <> ++ + +``` + +- Comencemos con la parte interesante de esta implementación, agreguemos una opción para mostrar/ocultar la barra lateral _sidebar.tsx_. + +_./src/components/sidebar.tsx_ + +```diff +import * as React from 'react'; + +const classNames = require('./sidebar.css'); + ++ interface Props { ++ isVisible: boolean; ++ } + +- export const SidebarComponent = () => ++ export const SidebarComponent = (props: Props) => +
+ Basic sidebar, first steps +
+``` + +- Ahora vamos a añadir algo de lógica para mostrar / ocultar la barra lateral en caso de que se actualice dicha opción. + + +_./src/sidebar.tsx_ + +```diff +import * as React from 'react'; + +const classNames = require('./sidebar.css'); + +interface Props { + isVisible: boolean; +}; + ++ const divStyle = (props: Props): React.CSSProperties => ({ ++ width: (props.isVisible) ? '23rem' : '0rem' ++ }); + +export const SidebarComponent = (props: Props) => +-
++
+ Basic sidebar, first steps +
+``` + +- Hagamos una prueba rápida para mostrar siempre la barra lateral: + +_./src/app.tsx_ + +```diff + return ( + <> +- ++ + +``` + +- Si arrancamos el proyecto veremos la barra lateral que hemos creado (un rectángulo gris). + + +```bash +npm start +``` +_¿Qué pasa si no puedo ver la barra lateral?_ Compruebe que _webpack.config.js_ y sus estilos se han aplicado, es posible que tenga que iniciar de nuevo _webpack-dev-sever_ (relanzar _npm start_), compruebe con dev tools que está cargando los estilos CSS. + +- Ahora a nivel de aplicación podemos recordar la opción de visibilidad, y añadir un botón para alternar la visualización de la barra lateral. + + +_./src/app.tsx_ + +```diff +export const App = () => { + const [name, setName] = React.useState("defaultUserName"); + const [editingName, setEditingName] = React.useState("defaultUserName"); + const [color, setColor] = React.useState({ + red: 20, + green: 40, + blue: 180 + }); ++ const[isVisible, setVisible] = React.useState(false); +``` + +_./src/app.tsx_ + +```diff + return ( + <> +- ++ + + + + ++
++ ++
+ +``` + +- Iniciemos la aplicación para comprobar cómo se comporta: + +```bash +npm start +``` + +> Ejercicio: la llamada en línea a la función dentro de _onClick_ no se +> considera una buena práctica (en cada render se recreará la función), +> vamos a refactorizarla en dos pasos: + +- Primero extraeremos esta lógica a una función, la llamaremos _toggleSidebarVisibility_. + +- Ahora envolvemos _visibility_ y _toggleSidebarVisibility_ en un _hook_ personalizado. + +* Hasta ahora todo va bien, pero ¿qué pasa si queremos que esta barra lateral sea un componente reutilizable? Podríamos simplemente mostrar el marco pero el contenido debe ser dinámico. + +* Comencemos por añadir algo de contenido al instanciar la barra lateral (_app.tsx_). + + +_./src/app.tsx_ + +```diff + <> +- ++ ++

Cool Scfi movies

++ ++
+ +``` + +> Tenemos un error, _children_ no está definido, vamos a arreglarlo en el +> siguiente paso.... + +- Ahora en _sidebar.tsx_ volcaremos este contenido usando {this.props.children} + +_./src/components/sidebar.tsx_ + +```diff +- export const SidebarComponent = (props: Props) => ( ++ export const SidebarComponent: React.StatelessComponent = (props) => ( + +
+- Basic side bar, first steps ++ {props.children} +
+); +``` + +- Probemos el ejemplo + +``` +npm start +``` + +# About Basefactor + Lemoncode + +We are an innovating team of Javascript experts, passionate about turning your ideas into robust products. + +[Basefactor, consultancy by Lemoncode](http://www.basefactor.com) provides consultancy and coaching services. + +[Lemoncode](http://lemoncode.net/services/en/#en-home) provides training services. + +For the LATAM/Spanish audience we are running an Online Front End Master degree, more info: http://lemoncode.net/master-frontend diff --git a/hooks/10_TableMock/package.json b/hooks/10_TableMock/package.json index 40171b2..d413868 100644 --- a/hooks/10_TableMock/package.json +++ b/hooks/10_TableMock/package.json @@ -4,7 +4,7 @@ "description": "React Typescript examples", "main": "index.js", "scripts": { - "start": "webpack-dev-server --mode development --inline --hot --open", + "start": "webpack-dev-server --mode development --hot --open", "build": "webpack --mode development" }, "keywords": [ @@ -15,28 +15,28 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.10.5", - "@babel/polyfill": "^7.10.4", - "@babel/preset-env": "^7.10.4", - "@types/node": "^14.0.24", - "@types/react": "^16.9.43", - "@types/react-dom": "^16.9.8", - "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.1.0", - "css-loader": "^3.6.0", - "file-loader": "^6.0.0", - "html-webpack-plugin": "^4.3.0", - "mini-css-extract-plugin": "^0.9.0", - "style-loader": "^1.2.1", - "typescript": "^3.9.7", - "url-loader": "^4.1.0", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.0" + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.20.2", + "@types/node": "^18.15.3", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "babel-loader": "^9.1.2", + "css-loader": "^6.7.3", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "mini-css-extract-plugin": "^2.7.3", + "style-loader": "^3.3.1", + "ts-loader": "^9.4.2", + "typescript": "^4.9.5", + "url-loader": "^4.1.1", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" }, "dependencies": { - "react": "^16.13.1", - "react-dom": "^16.13.1" + "react": "^18.2.0", + "react-dom": "^18.2.0" } } diff --git a/hooks/10_TableMock/src/api/memberApi.ts b/hooks/10_TableMock/src/api/memberApi.ts deleted file mode 100644 index b0ad6e1..0000000 --- a/hooks/10_TableMock/src/api/memberApi.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { MemberEntity } from "../model/member"; - -export const getMembersCollection = (): Promise => { - const promise = new Promise((resolve, reject) => { - setTimeout( - () => - resolve([ - { - id: 1457912, - login: "brauliodiez", - avatar_url: "https://avatars.githubusercontent.com/u/1457912?v=3" - }, - { - id: 4374977, - login: "Nasdan", - avatar_url: "https://avatars.githubusercontent.com/u/4374977?v=3" - } - ]), - 500 - ); - }); - - return promise; -}; diff --git a/hooks/10_TableMock/src/api/memberApi.tsx b/hooks/10_TableMock/src/api/memberApi.tsx new file mode 100644 index 0000000..ba18de2 --- /dev/null +++ b/hooks/10_TableMock/src/api/memberApi.tsx @@ -0,0 +1,24 @@ +import { MemberEntity } from "../model/member"; + +export const getMembersCollection = (): Promise => { + const promise = new Promise((resolve, reject) => { + setTimeout( + () => + resolve([ + { + id: 1457912, + login: "brauliodiez", + avatar_url: "https://avatars.githubusercontent.com/u/1457912?v=3" + }, + { + id: 4374977, + login: "Nasdan", + avatar_url: "https://avatars.githubusercontent.com/u/4374977?v=3" + } + ]), + 500 + ); + }); + + return promise; +}; \ No newline at end of file diff --git a/hooks/10_TableMock/src/app.tsx b/hooks/10_TableMock/src/app.tsx index d6623e0..eea1415 100644 --- a/hooks/10_TableMock/src/app.tsx +++ b/hooks/10_TableMock/src/app.tsx @@ -1,71 +1,52 @@ import * as React from "react"; -import { - HelloComponent, - NameEditComponent, - ColorBrowser, - ColorPicker, - SidebarComponent, - MemberTableComponent -} from "./components"; +import { ColorBrowser, HelloComponent, NameEditComponent, ColorPicker, SidebarComponent, MemberTableComponent } from "./components"; import { Color } from "./model/color"; +// import { HelloComponent } from "./components/hello"; +// import { NameEditComponent } from "./components/nameEdit"; export const App = () => { - const [name, setName] = React.useState("defaultUserName"); - const [editingName, setEditingName] = React.useState("defaultUserName"); - const [color, setColor] = React.useState({ - red: 20, - green: 40, - blue: 180 - }); - const [isVisible, setVisible] = React.useState(false); + const [name, setName] = React.useState('defaultUserName') + const [editingName, setEditingName] = React.useState("defaultUserName"); + const [color, setColor] = React.useState({ red: 20, green: 40, blue: 180 }) + const [isVisible, setVisible] = React.useState(false) + const setUsernameState = () => { + setName(editingName) + } - const loadUsername = () => { - setTimeout(() => { - setName("name from async call"); - setEditingName("name from async call"); - }, 500); - }; + const loadUsername = () => { + setTimeout(() => { + setName("name from async call"); + setEditingName("name from async call"); + }, 500); + }; - React.useEffect(() => { - loadUsername(); - }, []); - - const setUsernameState = () => { - setName(editingName); - }; - - return ( - <> - -

Cool Scfi movies

- -
- - - - - -
- -
- - ); -}; + React.useEffect(() => { + loadUsername() + }, []); + return ( + <> + +

Cool Scfi movies

+ +
+ + + + + +
+ +
+ + ); +}; \ No newline at end of file diff --git a/hooks/10_TableMock/src/components/colorBrowser.tsx b/hooks/10_TableMock/src/components/colorBrowser.tsx index 813746c..827ae71 100644 --- a/hooks/10_TableMock/src/components/colorBrowser.tsx +++ b/hooks/10_TableMock/src/components/colorBrowser.tsx @@ -1,16 +1,16 @@ import * as React from "react"; -import { Color } from "../model/color"; +import { Color } from "../model/color" interface Props { - color: Color; + color: Color; } -export const ColorBrowser: React.FC = (props) => { - const divStyle: React.CSSProperties = { - width: "11rem", - height: "7rem", - backgroundColor: `rgb(${props.color.red},${props.color.green}, ${props.color.blue})`, - }; +export const ColorBrowser = (props: Props) => { + const divStyle: React.CSSProperties = { + width: "11rem", + height: "7rem", + backgroundColor: `rgb(${props.color.red},${props.color.green},${props.color.blue})` + } - return
; -}; + return
; +} \ No newline at end of file diff --git a/hooks/10_TableMock/src/components/colorPicker.tsx b/hooks/10_TableMock/src/components/colorPicker.tsx index 4346cd4..aaa5e54 100644 --- a/hooks/10_TableMock/src/components/colorPicker.tsx +++ b/hooks/10_TableMock/src/components/colorPicker.tsx @@ -2,55 +2,46 @@ import * as React from "react"; import { Color } from "../model/color"; interface Props { - color: Color; - onColorUpdated: (color: Color) => void; + color: Color; + onColorUpdated: (color: Color) => void; } -const updateColor = (props: Props, colorId: keyof Color) => (value) => { - // keyof Color ensures only 'red', 'blue' or 'green' can be passed in. - props.onColorUpdated({ - ...props.color, // this creates a clone of the current props.color object... - [colorId]: value, // ... which gets one of its properties (colorId) immediately replaced by a new value. - }); -}; +interface PropsColorSlider { + key: string; + value: number; + onValueUpdated: (newValue: number) => void; +} -export const ColorPicker: React.FC = (props) => ( -
- -
- -
- - {props.color.blue} -
-
-); +const ColorSliderComponent = (props: PropsColorSlider) => { + return ( +
+ props.onValueUpdated(+event.target.value)} + /> + {props.value} +
+ ) +} -interface PropsColorSlider { - value: number; - onValueUpdated: (newValue: number) => void; +const updateColor = (props: Props, colorId: keyof Color) => (value) => { + props.onColorUpdated({ + ...props.color, + [colorId]: value + }) } -const ColorSliderComponent: React.FC = (props) => { - return ( -
- props.onValueUpdated(+event.target.value)} - /> - {props.value} -
- ); -}; +export const ColorPicker = (props: Props) => ( + <> + {Object.keys(props.color).map((field: keyof Color) => ( + + ))} + +); \ No newline at end of file diff --git a/hooks/10_TableMock/src/components/hello.tsx b/hooks/10_TableMock/src/components/hello.tsx index b6b7aca..b9b1d81 100644 --- a/hooks/10_TableMock/src/components/hello.tsx +++ b/hooks/10_TableMock/src/components/hello.tsx @@ -4,6 +4,6 @@ interface Props { userName: string; } -export const HelloComponent: React.FC = (props) => { - return

Hello user: {props.userName} !

; -}; +export const HelloComponent: React.FC = (props) => ( +

Hello user: {props.userName} !

+); diff --git a/hooks/10_TableMock/src/components/index.tsx b/hooks/10_TableMock/src/components/index.tsx index 7b909f0..33158d7 100644 --- a/hooks/10_TableMock/src/components/index.tsx +++ b/hooks/10_TableMock/src/components/index.tsx @@ -1,6 +1,16 @@ -export * from "./hello"; -export * from "./nameEdit"; -export * from "./colorBrowser"; -export * from "./colorPicker"; -export * from "./sidebar"; -export * from "./memberTable"; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { App } from '../app'; + +ReactDOM.render( + , + document.getElementById('root') +); + + +export * from "./hello" +export * from "./nameEdit" +export * from "./colorBrowser" +export * from './colorPicker' +export * from './sidebar' +export * from './memberTable' \ No newline at end of file diff --git a/hooks/10_TableMock/src/components/memberTable.tsx b/hooks/10_TableMock/src/components/memberTable.tsx index eee4479..75fc441 100644 --- a/hooks/10_TableMock/src/components/memberTable.tsx +++ b/hooks/10_TableMock/src/components/memberTable.tsx @@ -1,58 +1,29 @@ -import * as React from "react"; import { MemberEntity } from "../model/member"; import { getMembersCollection } from "../api/memberApi"; +import * as React from "react"; const useMemberCollection = () => { - const [memberCollection, setMemberCollection] = React.useState< - MemberEntity[] - >([]); + const [memberCollection, setMemberCollection] = React.useState([]) - const loadMemberCollection = () => { - getMembersCollection().then(memberCollection => - setMemberCollection(memberCollection) - ); - }; + const loadMemberCollection = () => { + getMembersCollection().then(useMemberCollection => setMemberCollection(memberCollection)) + } - return { memberCollection, loadMemberCollection }; -}; + return { memberCollection, loadMemberCollection } +} export const MemberTableComponent = () => { - const { memberCollection, loadMemberCollection } = useMemberCollection(); - - React.useEffect(() => { - loadMemberCollection(); - }, []); + const { memberCollection, loadMemberCollection } = useMemberCollection(); - return ( - <> - - - - - - - - - - {memberCollection.map(member => ( - - ))} - -
AvatarIdName
- - ); -}; + React.useEffect(() => { + loadMemberCollection() + }, []) -const MemberRow = ({ member }: { member: MemberEntity }) => ( - - - - - - {member.id} - - - {member.login} - - -); + return ( + <> + {memberCollection.map(member => ( +

{member.login}

+ ))} + + ) +} \ No newline at end of file diff --git a/hooks/10_TableMock/src/components/nameEdit.tsx b/hooks/10_TableMock/src/components/nameEdit.tsx index 7f9091e..d764808 100644 --- a/hooks/10_TableMock/src/components/nameEdit.tsx +++ b/hooks/10_TableMock/src/components/nameEdit.tsx @@ -1,29 +1,36 @@ import * as React from "react"; interface Props { - initialUserName: string; - editingName: string; - onNameUpdated: () => any; - onEditingNameUpdated: (newEditingName: string) => any; - disabled: boolean; + initialUserName: string; + onNameUpdated: () => any; + editingName: string; + onEditingNameUpdated: (newEditingName: string) => any; + disabled: boolean; } -export const NameEditComponent: React.FC = (props) => { - const onChange = (e: React.ChangeEvent) => { - props.onEditingNameUpdated(e.target.value); - }; +export const NameEditComponent = (props: Props) => { + // const [editingName, setEditingName] = React.useState(props.initialUserName); + const [lastInitialName, setLastInitialName] = React.useState(props.initialUserName); - const onNameSubmit = (event: any): any => { - props.onNameUpdated(); - }; + const onChange = (e: React.ChangeEvent) => { + // setEditingName(e.target.value); + props.onEditingNameUpdated(e.target.value); + } - return ( - <> - - - - - ); -}; + const onNameSubmit = (event: any): any => { + // props.onNameUpdated(editingName); + props.onNameUpdated(); + } + + // if (props.initialUserName !== lastInitialName) { + // setLastInitialName(props.initialUserName); + // setEditingName(props.initialUserName); + // } + return ( + <> + + + + + ) +} \ No newline at end of file diff --git a/hooks/10_TableMock/src/components/sidebar.css b/hooks/10_TableMock/src/components/sidebar.css index 907d868..2a47251 100644 --- a/hooks/10_TableMock/src/components/sidebar.css +++ b/hooks/10_TableMock/src/components/sidebar.css @@ -1,38 +1,47 @@ /* The side navigation menu */ .sidenav { - height: 100%; /* 100% Full-height */ - width: 0; /* 0 width - change this with JavaScript */ - position: fixed; /* Stay in place */ - z-index: 1; /* Stay on top */ - top: 0; - left: 0; - background-color: #808080; /* Gray*/ - overflow-x: hidden; /* Disable horizontal scroll */ - padding-top: 60px; /* Place content 60px from the top */ - transition: 0.5s; /* 0.5 second transition effect to slide in the sidenav */ + height: 100%; + /* 100% Full-height */ + width: 0; + /* 0 width - change this with JavaScript */ + position: fixed; + /* Stay in place */ + z-index: 1; + /* Stay on top */ + top: 0; + left: 0; + background-color: #808080; + /* Gray*/ + overflow-x: hidden; + /* Disable horizontal scroll */ + padding-top: 60px; + /* Place content 60px from the top */ + transition: 0.5s; + /* 0.5 second transition effect to slide in the sidenav */ } /* Position and style the close button (top right corner) */ .sidenav .closebtn { - position: absolute; - top: 0; - right: 25px; - font-size: 36px; - margin-left: 50px; + position: absolute; + top: 0; + right: 25px; + font-size: 36px; + margin-left: 50px; } /* Style page content - use this if you want to push the page content to the right when you open the side navigation */ #main { - transition: margin-left 0.5s; - padding: 20px; + transition: margin-left 0.5s; + padding: 20px; } /* On smaller screens, where height is less than 450px, change the style of the sidenav (less padding and a smaller font size) */ @media screen and (max-height: 450px) { - .sidenav { - padding-top: 15px; - } - .sidenav a { - font-size: 18px; - } -} + .sidenav { + padding-top: 15px; + } + + .sidenav a { + font-size: 18px; + } +} \ No newline at end of file diff --git a/hooks/10_TableMock/src/components/sidebar.tsx b/hooks/10_TableMock/src/components/sidebar.tsx index 762991e..19af0ee 100644 --- a/hooks/10_TableMock/src/components/sidebar.tsx +++ b/hooks/10_TableMock/src/components/sidebar.tsx @@ -3,17 +3,16 @@ import * as React from "react"; const classNames = require("./sidebar.css"); interface Props { - isVisible: boolean; + isVisible: boolean; + children: React.ReactNode; } const divStyle = (props: Props): React.CSSProperties => ({ - width: props.isVisible ? "23rem" : "0rem" -}); - -export const SidebarComponent: React.StatelessComponent = props => ( -
- {props.children} -
-); - + width: (props.isVisible) ? '23rem' : '0rem' +}) +export const SidebarComponent: React.FC = (props) => ( +
+ {props.children} +
+); \ No newline at end of file diff --git a/hooks/10_TableMock/src/index.html b/hooks/10_TableMock/src/index.html index c57efef..ff56f8d 100644 --- a/hooks/10_TableMock/src/index.html +++ b/hooks/10_TableMock/src/index.html @@ -1,13 +1,16 @@ - - - - - -
-

Sample app

-
-
- - + + + + + + + +
+

Sample app

+
+
+ + + \ No newline at end of file diff --git a/hooks/10_TableMock/src/index.tsx b/hooks/10_TableMock/src/index.tsx deleted file mode 100644 index 26ed977..0000000 --- a/hooks/10_TableMock/src/index.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import * as React from "react"; -import * as ReactDOM from "react-dom"; - -import { App } from "./app"; - -ReactDOM.render(, document.getElementById("root")); diff --git a/hooks/10_TableMock/src/model/color.ts b/hooks/10_TableMock/src/model/color.ts deleted file mode 100644 index 17acfed..0000000 --- a/hooks/10_TableMock/src/model/color.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface Color { - red: number; - green: number; - blue: number; -} diff --git a/hooks/10_TableMock/src/model/color.tsx b/hooks/10_TableMock/src/model/color.tsx new file mode 100644 index 0000000..c1783c6 --- /dev/null +++ b/hooks/10_TableMock/src/model/color.tsx @@ -0,0 +1,5 @@ +export interface Color { + red: number; + green: number; + blue: number; +} \ No newline at end of file diff --git a/hooks/10_TableMock/src/model/member.ts b/hooks/10_TableMock/src/model/member.tsx similarity index 100% rename from hooks/10_TableMock/src/model/member.ts rename to hooks/10_TableMock/src/model/member.tsx diff --git a/hooks/10_TableMock/webpack.config.js b/hooks/10_TableMock/webpack.config.js index c999658..9860631 100644 --- a/hooks/10_TableMock/webpack.config.js +++ b/hooks/10_TableMock/webpack.config.js @@ -1,80 +1,78 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const webpack = require("webpack"); -const path = require("path"); +var HtmlWebpackPlugin = require("html-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var webpack = require("webpack"); +var path = require("path"); -const basePath = __dirname; +var basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx", ".css"], + extensions: [".js", ".ts", ".tsx", ".css"] }, - entry: ["@babel/polyfill", "./index.tsx"], + entry: ["@babel/polyfill", "./components/index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js", + 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", + // inline: true, // Enable watch and live reload + // host: "localhost", + // port: 8080, + // stats: "errors-only", + static: { + directory: "./dist", + } }, module: { rules: [ { test: /\.(ts|tsx)$/, exclude: /node_modules/, - loader: "awesome-typescript-loader", - options: { - useBabel: true, - babelCore: "@babel/core", // needed for Babel v7 - }, + loader: "ts-loader", }, { test: /\.css$/, include: /node_modules/, - use: [MiniCssExtractPlugin.loader, "css-loader"], + use: [MiniCssExtractPlugin.loader, "css-loader"] }, + // Use CSS modules for custom stylesheets { test: /\.css$/, exclude: /node_modules/, use: [ MiniCssExtractPlugin.loader, { - loader: "css-loader", + loader: 'css-loader', options: { + modules: true, modules: { localIdentName: "[name]__[local]___[hash:base64:5]", }, - localsConvention: "camelCase", }, - }, - ], + } + ] }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]", - esModule: false, - }, - }, - ], + name: "assets/img/[name].[ext]?[hash]" + } + } + ] }, 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, + hash: true }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css", - }), - ], -}; + chunkFilename: "[id].css" + }) + ] +}; \ No newline at end of file From bf69675e0cf4734e8cbfe6a048ea8eb9dff64aee Mon Sep 17 00:00:00 2001 From: Uchan Date: Sat, 18 Mar 2023 11:59:17 +0900 Subject: [PATCH 19/36] excisize --- hooks/09_Sidebar/src/components/sidebar.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/hooks/09_Sidebar/src/components/sidebar.tsx b/hooks/09_Sidebar/src/components/sidebar.tsx index 6d1fe53..ebeb7e5 100644 --- a/hooks/09_Sidebar/src/components/sidebar.tsx +++ b/hooks/09_Sidebar/src/components/sidebar.tsx @@ -4,6 +4,7 @@ const classNames = require("./sidebar.css"); interface Props { isVisible: boolean; + children: React.ReactNode } const divStyle = (props: Props): React.CSSProperties => ({ From f7a74043a4f042f85332bb8fb3689268e07eaee9 Mon Sep 17 00:00:00 2001 From: Uchan Date: Sun, 19 Mar 2023 10:22:30 +0900 Subject: [PATCH 20/36] syusei --- .../src/components/memberTable.tsx | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/hooks/10_TableMock/src/components/memberTable.tsx b/hooks/10_TableMock/src/components/memberTable.tsx index 75fc441..a926fdc 100644 --- a/hooks/10_TableMock/src/components/memberTable.tsx +++ b/hooks/10_TableMock/src/components/memberTable.tsx @@ -6,8 +6,10 @@ const useMemberCollection = () => { const [memberCollection, setMemberCollection] = React.useState([]) const loadMemberCollection = () => { - getMembersCollection().then(useMemberCollection => setMemberCollection(memberCollection)) - } + getMembersCollection().then(memberCollection => + setMemberCollection(memberCollection) + ); + }; return { memberCollection, loadMemberCollection } } @@ -16,14 +18,31 @@ export const MemberTableComponent = () => { const { memberCollection, loadMemberCollection } = useMemberCollection(); React.useEffect(() => { + console.log(memberCollection) loadMemberCollection() }, []) return ( <> - {memberCollection.map(member => ( -

{member.login}

- ))} + + + + + + + + + + {memberCollection.map(member => ( + + + + + + ))} + +
AvatarIdname
{member.id}{member.login}
+ ) } \ No newline at end of file From c08b8010c00d5c83c333eef0a509ca469c13966a Mon Sep 17 00:00:00 2001 From: Uchan Date: Sun, 19 Mar 2023 10:25:52 +0900 Subject: [PATCH 21/36] table mock end --- hooks/10_TableMock/src/components/memberTable.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/hooks/10_TableMock/src/components/memberTable.tsx b/hooks/10_TableMock/src/components/memberTable.tsx index a926fdc..f9cda89 100644 --- a/hooks/10_TableMock/src/components/memberTable.tsx +++ b/hooks/10_TableMock/src/components/memberTable.tsx @@ -14,6 +14,13 @@ const useMemberCollection = () => { return { memberCollection, loadMemberCollection } } +const MemberRow = ({ member }: { member: MemberEntity }) => + + + {member.id} + {member.login} + + export const MemberTableComponent = () => { const { memberCollection, loadMemberCollection } = useMemberCollection(); @@ -34,11 +41,7 @@ export const MemberTableComponent = () => { {memberCollection.map(member => ( - - - {member.id} - {member.login} - + ))} From 4415b080ccc6699698510fe0eb172cbdddd79957 Mon Sep 17 00:00:00 2001 From: Uchan Date: Mon, 20 Mar 2023 08:41:44 +0900 Subject: [PATCH 22/36] table axios --- hooks/11_TableAxios/.babelrc | 13 -- hooks/11_TableAxios/package.json | 50 ++++---- hooks/11_TableAxios/src/api/memberApi.ts | 28 ----- hooks/11_TableAxios/src/api/memberApi.tsx | 25 ++++ hooks/11_TableAxios/src/app.tsx | 111 ++++++++---------- .../src/components/colorBrowser.tsx | 20 ++-- .../src/components/colorPicker.tsx | 83 ++++++------- hooks/11_TableAxios/src/components/hello.tsx | 6 +- hooks/11_TableAxios/src/components/index.tsx | 22 +++- .../src/components/memberTable.tsx | 91 +++++++------- .../11_TableAxios/src/components/nameEdit.tsx | 51 ++++---- .../11_TableAxios/src/components/sidebar.css | 57 +++++---- .../11_TableAxios/src/components/sidebar.tsx | 19 ++- hooks/11_TableAxios/src/index.html | 25 ++-- hooks/11_TableAxios/src/index.tsx | 6 - hooks/11_TableAxios/src/model/color.ts | 5 - hooks/11_TableAxios/src/model/color.tsx | 5 + .../src/model/{member.ts => member.tsx} | 0 hooks/11_TableAxios/webpack.config.js | 64 +++++----- 19 files changed, 323 insertions(+), 358 deletions(-) delete mode 100644 hooks/11_TableAxios/.babelrc delete mode 100644 hooks/11_TableAxios/src/api/memberApi.ts create mode 100644 hooks/11_TableAxios/src/api/memberApi.tsx delete mode 100644 hooks/11_TableAxios/src/index.tsx delete mode 100644 hooks/11_TableAxios/src/model/color.ts create mode 100644 hooks/11_TableAxios/src/model/color.tsx rename hooks/11_TableAxios/src/model/{member.ts => member.tsx} (100%) diff --git a/hooks/11_TableAxios/.babelrc b/hooks/11_TableAxios/.babelrc deleted file mode 100644 index 06770f7..0000000 --- a/hooks/11_TableAxios/.babelrc +++ /dev/null @@ -1,13 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "entry" - } - ], - "@babel/preset-typescript", - "@babel/preset-react" - ], - "plugins": ["@babel/plugin-transform-runtime"] -} diff --git a/hooks/11_TableAxios/package.json b/hooks/11_TableAxios/package.json index 0d0d92b..5f282d0 100644 --- a/hooks/11_TableAxios/package.json +++ b/hooks/11_TableAxios/package.json @@ -4,7 +4,7 @@ "description": "React Typescript examples", "main": "index.js", "scripts": { - "start": "webpack-dev-server --mode development --inline --hot --open", + "start": "webpack-dev-server --mode development --hot --open", "build": "webpack --mode development" }, "keywords": [ @@ -15,33 +15,29 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.10.5", - "@babel/plugin-transform-runtime": "^7.10.5", - "@babel/polyfill": "^7.10.4", - "@babel/preset-env": "^7.10.4", - "@babel/preset-react": "^7.10.4", - "@babel/preset-typescript": "^7.10.4", - "@types/node": "^14.0.24", - "@types/react": "^16.9.43", - "@types/react-dom": "^16.9.8", - "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.1.0", - "css-loader": "^3.6.0", - "file-loader": "^6.0.0", - "html-webpack-plugin": "^4.3.0", - "mini-css-extract-plugin": "^0.9.0", - "style-loader": "^1.2.1", - "typescript": "^3.9.7", - "url-loader": "^4.1.0", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.0" + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.20.2", + "@types/node": "^18.15.3", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "babel-loader": "^9.1.2", + "css-loader": "^6.7.3", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "mini-css-extract-plugin": "^2.7.3", + "style-loader": "^3.3.1", + "ts-loader": "^9.4.2", + "typescript": "^4.9.5", + "url-loader": "^4.1.1", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" }, "dependencies": { - "@babel/runtime": "^7.10.5", - "axios": "^0.19.2", - "react": "^16.13.1", - "react-dom": "^16.13.1" + "axios": "^1.3.4", + "react": "^18.2.0", + "react-dom": "^18.2.0" } } diff --git a/hooks/11_TableAxios/src/api/memberApi.ts b/hooks/11_TableAxios/src/api/memberApi.ts deleted file mode 100644 index 68ca97c..0000000 --- a/hooks/11_TableAxios/src/api/memberApi.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { MemberEntity } from "../model/member"; -import Axios, { AxiosResponse } from "axios"; - -const gitHubURL = "https://api.github.com"; -const gitHubMembersUrl = `${gitHubURL}/orgs/lemoncode/members`; - -export const getMembersCollection = (): Promise => { - const promise = new Promise((resolve, reject) => { - try { - Axios.get(gitHubMembersUrl).then(response => - resolve(mapMemberListApiToModel(response)) - ); - } catch (ex) { - reject(ex); - } - }); - - return promise; -}; - -const mapMemberListApiToModel = ({ - data -}: AxiosResponse): MemberEntity[] => - data.map(gitHubMember => ({ - id: gitHubMember.id, - login: gitHubMember.login, - avatar_url: gitHubMember.avatar_url - })); diff --git a/hooks/11_TableAxios/src/api/memberApi.tsx b/hooks/11_TableAxios/src/api/memberApi.tsx new file mode 100644 index 0000000..e772f60 --- /dev/null +++ b/hooks/11_TableAxios/src/api/memberApi.tsx @@ -0,0 +1,25 @@ +import { MemberEntity } from "../model/member"; +import Axios, { AxiosResponse } from 'axios'; + +const gitHubURL = 'https://api.github.com'; +const gitHubMembersUrl = `${gitHubURL}/orgs/lemoncode/members`; + +export const getMembersCollection = (): Promise => { + const promise = new Promise((resolve, reject) => { + try { + Axios.get(gitHubMembersUrl) + .then(response => resolve(mapMemberListApiToModel(response))); + } catch (ex) { + reject(ex) + + } + }) + return promise; +}; + +const mapMemberListApiToModel = ({ data }: AxiosResponse): MemberEntity[] => + data.map(gitHubMember => ({ + id: gitHubMember.id, + login: gitHubMember.login, + avatar_url: gitHubMember.avatar_url + })) \ No newline at end of file diff --git a/hooks/11_TableAxios/src/app.tsx b/hooks/11_TableAxios/src/app.tsx index d6623e0..eea1415 100644 --- a/hooks/11_TableAxios/src/app.tsx +++ b/hooks/11_TableAxios/src/app.tsx @@ -1,71 +1,52 @@ import * as React from "react"; -import { - HelloComponent, - NameEditComponent, - ColorBrowser, - ColorPicker, - SidebarComponent, - MemberTableComponent -} from "./components"; +import { ColorBrowser, HelloComponent, NameEditComponent, ColorPicker, SidebarComponent, MemberTableComponent } from "./components"; import { Color } from "./model/color"; +// import { HelloComponent } from "./components/hello"; +// import { NameEditComponent } from "./components/nameEdit"; export const App = () => { - const [name, setName] = React.useState("defaultUserName"); - const [editingName, setEditingName] = React.useState("defaultUserName"); - const [color, setColor] = React.useState({ - red: 20, - green: 40, - blue: 180 - }); - const [isVisible, setVisible] = React.useState(false); + const [name, setName] = React.useState('defaultUserName') + const [editingName, setEditingName] = React.useState("defaultUserName"); + const [color, setColor] = React.useState({ red: 20, green: 40, blue: 180 }) + const [isVisible, setVisible] = React.useState(false) + const setUsernameState = () => { + setName(editingName) + } - const loadUsername = () => { - setTimeout(() => { - setName("name from async call"); - setEditingName("name from async call"); - }, 500); - }; + const loadUsername = () => { + setTimeout(() => { + setName("name from async call"); + setEditingName("name from async call"); + }, 500); + }; - React.useEffect(() => { - loadUsername(); - }, []); - - const setUsernameState = () => { - setName(editingName); - }; - - return ( - <> - -

Cool Scfi movies

- -
- - - - - -
- -
- - ); -}; + React.useEffect(() => { + loadUsername() + }, []); + return ( + <> + +

Cool Scfi movies

+ +
+ + + + + +
+ +
+ + ); +}; \ No newline at end of file diff --git a/hooks/11_TableAxios/src/components/colorBrowser.tsx b/hooks/11_TableAxios/src/components/colorBrowser.tsx index 813746c..827ae71 100644 --- a/hooks/11_TableAxios/src/components/colorBrowser.tsx +++ b/hooks/11_TableAxios/src/components/colorBrowser.tsx @@ -1,16 +1,16 @@ import * as React from "react"; -import { Color } from "../model/color"; +import { Color } from "../model/color" interface Props { - color: Color; + color: Color; } -export const ColorBrowser: React.FC = (props) => { - const divStyle: React.CSSProperties = { - width: "11rem", - height: "7rem", - backgroundColor: `rgb(${props.color.red},${props.color.green}, ${props.color.blue})`, - }; +export const ColorBrowser = (props: Props) => { + const divStyle: React.CSSProperties = { + width: "11rem", + height: "7rem", + backgroundColor: `rgb(${props.color.red},${props.color.green},${props.color.blue})` + } - return
; -}; + return
; +} \ No newline at end of file diff --git a/hooks/11_TableAxios/src/components/colorPicker.tsx b/hooks/11_TableAxios/src/components/colorPicker.tsx index 4346cd4..aaa5e54 100644 --- a/hooks/11_TableAxios/src/components/colorPicker.tsx +++ b/hooks/11_TableAxios/src/components/colorPicker.tsx @@ -2,55 +2,46 @@ import * as React from "react"; import { Color } from "../model/color"; interface Props { - color: Color; - onColorUpdated: (color: Color) => void; + color: Color; + onColorUpdated: (color: Color) => void; } -const updateColor = (props: Props, colorId: keyof Color) => (value) => { - // keyof Color ensures only 'red', 'blue' or 'green' can be passed in. - props.onColorUpdated({ - ...props.color, // this creates a clone of the current props.color object... - [colorId]: value, // ... which gets one of its properties (colorId) immediately replaced by a new value. - }); -}; +interface PropsColorSlider { + key: string; + value: number; + onValueUpdated: (newValue: number) => void; +} -export const ColorPicker: React.FC = (props) => ( -
- -
- -
- - {props.color.blue} -
-
-); +const ColorSliderComponent = (props: PropsColorSlider) => { + return ( +
+ props.onValueUpdated(+event.target.value)} + /> + {props.value} +
+ ) +} -interface PropsColorSlider { - value: number; - onValueUpdated: (newValue: number) => void; +const updateColor = (props: Props, colorId: keyof Color) => (value) => { + props.onColorUpdated({ + ...props.color, + [colorId]: value + }) } -const ColorSliderComponent: React.FC = (props) => { - return ( -
- props.onValueUpdated(+event.target.value)} - /> - {props.value} -
- ); -}; +export const ColorPicker = (props: Props) => ( + <> + {Object.keys(props.color).map((field: keyof Color) => ( + + ))} + +); \ No newline at end of file diff --git a/hooks/11_TableAxios/src/components/hello.tsx b/hooks/11_TableAxios/src/components/hello.tsx index b6b7aca..b9b1d81 100644 --- a/hooks/11_TableAxios/src/components/hello.tsx +++ b/hooks/11_TableAxios/src/components/hello.tsx @@ -4,6 +4,6 @@ interface Props { userName: string; } -export const HelloComponent: React.FC = (props) => { - return

Hello user: {props.userName} !

; -}; +export const HelloComponent: React.FC = (props) => ( +

Hello user: {props.userName} !

+); diff --git a/hooks/11_TableAxios/src/components/index.tsx b/hooks/11_TableAxios/src/components/index.tsx index 7b909f0..33158d7 100644 --- a/hooks/11_TableAxios/src/components/index.tsx +++ b/hooks/11_TableAxios/src/components/index.tsx @@ -1,6 +1,16 @@ -export * from "./hello"; -export * from "./nameEdit"; -export * from "./colorBrowser"; -export * from "./colorPicker"; -export * from "./sidebar"; -export * from "./memberTable"; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { App } from '../app'; + +ReactDOM.render( + , + document.getElementById('root') +); + + +export * from "./hello" +export * from "./nameEdit" +export * from "./colorBrowser" +export * from './colorPicker' +export * from './sidebar' +export * from './memberTable' \ No newline at end of file diff --git a/hooks/11_TableAxios/src/components/memberTable.tsx b/hooks/11_TableAxios/src/components/memberTable.tsx index 4ae64fa..f6862b4 100644 --- a/hooks/11_TableAxios/src/components/memberTable.tsx +++ b/hooks/11_TableAxios/src/components/memberTable.tsx @@ -1,57 +1,50 @@ -import * as React from "react"; import { MemberEntity } from "../model/member"; import { getMembersCollection } from "../api/memberApi"; +import * as React from "react"; const useMemberCollection = () => { - const [memberCollection, setMemberCollection] = React.useState< - MemberEntity[] - >([]); + const [memberCollection, setMemberCollection] = React.useState([]) + + const loadMemberCollection = async () => { + const memberCollection = await getMembersCollection(); + setMemberCollection(memberCollection); + }; - const loadMemberCollection = async () => { - const memberCollection = await getMembersCollection(); - setMemberCollection(memberCollection); - }; + return { memberCollection, loadMemberCollection } +} - return { memberCollection, loadMemberCollection }; -}; +const MemberRow = ({ member }: { member: MemberEntity }) => + + + {member.id} + {member.login} + export const MemberTableComponent = () => { - const { memberCollection, loadMemberCollection } = useMemberCollection(); - - React.useEffect(() => { - loadMemberCollection(); - }, []); - - return ( - <> - - - - - - - - - - {memberCollection.map((member) => ( - - ))} - -
AvatarIdName
- - ); -}; - -const MemberRow = ({ member }: { member: MemberEntity }) => ( - - - - - - {member.id} - - - {member.login} - - -); + const { memberCollection, loadMemberCollection } = useMemberCollection(); + + React.useEffect(() => { + console.log(memberCollection) + loadMemberCollection() + }, []) + + return ( + <> + + + + + + + + + + {memberCollection.map(member => ( + + ))} + +
AvatarIdname
+ + + ) +} \ No newline at end of file diff --git a/hooks/11_TableAxios/src/components/nameEdit.tsx b/hooks/11_TableAxios/src/components/nameEdit.tsx index 7f9091e..d764808 100644 --- a/hooks/11_TableAxios/src/components/nameEdit.tsx +++ b/hooks/11_TableAxios/src/components/nameEdit.tsx @@ -1,29 +1,36 @@ import * as React from "react"; interface Props { - initialUserName: string; - editingName: string; - onNameUpdated: () => any; - onEditingNameUpdated: (newEditingName: string) => any; - disabled: boolean; + initialUserName: string; + onNameUpdated: () => any; + editingName: string; + onEditingNameUpdated: (newEditingName: string) => any; + disabled: boolean; } -export const NameEditComponent: React.FC = (props) => { - const onChange = (e: React.ChangeEvent) => { - props.onEditingNameUpdated(e.target.value); - }; +export const NameEditComponent = (props: Props) => { + // const [editingName, setEditingName] = React.useState(props.initialUserName); + const [lastInitialName, setLastInitialName] = React.useState(props.initialUserName); - const onNameSubmit = (event: any): any => { - props.onNameUpdated(); - }; + const onChange = (e: React.ChangeEvent) => { + // setEditingName(e.target.value); + props.onEditingNameUpdated(e.target.value); + } - return ( - <> - - - - - ); -}; + const onNameSubmit = (event: any): any => { + // props.onNameUpdated(editingName); + props.onNameUpdated(); + } + + // if (props.initialUserName !== lastInitialName) { + // setLastInitialName(props.initialUserName); + // setEditingName(props.initialUserName); + // } + return ( + <> + + + + + ) +} \ No newline at end of file diff --git a/hooks/11_TableAxios/src/components/sidebar.css b/hooks/11_TableAxios/src/components/sidebar.css index 907d868..2a47251 100644 --- a/hooks/11_TableAxios/src/components/sidebar.css +++ b/hooks/11_TableAxios/src/components/sidebar.css @@ -1,38 +1,47 @@ /* The side navigation menu */ .sidenav { - height: 100%; /* 100% Full-height */ - width: 0; /* 0 width - change this with JavaScript */ - position: fixed; /* Stay in place */ - z-index: 1; /* Stay on top */ - top: 0; - left: 0; - background-color: #808080; /* Gray*/ - overflow-x: hidden; /* Disable horizontal scroll */ - padding-top: 60px; /* Place content 60px from the top */ - transition: 0.5s; /* 0.5 second transition effect to slide in the sidenav */ + height: 100%; + /* 100% Full-height */ + width: 0; + /* 0 width - change this with JavaScript */ + position: fixed; + /* Stay in place */ + z-index: 1; + /* Stay on top */ + top: 0; + left: 0; + background-color: #808080; + /* Gray*/ + overflow-x: hidden; + /* Disable horizontal scroll */ + padding-top: 60px; + /* Place content 60px from the top */ + transition: 0.5s; + /* 0.5 second transition effect to slide in the sidenav */ } /* Position and style the close button (top right corner) */ .sidenav .closebtn { - position: absolute; - top: 0; - right: 25px; - font-size: 36px; - margin-left: 50px; + position: absolute; + top: 0; + right: 25px; + font-size: 36px; + margin-left: 50px; } /* Style page content - use this if you want to push the page content to the right when you open the side navigation */ #main { - transition: margin-left 0.5s; - padding: 20px; + transition: margin-left 0.5s; + padding: 20px; } /* On smaller screens, where height is less than 450px, change the style of the sidenav (less padding and a smaller font size) */ @media screen and (max-height: 450px) { - .sidenav { - padding-top: 15px; - } - .sidenav a { - font-size: 18px; - } -} + .sidenav { + padding-top: 15px; + } + + .sidenav a { + font-size: 18px; + } +} \ No newline at end of file diff --git a/hooks/11_TableAxios/src/components/sidebar.tsx b/hooks/11_TableAxios/src/components/sidebar.tsx index 762991e..19af0ee 100644 --- a/hooks/11_TableAxios/src/components/sidebar.tsx +++ b/hooks/11_TableAxios/src/components/sidebar.tsx @@ -3,17 +3,16 @@ import * as React from "react"; const classNames = require("./sidebar.css"); interface Props { - isVisible: boolean; + isVisible: boolean; + children: React.ReactNode; } const divStyle = (props: Props): React.CSSProperties => ({ - width: props.isVisible ? "23rem" : "0rem" -}); - -export const SidebarComponent: React.StatelessComponent = props => ( -
- {props.children} -
-); - + width: (props.isVisible) ? '23rem' : '0rem' +}) +export const SidebarComponent: React.FC = (props) => ( +
+ {props.children} +
+); \ No newline at end of file diff --git a/hooks/11_TableAxios/src/index.html b/hooks/11_TableAxios/src/index.html index c57efef..ff56f8d 100644 --- a/hooks/11_TableAxios/src/index.html +++ b/hooks/11_TableAxios/src/index.html @@ -1,13 +1,16 @@ - - - - - -
-

Sample app

-
-
- - + + + + + + + +
+

Sample app

+
+
+ + + \ No newline at end of file diff --git a/hooks/11_TableAxios/src/index.tsx b/hooks/11_TableAxios/src/index.tsx deleted file mode 100644 index 26ed977..0000000 --- a/hooks/11_TableAxios/src/index.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import * as React from "react"; -import * as ReactDOM from "react-dom"; - -import { App } from "./app"; - -ReactDOM.render(, document.getElementById("root")); diff --git a/hooks/11_TableAxios/src/model/color.ts b/hooks/11_TableAxios/src/model/color.ts deleted file mode 100644 index 17acfed..0000000 --- a/hooks/11_TableAxios/src/model/color.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface Color { - red: number; - green: number; - blue: number; -} diff --git a/hooks/11_TableAxios/src/model/color.tsx b/hooks/11_TableAxios/src/model/color.tsx new file mode 100644 index 0000000..c1783c6 --- /dev/null +++ b/hooks/11_TableAxios/src/model/color.tsx @@ -0,0 +1,5 @@ +export interface Color { + red: number; + green: number; + blue: number; +} \ No newline at end of file diff --git a/hooks/11_TableAxios/src/model/member.ts b/hooks/11_TableAxios/src/model/member.tsx similarity index 100% rename from hooks/11_TableAxios/src/model/member.ts rename to hooks/11_TableAxios/src/model/member.tsx diff --git a/hooks/11_TableAxios/webpack.config.js b/hooks/11_TableAxios/webpack.config.js index c999658..9860631 100644 --- a/hooks/11_TableAxios/webpack.config.js +++ b/hooks/11_TableAxios/webpack.config.js @@ -1,80 +1,78 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const webpack = require("webpack"); -const path = require("path"); +var HtmlWebpackPlugin = require("html-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var webpack = require("webpack"); +var path = require("path"); -const basePath = __dirname; +var basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx", ".css"], + extensions: [".js", ".ts", ".tsx", ".css"] }, - entry: ["@babel/polyfill", "./index.tsx"], + entry: ["@babel/polyfill", "./components/index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js", + 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", + // inline: true, // Enable watch and live reload + // host: "localhost", + // port: 8080, + // stats: "errors-only", + static: { + directory: "./dist", + } }, module: { rules: [ { test: /\.(ts|tsx)$/, exclude: /node_modules/, - loader: "awesome-typescript-loader", - options: { - useBabel: true, - babelCore: "@babel/core", // needed for Babel v7 - }, + loader: "ts-loader", }, { test: /\.css$/, include: /node_modules/, - use: [MiniCssExtractPlugin.loader, "css-loader"], + use: [MiniCssExtractPlugin.loader, "css-loader"] }, + // Use CSS modules for custom stylesheets { test: /\.css$/, exclude: /node_modules/, use: [ MiniCssExtractPlugin.loader, { - loader: "css-loader", + loader: 'css-loader', options: { + modules: true, modules: { localIdentName: "[name]__[local]___[hash:base64:5]", }, - localsConvention: "camelCase", }, - }, - ], + } + ] }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]", - esModule: false, - }, - }, - ], + name: "assets/img/[name].[ext]?[hash]" + } + } + ] }, 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, + hash: true }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css", - }), - ], -}; + chunkFilename: "[id].css" + }) + ] +}; \ No newline at end of file From e1261ffba0fed1b76661340bfff6fcf1930c7627 Mon Sep 17 00:00:00 2001 From: Uchan Date: Tue, 21 Mar 2023 08:58:49 +0900 Subject: [PATCH 23/36] react router --- hooks/12_ReactRouter/.babelrc | 12 ------ hooks/12_ReactRouter/package.json | 49 ++++++++++------------ hooks/12_ReactRouter/src/app.tsx | 29 +++++++------ hooks/12_ReactRouter/src/hello.tsx | 9 ++++ hooks/12_ReactRouter/src/index.tsx | 12 +++--- hooks/12_ReactRouter/src/nameEdit.tsx | 13 ++++++ hooks/12_ReactRouter/src/pages/pageA.tsx | 16 +++---- hooks/12_ReactRouter/src/pages/pageB.tsx | 16 +++---- hooks/12_ReactRouter/webpack.config.js | 53 +++++++++++------------- 9 files changed, 109 insertions(+), 100 deletions(-) delete mode 100644 hooks/12_ReactRouter/.babelrc create mode 100644 hooks/12_ReactRouter/src/hello.tsx create mode 100644 hooks/12_ReactRouter/src/nameEdit.tsx diff --git a/hooks/12_ReactRouter/.babelrc b/hooks/12_ReactRouter/.babelrc deleted file mode 100644 index d09d473..0000000 --- a/hooks/12_ReactRouter/.babelrc +++ /dev/null @@ -1,12 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "entry" - } - ], - "@babel/preset-typescript", - "@babel/preset-react" - ] -} diff --git a/hooks/12_ReactRouter/package.json b/hooks/12_ReactRouter/package.json index fb37736..2dd4ac8 100644 --- a/hooks/12_ReactRouter/package.json +++ b/hooks/12_ReactRouter/package.json @@ -4,7 +4,7 @@ "description": "React Typescript examples", "main": "index.js", "scripts": { - "start": "webpack-dev-server --mode development --inline --hot --open", + "start": "webpack-dev-server --mode development --hot --open", "build": "webpack --mode development" }, "keywords": [ @@ -15,32 +15,29 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.10.5", - "@babel/polyfill": "^7.10.4", - "@babel/preset-env": "^7.10.4", - "@babel/preset-react": "^7.10.4", - "@babel/preset-typescript": "^7.10.4", - "@types/node": "^14.0.24", - "@types/react": "^16.9.43", - "@types/react-dom": "^16.9.8", - "@types/react-router-dom": "^5.1.5", - "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.1.0", - "css-loader": "^3.6.0", - "file-loader": "^6.0.0", - "html-webpack-plugin": "^4.3.0", - "mini-css-extract-plugin": "^0.9.0", - "style-loader": "^1.2.1", - "typescript": "^3.9.7", - "url-loader": "^4.1.0", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.0" + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.20.2", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "@types/react-router-dom": "^5.3.3", + "babel-loader": "^9.1.2", + "css-loader": "^6.7.3", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "mini-css-extract-plugin": "^2.7.3", + "style-loader": "^3.3.1", + "ts-loader": "^9.4.2", + "typescript": "^4.9.5", + "url-loader": "^4.1.1", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" }, "dependencies": { - "react": "^16.13.1", - "react-dom": "^16.13.1", - "react-router-dom": "^5.2.0" + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.9.0" } } diff --git a/hooks/12_ReactRouter/src/app.tsx b/hooks/12_ReactRouter/src/app.tsx index 18beb8e..f3207a9 100644 --- a/hooks/12_ReactRouter/src/app.tsx +++ b/hooks/12_ReactRouter/src/app.tsx @@ -1,18 +1,21 @@ import * as React from "react"; -import { HashRouter, Switch, Route } from "react-router-dom"; +import { BrowserRouter, Route, Routes } from "react-router-dom"; import { PageA } from "./pages/pageA"; import { PageB } from "./pages/pageB"; +/** + * not use Switch (V6) + * @returns + */ export const App = () => { - - return ( - <> - - - - - - - - ); -}; + return ( + <> + + + } /> + } /> + + + + ); +}; \ No newline at end of file diff --git a/hooks/12_ReactRouter/src/hello.tsx b/hooks/12_ReactRouter/src/hello.tsx new file mode 100644 index 0000000..b9b1d81 --- /dev/null +++ b/hooks/12_ReactRouter/src/hello.tsx @@ -0,0 +1,9 @@ +import * as React from "react"; + +interface Props { + userName: string; +} + +export const HelloComponent: React.FC = (props) => ( +

Hello user: {props.userName} !

+); diff --git a/hooks/12_ReactRouter/src/index.tsx b/hooks/12_ReactRouter/src/index.tsx index 26ed977..0f847e1 100644 --- a/hooks/12_ReactRouter/src/index.tsx +++ b/hooks/12_ReactRouter/src/index.tsx @@ -1,6 +1,8 @@ -import * as React from "react"; -import * as ReactDOM from "react-dom"; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { App } from './app'; -import { App } from "./app"; - -ReactDOM.render(, document.getElementById("root")); +ReactDOM.render( + , + document.getElementById('root') +); diff --git a/hooks/12_ReactRouter/src/nameEdit.tsx b/hooks/12_ReactRouter/src/nameEdit.tsx new file mode 100644 index 0000000..a6ef1ef --- /dev/null +++ b/hooks/12_ReactRouter/src/nameEdit.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +interface Props { + userName: string; + onChange: (e: React.ChangeEvent) => void; +} + +export const NameEditComponent = (props: Props) => ( + <> + + + +) \ No newline at end of file diff --git a/hooks/12_ReactRouter/src/pages/pageA.tsx b/hooks/12_ReactRouter/src/pages/pageA.tsx index 1eab2e8..25799fc 100644 --- a/hooks/12_ReactRouter/src/pages/pageA.tsx +++ b/hooks/12_ReactRouter/src/pages/pageA.tsx @@ -1,9 +1,9 @@ -import * as React from "react"; -import { Link } from "react-router-dom"; +import * as React from "react" +import { Link } from "react-router-dom" -export const PageA = () => -
-

Hello from page A

-
- Navigate to Page B -
+export const PageA = () => +
+

Hello from page A

+
+ Navigate to Page B +
\ No newline at end of file diff --git a/hooks/12_ReactRouter/src/pages/pageB.tsx b/hooks/12_ReactRouter/src/pages/pageB.tsx index 39a86dd..c18f102 100644 --- a/hooks/12_ReactRouter/src/pages/pageB.tsx +++ b/hooks/12_ReactRouter/src/pages/pageB.tsx @@ -1,9 +1,9 @@ -import * as React from "react"; -import { Link } from "react-router-dom"; +import * as React from "react" +import { Link } from "react-router-dom" -export const PageB = () => -
-

Hello from page B

-
- Navigate to Page A -
+export const PageB = () => +
+

Hello from page B

+
+ Navigate to Page A +
\ No newline at end of file diff --git a/hooks/12_ReactRouter/webpack.config.js b/hooks/12_ReactRouter/webpack.config.js index 32eff84..1d6fce3 100644 --- a/hooks/12_ReactRouter/webpack.config.js +++ b/hooks/12_ReactRouter/webpack.config.js @@ -1,63 +1,60 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const webpack = require("webpack"); -const path = require("path"); +var HtmlWebpackPlugin = require("html-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var webpack = require("webpack"); +var path = require("path"); -const basePath = __dirname; +var basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"], + extensions: [".js", ".ts", ".tsx"] }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js", + 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", + // inline: true, // Enable watch and live reload + // host: "localhost", + // port: 8080, + // stats: "errors-only", + static: { + directory: "./dist", + } }, module: { rules: [ { test: /\.(ts|tsx)$/, exclude: /node_modules/, - loader: "awesome-typescript-loader", - options: { - useBabel: true, - babelCore: "@babel/core", // needed for Babel v7 - }, + loader: "ts-loader", }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"], + use: [MiniCssExtractPlugin.loader, "css-loader"] }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]", - esModule: false, - }, - }, - ], + name: "assets/img/[name].[ext]?[hash]" + } + } + ] }, 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, + hash: true }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css", - }), - ], -}; + chunkFilename: "[id].css" + }) + ] +}; \ No newline at end of file From 902d41f9fd343d5d86a10f38b3f0f5257df0199a Mon Sep 17 00:00:00 2001 From: Uchan Date: Wed, 22 Mar 2023 08:23:47 +0900 Subject: [PATCH 24/36] v6 unUsed RouteComponentProps --- hooks/13_LoginForm/.babelrc | 10 --- hooks/13_LoginForm/package.json | 52 +++++++------- hooks/13_LoginForm/src/api/login.ts | 10 --- hooks/13_LoginForm/src/app.tsx | 30 ++++---- hooks/13_LoginForm/src/common/index.ts | 1 - .../13_LoginForm/src/common/notification.tsx | 52 -------------- hooks/13_LoginForm/src/hello.tsx | 9 +++ hooks/13_LoginForm/src/index.html | 23 +++--- hooks/13_LoginForm/src/index.tsx | 12 ++-- hooks/13_LoginForm/src/model/login.ts | 9 --- hooks/13_LoginForm/src/nameEdit.tsx | 13 ++++ .../src/pages/login.component.tsx | 60 ---------------- .../src/pages/login.container.tsx | 70 ++++--------------- hooks/13_LoginForm/src/pages/loginPage.tsx | 9 +++ hooks/13_LoginForm/src/pages/pageB.tsx | 17 +++-- hooks/13_LoginForm/webpack.config.js | 53 +++++++------- 16 files changed, 139 insertions(+), 291 deletions(-) delete mode 100644 hooks/13_LoginForm/.babelrc delete mode 100644 hooks/13_LoginForm/src/api/login.ts delete mode 100644 hooks/13_LoginForm/src/common/index.ts delete mode 100644 hooks/13_LoginForm/src/common/notification.tsx create mode 100644 hooks/13_LoginForm/src/hello.tsx delete mode 100644 hooks/13_LoginForm/src/model/login.ts create mode 100644 hooks/13_LoginForm/src/nameEdit.tsx delete mode 100644 hooks/13_LoginForm/src/pages/login.component.tsx create mode 100644 hooks/13_LoginForm/src/pages/loginPage.tsx diff --git a/hooks/13_LoginForm/.babelrc b/hooks/13_LoginForm/.babelrc deleted file mode 100644 index 957cae3..0000000 --- a/hooks/13_LoginForm/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "entry" - } - ] - ] -} diff --git a/hooks/13_LoginForm/package.json b/hooks/13_LoginForm/package.json index 258ceb7..7d94c11 100644 --- a/hooks/13_LoginForm/package.json +++ b/hooks/13_LoginForm/package.json @@ -4,7 +4,7 @@ "description": "React Typescript examples", "main": "index.js", "scripts": { - "start": "webpack-dev-server --mode development --inline --hot --open", + "start": "webpack-dev-server --mode development --hot --open", "build": "webpack --mode development" }, "keywords": [ @@ -15,34 +15,30 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.10.5", - "@babel/polyfill": "^7.10.4", - "@babel/preset-env": "^7.10.4", - "@babel/preset-react": "^7.10.4", - "@babel/preset-typescript": "^7.10.4", - "@types/node": "^14.0.24", - "@types/react": "^16.9.43", - "@types/react-dom": "^16.9.8", - "@types/react-router-dom": "^5.1.5", - "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.1.0", - "css-loader": "^3.6.0", - "file-loader": "^6.0.0", - "html-webpack-plugin": "^4.3.0", - "mini-css-extract-plugin": "^0.9.0", - "style-loader": "^1.2.1", - "typescript": "^3.9.7", - "url-loader": "^4.1.0", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.0" + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.20.2", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "@types/react-router-dom": "^5.3.3", + "babel-loader": "^9.1.2", + "css-loader": "^6.7.3", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "mini-css-extract-plugin": "^2.7.3", + "style-loader": "^3.3.1", + "ts-loader": "^9.4.2", + "typescript": "^4.9.5", + "url-loader": "^4.1.1", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" }, "dependencies": { - "@material-ui/core": "^4.11.0", - "@material-ui/icons": "^4.9.1", - "react": "^16.13.1", - "react-dom": "^16.13.1", - "react-router-dom": "^5.2.0" + "@mui/material": "^5.11.14", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.9.0" } } diff --git a/hooks/13_LoginForm/src/api/login.ts b/hooks/13_LoginForm/src/api/login.ts deleted file mode 100644 index 6fd3e26..0000000 --- a/hooks/13_LoginForm/src/api/login.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { LoginEntity } from "../model/login"; - -// Just a fake loginAPI -export const isValidLogin = (loginInfo: LoginEntity): Promise => - new Promise((resolve) => { - setTimeout(() => { - // mock call - resolve(loginInfo.login === "admin" && loginInfo.password === "test"); - }, 500); - }); diff --git a/hooks/13_LoginForm/src/app.tsx b/hooks/13_LoginForm/src/app.tsx index 169d50d..fb7cec9 100644 --- a/hooks/13_LoginForm/src/app.tsx +++ b/hooks/13_LoginForm/src/app.tsx @@ -1,17 +1,21 @@ import * as React from "react"; -import { HashRouter, Switch, Route } from "react-router-dom"; -import { LoginContainer } from "./pages/login.container"; +import { BrowserRouter, Route, Routes } from "react-router-dom"; +import { LoginComponent } from "./pages/loginPage"; import { PageB } from "./pages/pageB"; +/** + * not use Switch (V6) + * @returns + */ export const App = () => { - return ( - <> - - - - - - - - ); -}; + return ( + <> + + + } /> + } /> + + + + ); +}; \ No newline at end of file diff --git a/hooks/13_LoginForm/src/common/index.ts b/hooks/13_LoginForm/src/common/index.ts deleted file mode 100644 index d9b217c..0000000 --- a/hooks/13_LoginForm/src/common/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './notification'; diff --git a/hooks/13_LoginForm/src/common/notification.tsx b/hooks/13_LoginForm/src/common/notification.tsx deleted file mode 100644 index 50e2b70..0000000 --- a/hooks/13_LoginForm/src/common/notification.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import * as React from "react"; -import Snackbar from "@material-ui/core/Snackbar"; -import IconButton from "@material-ui/core/IconButton"; -import CloseIcon from "@material-ui/icons/Close"; -import createStyles from "@material-ui/core/styles/createStyles"; -import makeStyles from "@material-ui/core/styles/makeStyles"; - -interface Props { - message: string; - show: boolean; - onClose: () => void; -} - -const useStyles = makeStyles((theme) => - createStyles({ - close: { - padding: theme.spacing(0.5), - }, - }) -); - -export const NotificationComponent: React.FC = (props) => { - const classes = useStyles(); - const { message, show, onClose } = props; - - return ( - {message}} - action={[ - - - , - ]} - /> - ); -}; diff --git a/hooks/13_LoginForm/src/hello.tsx b/hooks/13_LoginForm/src/hello.tsx new file mode 100644 index 0000000..b9b1d81 --- /dev/null +++ b/hooks/13_LoginForm/src/hello.tsx @@ -0,0 +1,9 @@ +import * as React from "react"; + +interface Props { + userName: string; +} + +export const HelloComponent: React.FC = (props) => ( +

Hello user: {props.userName} !

+); diff --git a/hooks/13_LoginForm/src/index.html b/hooks/13_LoginForm/src/index.html index 2ad4810..7594228 100644 --- a/hooks/13_LoginForm/src/index.html +++ b/hooks/13_LoginForm/src/index.html @@ -1,12 +1,15 @@ - - - - - -
-
-
- - + + + + + + + +
+
+
+ + + \ No newline at end of file diff --git a/hooks/13_LoginForm/src/index.tsx b/hooks/13_LoginForm/src/index.tsx index 26ed977..0f847e1 100644 --- a/hooks/13_LoginForm/src/index.tsx +++ b/hooks/13_LoginForm/src/index.tsx @@ -1,6 +1,8 @@ -import * as React from "react"; -import * as ReactDOM from "react-dom"; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { App } from './app'; -import { App } from "./app"; - -ReactDOM.render(, document.getElementById("root")); +ReactDOM.render( + , + document.getElementById('root') +); diff --git a/hooks/13_LoginForm/src/model/login.ts b/hooks/13_LoginForm/src/model/login.ts deleted file mode 100644 index 32854b7..0000000 --- a/hooks/13_LoginForm/src/model/login.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface LoginEntity { - login: string; - password: string; -} - -export const createEmptyLogin = (): LoginEntity => ({ - login: "", - password: "" -}); diff --git a/hooks/13_LoginForm/src/nameEdit.tsx b/hooks/13_LoginForm/src/nameEdit.tsx new file mode 100644 index 0000000..a6ef1ef --- /dev/null +++ b/hooks/13_LoginForm/src/nameEdit.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +interface Props { + userName: string; + onChange: (e: React.ChangeEvent) => void; +} + +export const NameEditComponent = (props: Props) => ( + <> + + + +) \ No newline at end of file diff --git a/hooks/13_LoginForm/src/pages/login.component.tsx b/hooks/13_LoginForm/src/pages/login.component.tsx deleted file mode 100644 index c78a485..0000000 --- a/hooks/13_LoginForm/src/pages/login.component.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import * as React from "react"; -import makeStyles from "@material-ui/styles/makeStyles"; -import createStyles from "@material-ui/styles/createStyles"; -import TextField from "@material-ui/core/TextField"; -import Button from "@material-ui/core/Button"; -import { LoginEntity, createEmptyLogin } from "../model/login"; - -interface PropsForm { - onLogin: (login: LoginEntity) => void; -} - -// https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useFormStyles = makeStyles((theme) => - createStyles({ - formContainer: { - display: "flex", - flexDirection: "column", - justifyContent: "center", - }, - }) -); - -export const LoginComponent: React.FC = (props) => { - const { onLogin } = props; - const [loginInfo, setLoginInfo] = React.useState( - createEmptyLogin() - ); - const classes = useFormStyles(); - const onTexFieldChange = (fieldId) => (e) => { - setLoginInfo({ - ...loginInfo, - [fieldId]: e.target.value, - }); - }; - - return ( -
- - - -
- ); -}; diff --git a/hooks/13_LoginForm/src/pages/login.container.tsx b/hooks/13_LoginForm/src/pages/login.container.tsx index 943c433..b5442a0 100644 --- a/hooks/13_LoginForm/src/pages/login.container.tsx +++ b/hooks/13_LoginForm/src/pages/login.container.tsx @@ -1,57 +1,15 @@ +import { createStyles } from "@mui/material"; +import { makeStyles } from "@mui/material/styles"; import * as React from "react"; -import { useHistory } from "react-router-dom"; -import { LoginEntity } from "../model/login"; -import { isValidLogin } from "../api/login"; -import { LoginComponent } from "./login.component"; -import Card from "@material-ui/core/Card"; -import CardHeader from "@material-ui/core/CardHeader"; -import CardContent from "@material-ui/core/CardContent"; -import createStyles from "@material-ui/styles/createStyles"; -import makeStyles from "@material-ui/styles/makeStyles"; -import { NotificationComponent } from "../common"; - -// https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useFormStyles = makeStyles((theme) => - createStyles({ - card: { - maxWidth: 400, - margin: "0 auto", - }, - }) -); - -interface Props {} - -export const LoginContainer: React.FC = (props) => { - const history = useHistory(); - const [isShowAlert, setShowAlert] = React.useState(false); - const classes = useFormStyles(); - - const loginSucceeded = (isValid: boolean) => { - if (isValid) { - history.push("/pageB"); - } else { - setShowAlert(true); - } - }; - - const handleLogin = (login: LoginEntity) => { - isValidLogin(login).then(loginSucceeded); - }; - - return ( - <> - - - - - setShowAlert(false)} - /> - - - - ); -}; +import { RouteComponentProps } from "react-router-dom"; + +const useStyles = makeStyles(theme => + createStyles({ + card: { + maxWidth: 400, + margin: "0 auto" + } + }) +) + +interface Props extends Route { } \ No newline at end of file diff --git a/hooks/13_LoginForm/src/pages/loginPage.tsx b/hooks/13_LoginForm/src/pages/loginPage.tsx new file mode 100644 index 0000000..0b708c5 --- /dev/null +++ b/hooks/13_LoginForm/src/pages/loginPage.tsx @@ -0,0 +1,9 @@ +import * as React from "react" +import { FormProps, Link } from "react-router-dom" + +export const LoginComponent: React.FC = (props) => +
+

Hello from login Page

+
+ Navigate to Page B +
\ No newline at end of file diff --git a/hooks/13_LoginForm/src/pages/pageB.tsx b/hooks/13_LoginForm/src/pages/pageB.tsx index 87ec471..a8853c0 100644 --- a/hooks/13_LoginForm/src/pages/pageB.tsx +++ b/hooks/13_LoginForm/src/pages/pageB.tsx @@ -1,10 +1,9 @@ -import * as React from "react"; -import { Link } from "react-router-dom"; +import * as React from "react" +import { Link } from "react-router-dom" -export const PageB = () => ( -
-

Hello from page B

-
- Navigate to Login -
-); +export const PageB = () => +
+

Hello from page B

+
+ Navigate to Login +
\ No newline at end of file diff --git a/hooks/13_LoginForm/webpack.config.js b/hooks/13_LoginForm/webpack.config.js index 32eff84..1d6fce3 100644 --- a/hooks/13_LoginForm/webpack.config.js +++ b/hooks/13_LoginForm/webpack.config.js @@ -1,63 +1,60 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const webpack = require("webpack"); -const path = require("path"); +var HtmlWebpackPlugin = require("html-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var webpack = require("webpack"); +var path = require("path"); -const basePath = __dirname; +var basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"], + extensions: [".js", ".ts", ".tsx"] }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js", + 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", + // inline: true, // Enable watch and live reload + // host: "localhost", + // port: 8080, + // stats: "errors-only", + static: { + directory: "./dist", + } }, module: { rules: [ { test: /\.(ts|tsx)$/, exclude: /node_modules/, - loader: "awesome-typescript-loader", - options: { - useBabel: true, - babelCore: "@babel/core", // needed for Babel v7 - }, + loader: "ts-loader", }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"], + use: [MiniCssExtractPlugin.loader, "css-loader"] }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]", - esModule: false, - }, - }, - ], + name: "assets/img/[name].[ext]?[hash]" + } + } + ] }, 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, + hash: true }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css", - }), - ], -}; + chunkFilename: "[id].css" + }) + ] +}; \ No newline at end of file From 88c870a03332f8b0fda9deb4f2385d6ae0f66f22 Mon Sep 17 00:00:00 2001 From: Uchan Date: Thu, 23 Mar 2023 08:49:03 +0900 Subject: [PATCH 25/36] =?UTF-8?q?=20history=E4=BD=BF=E3=81=88=E3=82=8B?= =?UTF-8?q?=E3=81=AE=E3=81=8B=E5=95=8F=E9=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hooks/13_LoginForm/package.json | 3 +++ hooks/13_LoginForm/src/app.tsx | 2 +- .../src/pages/login.component.tsx | 17 ++++++++++++++++ .../src/pages/login.container.tsx | 20 ++++++++++++++++--- 4 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 hooks/13_LoginForm/src/pages/login.component.tsx diff --git a/hooks/13_LoginForm/package.json b/hooks/13_LoginForm/package.json index 7d94c11..1acf660 100644 --- a/hooks/13_LoginForm/package.json +++ b/hooks/13_LoginForm/package.json @@ -36,7 +36,10 @@ "webpack-dev-server": "^4.11.1" }, "dependencies": { + "@emotion/react": "^11.10.6", + "@emotion/styled": "^11.10.6", "@mui/material": "^5.11.14", + "@mui/styled-engine": "^5.11.11", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.9.0" diff --git a/hooks/13_LoginForm/src/app.tsx b/hooks/13_LoginForm/src/app.tsx index fb7cec9..7b5b0e8 100644 --- a/hooks/13_LoginForm/src/app.tsx +++ b/hooks/13_LoginForm/src/app.tsx @@ -1,6 +1,6 @@ import * as React from "react"; import { BrowserRouter, Route, Routes } from "react-router-dom"; -import { LoginComponent } from "./pages/loginPage"; +import { LoginComponent } from "./pages/login.component"; import { PageB } from "./pages/pageB"; /** diff --git a/hooks/13_LoginForm/src/pages/login.component.tsx b/hooks/13_LoginForm/src/pages/login.component.tsx new file mode 100644 index 0000000..f7a93e0 --- /dev/null +++ b/hooks/13_LoginForm/src/pages/login.component.tsx @@ -0,0 +1,17 @@ +import { Button, TextField } from "@mui/material"; +import * as React from "react"; +import { FormProps } from "react-router-dom"; + +export const LoginComponent: React.FC = (props) => { + return (
+ + + +
) +} diff --git a/hooks/13_LoginForm/src/pages/login.container.tsx b/hooks/13_LoginForm/src/pages/login.container.tsx index b5442a0..e8f135c 100644 --- a/hooks/13_LoginForm/src/pages/login.container.tsx +++ b/hooks/13_LoginForm/src/pages/login.container.tsx @@ -1,7 +1,7 @@ -import { createStyles } from "@mui/material"; +import { Button, Card, CardContent, CardHeader, createStyles, TextField } from "@mui/material"; import { makeStyles } from "@mui/material/styles"; import * as React from "react"; -import { RouteComponentProps } from "react-router-dom"; +import { LoginComponent } from "./loginPage"; const useStyles = makeStyles(theme => createStyles({ @@ -12,4 +12,18 @@ const useStyles = makeStyles(theme => }) ) -interface Props extends Route { } \ No newline at end of file +interface Props { } + +export const LoginContainer: React.FC = (props) => { + // const { classes } = props; + + return ( + + + + + + + ); +}; + From f9e58a86defb865ea4fce15e160bda82e4191614 Mon Sep 17 00:00:00 2001 From: Uchan Date: Fri, 24 Mar 2023 09:04:55 +0900 Subject: [PATCH 26/36] refactor --- hooks/13_LoginForm/src/app.tsx | 3 +- .../src/pages/login.component.tsx | 10 ++++-- .../src/pages/login.container.tsx | 35 ++++++++++++------- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/hooks/13_LoginForm/src/app.tsx b/hooks/13_LoginForm/src/app.tsx index 7b5b0e8..600249f 100644 --- a/hooks/13_LoginForm/src/app.tsx +++ b/hooks/13_LoginForm/src/app.tsx @@ -1,6 +1,7 @@ import * as React from "react"; import { BrowserRouter, Route, Routes } from "react-router-dom"; import { LoginComponent } from "./pages/login.component"; +import { LoginContainer } from "./pages/login.container"; import { PageB } from "./pages/pageB"; /** @@ -12,7 +13,7 @@ export const App = () => { <> - } /> + } /> } /> diff --git a/hooks/13_LoginForm/src/pages/login.component.tsx b/hooks/13_LoginForm/src/pages/login.component.tsx index f7a93e0..5544482 100644 --- a/hooks/13_LoginForm/src/pages/login.component.tsx +++ b/hooks/13_LoginForm/src/pages/login.component.tsx @@ -2,7 +2,13 @@ import { Button, TextField } from "@mui/material"; import * as React from "react"; import { FormProps } from "react-router-dom"; -export const LoginComponent: React.FC = (props) => { +interface PropsForm { + onLogin: () => void; +} + +export const LoginComponent = (props: PropsForm) => { + const { onLogin } = props; + return (
= (props) => { > - +
) } diff --git a/hooks/13_LoginForm/src/pages/login.container.tsx b/hooks/13_LoginForm/src/pages/login.container.tsx index e8f135c..9f1effe 100644 --- a/hooks/13_LoginForm/src/pages/login.container.tsx +++ b/hooks/13_LoginForm/src/pages/login.container.tsx @@ -1,27 +1,36 @@ -import { Button, Card, CardContent, CardHeader, createStyles, TextField } from "@mui/material"; -import { makeStyles } from "@mui/material/styles"; +import { Button, Card, CardContent, CardHeader, createStyles, makeStyles, TextField } from "@mui/material"; import * as React from "react"; -import { LoginComponent } from "./loginPage"; +import { RouterProps, useNavigate } from "react-router-dom"; +import { LoginComponent } from "./login.component"; -const useStyles = makeStyles(theme => - createStyles({ - card: { - maxWidth: 400, - margin: "0 auto" - } - }) -) +// const useStyles = makeStyles(theme => +// createStyles({ +// card: { +// maxWidth: 400, +// margin: "0 auto" +// } +// }) +// ) interface Props { } export const LoginContainer: React.FC = (props) => { - // const { classes } = props; + // const navigate = useNavigate(); + + // const onLogin = () => { + // console.log("on login") + // navigate('/pageB') + // } + + console.log("login container") return ( - + ); From 833d7d69a5627df1476d37ee2d2c17e667f191a7 Mon Sep 17 00:00:00 2001 From: Uchan Date: Sat, 25 Mar 2023 10:52:14 +0900 Subject: [PATCH 27/36] implements LoginApi --- hooks/13_LoginForm/src/api/login.ts | 10 +++++ hooks/13_LoginForm/src/model/login.ts | 9 +++++ .../src/pages/login.component.tsx | 9 ++++- .../src/pages/login.container.tsx | 39 ++++++++++--------- 4 files changed, 46 insertions(+), 21 deletions(-) create mode 100644 hooks/13_LoginForm/src/api/login.ts create mode 100644 hooks/13_LoginForm/src/model/login.ts diff --git a/hooks/13_LoginForm/src/api/login.ts b/hooks/13_LoginForm/src/api/login.ts new file mode 100644 index 0000000..6fd3e26 --- /dev/null +++ b/hooks/13_LoginForm/src/api/login.ts @@ -0,0 +1,10 @@ +import { LoginEntity } from "../model/login"; + +// Just a fake loginAPI +export const isValidLogin = (loginInfo: LoginEntity): Promise => + new Promise((resolve) => { + setTimeout(() => { + // mock call + resolve(loginInfo.login === "admin" && loginInfo.password === "test"); + }, 500); + }); diff --git a/hooks/13_LoginForm/src/model/login.ts b/hooks/13_LoginForm/src/model/login.ts new file mode 100644 index 0000000..5b7d14a --- /dev/null +++ b/hooks/13_LoginForm/src/model/login.ts @@ -0,0 +1,9 @@ +export interface LoginEntity { + login: string; + password: string; +} + +export const createEmptyLogin = (): LoginEntity => ({ + login: "", + password: "", +}); diff --git a/hooks/13_LoginForm/src/pages/login.component.tsx b/hooks/13_LoginForm/src/pages/login.component.tsx index 5544482..f157441 100644 --- a/hooks/13_LoginForm/src/pages/login.component.tsx +++ b/hooks/13_LoginForm/src/pages/login.component.tsx @@ -1,14 +1,19 @@ import { Button, TextField } from "@mui/material"; import * as React from "react"; import { FormProps } from "react-router-dom"; +import { createEmptyLogin, LoginEntity } from "../model/login"; interface PropsForm { - onLogin: () => void; + onLogin: (login: LoginEntity) => void; } export const LoginComponent = (props: PropsForm) => { const { onLogin } = props; + const [loginInfo, setLoginInfo] = React.useState( + createEmptyLogin() + ); + return (
{ > - +
) } diff --git a/hooks/13_LoginForm/src/pages/login.container.tsx b/hooks/13_LoginForm/src/pages/login.container.tsx index 9f1effe..b6f1b10 100644 --- a/hooks/13_LoginForm/src/pages/login.container.tsx +++ b/hooks/13_LoginForm/src/pages/login.container.tsx @@ -1,36 +1,37 @@ -import { Button, Card, CardContent, CardHeader, createStyles, makeStyles, TextField } from "@mui/material"; +import { Card, CardContent, CardHeader } from "@mui/material"; import * as React from "react"; -import { RouterProps, useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import { LoginComponent } from "./login.component"; +import { LoginEntity, createEmptyLogin } from "../model/login"; +import { isValidLogin } from "../api/login"; -// const useStyles = makeStyles(theme => -// createStyles({ -// card: { -// maxWidth: 400, -// margin: "0 auto" -// } -// }) -// ) interface Props { } export const LoginContainer: React.FC = (props) => { - // const navigate = useNavigate(); + const [loginInfo, setLoginInfo] = React.useState( + createEmptyLogin() + ) - // const onLogin = () => { - // console.log("on login") - // navigate('/pageB') - // } + const navigate = useNavigate(); + + const loginSucceeded = (isValid: boolean) => { + console.log(isValid) + if (isValid) { + navigate('/pageB') + } + } + + const handleLogin = (login: LoginEntity) => { + isValidLogin(login).then(loginSucceeded); + }; - console.log("login container") return ( - + ); From 9c42741ccadfa32ac38257c25193c46bac9e2ae4 Mon Sep 17 00:00:00 2001 From: Uchan Date: Sun, 26 Mar 2023 18:14:11 +0900 Subject: [PATCH 28/36] =?UTF-8?q?=E6=AE=8B=E3=81=99=E3=81=AF=E3=82=B9?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=AB=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hooks/13_LoginForm/package.json | 1 + hooks/13_LoginForm/src/common/index.ts | 1 + .../13_LoginForm/src/common/notification.tsx | 41 +++++++++++++++++++ .../src/pages/login.component.tsx | 11 ++++- .../src/pages/login.container.tsx | 25 +++++++---- 5 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 hooks/13_LoginForm/src/common/index.ts create mode 100644 hooks/13_LoginForm/src/common/notification.tsx diff --git a/hooks/13_LoginForm/package.json b/hooks/13_LoginForm/package.json index 1acf660..8f7c3c5 100644 --- a/hooks/13_LoginForm/package.json +++ b/hooks/13_LoginForm/package.json @@ -38,6 +38,7 @@ "dependencies": { "@emotion/react": "^11.10.6", "@emotion/styled": "^11.10.6", + "@mui/icons-material": "^5.11.11", "@mui/material": "^5.11.14", "@mui/styled-engine": "^5.11.11", "react": "^18.2.0", diff --git a/hooks/13_LoginForm/src/common/index.ts b/hooks/13_LoginForm/src/common/index.ts new file mode 100644 index 0000000..dd99c4d --- /dev/null +++ b/hooks/13_LoginForm/src/common/index.ts @@ -0,0 +1 @@ +export * from "./notification"; diff --git a/hooks/13_LoginForm/src/common/notification.tsx b/hooks/13_LoginForm/src/common/notification.tsx new file mode 100644 index 0000000..a5725a2 --- /dev/null +++ b/hooks/13_LoginForm/src/common/notification.tsx @@ -0,0 +1,41 @@ +import { IconButton, Snackbar } from "@mui/material"; +import CloseIcon from '@mui/icons-material/Close'; +import * as React from "react"; + +interface Props { + message: string; + show: boolean; + onClose: () => void; +} + + + +export const NotificationComponent = (props: Props) => { + const { message, show, onClose } = props; + + return ( + {message}} + action={[ + + + + ]} + /> + ); +}; \ No newline at end of file diff --git a/hooks/13_LoginForm/src/pages/login.component.tsx b/hooks/13_LoginForm/src/pages/login.component.tsx index f157441..fa42257 100644 --- a/hooks/13_LoginForm/src/pages/login.component.tsx +++ b/hooks/13_LoginForm/src/pages/login.component.tsx @@ -14,6 +14,13 @@ export const LoginComponent = (props: PropsForm) => { createEmptyLogin() ); + const onTextFieldChange = (fieldId) => (e) => { + setLoginInfo({ + ...loginInfo, + [fieldId]: e.target.value + }) + } + return (
{ justifyContent: "center" }} > - - + +
) } diff --git a/hooks/13_LoginForm/src/pages/login.container.tsx b/hooks/13_LoginForm/src/pages/login.container.tsx index b6f1b10..ae3fc61 100644 --- a/hooks/13_LoginForm/src/pages/login.container.tsx +++ b/hooks/13_LoginForm/src/pages/login.container.tsx @@ -1,10 +1,10 @@ -import { Card, CardContent, CardHeader } from "@mui/material"; +import { Card, CardContent, CardHeader, createStyles, makeStyles } from "@mui/material"; import * as React from "react"; import { useNavigate } from "react-router-dom"; import { LoginComponent } from "./login.component"; import { LoginEntity, createEmptyLogin } from "../model/login"; import { isValidLogin } from "../api/login"; - +import { NotificationComponent } from "../common"; interface Props { } @@ -12,6 +12,7 @@ export const LoginContainer: React.FC = (props) => { const [loginInfo, setLoginInfo] = React.useState( createEmptyLogin() ) + const [isShowAlert, setShowAlert] = React.useState(false); const navigate = useNavigate(); @@ -19,6 +20,8 @@ export const LoginContainer: React.FC = (props) => { console.log(isValid) if (isValid) { navigate('/pageB') + } else { + setShowAlert(true) } } @@ -28,12 +31,18 @@ export const LoginContainer: React.FC = (props) => { return ( - - - - - - + <> + + + + + + + setShowAlert(false)} /> + ); }; From 670c01df4736584e60037f485a2e0451796c0ae2 Mon Sep 17 00:00:00 2001 From: Uchan Date: Mon, 27 Mar 2023 08:37:17 +0900 Subject: [PATCH 29/36] makeStyles -> styled --- .../src/pages/login.container.tsx | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/hooks/13_LoginForm/src/pages/login.container.tsx b/hooks/13_LoginForm/src/pages/login.container.tsx index ae3fc61..954641e 100644 --- a/hooks/13_LoginForm/src/pages/login.container.tsx +++ b/hooks/13_LoginForm/src/pages/login.container.tsx @@ -1,4 +1,4 @@ -import { Card, CardContent, CardHeader, createStyles, makeStyles } from "@mui/material"; +import { Card, CardContent, CardHeader, createStyles, makeStyles, styled } from "@mui/material"; import * as React from "react"; import { useNavigate } from "react-router-dom"; import { LoginComponent } from "./login.component"; @@ -8,6 +8,20 @@ import { NotificationComponent } from "../common"; interface Props { } +// const useStyles = makeStyles(theme => +// createStyles({ +// card: { +// maxWidth: 400, +// margin: "0 auto" +// } +// }) +// ); + +const SampleCardStyled = styled(Card)(({ theme }) => ({ + maxWidth: 400, + margin: "0 auto" +})) + export const LoginContainer: React.FC = (props) => { const [loginInfo, setLoginInfo] = React.useState( createEmptyLogin() @@ -29,15 +43,14 @@ export const LoginContainer: React.FC = (props) => { isValidLogin(login).then(loginSucceeded); }; - return ( <> - + - + Date: Tue, 28 Mar 2023 08:44:12 +0900 Subject: [PATCH 30/36] end LoginForm --- .../src/pages/login.component.tsx | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/hooks/13_LoginForm/src/pages/login.component.tsx b/hooks/13_LoginForm/src/pages/login.component.tsx index fa42257..dd7152b 100644 --- a/hooks/13_LoginForm/src/pages/login.component.tsx +++ b/hooks/13_LoginForm/src/pages/login.component.tsx @@ -1,4 +1,5 @@ -import { Button, TextField } from "@mui/material"; +import { Button, Divider, TextField } from "@mui/material"; +import { styled } from "@mui/system"; import * as React from "react"; import { FormProps } from "react-router-dom"; import { createEmptyLogin, LoginEntity } from "../model/login"; @@ -7,6 +8,16 @@ interface PropsForm { onLogin: (login: LoginEntity) => void; } +// const useFormStyles = makeStyles(theme => +// createStyles({ +// formContainer: { +// display: "flex", +// flexDirection: "column", +// justifyContent: "center" +// } +// }) +// ); + export const LoginComponent = (props: PropsForm) => { const { onLogin } = props; @@ -21,15 +32,15 @@ export const LoginComponent = (props: PropsForm) => { }) } - return (
- - - -
) + }}> + + + +
+ ) } From 4b861b82d097955ea69238978f33dde1cf77f85a Mon Sep 17 00:00:00 2001 From: Uchan Date: Wed, 29 Mar 2023 08:59:16 +0900 Subject: [PATCH 31/36] FormValidation --- hooks/14_FormValidation/.babelrc | 10 -- hooks/14_FormValidation/package.json | 62 +++++------ hooks/14_FormValidation/src/app.tsx | 29 ++--- hooks/14_FormValidation/src/common/index.ts | 4 +- .../src/common/notification.tsx | 79 ++++++-------- .../src/common/textField.component.tsx | 41 +++---- hooks/14_FormValidation/src/hello.tsx | 9 ++ hooks/14_FormValidation/src/index.html | 23 ++-- hooks/14_FormValidation/src/index.tsx | 12 ++- hooks/14_FormValidation/src/model/login.ts | 2 +- hooks/14_FormValidation/src/nameEdit.tsx | 13 +++ .../src/pages/login.component.tsx | 85 +++++++-------- .../src/pages/login.container.tsx | 101 +++++++++--------- .../src/pages/login.validation.ts | 11 -- .../14_FormValidation/src/pages/loginPage.tsx | 9 ++ hooks/14_FormValidation/src/pages/pageB.tsx | 17 ++- hooks/14_FormValidation/webpack.config.js | 53 +++++---- 17 files changed, 281 insertions(+), 279 deletions(-) delete mode 100644 hooks/14_FormValidation/.babelrc create mode 100644 hooks/14_FormValidation/src/hello.tsx create mode 100644 hooks/14_FormValidation/src/nameEdit.tsx delete mode 100644 hooks/14_FormValidation/src/pages/login.validation.ts create mode 100644 hooks/14_FormValidation/src/pages/loginPage.tsx diff --git a/hooks/14_FormValidation/.babelrc b/hooks/14_FormValidation/.babelrc deleted file mode 100644 index 957cae3..0000000 --- a/hooks/14_FormValidation/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "entry" - } - ] - ] -} diff --git a/hooks/14_FormValidation/package.json b/hooks/14_FormValidation/package.json index 7916951..a6f809b 100644 --- a/hooks/14_FormValidation/package.json +++ b/hooks/14_FormValidation/package.json @@ -4,7 +4,7 @@ "description": "React Typescript examples", "main": "index.js", "scripts": { - "start": "webpack-dev-server --mode development --inline --hot --open", + "start": "webpack-dev-server --mode development --hot --open", "build": "webpack --mode development" }, "keywords": [ @@ -15,37 +15,37 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.10.5", - "@babel/polyfill": "^7.10.4", - "@babel/preset-env": "^7.10.4", - "@babel/preset-react": "^7.10.4", - "@babel/preset-typescript": "^7.10.4", - "@types/node": "^14.0.24", - "@types/react": "^16.9.43", - "@types/react-dom": "^16.9.8", - "@types/react-router-dom": "^5.1.5", - "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.1.0", - "css-loader": "^3.6.0", - "file-loader": "^6.0.0", - "html-webpack-plugin": "^4.3.0", - "mini-css-extract-plugin": "^0.9.0", - "style-loader": "^1.2.1", - "typescript": "^3.9.7", - "url-loader": "^4.1.0", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.0" + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.20.2", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "@types/react-router-dom": "^5.3.3", + "babel-loader": "^9.1.2", + "css-loader": "^6.7.3", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "mini-css-extract-plugin": "^2.7.3", + "style-loader": "^3.3.1", + "ts-loader": "^9.4.2", + "typescript": "^4.9.5", + "url-loader": "^4.1.1", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" }, "dependencies": { - "@lemoncode/fonk": "^1.3.0", + "@emotion/react": "^11.10.6", + "@emotion/styled": "^11.10.6", + "@lemoncode/fonk": "^1.5.4", "@lemoncode/fonk-formik": "^4.0.1", - "@material-ui/core": "^4.11.0", - "@material-ui/icons": "^4.9.1", - "formik": "^2.1.5", - "react": "^16.13.1", - "react-dom": "^16.13.1", - "react-router-dom": "^5.2.0" + "@mui/icons-material": "^5.11.11", + "@mui/material": "^5.11.14", + "@mui/styled-engine": "^5.11.11", + "formik": "^2.2.9", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.9.0" } -} +} \ No newline at end of file diff --git a/hooks/14_FormValidation/src/app.tsx b/hooks/14_FormValidation/src/app.tsx index 169d50d..600249f 100644 --- a/hooks/14_FormValidation/src/app.tsx +++ b/hooks/14_FormValidation/src/app.tsx @@ -1,17 +1,22 @@ import * as React from "react"; -import { HashRouter, Switch, Route } from "react-router-dom"; +import { BrowserRouter, Route, Routes } from "react-router-dom"; +import { LoginComponent } from "./pages/login.component"; import { LoginContainer } from "./pages/login.container"; import { PageB } from "./pages/pageB"; +/** + * not use Switch (V6) + * @returns + */ export const App = () => { - return ( - <> - - - - - - - - ); -}; + return ( + <> + + + } /> + } /> + + + + ); +}; \ No newline at end of file diff --git a/hooks/14_FormValidation/src/common/index.ts b/hooks/14_FormValidation/src/common/index.ts index f377fb5..c5107ec 100644 --- a/hooks/14_FormValidation/src/common/index.ts +++ b/hooks/14_FormValidation/src/common/index.ts @@ -1,2 +1,2 @@ -export * from './notification'; -export * from './textField.component'; \ No newline at end of file +export * from "./notification"; +export * from "./TextFieldComponent"; diff --git a/hooks/14_FormValidation/src/common/notification.tsx b/hooks/14_FormValidation/src/common/notification.tsx index 50e2b70..a5725a2 100644 --- a/hooks/14_FormValidation/src/common/notification.tsx +++ b/hooks/14_FormValidation/src/common/notification.tsx @@ -1,52 +1,41 @@ +import { IconButton, Snackbar } from "@mui/material"; +import CloseIcon from '@mui/icons-material/Close'; import * as React from "react"; -import Snackbar from "@material-ui/core/Snackbar"; -import IconButton from "@material-ui/core/IconButton"; -import CloseIcon from "@material-ui/icons/Close"; -import createStyles from "@material-ui/core/styles/createStyles"; -import makeStyles from "@material-ui/core/styles/makeStyles"; interface Props { - message: string; - show: boolean; - onClose: () => void; + message: string; + show: boolean; + onClose: () => void; } -const useStyles = makeStyles((theme) => - createStyles({ - close: { - padding: theme.spacing(0.5), - }, - }) -); -export const NotificationComponent: React.FC = (props) => { - const classes = useStyles(); - const { message, show, onClose } = props; - return ( - {message}} - action={[ - - - , - ]} - /> - ); -}; +export const NotificationComponent = (props: Props) => { + const { message, show, onClose } = props; + + return ( + {message}} + action={[ + + + + ]} + /> + ); +}; \ No newline at end of file diff --git a/hooks/14_FormValidation/src/common/textField.component.tsx b/hooks/14_FormValidation/src/common/textField.component.tsx index 718e117..957a4c8 100644 --- a/hooks/14_FormValidation/src/common/textField.component.tsx +++ b/hooks/14_FormValidation/src/common/textField.component.tsx @@ -1,25 +1,26 @@ import * as React from "react"; import { useField } from "formik"; -import MuiTextField, { TextFieldProps } from "@material-ui/core/TextField"; +import { TextField, TextFieldProps } from "@mui/material"; export const TextFieldComponent: React.FC = (props) => { - const [field, meta] = useField(props.name); - const textFieldProps = Boolean(field) ? field : props; - const hasError = Boolean(meta && meta.touched && meta.error); + const [field, meta] = useField(props.name); + const TextFieldProps = Boolean(field) ? field : props; + const hasError = Boolean(meta && meta.touched && meta.error); - return ( - <> - - - ); -}; + return ( + <> + + + + ); +} \ No newline at end of file diff --git a/hooks/14_FormValidation/src/hello.tsx b/hooks/14_FormValidation/src/hello.tsx new file mode 100644 index 0000000..b9b1d81 --- /dev/null +++ b/hooks/14_FormValidation/src/hello.tsx @@ -0,0 +1,9 @@ +import * as React from "react"; + +interface Props { + userName: string; +} + +export const HelloComponent: React.FC = (props) => ( +

Hello user: {props.userName} !

+); diff --git a/hooks/14_FormValidation/src/index.html b/hooks/14_FormValidation/src/index.html index 2ad4810..7594228 100644 --- a/hooks/14_FormValidation/src/index.html +++ b/hooks/14_FormValidation/src/index.html @@ -1,12 +1,15 @@ - - - - - -
-
-
- - + + + + + + + +
+
+
+ + + \ No newline at end of file diff --git a/hooks/14_FormValidation/src/index.tsx b/hooks/14_FormValidation/src/index.tsx index 26ed977..0f847e1 100644 --- a/hooks/14_FormValidation/src/index.tsx +++ b/hooks/14_FormValidation/src/index.tsx @@ -1,6 +1,8 @@ -import * as React from "react"; -import * as ReactDOM from "react-dom"; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { App } from './app'; -import { App } from "./app"; - -ReactDOM.render(, document.getElementById("root")); +ReactDOM.render( + , + document.getElementById('root') +); diff --git a/hooks/14_FormValidation/src/model/login.ts b/hooks/14_FormValidation/src/model/login.ts index 32854b7..5b7d14a 100644 --- a/hooks/14_FormValidation/src/model/login.ts +++ b/hooks/14_FormValidation/src/model/login.ts @@ -5,5 +5,5 @@ export interface LoginEntity { export const createEmptyLogin = (): LoginEntity => ({ login: "", - password: "" + password: "", }); diff --git a/hooks/14_FormValidation/src/nameEdit.tsx b/hooks/14_FormValidation/src/nameEdit.tsx new file mode 100644 index 0000000..a6ef1ef --- /dev/null +++ b/hooks/14_FormValidation/src/nameEdit.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +interface Props { + userName: string; + onChange: (e: React.ChangeEvent) => void; +} + +export const NameEditComponent = (props: Props) => ( + <> + + + +) \ No newline at end of file diff --git a/hooks/14_FormValidation/src/pages/login.component.tsx b/hooks/14_FormValidation/src/pages/login.component.tsx index e968d5d..dd7152b 100644 --- a/hooks/14_FormValidation/src/pages/login.component.tsx +++ b/hooks/14_FormValidation/src/pages/login.component.tsx @@ -1,53 +1,46 @@ +import { Button, Divider, TextField } from "@mui/material"; +import { styled } from "@mui/system"; import * as React from "react"; -import { LoginEntity, createEmptyLogin } from "../model/login"; -import { TextFieldComponent } from "../common"; -import { Form } from "formik"; -import createStyles from "@material-ui/styles/createStyles"; -import makeStyles from "@material-ui/styles/makeStyles"; -import Button from "@material-ui/core/Button"; -import { loginFormValidation } from "./login.validation"; -import { Formik } from "formik"; +import { FormProps } from "react-router-dom"; +import { createEmptyLogin, LoginEntity } from "../model/login"; interface PropsForm { - onLogin: (login: LoginEntity) => void; + onLogin: (login: LoginEntity) => void; } -// https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useFormStyles = makeStyles((theme) => - createStyles({ - formContainer: { - display: "flex", - flexDirection: "column", - justifyContent: "center", - }, - }) -); +// const useFormStyles = makeStyles(theme => +// createStyles({ +// formContainer: { +// display: "flex", +// flexDirection: "column", +// justifyContent: "center" +// } +// }) +// ); -export const LoginComponent: React.FC = (props) => { - const classes = useFormStyles(); - const { onLogin } = props; +export const LoginComponent = (props: PropsForm) => { + const { onLogin } = props; - return ( - - {() => ( -
-
- - - -
-
- )} -
- ); -}; + const [loginInfo, setLoginInfo] = React.useState( + createEmptyLogin() + ); + + const onTextFieldChange = (fieldId) => (e) => { + setLoginInfo({ + ...loginInfo, + [fieldId]: e.target.value + }) + } + + return ( +
+ + + +
+ ) +} diff --git a/hooks/14_FormValidation/src/pages/login.container.tsx b/hooks/14_FormValidation/src/pages/login.container.tsx index 1da3ed8..954641e 100644 --- a/hooks/14_FormValidation/src/pages/login.container.tsx +++ b/hooks/14_FormValidation/src/pages/login.container.tsx @@ -1,58 +1,61 @@ +import { Card, CardContent, CardHeader, createStyles, makeStyles, styled } from "@mui/material"; import * as React from "react"; -import { useHistory } from "react-router-dom"; -import { LoginEntity } from "../model/login"; -import { isValidLogin } from "../api/login"; +import { useNavigate } from "react-router-dom"; import { LoginComponent } from "./login.component"; -import Card from "@material-ui/core/Card"; -import CardHeader from "@material-ui/core/CardHeader"; -import CardContent from "@material-ui/core/CardContent"; -import createStyles from "@material-ui/styles/createStyles"; -import makeStyles from "@material-ui/styles/makeStyles"; +import { LoginEntity, createEmptyLogin } from "../model/login"; +import { isValidLogin } from "../api/login"; import { NotificationComponent } from "../common"; -// https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useFormStyles = makeStyles((theme) => - createStyles({ - card: { - maxWidth: 400, - margin: "0 auto", - }, - }) -); +interface Props { } -interface Props {} -interface Props {} +// const useStyles = makeStyles(theme => +// createStyles({ +// card: { +// maxWidth: 400, +// margin: "0 auto" +// } +// }) +// ); + +const SampleCardStyled = styled(Card)(({ theme }) => ({ + maxWidth: 400, + margin: "0 auto" +})) export const LoginContainer: React.FC = (props) => { - const history = useHistory(); - const [isShowAlert, setShowAlert] = React.useState(false); - const classes = useFormStyles(); - - const loginSucceeded = (isValid: boolean) => { - if (isValid) { - history.push("/pageB"); - } else { - setShowAlert(true); + const [loginInfo, setLoginInfo] = React.useState( + createEmptyLogin() + ) + const [isShowAlert, setShowAlert] = React.useState(false); + + const navigate = useNavigate(); + + const loginSucceeded = (isValid: boolean) => { + console.log(isValid) + if (isValid) { + navigate('/pageB') + } else { + setShowAlert(true) + } } - }; - - const handleLogin = (login: LoginEntity) => { - isValidLogin(login).then(loginSucceeded); - }; - - return ( - <> - - - - - setShowAlert(false)} - /> - - - - ); + + const handleLogin = (login: LoginEntity) => { + isValidLogin(login).then(loginSucceeded); + }; + + return ( + <> + + + + + + + setShowAlert(false)} /> + + ); }; + diff --git a/hooks/14_FormValidation/src/pages/login.validation.ts b/hooks/14_FormValidation/src/pages/login.validation.ts deleted file mode 100644 index 2094212..0000000 --- a/hooks/14_FormValidation/src/pages/login.validation.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { ValidationSchema, Validators } from "@lemoncode/fonk"; -import { createFormikValidation } from "@lemoncode/fonk-formik"; - -const validationSchema: ValidationSchema = { - field: { - login: [Validators.required], - password: [Validators.required], - }, -}; - -export const loginFormValidation = createFormikValidation(validationSchema); diff --git a/hooks/14_FormValidation/src/pages/loginPage.tsx b/hooks/14_FormValidation/src/pages/loginPage.tsx new file mode 100644 index 0000000..0b708c5 --- /dev/null +++ b/hooks/14_FormValidation/src/pages/loginPage.tsx @@ -0,0 +1,9 @@ +import * as React from "react" +import { FormProps, Link } from "react-router-dom" + +export const LoginComponent: React.FC = (props) => +
+

Hello from login Page

+
+ Navigate to Page B +
\ No newline at end of file diff --git a/hooks/14_FormValidation/src/pages/pageB.tsx b/hooks/14_FormValidation/src/pages/pageB.tsx index 87ec471..a8853c0 100644 --- a/hooks/14_FormValidation/src/pages/pageB.tsx +++ b/hooks/14_FormValidation/src/pages/pageB.tsx @@ -1,10 +1,9 @@ -import * as React from "react"; -import { Link } from "react-router-dom"; +import * as React from "react" +import { Link } from "react-router-dom" -export const PageB = () => ( -
-

Hello from page B

-
- Navigate to Login -
-); +export const PageB = () => +
+

Hello from page B

+
+ Navigate to Login +
\ No newline at end of file diff --git a/hooks/14_FormValidation/webpack.config.js b/hooks/14_FormValidation/webpack.config.js index 32eff84..1d6fce3 100644 --- a/hooks/14_FormValidation/webpack.config.js +++ b/hooks/14_FormValidation/webpack.config.js @@ -1,63 +1,60 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const webpack = require("webpack"); -const path = require("path"); +var HtmlWebpackPlugin = require("html-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var webpack = require("webpack"); +var path = require("path"); -const basePath = __dirname; +var basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"], + extensions: [".js", ".ts", ".tsx"] }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js", + 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", + // inline: true, // Enable watch and live reload + // host: "localhost", + // port: 8080, + // stats: "errors-only", + static: { + directory: "./dist", + } }, module: { rules: [ { test: /\.(ts|tsx)$/, exclude: /node_modules/, - loader: "awesome-typescript-loader", - options: { - useBabel: true, - babelCore: "@babel/core", // needed for Babel v7 - }, + loader: "ts-loader", }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"], + use: [MiniCssExtractPlugin.loader, "css-loader"] }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]", - esModule: false, - }, - }, - ], + name: "assets/img/[name].[ext]?[hash]" + } + } + ] }, 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, + hash: true }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css", - }), - ], -}; + chunkFilename: "[id].css" + }) + ] +}; \ No newline at end of file From 7e32a2ba467de699ec5bc5918d132f0a4fdff62a Mon Sep 17 00:00:00 2001 From: Uchan Date: Thu, 30 Mar 2023 08:29:17 +0900 Subject: [PATCH 32/36] =?UTF-8?q?=E6=AE=8B=E3=81=99=E3=81=AF=E3=83=AA?= =?UTF-8?q?=E3=83=95=E3=82=A1=E3=82=AF=E3=82=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hooks/14_FormValidation/src/common/index.ts | 2 +- .../src/pages/login.component.tsx | 52 +++++++++++++++---- .../src/pages/login.validation.ts | 14 +++++ 3 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 hooks/14_FormValidation/src/pages/login.validation.ts diff --git a/hooks/14_FormValidation/src/common/index.ts b/hooks/14_FormValidation/src/common/index.ts index c5107ec..fe9e7da 100644 --- a/hooks/14_FormValidation/src/common/index.ts +++ b/hooks/14_FormValidation/src/common/index.ts @@ -1,2 +1,2 @@ export * from "./notification"; -export * from "./TextFieldComponent"; +export * from "./textField.component"; diff --git a/hooks/14_FormValidation/src/pages/login.component.tsx b/hooks/14_FormValidation/src/pages/login.component.tsx index dd7152b..6b64353 100644 --- a/hooks/14_FormValidation/src/pages/login.component.tsx +++ b/hooks/14_FormValidation/src/pages/login.component.tsx @@ -1,8 +1,11 @@ import { Button, Divider, TextField } from "@mui/material"; -import { styled } from "@mui/system"; +// import { styled } from "@mui/system"; import * as React from "react"; -import { FormProps } from "react-router-dom"; +// import { FormProps } from "react-router-dom"; import { createEmptyLogin, LoginEntity } from "../model/login"; +import { loginFormValidation } from "./login.validation"; +import { TextFieldComponent } from "../common"; +import { Form, Formik } from "formik"; interface PropsForm { onLogin: (login: LoginEntity) => void; @@ -33,14 +36,41 @@ export const LoginComponent = (props: PropsForm) => { } return ( -
- - - -
+ + {() => ( +
+ //
+ + + +
+
+ )} +
+ + + + + //
+ // + // + // + //
) } diff --git a/hooks/14_FormValidation/src/pages/login.validation.ts b/hooks/14_FormValidation/src/pages/login.validation.ts new file mode 100644 index 0000000..5b4a9c6 --- /dev/null +++ b/hooks/14_FormValidation/src/pages/login.validation.ts @@ -0,0 +1,14 @@ +import { + createFormValidation, + ValidationSchema, + Validators, +} from "@lemoncode/fonk"; + +const validationSchema: ValidationSchema = { + field: { + login: [Validators.required], + password: [Validators.required], + }, +}; + +export const loginFormValidation = createFormValidation(validationSchema); From 0d7d519bf238ba233775636fc6a482a6a023f1b6 Mon Sep 17 00:00:00 2001 From: Uchan Date: Fri, 31 Mar 2023 08:31:12 +0900 Subject: [PATCH 33/36] Context --- hooks/15_Context/.babelrc | 10 --- hooks/15_Context/{src => }/api/login.ts | 0 hooks/15_Context/app.tsx | 22 ++++++ hooks/15_Context/{src => }/common/index.ts | 1 - hooks/15_Context/common/notification.tsx | 41 ++++++++++ hooks/15_Context/common/sessionContext.tsx | 31 ++++++++ .../15_Context/common/textField.component.tsx | 26 +++++++ hooks/15_Context/hello.tsx | 9 +++ hooks/15_Context/index.html | 15 ++++ hooks/15_Context/index.tsx | 8 ++ hooks/15_Context/{src => }/model/login.ts | 2 +- hooks/15_Context/nameEdit.tsx | 13 ++++ hooks/15_Context/package.json | 62 +++++++-------- hooks/15_Context/pages/login.component.tsx | 76 +++++++++++++++++++ hooks/15_Context/pages/login.container.tsx | 61 +++++++++++++++ hooks/15_Context/pages/login.validation.ts | 14 ++++ hooks/15_Context/pages/loginPage.tsx | 9 +++ hooks/15_Context/pages/pageB.tsx | 9 +++ hooks/15_Context/src/app.tsx | 20 ----- hooks/15_Context/src/common/notification.tsx | 52 ------------- .../15_Context/src/common/sessionContext.tsx | 29 ------- .../src/common/textField.component.tsx | 25 ------ hooks/15_Context/src/index.html | 12 --- hooks/15_Context/src/index.tsx | 6 -- .../15_Context/src/pages/login.component.tsx | 57 -------------- .../15_Context/src/pages/login.container.tsx | 59 -------------- .../15_Context/src/pages/login.validation.ts | 11 --- hooks/15_Context/src/pages/pageB.tsx | 16 ---- hooks/15_Context/webpack.config.js | 53 ++++++------- 29 files changed, 391 insertions(+), 358 deletions(-) delete mode 100644 hooks/15_Context/.babelrc rename hooks/15_Context/{src => }/api/login.ts (100%) create mode 100644 hooks/15_Context/app.tsx rename hooks/15_Context/{src => }/common/index.ts (67%) create mode 100644 hooks/15_Context/common/notification.tsx create mode 100644 hooks/15_Context/common/sessionContext.tsx create mode 100644 hooks/15_Context/common/textField.component.tsx create mode 100644 hooks/15_Context/hello.tsx create mode 100644 hooks/15_Context/index.html create mode 100644 hooks/15_Context/index.tsx rename hooks/15_Context/{src => }/model/login.ts (89%) create mode 100644 hooks/15_Context/nameEdit.tsx create mode 100644 hooks/15_Context/pages/login.component.tsx create mode 100644 hooks/15_Context/pages/login.container.tsx create mode 100644 hooks/15_Context/pages/login.validation.ts create mode 100644 hooks/15_Context/pages/loginPage.tsx create mode 100644 hooks/15_Context/pages/pageB.tsx delete mode 100644 hooks/15_Context/src/app.tsx delete mode 100644 hooks/15_Context/src/common/notification.tsx delete mode 100644 hooks/15_Context/src/common/sessionContext.tsx delete mode 100644 hooks/15_Context/src/common/textField.component.tsx delete mode 100644 hooks/15_Context/src/index.html delete mode 100644 hooks/15_Context/src/index.tsx delete mode 100644 hooks/15_Context/src/pages/login.component.tsx delete mode 100644 hooks/15_Context/src/pages/login.container.tsx delete mode 100644 hooks/15_Context/src/pages/login.validation.ts delete mode 100644 hooks/15_Context/src/pages/pageB.tsx diff --git a/hooks/15_Context/.babelrc b/hooks/15_Context/.babelrc deleted file mode 100644 index 957cae3..0000000 --- a/hooks/15_Context/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "useBuiltIns": "entry" - } - ] - ] -} diff --git a/hooks/15_Context/src/api/login.ts b/hooks/15_Context/api/login.ts similarity index 100% rename from hooks/15_Context/src/api/login.ts rename to hooks/15_Context/api/login.ts diff --git a/hooks/15_Context/app.tsx b/hooks/15_Context/app.tsx new file mode 100644 index 0000000..600249f --- /dev/null +++ b/hooks/15_Context/app.tsx @@ -0,0 +1,22 @@ +import * as React from "react"; +import { BrowserRouter, Route, Routes } from "react-router-dom"; +import { LoginComponent } from "./pages/login.component"; +import { LoginContainer } from "./pages/login.container"; +import { PageB } from "./pages/pageB"; + +/** + * not use Switch (V6) + * @returns + */ +export const App = () => { + return ( + <> + + + } /> + } /> + + + + ); +}; \ No newline at end of file diff --git a/hooks/15_Context/src/common/index.ts b/hooks/15_Context/common/index.ts similarity index 67% rename from hooks/15_Context/src/common/index.ts rename to hooks/15_Context/common/index.ts index feefdf2..fe9e7da 100644 --- a/hooks/15_Context/src/common/index.ts +++ b/hooks/15_Context/common/index.ts @@ -1,3 +1,2 @@ export * from "./notification"; export * from "./textField.component"; -export * from "./sessionContext"; diff --git a/hooks/15_Context/common/notification.tsx b/hooks/15_Context/common/notification.tsx new file mode 100644 index 0000000..a5725a2 --- /dev/null +++ b/hooks/15_Context/common/notification.tsx @@ -0,0 +1,41 @@ +import { IconButton, Snackbar } from "@mui/material"; +import CloseIcon from '@mui/icons-material/Close'; +import * as React from "react"; + +interface Props { + message: string; + show: boolean; + onClose: () => void; +} + + + +export const NotificationComponent = (props: Props) => { + const { message, show, onClose } = props; + + return ( + {message}} + action={[ + + + + ]} + /> + ); +}; \ No newline at end of file diff --git a/hooks/15_Context/common/sessionContext.tsx b/hooks/15_Context/common/sessionContext.tsx new file mode 100644 index 0000000..f75f2c6 --- /dev/null +++ b/hooks/15_Context/common/sessionContext.tsx @@ -0,0 +1,31 @@ +import * as React from "react"; + +export interface SessionContextProps { + login: string; + updateLogin: (value: string) => void; +} + +export const createDefaultUser = (): SessionContextProps => ({ + login: "no user", + updateLogin: value => { + console.warn( + "if you are reading this, likely you forgot to add the provider on top of your app" + ); + } +}); + +export interface Props { + children: React.ReactNode; +} + +export const SessionProvider: React.FunctionComponent = (props: Props) => { + const [login, setLogin] = React.useState(""); + + return ( + + {props.children} + + ); +}; + +export const SessionContext = React.createContext(createDefaultUser()); \ No newline at end of file diff --git a/hooks/15_Context/common/textField.component.tsx b/hooks/15_Context/common/textField.component.tsx new file mode 100644 index 0000000..957a4c8 --- /dev/null +++ b/hooks/15_Context/common/textField.component.tsx @@ -0,0 +1,26 @@ +import * as React from "react"; +import { useField } from "formik"; +import { TextField, TextFieldProps } from "@mui/material"; + +export const TextFieldComponent: React.FC = (props) => { + const [field, meta] = useField(props.name); + const TextFieldProps = Boolean(field) ? field : props; + const hasError = Boolean(meta && meta.touched && meta.error); + + return ( + <> + + + + ); +} \ No newline at end of file diff --git a/hooks/15_Context/hello.tsx b/hooks/15_Context/hello.tsx new file mode 100644 index 0000000..b9b1d81 --- /dev/null +++ b/hooks/15_Context/hello.tsx @@ -0,0 +1,9 @@ +import * as React from "react"; + +interface Props { + userName: string; +} + +export const HelloComponent: React.FC = (props) => ( +

Hello user: {props.userName} !

+); diff --git a/hooks/15_Context/index.html b/hooks/15_Context/index.html new file mode 100644 index 0000000..7594228 --- /dev/null +++ b/hooks/15_Context/index.html @@ -0,0 +1,15 @@ + + + + + + + + + +
+
+
+ + + \ No newline at end of file diff --git a/hooks/15_Context/index.tsx b/hooks/15_Context/index.tsx new file mode 100644 index 0000000..0f847e1 --- /dev/null +++ b/hooks/15_Context/index.tsx @@ -0,0 +1,8 @@ +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { App } from './app'; + +ReactDOM.render( + , + document.getElementById('root') +); diff --git a/hooks/15_Context/src/model/login.ts b/hooks/15_Context/model/login.ts similarity index 89% rename from hooks/15_Context/src/model/login.ts rename to hooks/15_Context/model/login.ts index 32854b7..5b7d14a 100644 --- a/hooks/15_Context/src/model/login.ts +++ b/hooks/15_Context/model/login.ts @@ -5,5 +5,5 @@ export interface LoginEntity { export const createEmptyLogin = (): LoginEntity => ({ login: "", - password: "" + password: "", }); diff --git a/hooks/15_Context/nameEdit.tsx b/hooks/15_Context/nameEdit.tsx new file mode 100644 index 0000000..a6ef1ef --- /dev/null +++ b/hooks/15_Context/nameEdit.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +interface Props { + userName: string; + onChange: (e: React.ChangeEvent) => void; +} + +export const NameEditComponent = (props: Props) => ( + <> + + + +) \ No newline at end of file diff --git a/hooks/15_Context/package.json b/hooks/15_Context/package.json index 7916951..a6f809b 100644 --- a/hooks/15_Context/package.json +++ b/hooks/15_Context/package.json @@ -4,7 +4,7 @@ "description": "React Typescript examples", "main": "index.js", "scripts": { - "start": "webpack-dev-server --mode development --inline --hot --open", + "start": "webpack-dev-server --mode development --hot --open", "build": "webpack --mode development" }, "keywords": [ @@ -15,37 +15,37 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.10.5", - "@babel/polyfill": "^7.10.4", - "@babel/preset-env": "^7.10.4", - "@babel/preset-react": "^7.10.4", - "@babel/preset-typescript": "^7.10.4", - "@types/node": "^14.0.24", - "@types/react": "^16.9.43", - "@types/react-dom": "^16.9.8", - "@types/react-router-dom": "^5.1.5", - "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.1.0", - "css-loader": "^3.6.0", - "file-loader": "^6.0.0", - "html-webpack-plugin": "^4.3.0", - "mini-css-extract-plugin": "^0.9.0", - "style-loader": "^1.2.1", - "typescript": "^3.9.7", - "url-loader": "^4.1.0", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.0" + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/polyfill": "^7.12.1", + "@babel/preset-env": "^7.20.2", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "@types/react-router-dom": "^5.3.3", + "babel-loader": "^9.1.2", + "css-loader": "^6.7.3", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "mini-css-extract-plugin": "^2.7.3", + "style-loader": "^3.3.1", + "ts-loader": "^9.4.2", + "typescript": "^4.9.5", + "url-loader": "^4.1.1", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" }, "dependencies": { - "@lemoncode/fonk": "^1.3.0", + "@emotion/react": "^11.10.6", + "@emotion/styled": "^11.10.6", + "@lemoncode/fonk": "^1.5.4", "@lemoncode/fonk-formik": "^4.0.1", - "@material-ui/core": "^4.11.0", - "@material-ui/icons": "^4.9.1", - "formik": "^2.1.5", - "react": "^16.13.1", - "react-dom": "^16.13.1", - "react-router-dom": "^5.2.0" + "@mui/icons-material": "^5.11.11", + "@mui/material": "^5.11.14", + "@mui/styled-engine": "^5.11.11", + "formik": "^2.2.9", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.9.0" } -} +} \ No newline at end of file diff --git a/hooks/15_Context/pages/login.component.tsx b/hooks/15_Context/pages/login.component.tsx new file mode 100644 index 0000000..6b64353 --- /dev/null +++ b/hooks/15_Context/pages/login.component.tsx @@ -0,0 +1,76 @@ +import { Button, Divider, TextField } from "@mui/material"; +// import { styled } from "@mui/system"; +import * as React from "react"; +// import { FormProps } from "react-router-dom"; +import { createEmptyLogin, LoginEntity } from "../model/login"; +import { loginFormValidation } from "./login.validation"; +import { TextFieldComponent } from "../common"; +import { Form, Formik } from "formik"; + +interface PropsForm { + onLogin: (login: LoginEntity) => void; +} + +// const useFormStyles = makeStyles(theme => +// createStyles({ +// formContainer: { +// display: "flex", +// flexDirection: "column", +// justifyContent: "center" +// } +// }) +// ); + +export const LoginComponent = (props: PropsForm) => { + const { onLogin } = props; + + const [loginInfo, setLoginInfo] = React.useState( + createEmptyLogin() + ); + + const onTextFieldChange = (fieldId) => (e) => { + setLoginInfo({ + ...loginInfo, + [fieldId]: e.target.value + }) + } + + return ( + + {() => ( +
+ //
+ + + +
+
+ )} +
+ + + + + //
+ // + // + // + //
+ ) +} diff --git a/hooks/15_Context/pages/login.container.tsx b/hooks/15_Context/pages/login.container.tsx new file mode 100644 index 0000000..954641e --- /dev/null +++ b/hooks/15_Context/pages/login.container.tsx @@ -0,0 +1,61 @@ +import { Card, CardContent, CardHeader, createStyles, makeStyles, styled } from "@mui/material"; +import * as React from "react"; +import { useNavigate } from "react-router-dom"; +import { LoginComponent } from "./login.component"; +import { LoginEntity, createEmptyLogin } from "../model/login"; +import { isValidLogin } from "../api/login"; +import { NotificationComponent } from "../common"; + +interface Props { } + +// const useStyles = makeStyles(theme => +// createStyles({ +// card: { +// maxWidth: 400, +// margin: "0 auto" +// } +// }) +// ); + +const SampleCardStyled = styled(Card)(({ theme }) => ({ + maxWidth: 400, + margin: "0 auto" +})) + +export const LoginContainer: React.FC = (props) => { + const [loginInfo, setLoginInfo] = React.useState( + createEmptyLogin() + ) + const [isShowAlert, setShowAlert] = React.useState(false); + + const navigate = useNavigate(); + + const loginSucceeded = (isValid: boolean) => { + console.log(isValid) + if (isValid) { + navigate('/pageB') + } else { + setShowAlert(true) + } + } + + const handleLogin = (login: LoginEntity) => { + isValidLogin(login).then(loginSucceeded); + }; + + return ( + <> + + + + + + + setShowAlert(false)} /> + + ); +}; + diff --git a/hooks/15_Context/pages/login.validation.ts b/hooks/15_Context/pages/login.validation.ts new file mode 100644 index 0000000..5b4a9c6 --- /dev/null +++ b/hooks/15_Context/pages/login.validation.ts @@ -0,0 +1,14 @@ +import { + createFormValidation, + ValidationSchema, + Validators, +} from "@lemoncode/fonk"; + +const validationSchema: ValidationSchema = { + field: { + login: [Validators.required], + password: [Validators.required], + }, +}; + +export const loginFormValidation = createFormValidation(validationSchema); diff --git a/hooks/15_Context/pages/loginPage.tsx b/hooks/15_Context/pages/loginPage.tsx new file mode 100644 index 0000000..0b708c5 --- /dev/null +++ b/hooks/15_Context/pages/loginPage.tsx @@ -0,0 +1,9 @@ +import * as React from "react" +import { FormProps, Link } from "react-router-dom" + +export const LoginComponent: React.FC = (props) => +
+

Hello from login Page

+
+ Navigate to Page B +
\ No newline at end of file diff --git a/hooks/15_Context/pages/pageB.tsx b/hooks/15_Context/pages/pageB.tsx new file mode 100644 index 0000000..a8853c0 --- /dev/null +++ b/hooks/15_Context/pages/pageB.tsx @@ -0,0 +1,9 @@ +import * as React from "react" +import { Link } from "react-router-dom" + +export const PageB = () => +
+

Hello from page B

+
+ Navigate to Login +
\ No newline at end of file diff --git a/hooks/15_Context/src/app.tsx b/hooks/15_Context/src/app.tsx deleted file mode 100644 index 89ae266..0000000 --- a/hooks/15_Context/src/app.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import * as React from "react"; -import { HashRouter, Switch, Route } from "react-router-dom"; -import { LoginContainer } from "./pages/login.container"; -import { PageB } from "./pages/pageB"; -import { SessionProvider } from "./common"; - -export const App = () => { - return ( - <> - - - - - - - - - - ); -}; diff --git a/hooks/15_Context/src/common/notification.tsx b/hooks/15_Context/src/common/notification.tsx deleted file mode 100644 index 50e2b70..0000000 --- a/hooks/15_Context/src/common/notification.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import * as React from "react"; -import Snackbar from "@material-ui/core/Snackbar"; -import IconButton from "@material-ui/core/IconButton"; -import CloseIcon from "@material-ui/icons/Close"; -import createStyles from "@material-ui/core/styles/createStyles"; -import makeStyles from "@material-ui/core/styles/makeStyles"; - -interface Props { - message: string; - show: boolean; - onClose: () => void; -} - -const useStyles = makeStyles((theme) => - createStyles({ - close: { - padding: theme.spacing(0.5), - }, - }) -); - -export const NotificationComponent: React.FC = (props) => { - const classes = useStyles(); - const { message, show, onClose } = props; - - return ( - {message}} - action={[ - - - , - ]} - /> - ); -}; diff --git a/hooks/15_Context/src/common/sessionContext.tsx b/hooks/15_Context/src/common/sessionContext.tsx deleted file mode 100644 index 4edab12..0000000 --- a/hooks/15_Context/src/common/sessionContext.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import * as React from "react"; - -export interface SessionContextProps { - login: string; - updateLogin: (value) => void; -} - -export const createDefaultUser = (): SessionContextProps => ({ - login: "no user", - updateLogin: (value) => { - console.warn( - "if you are reading this, likely you forgot to add the provider on top of your app" - ); - }, -}); - -export const SessionContext = React.createContext( - createDefaultUser() -); - -export const SessionProvider: React.FC = (props) => { - const [login, setLogin] = React.useState(""); - - return ( - - {props.children} - - ); -}; diff --git a/hooks/15_Context/src/common/textField.component.tsx b/hooks/15_Context/src/common/textField.component.tsx deleted file mode 100644 index 718e117..0000000 --- a/hooks/15_Context/src/common/textField.component.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import * as React from "react"; -import { useField } from "formik"; -import MuiTextField, { TextFieldProps } from "@material-ui/core/TextField"; - -export const TextFieldComponent: React.FC = (props) => { - const [field, meta] = useField(props.name); - const textFieldProps = Boolean(field) ? field : props; - const hasError = Boolean(meta && meta.touched && meta.error); - - return ( - <> - - - ); -}; diff --git a/hooks/15_Context/src/index.html b/hooks/15_Context/src/index.html deleted file mode 100644 index 2ad4810..0000000 --- a/hooks/15_Context/src/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - -
-
-
- - diff --git a/hooks/15_Context/src/index.tsx b/hooks/15_Context/src/index.tsx deleted file mode 100644 index 26ed977..0000000 --- a/hooks/15_Context/src/index.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import * as React from "react"; -import * as ReactDOM from "react-dom"; - -import { App } from "./app"; - -ReactDOM.render(, document.getElementById("root")); diff --git a/hooks/15_Context/src/pages/login.component.tsx b/hooks/15_Context/src/pages/login.component.tsx deleted file mode 100644 index 2c4adb0..0000000 --- a/hooks/15_Context/src/pages/login.component.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import * as React from "react"; -import { LoginEntity, createEmptyLogin } from "../model/login"; -import { TextFieldComponent } from "../common"; -import { Form } from "formik"; -import createStyles from "@material-ui/styles/createStyles"; -import makeStyles from "@material-ui/styles/makeStyles"; -import Button from "@material-ui/core/Button"; -import { loginFormValidation } from "./login.validation"; -import { Formik } from "formik"; - -interface PropsForm { - onLogin: (login: LoginEntity) => void; -} - -// https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useFormStyles = makeStyles((theme) => - createStyles({ - formContainer: { - display: "flex", - flexDirection: "column", - justifyContent: "center", - }, - card: { - maxWidth: 400, - margin: "0 auto", - }, - }) -); - -export const LoginComponent: React.FC = (props) => { - const classes = useFormStyles(); - const { onLogin } = props; - - return ( - - {() => ( -
-
- - - -
-
- )} -
- ); -}; diff --git a/hooks/15_Context/src/pages/login.container.tsx b/hooks/15_Context/src/pages/login.container.tsx deleted file mode 100644 index e3e65ca..0000000 --- a/hooks/15_Context/src/pages/login.container.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import * as React from "react"; -import { useHistory } from "react-router-dom"; -import { LoginEntity } from "../model/login"; -import { isValidLogin } from "../api/login"; -import { LoginComponent } from "./login.component"; -import Card from "@material-ui/core/Card"; -import CardHeader from "@material-ui/core/CardHeader"; -import CardContent from "@material-ui/core/CardContent"; -import createStyles from "@material-ui/styles/createStyles"; -import makeStyles from "@material-ui/styles/makeStyles"; -import { NotificationComponent, SessionContext } from "../common"; - -// https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useFormStyles = makeStyles((theme) => - createStyles({ - card: { - maxWidth: 400, - margin: "0 auto", - }, - }) -); - -interface Props {} - -export const LoginContainer: React.FC = (props) => { - const loginContext = React.useContext(SessionContext); - const history = useHistory(); - const [isShowAlert, setShowAlert] = React.useState(false); - const classes = useFormStyles(); - - const loginSucceeded = (isValid: boolean, login: LoginEntity) => { - if (isValid) { - history.push("/pageB"); - loginContext.updateLogin(login.login); - } else { - setShowAlert(true); - } - }; - - const handleLogin = (login: LoginEntity) => { - isValidLogin(login).then((isValid) => loginSucceeded(isValid, login)); - }; - - return ( - <> - - - - - setShowAlert(false)} - /> - - - - ); -}; diff --git a/hooks/15_Context/src/pages/login.validation.ts b/hooks/15_Context/src/pages/login.validation.ts deleted file mode 100644 index 2094212..0000000 --- a/hooks/15_Context/src/pages/login.validation.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { ValidationSchema, Validators } from "@lemoncode/fonk"; -import { createFormikValidation } from "@lemoncode/fonk-formik"; - -const validationSchema: ValidationSchema = { - field: { - login: [Validators.required], - password: [Validators.required], - }, -}; - -export const loginFormValidation = createFormikValidation(validationSchema); diff --git a/hooks/15_Context/src/pages/pageB.tsx b/hooks/15_Context/src/pages/pageB.tsx deleted file mode 100644 index ccf7598..0000000 --- a/hooks/15_Context/src/pages/pageB.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import * as React from "react"; -import { Link } from "react-router-dom"; -import { SessionContext } from "../common"; - -export const PageB: React.FC = () => { - const loginContext = React.useContext(SessionContext); - - return ( -
-

Hello from page B

-

User logged in: {loginContext.login}

-
- Navigate to Login -
- ); -}; diff --git a/hooks/15_Context/webpack.config.js b/hooks/15_Context/webpack.config.js index 32eff84..1d6fce3 100644 --- a/hooks/15_Context/webpack.config.js +++ b/hooks/15_Context/webpack.config.js @@ -1,63 +1,60 @@ -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const webpack = require("webpack"); -const path = require("path"); +var HtmlWebpackPlugin = require("html-webpack-plugin"); +var MiniCssExtractPlugin = require("mini-css-extract-plugin"); +var webpack = require("webpack"); +var path = require("path"); -const basePath = __dirname; +var basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"], + extensions: [".js", ".ts", ".tsx"] }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js", + 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", + // inline: true, // Enable watch and live reload + // host: "localhost", + // port: 8080, + // stats: "errors-only", + static: { + directory: "./dist", + } }, module: { rules: [ { test: /\.(ts|tsx)$/, exclude: /node_modules/, - loader: "awesome-typescript-loader", - options: { - useBabel: true, - babelCore: "@babel/core", // needed for Babel v7 - }, + loader: "ts-loader", }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"], + use: [MiniCssExtractPlugin.loader, "css-loader"] }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]", - esModule: false, - }, - }, - ], + name: "assets/img/[name].[ext]?[hash]" + } + } + ] }, 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, + hash: true }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css", - }), - ], -}; + chunkFilename: "[id].css" + }) + ] +}; \ No newline at end of file From a65782f02204342b48975a037f3f2e0191dc8610 Mon Sep 17 00:00:00 2001 From: Uchan Date: Sat, 1 Apr 2023 20:59:22 +0900 Subject: [PATCH 34/36] context --- hooks/15_Context/{ => src}/api/login.ts | 0 hooks/15_Context/{ => src}/app.tsx | 2 ++ hooks/15_Context/{ => src}/common/index.ts | 1 + hooks/15_Context/{ => src}/common/notification.tsx | 0 hooks/15_Context/{ => src}/common/sessionContext.tsx | 0 hooks/15_Context/{ => src}/common/textField.component.tsx | 0 hooks/15_Context/{ => src}/hello.tsx | 0 hooks/15_Context/{ => src}/index.html | 0 hooks/15_Context/{ => src}/index.tsx | 0 hooks/15_Context/{ => src}/model/login.ts | 0 hooks/15_Context/{ => src}/nameEdit.tsx | 0 hooks/15_Context/{ => src}/pages/login.component.tsx | 0 hooks/15_Context/{ => src}/pages/login.container.tsx | 0 hooks/15_Context/{ => src}/pages/login.validation.ts | 0 hooks/15_Context/{ => src}/pages/loginPage.tsx | 0 hooks/15_Context/{ => src}/pages/pageB.tsx | 0 16 files changed, 3 insertions(+) rename hooks/15_Context/{ => src}/api/login.ts (100%) rename hooks/15_Context/{ => src}/app.tsx (81%) rename hooks/15_Context/{ => src}/common/index.ts (65%) rename hooks/15_Context/{ => src}/common/notification.tsx (100%) rename hooks/15_Context/{ => src}/common/sessionContext.tsx (100%) rename hooks/15_Context/{ => src}/common/textField.component.tsx (100%) rename hooks/15_Context/{ => src}/hello.tsx (100%) rename hooks/15_Context/{ => src}/index.html (100%) rename hooks/15_Context/{ => src}/index.tsx (100%) rename hooks/15_Context/{ => src}/model/login.ts (100%) rename hooks/15_Context/{ => src}/nameEdit.tsx (100%) rename hooks/15_Context/{ => src}/pages/login.component.tsx (100%) rename hooks/15_Context/{ => src}/pages/login.container.tsx (100%) rename hooks/15_Context/{ => src}/pages/login.validation.ts (100%) rename hooks/15_Context/{ => src}/pages/loginPage.tsx (100%) rename hooks/15_Context/{ => src}/pages/pageB.tsx (100%) diff --git a/hooks/15_Context/api/login.ts b/hooks/15_Context/src/api/login.ts similarity index 100% rename from hooks/15_Context/api/login.ts rename to hooks/15_Context/src/api/login.ts diff --git a/hooks/15_Context/app.tsx b/hooks/15_Context/src/app.tsx similarity index 81% rename from hooks/15_Context/app.tsx rename to hooks/15_Context/src/app.tsx index 600249f..29c2445 100644 --- a/hooks/15_Context/app.tsx +++ b/hooks/15_Context/src/app.tsx @@ -1,5 +1,6 @@ import * as React from "react"; import { BrowserRouter, Route, Routes } from "react-router-dom"; +import { SessionProvider } from "./common/sessionContext"; import { LoginComponent } from "./pages/login.component"; import { LoginContainer } from "./pages/login.container"; import { PageB } from "./pages/pageB"; @@ -13,6 +14,7 @@ export const App = () => { <> + {/* } /> */} } /> } /> diff --git a/hooks/15_Context/common/index.ts b/hooks/15_Context/src/common/index.ts similarity index 65% rename from hooks/15_Context/common/index.ts rename to hooks/15_Context/src/common/index.ts index fe9e7da..ad4d962 100644 --- a/hooks/15_Context/common/index.ts +++ b/hooks/15_Context/src/common/index.ts @@ -1,2 +1,3 @@ export * from "./notification"; export * from "./textField.component"; +// export * from "./sessionContext"; diff --git a/hooks/15_Context/common/notification.tsx b/hooks/15_Context/src/common/notification.tsx similarity index 100% rename from hooks/15_Context/common/notification.tsx rename to hooks/15_Context/src/common/notification.tsx diff --git a/hooks/15_Context/common/sessionContext.tsx b/hooks/15_Context/src/common/sessionContext.tsx similarity index 100% rename from hooks/15_Context/common/sessionContext.tsx rename to hooks/15_Context/src/common/sessionContext.tsx diff --git a/hooks/15_Context/common/textField.component.tsx b/hooks/15_Context/src/common/textField.component.tsx similarity index 100% rename from hooks/15_Context/common/textField.component.tsx rename to hooks/15_Context/src/common/textField.component.tsx diff --git a/hooks/15_Context/hello.tsx b/hooks/15_Context/src/hello.tsx similarity index 100% rename from hooks/15_Context/hello.tsx rename to hooks/15_Context/src/hello.tsx diff --git a/hooks/15_Context/index.html b/hooks/15_Context/src/index.html similarity index 100% rename from hooks/15_Context/index.html rename to hooks/15_Context/src/index.html diff --git a/hooks/15_Context/index.tsx b/hooks/15_Context/src/index.tsx similarity index 100% rename from hooks/15_Context/index.tsx rename to hooks/15_Context/src/index.tsx diff --git a/hooks/15_Context/model/login.ts b/hooks/15_Context/src/model/login.ts similarity index 100% rename from hooks/15_Context/model/login.ts rename to hooks/15_Context/src/model/login.ts diff --git a/hooks/15_Context/nameEdit.tsx b/hooks/15_Context/src/nameEdit.tsx similarity index 100% rename from hooks/15_Context/nameEdit.tsx rename to hooks/15_Context/src/nameEdit.tsx diff --git a/hooks/15_Context/pages/login.component.tsx b/hooks/15_Context/src/pages/login.component.tsx similarity index 100% rename from hooks/15_Context/pages/login.component.tsx rename to hooks/15_Context/src/pages/login.component.tsx diff --git a/hooks/15_Context/pages/login.container.tsx b/hooks/15_Context/src/pages/login.container.tsx similarity index 100% rename from hooks/15_Context/pages/login.container.tsx rename to hooks/15_Context/src/pages/login.container.tsx diff --git a/hooks/15_Context/pages/login.validation.ts b/hooks/15_Context/src/pages/login.validation.ts similarity index 100% rename from hooks/15_Context/pages/login.validation.ts rename to hooks/15_Context/src/pages/login.validation.ts diff --git a/hooks/15_Context/pages/loginPage.tsx b/hooks/15_Context/src/pages/loginPage.tsx similarity index 100% rename from hooks/15_Context/pages/loginPage.tsx rename to hooks/15_Context/src/pages/loginPage.tsx diff --git a/hooks/15_Context/pages/pageB.tsx b/hooks/15_Context/src/pages/pageB.tsx similarity index 100% rename from hooks/15_Context/pages/pageB.tsx rename to hooks/15_Context/src/pages/pageB.tsx From 4d7512c4340414a95f66b9e4b332a6b44edc88b5 Mon Sep 17 00:00:00 2001 From: Uchan Date: Sun, 2 Apr 2023 19:00:18 +0900 Subject: [PATCH 35/36] =?UTF-8?q?=E3=81=93=E3=81=AE=E6=9B=B8=E3=81=8D?= =?UTF-8?q?=E6=96=B9=E3=81=A0=E3=81=A8=E3=83=AC=E3=83=B3=E3=83=80=E3=83=AA?= =?UTF-8?q?=E3=83=B3=E3=82=B0=E3=81=AF=E3=81=86=E3=81=BE=E3=81=8F=E3=81=84?= =?UTF-8?q?=E3=81=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hooks/15_Context/src/app.tsx | 7 ++++--- hooks/15_Context/src/common/sessionContext.tsx | 9 +++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/hooks/15_Context/src/app.tsx b/hooks/15_Context/src/app.tsx index 29c2445..f7420a7 100644 --- a/hooks/15_Context/src/app.tsx +++ b/hooks/15_Context/src/app.tsx @@ -14,11 +14,12 @@ export const App = () => { <> - {/* } /> */} - } /> + } > + {/* } /> */} + } /> - + ); }; \ No newline at end of file diff --git a/hooks/15_Context/src/common/sessionContext.tsx b/hooks/15_Context/src/common/sessionContext.tsx index f75f2c6..19ca35f 100644 --- a/hooks/15_Context/src/common/sessionContext.tsx +++ b/hooks/15_Context/src/common/sessionContext.tsx @@ -1,4 +1,6 @@ import * as React from "react"; +import { LoginContainer } from "../pages/login.container"; +import { Route, Routes } from "react-router-dom"; export interface SessionContextProps { login: string; @@ -15,7 +17,7 @@ export const createDefaultUser = (): SessionContextProps => ({ }); export interface Props { - children: React.ReactNode; + children?: React.ReactNode; } export const SessionProvider: React.FunctionComponent = (props: Props) => { @@ -23,7 +25,10 @@ export const SessionProvider: React.FunctionComponent = (props: Props) => { return ( - {props.children} + {/* {props.children} */} + + } /> + ); }; From ce6c9f1d79fdb001a98a42e72bc7fb32de723676 Mon Sep 17 00:00:00 2001 From: Uchan Date: Mon, 3 Apr 2023 08:02:59 +0900 Subject: [PATCH 36/36] context end! --- hooks/15_Context/src/app.tsx | 2 +- hooks/15_Context/src/pages/login.component.tsx | 9 ++++++--- hooks/15_Context/src/pages/login.container.tsx | 2 +- hooks/15_Context/tsconfig.json | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/hooks/15_Context/src/app.tsx b/hooks/15_Context/src/app.tsx index f7420a7..e50e894 100644 --- a/hooks/15_Context/src/app.tsx +++ b/hooks/15_Context/src/app.tsx @@ -15,7 +15,7 @@ export const App = () => { } > - {/* } /> */} + } > } /> diff --git a/hooks/15_Context/src/pages/login.component.tsx b/hooks/15_Context/src/pages/login.component.tsx index 6b64353..6272a90 100644 --- a/hooks/15_Context/src/pages/login.component.tsx +++ b/hooks/15_Context/src/pages/login.component.tsx @@ -29,6 +29,7 @@ export const LoginComponent = (props: PropsForm) => { ); const onTextFieldChange = (fieldId) => (e) => { + console.log(e); setLoginInfo({ ...loginInfo, [fieldId]: e.target.value @@ -43,17 +44,19 @@ export const LoginComponent = (props: PropsForm) => { > {() => (
- //
+ name="login" + /> + name="password" + />
diff --git a/hooks/15_Context/src/pages/login.container.tsx b/hooks/15_Context/src/pages/login.container.tsx index 954641e..5c892f2 100644 --- a/hooks/15_Context/src/pages/login.container.tsx +++ b/hooks/15_Context/src/pages/login.container.tsx @@ -31,7 +31,6 @@ export const LoginContainer: React.FC = (props) => { const navigate = useNavigate(); const loginSucceeded = (isValid: boolean) => { - console.log(isValid) if (isValid) { navigate('/pageB') } else { @@ -40,6 +39,7 @@ export const LoginContainer: React.FC = (props) => { } const handleLogin = (login: LoginEntity) => { + console.log(login); isValidLogin(login).then(loginSucceeded); }; diff --git a/hooks/15_Context/tsconfig.json b/hooks/15_Context/tsconfig.json index f90a3f0..3cd3eef 100644 --- a/hooks/15_Context/tsconfig.json +++ b/hooks/15_Context/tsconfig.json @@ -8,7 +8,7 @@ "jsx": "react", "sourceMap": true, "noLib": false, - "suppressImplicitAnyIndexErrors": true + "suppressImplicitAnyIndexErrors": false }, "compileOnSave": false, "exclude": ["node_modules"]