Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
alexjg committed May 2, 2024
0 parents commit 0326cfb
Show file tree
Hide file tree
Showing 17 changed files with 2,597 additions and 0 deletions.
18 changes: 18 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended",
],
ignorePatterns: ["dist", ".eslintrc.cjs"],
parser: "@typescript-eslint/parser",
plugins: ["react-refresh"],
rules: {
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
},
}
51 changes: 51 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Simple workflow for deploying static content to GitHub Pages
name: Deploy static content to Pages

on:
# Runs on pushes targeting the default branch
push:
branches: ["main"]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# Sets the GITHUB_TOKEN permissions to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# Allow one concurrent deployment
concurrency:
group: "pages"
cancel-in-progress: true

jobs:
# Single deploy job since we're just deploying
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- name: Install dependencies
run: yarn
- name: Build
run: yarn build
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
# Upload dist folder
path: "./dist"
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
26 changes: 26 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

# 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?

19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Vite + Automerge + Prosemirror

This is a simple example of how to use Vite, Automerge and Prosemirror together.

First install everything

```
yarn install
```

Then run the server

```
yarn dev
```

Now if you visit `loalhost:5173` you should see a text editor. If you copy the
URL and open it in another tab (or another browser), you should see the same
text editor. Edits from one tab will be reflected in the other.
14 changes: 14 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!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>Meet Automerge</title>
</head>

<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
40 changes: 40 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "prosemirror-play",
"private": true,
"version": "1.1.9",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"@automerge/automerge": "^2.2.0",
"@automerge/automerge-repo": "^1.1.9",
"@automerge/automerge-repo-network-broadcastchannel": "^1.1.9",
"@automerge/automerge-repo-network-websocket": "^1.1.9",
"@automerge/automerge-repo-react-hooks": "^1.1.9",
"@automerge/automerge-repo-storage-indexeddb": "^1.1.9",
"@automerge/prosemirror": "^0.0.9",
"prosemirror-example-setup": "^1.2.2",
"prosemirror-model": "^1.20.0",
"prosemirror-state": "^1.4.3",
"prosemirror-view": "^1.33.5",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.2.64",
"@types/react-dom": "^18.2.21",
"@typescript-eslint/eslint-plugin": "^7.3.1",
"@typescript-eslint/parser": "^7.3.1",
"@vitejs/plugin-react": "^4.2.1",
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"typescript": "^5.2.2",
"vite": "^5.1.6",
"vite-plugin-wasm": "^3"
}
}
55 changes: 55 additions & 0 deletions src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
display:flex;
flex-direction: column;
width: 100%;
height: 100vh;
}

/* center the editor inside the #root */
#editor {
margin: 0 auto;
width: 100%;
max-width: 800px;
flex: 1;
background-color: #f8f9fa;
color: #333;
}

.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;
}
76 changes: 76 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { AutomergeUrl, DocHandleChangePayload } from "@automerge/automerge-repo"
import { useHandle } from "@automerge/automerge-repo-react-hooks"
import { useEffect, useRef, useState } from "react"
import {EditorState, Transaction} from "prosemirror-state"
import {EditorView} from "prosemirror-view"
import {exampleSetup} from "prosemirror-example-setup"
import { AutoMirror } from "@automerge/prosemirror"
import "prosemirror-example-setup/style/style.css"
import "prosemirror-menu/style/menu.css"
import "prosemirror-view/style/prosemirror.css"
import "./App.css"

function App({ docUrl }: { docUrl: AutomergeUrl }) {
const editorRoot = useRef<HTMLDivElement>(null)
const handle = useHandle<{text: string}>(docUrl)
const [loaded, setLoaded] = useState(handle && handle.docSync() != null)
useEffect(() => {
if (handle != null) {
handle.whenReady().then(() => {
if (handle.docSync() != null) {
setLoaded(true)
}
})
}
}, [handle])

const [view, setView] = useState<EditorView | null>(null)

Check failure on line 27 in src/App.tsx

View workflow job for this annotation

GitHub Actions / deploy

'view' is declared but its value is never read.
useEffect(() => {
// We're not using this for anything yet, but this `AutoMirror` object is
// where we will integrate prosemirror with automerge
const mirror = new AutoMirror(["text"])
let view: EditorView
const onPatch: (args: DocHandleChangePayload<unknown>) => void = ({
doc,
patches,
patchInfo,
}) => {
//console.log(`${name}: patch received`)
const newState = mirror.reconcilePatch(
patchInfo.before,
doc,
patches,
view!.state,
)
view!.updateState(newState)
}
if (editorRoot.current != null && loaded) {
view = new EditorView(editorRoot.current, {
state: EditorState.create({
schema: mirror.schema, // It's important that we use the schema from the mirror
plugins: exampleSetup({schema: mirror.schema}),
doc: mirror.initialize(handle!),
}),
dispatchTransaction: (tx: Transaction) => {
const newState = mirror.intercept(handle!, tx, view!.state)
view!.updateState(newState)
},
})
setView(view)
handle!.on("change", onPatch)
}
return () => {
if (handle != null) {
handle.off("change", onPatch)
}
setView(null)
if (view != null) {
view.destroy()
}
}
}, [editorRoot, loaded])

return <div id="editor" ref={editorRoot}></div>
}

export default App
Binary file added src/assets/automerge.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/react.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
69 changes: 69 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;

color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;

font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}

a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}

body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}

h1 {
font-size: 3.2em;
line-height: 1.1;
}

button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}

@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}
Loading

0 comments on commit 0326cfb

Please sign in to comment.