about summary refs log tree commit diff
path: root/boilerplate/typescript/src
diff options
context:
space:
mode:
authorWilliam Carroll <wpcarro@gmail.com>2020-03-23T22·12+0000
committerWilliam Carroll <wpcarro@gmail.com>2020-03-23T22·43+0000
commit9fdf4d00fa4abcdb356a919d293fd8686407ccf9 (patch)
tree3227c211118bcfe60f46c6f442fbc5035b2166d9 /boilerplate/typescript/src
parent1cc1ce5ccf88adcbd064ac46a070b94faa04b871 (diff)
Support boilerplate for TypeScript projects
I would like to support boilerplate code for ReasonML, TypeScript,
ClojureScript, and Elm projects before I specialize in any of these
frameworks. All of my projects should use TailwindCSS.

All of this boilerplate should offer:
- Same command to start developing
- Same API to build and deploy
- TailwindCSS support
- Basic boilerplate for components, state, and routes

This TypeScript boilerplate is not complete, but I would like to commit the
progress in case I do not return to this for awhile.
Diffstat (limited to 'boilerplate/typescript/src')
-rw-r--r--boilerplate/typescript/src/App.tsx52
-rw-r--r--boilerplate/typescript/src/index.css3
-rw-r--r--boilerplate/typescript/src/index.html11
-rw-r--r--boilerplate/typescript/src/index.tsx12
-rw-r--r--boilerplate/typescript/src/math.ts3
-rw-r--r--boilerplate/typescript/src/store.ts26
6 files changed, 107 insertions, 0 deletions
diff --git a/boilerplate/typescript/src/App.tsx b/boilerplate/typescript/src/App.tsx
new file mode 100644
index 000000000000..4fae1b36ac4d
--- /dev/null
+++ b/boilerplate/typescript/src/App.tsx
@@ -0,0 +1,52 @@
+import React, { useEffect } from "react";
+import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
+import { useDispatch } from "react-redux";
+import { actions, useTypedSelector } from "./store";
+import { Link } from "react-router-dom";
+
+const App: React.FC = () => {
+  const dispatch = useDispatch();
+  const { isLoading } = useTypedSelector(state => ({
+    isLoading: state.isLoading,
+  }));
+
+  return (
+    <Router>
+      <nav className="bg-blue-400">
+        <ul className="container mx-auto justify-between flex py-6 text-white">
+          <li>
+            <Link to="/">Home</Link>
+          </li>
+          <li>
+            <Link to="/about">About</Link>
+          </li>
+          <li>
+            <Link to="/contact">Contact</Link>
+          </li>
+        </ul>
+      </nav>
+      <Switch>
+        <Route exact path="/">
+          <div className="container mx-auto">
+            <h1>Welcome to the home page. Loading: {isLoading ? "true" : "false"}</h1>
+            <button
+              className="bg-gray-300 py-4 px-6"
+              onClick={() => dispatch(actions.toggleIsLoading())}>isLoading</button>
+          </div>
+        </Route>
+        <Route exact path="/about">
+          <div className="container mx-auto">
+            <h1>Here is the about page.</h1>
+          </div>
+        </Route>
+        <Route exact path="/contact">
+          <div className="container mx-auto">
+            <h1>Here is the contact page.</h1>
+          </div>
+        </Route>
+      </Switch>
+    </Router>
+  );
+};
+
+export default App;
diff --git a/boilerplate/typescript/src/index.css b/boilerplate/typescript/src/index.css
new file mode 100644
index 000000000000..b5c61c956711
--- /dev/null
+++ b/boilerplate/typescript/src/index.css
@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
diff --git a/boilerplate/typescript/src/index.html b/boilerplate/typescript/src/index.html
new file mode 100644
index 000000000000..05dd7ad95e79
--- /dev/null
+++ b/boilerplate/typescript/src/index.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8">
+    <link rel="stylesheet" href="./index.css">
+  </head>
+  <body>
+    <div id="mount"></div>
+    <script src="./index.tsx"></script>
+  </body>
+</html>
diff --git a/boilerplate/typescript/src/index.tsx b/boilerplate/typescript/src/index.tsx
new file mode 100644
index 000000000000..dc28dc4a9cc8
--- /dev/null
+++ b/boilerplate/typescript/src/index.tsx
@@ -0,0 +1,12 @@
+import React from "react";
+import ReactDOM from "react-dom";
+import App from "./App";
+import { Provider } from "react-redux";
+import store from "./store";
+
+ReactDOM.render(
+  <Provider store={store}>
+    <App />
+  </Provider>,
+  document.getElementById("mount")
+);
diff --git a/boilerplate/typescript/src/math.ts b/boilerplate/typescript/src/math.ts
new file mode 100644
index 000000000000..a6e31168888d
--- /dev/null
+++ b/boilerplate/typescript/src/math.ts
@@ -0,0 +1,3 @@
+export const add = (x: number, y: number): number => {
+  return x + y;
+}
diff --git a/boilerplate/typescript/src/store.ts b/boilerplate/typescript/src/store.ts
new file mode 100644
index 000000000000..03e980a491cc
--- /dev/null
+++ b/boilerplate/typescript/src/store.ts
@@ -0,0 +1,26 @@
+import { createSlice, configureStore, PayloadAction } from "@reduxjs/toolkit";
+import { useSelector, TypedUseSelectorHook } from "react-redux";
+
+export interface State {
+  isLoading: boolean;
+}
+
+const initialState: State = {
+  isLoading: true,
+};
+
+export const { actions, reducer } = createSlice({
+  name: "application",
+  initialState,
+  reducers: {
+    toggleIsLoading: state => ({ ...state, isLoading: !state.isLoading }),
+  }
+});
+
+/**
+ * Defining and consuming this allows us to avoid annotating State in all of our
+ * selectors.
+ */
+export const useTypedSelector: TypedUseSelectorHook<State> = useSelector;
+
+export default configureStore({ reducer });