Skip to content

Commit b468b43

Browse files
docs: add demo app
1 parent e1267e6 commit b468b43

15 files changed

+1961
-22
lines changed

.changeset/config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"access": "public",
88
"baseBranch": "main",
99
"updateInternalDependencies": "patch",
10-
"ignore": [],
10+
"ignore": ["demo"],
1111
"privatePackages": false,
1212
"bumpVersionsWithWorkspaceProtocolOnly": true
1313
}

apps/demo/.eslintrc.cjs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module.exports = {
2+
root: true,
3+
env: { browser: true, es2020: true },
4+
extends: [
5+
'eslint:recommended',
6+
'plugin:@typescript-eslint/recommended',
7+
'plugin:react-hooks/recommended',
8+
],
9+
ignorePatterns: ['dist', '.eslintrc.cjs'],
10+
parser: '@typescript-eslint/parser',
11+
plugins: ['react-refresh'],
12+
rules: {
13+
'react-refresh/only-export-components': [
14+
'warn',
15+
{ allowConstantExport: true },
16+
],
17+
},
18+
}

apps/demo/.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?

apps/demo/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8+
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9+
10+
## Expanding the ESLint configuration
11+
12+
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
13+
14+
- Configure the top-level `parserOptions` property like this:
15+
16+
```js
17+
export default {
18+
// other rules...
19+
parserOptions: {
20+
ecmaVersion: 'latest',
21+
sourceType: 'module',
22+
project: ['./tsconfig.json', './tsconfig.node.json'],
23+
tsconfigRootDir: __dirname,
24+
},
25+
}
26+
```
27+
28+
- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
29+
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
30+
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list

apps/demo/index.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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>Vite + React + TS</title>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/main.tsx"></script>
12+
</body>
13+
</html>

apps/demo/package.json

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "demo",
3+
"private": true,
4+
"version": "0.0.0",
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite --port=3000",
8+
"build": "tsc && vite build",
9+
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
10+
"preview": "vite preview"
11+
},
12+
"dependencies": {
13+
"@codemirror/lang-javascript": "^6.2.2",
14+
"@emotion/react": "^11.11.4",
15+
"@emotion/styled": "^11.11.5",
16+
"@fontsource/inter": "^5.0.18",
17+
"@mui/icons-material": "^5.15.15",
18+
"@mui/joy": "5.0.0-beta.36",
19+
"@opentf/obj-diff": "^0.1.2",
20+
"@opentf/std": "^0.10.0",
21+
"@uiw/react-codemirror": "^4.21.25",
22+
"prettier": "^3.2.5",
23+
"react": "^18.2.0",
24+
"react-dom": "^18.2.0"
25+
},
26+
"devDependencies": {
27+
"@types/react": "^18.2.66",
28+
"@types/react-dom": "^18.2.22",
29+
"@typescript-eslint/eslint-plugin": "^7.2.0",
30+
"@typescript-eslint/parser": "^7.2.0",
31+
"@vitejs/plugin-react-swc": "^3.5.0",
32+
"eslint": "^8.57.0",
33+
"eslint-plugin-react-hooks": "^4.6.0",
34+
"eslint-plugin-react-refresh": "^0.4.6",
35+
"typescript": "^5.2.2",
36+
"vite": "^5.2.0"
37+
}
38+
}

apps/demo/public/Logo.svg

Lines changed: 19 additions & 0 deletions
Loading

apps/demo/src/App.tsx

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
import { Alert, Box, Link, Sheet, TabPanel, Typography } from "@mui/joy";
2+
import CodeMirror from "@uiw/react-codemirror";
3+
import { javascript } from "@codemirror/lang-javascript";
4+
import { useCallback, useEffect, useState } from "react";
5+
import { diff } from "@opentf/obj-diff";
6+
import Tabs from "@mui/joy/Tabs";
7+
import TabList from "@mui/joy/TabList";
8+
import Tab from "@mui/joy/Tab";
9+
import Launch from "@mui/icons-material/Launch";
10+
import prettier from "prettier/standalone";
11+
import * as babelPlugin from "prettier/parser-babel";
12+
import * as estreeParser from "prettier/plugins/estree";
13+
14+
async function format(code) {
15+
const formatted = await prettier.format(`const a = ${code}`, {
16+
parser: "babel",
17+
plugins: [babelPlugin, estreeParser],
18+
semi: false,
19+
trailingComma: "none",
20+
});
21+
22+
return formatted.replace("const a = ", "");
23+
}
24+
25+
function App() {
26+
const [obj1Val, setObj1Val] = useState(`{
27+
a: 1, b: 2
28+
}`);
29+
const [obj2Val, setObj2Val] = useState(`{
30+
a: 2, c: 5
31+
}`);
32+
const [raw, setRaw] = useState([]);
33+
34+
useEffect(() => {
35+
async function runFormat() {
36+
setObj1Val(await format(obj1Val));
37+
setObj2Val(await format(obj2Val));
38+
}
39+
40+
runFormat();
41+
}, []);
42+
43+
const onChange1 = useCallback((val: string) => {
44+
setObj1Val(val);
45+
}, []);
46+
47+
const onChange2 = useCallback((val: string) => {
48+
setObj2Val(val);
49+
}, []);
50+
51+
useEffect(() => {
52+
try {
53+
const a = eval(`const a = ${obj1Val}; a`);
54+
const b = eval(`const a = ${obj2Val}; a`);
55+
setRaw(diff(a, b));
56+
} catch (error) {
57+
console.log("error");
58+
}
59+
}, [obj1Val, obj2Val]);
60+
61+
return (
62+
<Box sx={{}}>
63+
<Box
64+
sx={{
65+
borderBottom: "1px solid grey",
66+
p: 1,
67+
px: 3,
68+
display: "flex",
69+
justifyContent: "space-between",
70+
}}
71+
>
72+
<Box sx={{ display: "flex" }}>
73+
<img src="/Logo.svg" alt="Logo" height="35" />
74+
<Typography level="h4" sx={{ ml: 2, letterSpacing: "2px" }}>
75+
obj-diff
76+
</Typography>
77+
</Box>
78+
<Link
79+
href="https://github.com/Open-Tech-Foundation/obj-diff"
80+
endDecorator={<Launch fontSize="inherit" />}
81+
target="_blank"
82+
rel="noopener"
83+
fontSize="sm"
84+
>
85+
Github
86+
</Link>
87+
</Box>
88+
<Box sx={{ display: "flex", justifyContent: "center", mt: 2 }}>
89+
<Alert variant="soft" color="success">
90+
<Typography level="body-md">
91+
🚀 The Fast, Accurate, JavaScript Objects Diffing Library.
92+
</Typography>
93+
</Alert>
94+
</Box>
95+
<Box
96+
sx={{
97+
display: "grid",
98+
gridTemplateColumns: "1fr 10px 1fr 10px 1fr",
99+
p: "50px",
100+
height: "600px",
101+
boxSizing: "border-box",
102+
}}
103+
>
104+
<Box sx={{ height: "100%", overflow: "hidden" }}>
105+
<Sheet
106+
variant="outlined"
107+
sx={{
108+
height: "100%",
109+
overflow: "hidden",
110+
display: "flex",
111+
flexDirection: "column",
112+
boxSizing: "border-box",
113+
}}
114+
>
115+
<Typography level="body-sm" sx={{ textAlign: "center" }}>
116+
Object 1
117+
</Typography>
118+
<Box sx={{ height: "calc(100% - 25px)", overflow: "auto" }}>
119+
<CodeMirror
120+
value={obj1Val}
121+
extensions={[javascript()]}
122+
onChange={onChange1}
123+
height="100%"
124+
/>
125+
</Box>
126+
</Sheet>
127+
</Box>
128+
<Box />
129+
<Box sx={{ height: "100%", overflow: "hidden" }}>
130+
<Sheet
131+
variant="outlined"
132+
sx={{
133+
height: "100%",
134+
overflow: "hidden",
135+
display: "flex",
136+
flexDirection: "column",
137+
boxSizing: "border-box",
138+
}}
139+
>
140+
<Typography level="body-sm" sx={{ textAlign: "center" }}>
141+
Object 2
142+
</Typography>
143+
<Box sx={{ height: "calc(100% - 25px)", overflow: "auto" }}>
144+
<CodeMirror
145+
value={obj2Val}
146+
extensions={[javascript()]}
147+
onChange={onChange2}
148+
/>
149+
</Box>
150+
</Sheet>
151+
</Box>
152+
<Box />
153+
<Box sx={{ height: "100%", overflow: "hidden" }}>
154+
<Sheet
155+
variant="outlined"
156+
sx={{ height: "100%", boxSizing: "border-box" }}
157+
>
158+
<Tabs
159+
aria-label="Basic tabs"
160+
defaultValue={0}
161+
sx={{ height: "100%" }}
162+
>
163+
<TabList sx={{ display: "flex", justifyContent: "center" }}>
164+
<Tab>Visualize</Tab>
165+
<Tab>Raw</Tab>
166+
</TabList>
167+
<TabPanel
168+
value={0}
169+
sx={{ height: "calc(100% - 35px)", overflow: "auto" }}
170+
></TabPanel>
171+
<TabPanel
172+
value={1}
173+
sx={{ height: "calc(100% - 35px)", overflow: "auto" }}
174+
>
175+
<Box component="pre">{JSON.stringify(raw, null, 4)}</Box>
176+
</TabPanel>
177+
</Tabs>
178+
</Sheet>
179+
</Box>
180+
</Box>
181+
182+
<Box sx={{ display: "flex", justifyContent: "center", mt: 2 }}>
183+
<Box sx={{ mr: 1 }} component="span">
184+
{" "}
185+
© 2024
186+
</Box>
187+
<Link href="https://open-tech-foundation.pages.dev/">
188+
Open Tech Foundation
189+
</Link>
190+
.
191+
</Box>
192+
</Box>
193+
);
194+
}
195+
196+
export default App;

apps/demo/src/index.css

Whitespace-only changes.

apps/demo/src/main.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from "react";
2+
import ReactDOM from "react-dom/client";
3+
import { CssVarsProvider } from "@mui/joy/styles";
4+
import CssBaseline from "@mui/joy/CssBaseline";
5+
import App from "./App.tsx";
6+
import "@fontsource/inter";
7+
import "./index.css";
8+
9+
ReactDOM.createRoot(document.getElementById("root")!).render(
10+
<React.StrictMode>
11+
<CssVarsProvider defaultMode="light">
12+
{/* must be used under CssVarsProvider */}
13+
<CssBaseline />
14+
15+
{/* The rest of your application */}
16+
<App />
17+
</CssVarsProvider>
18+
</React.StrictMode>
19+
);

apps/demo/src/vite-env.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/// <reference types="vite/client" />

0 commit comments

Comments
 (0)