gw-my-vite-app 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env +1 -0
- package/.github/workflows/build.yml +24 -0
- package/.github/workflows/publish.yml +30 -0
- package/README.md +81 -0
- package/eslint.config.js +41 -0
- package/index.html +13 -0
- package/package.json +34 -0
- package/src/App.css +42 -0
- package/src/App.tsx +22 -0
- package/src/components/Footer.tsx +149 -0
- package/src/components/Header.tsx +12 -0
- package/src/index.css +68 -0
- package/src/main.tsx +15 -0
- package/src/styles/main.scss +3 -0
- package/tsconfig.app.json +28 -0
- package/tsconfig.json +11 -0
- package/tsconfig.node.json +26 -0
- package/vite.config.ts +7 -0
package/.env
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VITE_API_KEY=123456789
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Build
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- "**"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- name: Checkout code
|
|
13
|
+
uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- name: Set up Node.js
|
|
16
|
+
uses: actions/setup-node@v4
|
|
17
|
+
with:
|
|
18
|
+
node-version: "20"
|
|
19
|
+
|
|
20
|
+
- name: Install dependencies
|
|
21
|
+
run: npm ci
|
|
22
|
+
|
|
23
|
+
- name: Build
|
|
24
|
+
run: npm run build
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: Build and Publish to npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build-and-publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- name: Checkout code
|
|
13
|
+
uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- name: Set up Node.js
|
|
16
|
+
uses: actions/setup-node@v4
|
|
17
|
+
with:
|
|
18
|
+
node-version: "18"
|
|
19
|
+
registry-url: "https://registry.npmjs.org/"
|
|
20
|
+
|
|
21
|
+
- name: Install dependencies
|
|
22
|
+
run: npm ci
|
|
23
|
+
|
|
24
|
+
- name: Build
|
|
25
|
+
run: npm run build
|
|
26
|
+
|
|
27
|
+
- name: Publish to npm
|
|
28
|
+
run: npm publish
|
|
29
|
+
env:
|
|
30
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# React + TypeScript + Vite
|
|
2
|
+
|
|
3
|
+
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
|
4
|
+
|
|
5
|
+
Currently, two official plugins are available:
|
|
6
|
+
|
|
7
|
+
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
|
|
8
|
+
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
|
9
|
+
|
|
10
|
+
## React Compiler
|
|
11
|
+
|
|
12
|
+
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
|
|
13
|
+
|
|
14
|
+
## Expanding the ESLint configuration
|
|
15
|
+
|
|
16
|
+
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
export default defineConfig([
|
|
20
|
+
globalIgnores(["dist"]),
|
|
21
|
+
{
|
|
22
|
+
files: ["**/*.{ts,tsx}"],
|
|
23
|
+
extends: [
|
|
24
|
+
// Other configs...
|
|
25
|
+
|
|
26
|
+
// Remove tseslint.configs.recommended and replace with this
|
|
27
|
+
tseslint.configs.recommendedTypeChecked,
|
|
28
|
+
// Alternatively, use this for stricter rules
|
|
29
|
+
tseslint.configs.strictTypeChecked,
|
|
30
|
+
// Optionally, add this for stylistic rules
|
|
31
|
+
tseslint.configs.stylisticTypeChecked,
|
|
32
|
+
|
|
33
|
+
// Other configs...
|
|
34
|
+
],
|
|
35
|
+
languageOptions: {
|
|
36
|
+
parserOptions: {
|
|
37
|
+
project: ["./tsconfig.node.json", "./tsconfig.app.json"],
|
|
38
|
+
tsconfigRootDir: import.meta.dirname,
|
|
39
|
+
},
|
|
40
|
+
// other options...
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
]);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
// eslint.config.js
|
|
50
|
+
import reactX from "eslint-plugin-react-x";
|
|
51
|
+
import reactDom from "eslint-plugin-react-dom";
|
|
52
|
+
|
|
53
|
+
export default defineConfig([
|
|
54
|
+
globalIgnores(["dist"]),
|
|
55
|
+
{
|
|
56
|
+
files: ["**/*.{ts,tsx}"],
|
|
57
|
+
extends: [
|
|
58
|
+
// Other configs...
|
|
59
|
+
// Enable lint rules for React
|
|
60
|
+
reactX.configs["recommended-typescript"],
|
|
61
|
+
// Enable lint rules for React DOM
|
|
62
|
+
reactDom.configs.recommended,
|
|
63
|
+
],
|
|
64
|
+
languageOptions: {
|
|
65
|
+
parserOptions: {
|
|
66
|
+
project: ["./tsconfig.node.json", "./tsconfig.app.json"],
|
|
67
|
+
tsconfigRootDir: import.meta.dirname,
|
|
68
|
+
},
|
|
69
|
+
// other options...
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
]);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Notes/Objectives
|
|
76
|
+
|
|
77
|
+
1. Make a super simple web app with Typescript
|
|
78
|
+
2. Set up typescript rules
|
|
79
|
+
3. Purposely make a lot of typescript errors in the Footer.tsx file to make sure the typescript rules work
|
|
80
|
+
4. Set up github actions to run when there is a push to a branch
|
|
81
|
+
5. Github actions will then run `npm run build`, which is short for `tsc -b && vite build`. `tsc -b` runs the typescript compiler in build mode and reports any errors
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import js from "@eslint/js";
|
|
2
|
+
import globals from "globals";
|
|
3
|
+
import reactHooks from "eslint-plugin-react-hooks";
|
|
4
|
+
import reactRefresh from "eslint-plugin-react-refresh";
|
|
5
|
+
import tseslint from "typescript-eslint";
|
|
6
|
+
import { defineConfig, globalIgnores } from "eslint/config";
|
|
7
|
+
|
|
8
|
+
export default defineConfig([
|
|
9
|
+
globalIgnores(["dist"]),
|
|
10
|
+
{
|
|
11
|
+
files: ["**/*.{ts,tsx}"],
|
|
12
|
+
plugins: {
|
|
13
|
+
"@typescript-eslint": tseslint.plugin,
|
|
14
|
+
},
|
|
15
|
+
extends: [
|
|
16
|
+
js.configs.recommended,
|
|
17
|
+
tseslint.configs.recommended,
|
|
18
|
+
reactHooks.configs.flat.recommended,
|
|
19
|
+
reactRefresh.configs.vite,
|
|
20
|
+
],
|
|
21
|
+
languageOptions: {
|
|
22
|
+
ecmaVersion: 2020,
|
|
23
|
+
globals: globals.browser,
|
|
24
|
+
},
|
|
25
|
+
rules: {
|
|
26
|
+
"@typescript-eslint/explicit-function-return-type": [
|
|
27
|
+
"error",
|
|
28
|
+
{
|
|
29
|
+
allowExpressions: false,
|
|
30
|
+
allowTypedFunctionExpressions: false,
|
|
31
|
+
allowHigherOrderFunctions: false,
|
|
32
|
+
allowDirectConstAssertionInArrowFunctions: false,
|
|
33
|
+
allowConciseArrowFunctionExpressionsStartingWithVoid: false,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
"@typescript-eslint/no-unused-vars": "error",
|
|
37
|
+
"@typescript-eslint/no-explicit-any": "error",
|
|
38
|
+
"@typescript-eslint/no-non-null-assertion": "error",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
]);
|
package/index.html
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>my-vite-app</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="root"></div>
|
|
11
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "gw-my-vite-app",
|
|
3
|
+
"private": false,
|
|
4
|
+
"version": "0.0.5",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "tsc -b && vite build",
|
|
9
|
+
"lint": "eslint .",
|
|
10
|
+
"preview": "vite preview"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"react": "^19.2.0",
|
|
14
|
+
"react-dom": "^19.2.0",
|
|
15
|
+
"sass": "^1.97.3"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@eslint/js": "^9.39.1",
|
|
19
|
+
"@types/node": "^24.10.1",
|
|
20
|
+
"@types/react": "^19.2.5",
|
|
21
|
+
"@types/react-dom": "^19.2.3",
|
|
22
|
+
"@typescript-eslint/eslint-plugin": "^8.54.0",
|
|
23
|
+
"@typescript-eslint/parser": "^8.54.0",
|
|
24
|
+
"@vitejs/plugin-react": "^5.1.1",
|
|
25
|
+
"eslint": "^9.39.2",
|
|
26
|
+
"eslint-plugin-react": "^7.37.5",
|
|
27
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
28
|
+
"eslint-plugin-react-refresh": "^0.4.24",
|
|
29
|
+
"globals": "^16.5.0",
|
|
30
|
+
"typescript": "~5.9.3",
|
|
31
|
+
"typescript-eslint": "^8.46.4",
|
|
32
|
+
"vite": "^7.2.4"
|
|
33
|
+
}
|
|
34
|
+
}
|
package/src/App.css
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#root {
|
|
2
|
+
max-width: 1280px;
|
|
3
|
+
margin: 0 auto;
|
|
4
|
+
padding: 2rem;
|
|
5
|
+
text-align: center;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.logo {
|
|
9
|
+
height: 6em;
|
|
10
|
+
padding: 1.5em;
|
|
11
|
+
will-change: filter;
|
|
12
|
+
transition: filter 300ms;
|
|
13
|
+
}
|
|
14
|
+
.logo:hover {
|
|
15
|
+
filter: drop-shadow(0 0 2em #646cffaa);
|
|
16
|
+
}
|
|
17
|
+
.logo.react:hover {
|
|
18
|
+
filter: drop-shadow(0 0 2em #61dafbaa);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@keyframes logo-spin {
|
|
22
|
+
from {
|
|
23
|
+
transform: rotate(0deg);
|
|
24
|
+
}
|
|
25
|
+
to {
|
|
26
|
+
transform: rotate(360deg);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
31
|
+
a:nth-of-type(2) .logo {
|
|
32
|
+
animation: logo-spin infinite 20s linear;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.card {
|
|
37
|
+
padding: 2em;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.read-the-docs {
|
|
41
|
+
color: #888;
|
|
42
|
+
}
|
package/src/App.tsx
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import "./App.css";
|
|
4
|
+
import Header from "./components/Header";
|
|
5
|
+
import "./styles/main.scss";
|
|
6
|
+
|
|
7
|
+
function App(): React.ReactNode {
|
|
8
|
+
const [count, setCount] = useState(0);
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<>
|
|
12
|
+
<Header />
|
|
13
|
+
<div className="card">
|
|
14
|
+
<button onClick={(): void => setCount((count): number => count + 1)}>
|
|
15
|
+
count is {count}
|
|
16
|
+
</button>
|
|
17
|
+
</div>
|
|
18
|
+
</>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default App;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// import React from "react";
|
|
2
|
+
|
|
3
|
+
// // 1. TS: unused variable
|
|
4
|
+
// const unusedVar = 42;
|
|
5
|
+
|
|
6
|
+
// // 2. TS: implicit `any` (no type annotation)
|
|
7
|
+
// function badFunction(param) {
|
|
8
|
+
// return param + 1;
|
|
9
|
+
// }
|
|
10
|
+
|
|
11
|
+
// // 3. TS: no explicit return type
|
|
12
|
+
// // function missingReturnType(value: string) {
|
|
13
|
+
// function missingReturnType(value: string): number {
|
|
14
|
+
// return value.length;
|
|
15
|
+
// }
|
|
16
|
+
|
|
17
|
+
// // 4. TS: no explicit `void` for functions that don’t return
|
|
18
|
+
// function logMessage(message): void {
|
|
19
|
+
// console.log(message);
|
|
20
|
+
// }
|
|
21
|
+
|
|
22
|
+
// // 5. TS: unused parameter
|
|
23
|
+
// function handleEvent(e: React.MouseEvent) {
|
|
24
|
+
// // e is not used
|
|
25
|
+
// console.log(e);
|
|
26
|
+
// }
|
|
27
|
+
|
|
28
|
+
// // 6. TS: non‑nullable assertion (`!`) on possibly undefined
|
|
29
|
+
// interface User {
|
|
30
|
+
// name: string;
|
|
31
|
+
// }
|
|
32
|
+
// const user: User | null = null;
|
|
33
|
+
// const userName = user!.name;
|
|
34
|
+
|
|
35
|
+
// // 7. TS: `any` usage
|
|
36
|
+
// const data: any = fetch("/api");
|
|
37
|
+
|
|
38
|
+
// // 8. TS: missing `@typescript-eslint/explicit-member-accessibility`
|
|
39
|
+
// class BadClass {
|
|
40
|
+
// field = "oops"; // implicit public
|
|
41
|
+
// }
|
|
42
|
+
|
|
43
|
+
// // 9. TS: no explicit `unknown` / `never` handling
|
|
44
|
+
// function riskyCast(value: unknown) {
|
|
45
|
+
// return value as string; // unsafe cast
|
|
46
|
+
// }
|
|
47
|
+
|
|
48
|
+
// // 10. TS: missing `@typescript-eslint/no‑implicit‑any` / implicit `any[]`
|
|
49
|
+
// const numbers = []; // inferred as `any[]`
|
|
50
|
+
// numbers.push("not a number");
|
|
51
|
+
|
|
52
|
+
// // 11. React: missing `key` on list
|
|
53
|
+
// function BadList({ items }: { items: string[] }) {
|
|
54
|
+
// return (
|
|
55
|
+
// <ul>
|
|
56
|
+
// {items.map((item) => (
|
|
57
|
+
// <li>{item}</li> // no `key`
|
|
58
|
+
// ))}
|
|
59
|
+
// </ul>
|
|
60
|
+
// );
|
|
61
|
+
// }
|
|
62
|
+
|
|
63
|
+
// // 12. React: unnecessary `div` wrapper (unnecessary wrapper)
|
|
64
|
+
// function ExtraWrapper() {
|
|
65
|
+
// return (
|
|
66
|
+
// <div>
|
|
67
|
+
// <p>Hello</p>
|
|
68
|
+
// </div>
|
|
69
|
+
// );
|
|
70
|
+
// }
|
|
71
|
+
|
|
72
|
+
// // 13. React: missing `alt` on `img`
|
|
73
|
+
// function MissingAlt() {
|
|
74
|
+
// return <img src="/logo.png" />; // no `alt`
|
|
75
|
+
// }
|
|
76
|
+
|
|
77
|
+
// // 14. React: inline style as string (invalid style prop)
|
|
78
|
+
// function InlineStyleString() {
|
|
79
|
+
// return <div style="color: red">Bad style</div>;
|
|
80
|
+
// }
|
|
81
|
+
|
|
82
|
+
// // 15. React: no `onClick` handler on interactive element
|
|
83
|
+
// function NoHandler() {
|
|
84
|
+
// return <button>Click me</button>; // no `onClick`
|
|
85
|
+
// }
|
|
86
|
+
|
|
87
|
+
// // 16. React: missing dependency in `useEffect`
|
|
88
|
+
// import { useState, useEffect } from "react";
|
|
89
|
+
// function MissingDeps() {
|
|
90
|
+
// const [count, setCount] = useState(0);
|
|
91
|
+
// const [name] = useState("Alice");
|
|
92
|
+
|
|
93
|
+
// useEffect(() => {
|
|
94
|
+
// setCount(count + 1);
|
|
95
|
+
// // missing `name` in deps
|
|
96
|
+
// }, []);
|
|
97
|
+
|
|
98
|
+
// return <div>{count}</div>;
|
|
99
|
+
// }
|
|
100
|
+
|
|
101
|
+
// // 17. React: direct mutation of props
|
|
102
|
+
// function MutateProps({ items }: { items: string[] }) {
|
|
103
|
+
// items.push("new item"); // mutating props
|
|
104
|
+
// return <div>{items.join(", ")}</div>;
|
|
105
|
+
// }
|
|
106
|
+
|
|
107
|
+
// // 18. React: no explicit `React.FC` / props typing (if rule is on)
|
|
108
|
+
// function UntypedProps(props) {
|
|
109
|
+
// return <div>{props.message}</div>;
|
|
110
|
+
// }
|
|
111
|
+
|
|
112
|
+
// // 19. React: `defaultProps` with TypeScript (deprecated pattern)
|
|
113
|
+
// const ComponentWithDefaults = (props: { name?: string }) => {
|
|
114
|
+
// return <div>Hello {props.name}</div>;
|
|
115
|
+
// };
|
|
116
|
+
// ComponentWithDefaults.defaultProps = {
|
|
117
|
+
// name: "World",
|
|
118
|
+
// };
|
|
119
|
+
|
|
120
|
+
// // 20. React: invalid `key` type (using index as key)
|
|
121
|
+
// function BadKey({ items }: { items: string[] }) {
|
|
122
|
+
// return (
|
|
123
|
+
// <ul>
|
|
124
|
+
// {items.map((item, index) => (
|
|
125
|
+
// <li key={index}>{item}</li> // index as key
|
|
126
|
+
// ))}
|
|
127
|
+
// </ul>
|
|
128
|
+
// );
|
|
129
|
+
// }
|
|
130
|
+
|
|
131
|
+
// console.log(
|
|
132
|
+
// unusedVar,
|
|
133
|
+
// missingReturnType,
|
|
134
|
+
// badFunction,
|
|
135
|
+
// logMessage,
|
|
136
|
+
// handleEvent,
|
|
137
|
+
// userName,
|
|
138
|
+
// data,
|
|
139
|
+
// riskyCast,
|
|
140
|
+
// BadList,
|
|
141
|
+
// ExtraWrapper,
|
|
142
|
+
// MissingAlt,
|
|
143
|
+
// InlineStyleString,
|
|
144
|
+
// NoHandler,
|
|
145
|
+
// MissingDeps,
|
|
146
|
+
// MutateProps,
|
|
147
|
+
// UntypedProps,
|
|
148
|
+
// BadKey
|
|
149
|
+
// );
|
package/src/index.css
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
3
|
+
line-height: 1.5;
|
|
4
|
+
font-weight: 400;
|
|
5
|
+
|
|
6
|
+
color-scheme: light dark;
|
|
7
|
+
color: rgba(255, 255, 255, 0.87);
|
|
8
|
+
background-color: #242424;
|
|
9
|
+
|
|
10
|
+
font-synthesis: none;
|
|
11
|
+
text-rendering: optimizeLegibility;
|
|
12
|
+
-webkit-font-smoothing: antialiased;
|
|
13
|
+
-moz-osx-font-smoothing: grayscale;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
a {
|
|
17
|
+
font-weight: 500;
|
|
18
|
+
color: #646cff;
|
|
19
|
+
text-decoration: inherit;
|
|
20
|
+
}
|
|
21
|
+
a:hover {
|
|
22
|
+
color: #535bf2;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
body {
|
|
26
|
+
margin: 0;
|
|
27
|
+
display: flex;
|
|
28
|
+
place-items: center;
|
|
29
|
+
min-width: 320px;
|
|
30
|
+
min-height: 100vh;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
h1 {
|
|
34
|
+
font-size: 3.2em;
|
|
35
|
+
line-height: 1.1;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
button {
|
|
39
|
+
border-radius: 8px;
|
|
40
|
+
border: 1px solid transparent;
|
|
41
|
+
padding: 0.6em 1.2em;
|
|
42
|
+
font-size: 1em;
|
|
43
|
+
font-weight: 500;
|
|
44
|
+
font-family: inherit;
|
|
45
|
+
background-color: #1a1a1a;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
transition: border-color 0.25s;
|
|
48
|
+
}
|
|
49
|
+
button:hover {
|
|
50
|
+
border-color: #646cff;
|
|
51
|
+
}
|
|
52
|
+
button:focus,
|
|
53
|
+
button:focus-visible {
|
|
54
|
+
outline: 4px auto -webkit-focus-ring-color;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@media (prefers-color-scheme: light) {
|
|
58
|
+
:root {
|
|
59
|
+
color: #213547;
|
|
60
|
+
background-color: #ffffff;
|
|
61
|
+
}
|
|
62
|
+
a:hover {
|
|
63
|
+
color: #747bff;
|
|
64
|
+
}
|
|
65
|
+
button {
|
|
66
|
+
background-color: #f9f9f9;
|
|
67
|
+
}
|
|
68
|
+
}
|
package/src/main.tsx
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { StrictMode } from "react";
|
|
2
|
+
import { createRoot } from "react-dom/client";
|
|
3
|
+
import "./index.css";
|
|
4
|
+
import App from "./App.tsx";
|
|
5
|
+
|
|
6
|
+
const rootElement = document.getElementById("root");
|
|
7
|
+
if (rootElement) {
|
|
8
|
+
createRoot(rootElement).render(
|
|
9
|
+
<StrictMode>
|
|
10
|
+
<App />
|
|
11
|
+
</StrictMode>
|
|
12
|
+
);
|
|
13
|
+
} else {
|
|
14
|
+
console.error("Root element not found");
|
|
15
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
4
|
+
"target": "ES2022",
|
|
5
|
+
"useDefineForClassFields": true,
|
|
6
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
7
|
+
"module": "ESNext",
|
|
8
|
+
"types": ["vite/client"],
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
|
|
11
|
+
/* Bundler mode */
|
|
12
|
+
"moduleResolution": "bundler",
|
|
13
|
+
"allowImportingTsExtensions": true,
|
|
14
|
+
"verbatimModuleSyntax": true,
|
|
15
|
+
"moduleDetection": "force",
|
|
16
|
+
"noEmit": true,
|
|
17
|
+
"jsx": "react-jsx",
|
|
18
|
+
|
|
19
|
+
/* Linting */
|
|
20
|
+
"strict": true,
|
|
21
|
+
"noUnusedLocals": true,
|
|
22
|
+
"noUnusedParameters": true,
|
|
23
|
+
"erasableSyntaxOnly": true,
|
|
24
|
+
"noFallthroughCasesInSwitch": true,
|
|
25
|
+
"noUncheckedSideEffectImports": true
|
|
26
|
+
},
|
|
27
|
+
"include": ["src"]
|
|
28
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
|
4
|
+
"target": "ES2023",
|
|
5
|
+
"lib": ["ES2023"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"types": ["node"],
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
|
|
10
|
+
/* Bundler mode */
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"allowImportingTsExtensions": true,
|
|
13
|
+
"verbatimModuleSyntax": true,
|
|
14
|
+
"moduleDetection": "force",
|
|
15
|
+
"noEmit": true,
|
|
16
|
+
|
|
17
|
+
/* Linting */
|
|
18
|
+
"strict": true,
|
|
19
|
+
"noUnusedLocals": true,
|
|
20
|
+
"noUnusedParameters": true,
|
|
21
|
+
"erasableSyntaxOnly": true,
|
|
22
|
+
"noFallthroughCasesInSwitch": true,
|
|
23
|
+
"noUncheckedSideEffectImports": true
|
|
24
|
+
},
|
|
25
|
+
"include": ["vite.config.ts"]
|
|
26
|
+
}
|