diff --git a/.gitignore b/.gitignore index a547bf3..baba7a6 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ dist-ssr *.njsproj *.sln *.sw? + +*.tsbuildinfo \ No newline at end of file diff --git a/README.md b/README.md index 74872fd..7b48f60 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,3 @@ -# React + TypeScript + Vite +# cubeviz -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. - -Currently, two official plugins are available: - -- [@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 -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh - -## Expanding the ESLint configuration - -If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: - -- Configure the top-level `parserOptions` property like this: - -```js -export default tseslint.config({ - languageOptions: { - // other options... - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - }, -}) -``` - -- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` -- Optionally add `...tseslint.configs.stylisticTypeChecked` -- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: - -```js -// eslint.config.js -import react from 'eslint-plugin-react' - -export default tseslint.config({ - // Set the react version - settings: { react: { version: '18.3' } }, - plugins: { - // Add the react plugin - react, - }, - rules: { - // other rules... - // Enable its recommended rules - ...react.configs.recommended.rules, - ...react.configs['jsx-runtime'].rules, - }, -}) -``` +Cubical type theory visualizer. \ No newline at end of file diff --git a/bun.lockb b/bun.lockb index 5d46ce1..ea578d9 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 88a626c..919e5d2 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@react-three/drei": "^9.114.0", "@react-three/fiber": "^8.17.8", "@types/three": "^0.169.0", + "jotai": "^2.10.0", "meshline": "^3.3.1", "react": "^18.3.1", "react-dom": "^18.3.1", diff --git a/src/App.css b/src/App.css deleted file mode 100644 index b9d355d..0000000 --- a/src/App.css +++ /dev/null @@ -1,42 +0,0 @@ -#root { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; -} - -.logo { - height: 6em; - padding: 1.5em; - will-change: filter; - transition: filter 300ms; -} -.logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); -} -.logo.react:hover { - filter: drop-shadow(0 0 2em #61dafbaa); -} - -@keyframes logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} - -@media (prefers-reduced-motion: no-preference) { - a:nth-of-type(2) .logo { - animation: logo-spin infinite 20s linear; - } -} - -.card { - padding: 2em; -} - -.read-the-docs { - color: #888; -} diff --git a/src/App.tsx b/src/App.tsx index 497920e..1ee5347 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,63 +1,15 @@ -import { ReactNode, useCallback, useRef, useState } from "react"; -import { Canvas, extend, useFrame } from "@react-three/fiber"; -import { OrbitControls, OrthographicCamera } from "@react-three/drei"; -import { BoxGeometry, EdgesGeometry, LineBasicMaterial } from "three"; -import { InlineMath, BlockMath } from "react-katex"; -import { createPortal } from "react-dom"; +import { Canvas } from "@react-three/fiber"; +import { OrbitControls } from "@react-three/drei"; -import "./App.css"; import styles from "./styles.module.scss"; import "katex/dist/katex.min.css"; import Point from "./components/Point"; import Path from "./components/Path"; +import { SettingsBox } from "./SettingsContext"; // https://threejs.org/manual/#en/align-html-elements-to-3d -function createBox({ dimensions, ...props }) { - // This reference gives us direct access to the THREE.Mesh object - const ref = useRef(); - // Hold state for hovered and clicked events - const [hovered, hover] = useState(false); - const [clicked, click] = useState(false); - - const box = new BoxGeometry(1, 1, 1); - const edges = new EdgesGeometry(box); - - const label = ( -
- helloge {JSON.stringify(clicked)} - -
- ); - - // Return the view, these are regular Threejs elements expressed in JSX - const view = ( - click(!clicked)} - onPointerOver={(event) => hover(true)} - onPointerOut={(event) => hover(false)} - > - {/* */} - {/* */} - - - - ); - - return [view, label]; -} - function App() { - const [labelContainerEl, setLabelContainerEl] = - useState(null); - const labelContainerRef = useCallback((el) => { - if (el) setLabelContainerEl(el); - }, []); - let coords: [number, number, number][] = [ [0, 0, 0], [0, 0, 1], @@ -84,7 +36,8 @@ function App() { ); return ( - <> +
+ @@ -105,7 +58,16 @@ function App() { ))} - +
+ + Source + +
+
); } diff --git a/src/SettingsContext.tsx b/src/SettingsContext.tsx new file mode 100644 index 0000000..630f8db --- /dev/null +++ b/src/SettingsContext.tsx @@ -0,0 +1,20 @@ +import { atom, useAtom } from "jotai"; +import styles from "./styles.module.scss"; + +export const showEmptyAtom = atom(true); + +export function SettingsBox() { + const [showEmpty, setShowEmpty] = useAtom(showEmptyAtom); + + return ( +
+ setShowEmpty((v) => !v)} + /> + +
+ ); +} diff --git a/src/components/EditBox.tsx b/src/components/EditBox.tsx index ea5a7ff..9d35d4d 100644 --- a/src/components/EditBox.tsx +++ b/src/components/EditBox.tsx @@ -1,20 +1,23 @@ -import { useCallback, useState } from "react"; -import { InlineMath } from "react-katex"; +import { type FormEvent, useCallback, useState } from "react"; +import { BlockMath } from "react-katex"; import styles from "./EditBox.module.scss"; +import { showEmptyAtom } from "../SettingsContext"; +import { useAtomValue } from "jotai"; -export interface EditBoxProps {} +// export interface EditBoxProps {} -export default function EditBox({}: EditBoxProps) { +export default function EditBox() { const [value, setValue] = useState(""); const [isEditing, setIsEditing] = useState(false); + const showEmpty = useAtomValue(showEmptyAtom); const handleDblClick = useCallback(() => { if (!isEditing) setIsEditing(true); }, [isEditing]); const done = useCallback( - (evt) => { + (evt: FormEvent) => { evt.preventDefault(); if (isEditing) setIsEditing(false); }, @@ -26,15 +29,18 @@ export default function EditBox({}: EditBoxProps) { {isEditing ? (
autoFocus={true} + onBlur={done} value={value} onChange={(evt) => setValue(evt.target.value)} + placeholder="Type latex code..." />
) : value === "" ? ( - (empty) + {showEmpty ? <>(empty) : ""} ) : ( - + )} ); diff --git a/src/components/Path.tsx b/src/components/Path.tsx index 4af3a4c..1ccbb2a 100644 --- a/src/components/Path.tsx +++ b/src/components/Path.tsx @@ -1,6 +1,6 @@ -import { extend, useFrame } from "@react-three/fiber"; +import { extend } from "@react-three/fiber"; import { Html, Line } from "@react-three/drei"; -import { MeshLineGeometry, MeshLineMaterial, raycast } from "meshline"; +import { MeshLineGeometry, MeshLineMaterial } from "meshline"; import EditBox from "./EditBox"; extend({ MeshLineGeometry, MeshLineMaterial }); diff --git a/src/styles.module.scss b/src/styles.module.scss index 75d6a64..60505d7 100644 --- a/src/styles.module.scss +++ b/src/styles.module.scss @@ -1,11 +1,28 @@ -.canvas { +.container { + display: grid; + position: relative; width: 100%; height: 100%; } -.labels { - position: absolute; - left: 0; - top: 0; +.canvas { + grid-area: 1 / 1; + position: relative; + width: 100%; + height: 100%; +} + +.header { + grid-area: 1 / 1; + place-self: start center; + z-index: 50; + padding: 10px; +} + +.footer { + grid-area: 1 / 1; + place-self: end end; + z-index: 50; + padding: 10px; } \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts index 5a33944..14a49d6 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,7 +1,8 @@ -import { defineConfig } from 'vite' -import react from '@vitejs/plugin-react' +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; // https://vitejs.dev/config/ export default defineConfig({ + base: "/cubeviz", plugins: [react()], -}) +});