Initial commit
This commit is contained in:
		
							
								
								
									
										27
									
								
								.eslintrc.cjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								.eslintrc.cjs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
/* eslint-env node */
 | 
			
		||||
 | 
			
		||||
module.exports = {
 | 
			
		||||
  root: true,
 | 
			
		||||
  env: { browser: true, es2020: true },
 | 
			
		||||
  extends: [
 | 
			
		||||
    'eslint:recommended',
 | 
			
		||||
    'plugin:@typescript-eslint/recommended',
 | 
			
		||||
    'plugin:@typescript-eslint/recommended-requiring-type-checking',
 | 
			
		||||
    'plugin:react-hooks/recommended',
 | 
			
		||||
  ],
 | 
			
		||||
  parser: '@typescript-eslint/parser',
 | 
			
		||||
  parserOptions: {
 | 
			
		||||
    ecmaVersion: 'latest',
 | 
			
		||||
    sourceType: 'module',
 | 
			
		||||
    project: true,
 | 
			
		||||
    tsconfigRootDir: __dirname,
 | 
			
		||||
  },
 | 
			
		||||
  plugins: ['react-refresh'],
 | 
			
		||||
  rules: {
 | 
			
		||||
    'react-refresh/only-export-components': [
 | 
			
		||||
      'warn',
 | 
			
		||||
      { allowConstantExport: true },
 | 
			
		||||
    ],
 | 
			
		||||
    '@typescript-eslint/no-non-null-assertion': 'off',
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										24
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
# Logs
 | 
			
		||||
logs
 | 
			
		||||
*.log
 | 
			
		||||
npm-debug.log*
 | 
			
		||||
yarn-debug.log*
 | 
			
		||||
yarn-error.log*
 | 
			
		||||
pnpm-debug.log*
 | 
			
		||||
lerna-debug.log*
 | 
			
		||||
 | 
			
		||||
node_modules
 | 
			
		||||
dist
 | 
			
		||||
dist-ssr
 | 
			
		||||
*.local
 | 
			
		||||
 | 
			
		||||
# Editor directories and files
 | 
			
		||||
.vscode/*
 | 
			
		||||
!.vscode/extensions.json
 | 
			
		||||
.idea
 | 
			
		||||
.DS_Store
 | 
			
		||||
*.suo
 | 
			
		||||
*.ntvs*
 | 
			
		||||
*.njsproj
 | 
			
		||||
*.sln
 | 
			
		||||
*.sw?
 | 
			
		||||
							
								
								
									
										7
									
								
								.prettierignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								.prettierignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
**/.git
 | 
			
		||||
**/.svn
 | 
			
		||||
**/.hg
 | 
			
		||||
**/node_modules
 | 
			
		||||
/public
 | 
			
		||||
/dist
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								.prettierrc.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								.prettierrc.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
/** @type {import("prettier").Options} */
 | 
			
		||||
const config = {
 | 
			
		||||
  trailingComma: 'es5',
 | 
			
		||||
  tabWidth: 2,
 | 
			
		||||
  semi: true,
 | 
			
		||||
  singleQuote: true,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default config;
 | 
			
		||||
							
								
								
									
										13
									
								
								index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
<!doctype html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="UTF-8" />
 | 
			
		||||
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 | 
			
		||||
    <title>Excalidraw with WebRTC</title>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div id="root"></div>
 | 
			
		||||
    <script type="module" src="/src/main.tsx"></script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										37
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "excalidraw-p2p",
 | 
			
		||||
  "private": true,
 | 
			
		||||
  "version": "0.0.0",
 | 
			
		||||
  "type": "module",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "dev": "vite",
 | 
			
		||||
    "build": "tsc && vite build",
 | 
			
		||||
    "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
 | 
			
		||||
    "fmt": "prettier --write \"**/*.{ts,tsx,js,cjs,json,html,css}\"",
 | 
			
		||||
    "preview": "vite preview"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@emotion/react": "^11.11.1",
 | 
			
		||||
    "@emotion/styled": "^11.11.0",
 | 
			
		||||
    "@excalidraw/excalidraw": "^0.15.2",
 | 
			
		||||
    "@fontsource/roboto": "^5.0.5",
 | 
			
		||||
    "@mui/icons-material": "^5.14.1",
 | 
			
		||||
    "@mui/material": "^5.14.1",
 | 
			
		||||
    "jotai": "^2.2.2",
 | 
			
		||||
    "react": "^18.2.0",
 | 
			
		||||
    "react-dom": "^18.2.0"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@types/react": "^18.2.14",
 | 
			
		||||
    "@types/react-dom": "^18.2.6",
 | 
			
		||||
    "@typescript-eslint/eslint-plugin": "^5.61.0",
 | 
			
		||||
    "@typescript-eslint/parser": "^5.61.0",
 | 
			
		||||
    "@vitejs/plugin-react-swc": "^3.3.2",
 | 
			
		||||
    "eslint": "^8.44.0",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.6.0",
 | 
			
		||||
    "eslint-plugin-react-refresh": "^0.4.1",
 | 
			
		||||
    "prettier": "^3.0.0",
 | 
			
		||||
    "typescript": "^5.0.2",
 | 
			
		||||
    "vite": "^4.4.0"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2090
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										2090
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										119
									
								
								src/App.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								src/App.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
			
		||||
import { Excalidraw, Sidebar } from '@excalidraw/excalidraw';
 | 
			
		||||
import { Box, Button, Container } from '@mui/material';
 | 
			
		||||
import type {
 | 
			
		||||
  ExcalidrawProps,
 | 
			
		||||
  ExcalidrawImperativeAPI,
 | 
			
		||||
} from '@excalidraw/excalidraw/types/types';
 | 
			
		||||
import { FC, useState } from 'react';
 | 
			
		||||
 | 
			
		||||
const ExcalidrawContainer: FC<
 | 
			
		||||
  ExcalidrawProps & { refCallback: (api: ExcalidrawImperativeAPI) => void }
 | 
			
		||||
> = (props) => {
 | 
			
		||||
  return (
 | 
			
		||||
    <Container>
 | 
			
		||||
      <Box
 | 
			
		||||
        sx={{
 | 
			
		||||
          border: '1.5px solid',
 | 
			
		||||
          width: '95vw',
 | 
			
		||||
          height: '95vh',
 | 
			
		||||
        }}
 | 
			
		||||
      >
 | 
			
		||||
        <Excalidraw {...props} ref={props.refCallback} />
 | 
			
		||||
      </Box>
 | 
			
		||||
    </Container>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function App() {
 | 
			
		||||
  // TODO: jotai premitives
 | 
			
		||||
  const isCollaborating = false;
 | 
			
		||||
 | 
			
		||||
  const [excalidrawAPI, setExcalidrawAPI] = useState<ExcalidrawImperativeAPI>();
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Container
 | 
			
		||||
      sx={{
 | 
			
		||||
        display: 'grid',
 | 
			
		||||
        height: '100%',
 | 
			
		||||
        width: '100%',
 | 
			
		||||
        placeContent: 'center',
 | 
			
		||||
        overflow: 'hidden',
 | 
			
		||||
      }}
 | 
			
		||||
    >
 | 
			
		||||
      <ExcalidrawContainer
 | 
			
		||||
        refCallback={(api) => setExcalidrawAPI(api)}
 | 
			
		||||
        isCollaborating={isCollaborating}
 | 
			
		||||
        autoFocus={true}
 | 
			
		||||
        name="Excalidraw with WebRTC"
 | 
			
		||||
        renderTopRightUI={() => {
 | 
			
		||||
          return (
 | 
			
		||||
            <Button
 | 
			
		||||
              onClick={() => {
 | 
			
		||||
                excalidrawAPI?.toggleMenu('customSidebar');
 | 
			
		||||
              }}
 | 
			
		||||
            >
 | 
			
		||||
              Button
 | 
			
		||||
            </Button>
 | 
			
		||||
          );
 | 
			
		||||
        }}
 | 
			
		||||
        renderSidebar={() => {
 | 
			
		||||
          return (
 | 
			
		||||
            <Sidebar dockable={true}>
 | 
			
		||||
              <Sidebar.Header> Header </Sidebar.Header>
 | 
			
		||||
              <Button>Button</Button>
 | 
			
		||||
            </Sidebar>
 | 
			
		||||
          );
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
    </Container>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
export interface ExcalidrawProps {
 | 
			
		||||
    // Render UI elements
 | 
			
		||||
    renderTopRightUI?: (isMobile: boolean, appState: AppState) => JSX.Element | null;
 | 
			
		||||
    renderSidebar?: () => JSX.Element | null;
 | 
			
		||||
 | 
			
		||||
    onChange?: (elements: readonly ExcalidrawElement[], appState: AppState, files: BinaryFiles) => void;
 | 
			
		||||
    initialData?: ExcalidrawInitialDataState | null | Promise<ExcalidrawInitialDataState | null>;
 | 
			
		||||
    excalidrawRef?: ForwardRef<ExcalidrawAPIRefValue>;
 | 
			
		||||
    isCollaborating?: boolean;
 | 
			
		||||
    onPointerUpdate?: (payload: {
 | 
			
		||||
        pointer: {
 | 
			
		||||
            x: number;
 | 
			
		||||
            y: number;
 | 
			
		||||
        };
 | 
			
		||||
        button: "down" | "up";
 | 
			
		||||
        pointersMap: Gesture["pointers"];
 | 
			
		||||
    }) => void;
 | 
			
		||||
    onPaste?: (data: ClipboardData, event: ClipboardEvent | null) => Promise<boolean> | boolean;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    langCode?: Language["code"];
 | 
			
		||||
    onPointerDown?: (activeTool: AppState["activeTool"], pointerDownState: PointerDownState) => void;
 | 
			
		||||
    generateIdForFile?: (file: File) => string | Promise<string>;
 | 
			
		||||
    UIOptions?: Partial<UIOptions>;
 | 
			
		||||
    renderCustomStats?: (elements: readonly NonDeletedExcalidrawElement[], appState: AppState) => JSX.Element;
 | 
			
		||||
 | 
			
		||||
    viewModeEnabled?: boolean;
 | 
			
		||||
    zenModeEnabled?: boolean;
 | 
			
		||||
    gridModeEnabled?: boolean;
 | 
			
		||||
    libraryReturnUrl?: string;
 | 
			
		||||
    name?: string;
 | 
			
		||||
    theme?: Theme;
 | 
			
		||||
    detectScroll?: boolean;
 | 
			
		||||
    handleKeyboardGlobally?: boolean;
 | 
			
		||||
    onLibraryChange?: (libraryItems: LibraryItems) => void | Promise<any>;
 | 
			
		||||
    autoFocus?: boolean;
 | 
			
		||||
    onLinkOpen?: (element: NonDeletedExcalidrawElement, event: CustomEvent<{
 | 
			
		||||
        nativeEvent: MouseEvent | React.PointerEvent<HTMLCanvasElement>;
 | 
			
		||||
    }>) => void;
 | 
			
		||||
    onScrollChange?: (scrollX: number, scrollY: number) => void;
 | 
			
		||||
    children?: React.ReactNode;
 | 
			
		||||
}
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
export default App;
 | 
			
		||||
							
								
								
									
										14
									
								
								src/main.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/main.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import ReactDOM from 'react-dom/client';
 | 
			
		||||
import App from './App.tsx';
 | 
			
		||||
 | 
			
		||||
import '@fontsource/roboto/300.css';
 | 
			
		||||
import '@fontsource/roboto/400.css';
 | 
			
		||||
import '@fontsource/roboto/500.css';
 | 
			
		||||
import '@fontsource/roboto/700.css';
 | 
			
		||||
 | 
			
		||||
ReactDOM.createRoot(document.getElementById('root')!).render(
 | 
			
		||||
  <React.StrictMode>
 | 
			
		||||
    <App />
 | 
			
		||||
  </React.StrictMode>
 | 
			
		||||
);
 | 
			
		||||
							
								
								
									
										1
									
								
								src/vite-env.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/vite-env.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
/// <reference types="vite/client" />
 | 
			
		||||
							
								
								
									
										25
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
{
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    "target": "ES2020",
 | 
			
		||||
    "useDefineForClassFields": true,
 | 
			
		||||
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
 | 
			
		||||
    "module": "ESNext",
 | 
			
		||||
    "skipLibCheck": true,
 | 
			
		||||
 | 
			
		||||
    /* Bundler mode */
 | 
			
		||||
    "moduleResolution": "bundler",
 | 
			
		||||
    "allowImportingTsExtensions": true,
 | 
			
		||||
    "resolveJsonModule": true,
 | 
			
		||||
    "isolatedModules": true,
 | 
			
		||||
    "noEmit": true,
 | 
			
		||||
    "jsx": "react-jsx",
 | 
			
		||||
 | 
			
		||||
    /* Linting */
 | 
			
		||||
    "strict": true,
 | 
			
		||||
    "noUnusedLocals": true,
 | 
			
		||||
    "noUnusedParameters": true,
 | 
			
		||||
    "noFallthroughCasesInSwitch": true
 | 
			
		||||
  },
 | 
			
		||||
  "include": ["src"],
 | 
			
		||||
  "references": [{ "path": "./tsconfig.node.json" }]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								tsconfig.node.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								tsconfig.node.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
{
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    "composite": true,
 | 
			
		||||
    "skipLibCheck": true,
 | 
			
		||||
    "module": "ESNext",
 | 
			
		||||
    "moduleResolution": "bundler",
 | 
			
		||||
    "allowSyntheticDefaultImports": true
 | 
			
		||||
  },
 | 
			
		||||
  "include": ["vite.config.ts"]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								vite.config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vite.config.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
import { defineConfig } from 'vite';
 | 
			
		||||
import react from '@vitejs/plugin-react-swc';
 | 
			
		||||
 | 
			
		||||
// https://vitejs.dev/config/
 | 
			
		||||
export default defineConfig({
 | 
			
		||||
  plugins: [react()],
 | 
			
		||||
});
 | 
			
		||||
		Reference in New Issue
	
	Block a user