diff --git a/README.md b/README.md index f966765..98ba46e 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,24 @@ Joshua Seigler - October 2022 ## Usage -`npm run start` for development or local hosting +NPM scripts (run with npm run scriptname) -`npm run build` to populate `./dist` with a packaged build, ready for upload +### `start` -`npm run clean` to delete `./dist` and various cache folders +Run the project locally at http://localhost:1234 and watch for code changes -`npm run publish` to upload `./dist` to the GitHub Pages branch +### `publish` + +Runs scripts `clean`, `build`, and `deploy` in order. + +### `clean` + +Deletes `./dist` + +### `build` + +Populate `./dist` with a packaged build, ready for upload + +### `deploy` + +Replace the contents of branch `gh-pages` with the contents of `./dist` diff --git a/package-lock.json b/package-lock.json index 2a88e6b..267aa91 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@types/react": "^18.0.21", "@types/react-dom": "^18.0.6", "@types/react-router-dom": "^5.3.3", + "localforage": "^1.10.0", "react-dom": "^18.2.0", "react-router": "^6.4.2", "react-router-dom": "^6.4.2", @@ -2003,6 +2004,11 @@ "entities": "^3.0.1" } }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -2054,6 +2060,14 @@ "node": ">=6" } }, + "node_modules/lie": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==", + "dependencies": { + "immediate": "~3.0.5" + } + }, "node_modules/lightningcss": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.16.0.tgz", @@ -2288,6 +2302,14 @@ "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", "dev": true }, + "node_modules/localforage": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", + "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==", + "dependencies": { + "lie": "3.1.1" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -4155,6 +4177,11 @@ "entities": "^3.0.1" } }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -4194,6 +4221,14 @@ "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", "dev": true }, + "lie": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==", + "requires": { + "immediate": "~3.0.5" + } + }, "lightningcss": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.16.0.tgz", @@ -4300,6 +4335,14 @@ } } }, + "localforage": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", + "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==", + "requires": { + "lie": "3.1.1" + } + }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", diff --git a/package.json b/package.json index 5545896..00472cb 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,9 @@ "test": "echo \"Error: no test specified\" && exit 1", "start": "parcel", "build": "parcel build", - "deploy": "git-directory-deploy --directory dist/", - "clean": "rm -rf ./dist ./.cache ./.parcel-cache" + "deploy": "echo > ./dist/.nojekyll && git-directory-deploy --directory dist/", + "clean": "rm -rf ./dist", + "publish": "npm run clean && npm run build && npm run deploy" }, "keywords": [ "presentation", @@ -24,6 +25,7 @@ "@types/react": "^18.0.21", "@types/react-dom": "^18.0.6", "@types/react-router-dom": "^5.3.3", + "localforage": "^1.10.0", "react-dom": "^18.2.0", "react-router": "^6.4.2", "react-router-dom": "^6.4.2", diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..4c67bdb --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,53 @@ +import React from 'react' +import { Link, NavLink, Route, Routes } from 'react-router-dom' +import { strategies } from './strategies' +import { ErrorPage } from './error-page' + +export function App() { + return ( + <> +
+

React State Management

+ +
+
+ + }> + } /> + {strategies.map(({ name, component: StrategyComponent }) => ( + } /> + ))} + } /> + + + + ) +} + +function NotFound() { + return ( +
+

You took a wrong turn

+

There's nothing here.

+
+ ) +} + +function Introduction() { + return ( +
+

Introduction

+

Here are some ways to store state in a React Application.

+
+ ) +} diff --git a/src/index.tsx b/src/index.tsx index 82e8ede..622ba51 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,21 +1,21 @@ import React from 'react' -import ReactDOM from 'react-dom' +import { createRoot } from 'react-dom/client' import { createBrowserRouter, RouterProvider } from 'react-router-dom' import { ErrorPage } from './error-page' -import { Root } from './routes/root' +import { App } from './App' const router = createBrowserRouter([ { - path: '/', - element: , + path: '/*', + element: , errorElement: } ]) const appEntry = document.getElementById('app') -ReactDOM.render( +const root = createRoot(appEntry!) +root.render( - , - appEntry + ) diff --git a/src/routes/root.tsx b/src/routes/root.tsx deleted file mode 100644 index c17506f..0000000 --- a/src/routes/root.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import React from 'react' - -export function Root() { - return

React State Management

-} diff --git a/src/strategies/index.ts b/src/strategies/index.ts new file mode 100644 index 0000000..1253936 --- /dev/null +++ b/src/strategies/index.ts @@ -0,0 +1,3 @@ +import { UseState } from "./useState"; + +export const strategies = [{ name: 'useState', component: UseState }] diff --git a/src/strategies/useState.tsx b/src/strategies/useState.tsx new file mode 100644 index 0000000..bfa4504 --- /dev/null +++ b/src/strategies/useState.tsx @@ -0,0 +1,40 @@ +import React, { useState } from 'react' + +type Todo = { + id: string + text: string + status: 'incomplete' | 'complete' | 'hidden' +} + +export function UseState() { + const [todos, setTodos] = useState([]) + const [newTodoText, setNewTodoText] = useState('') + + function addTodo() { + const newTodo = { + id: crypto.randomUUID(), + text: newTodoText, + status: 'incomplete' as const + } + setTodos((t) => [...t, newTodo]) + } + + return ( +
+
{ + e.preventDefault() + addTodo() + }}> + +
+
+ ) +}