diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 61d1dd1..f5f7ed8 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -2,6 +2,8 @@ name: Build and Push Docker Image on: push: + branches: + - dev pull_request: workflow_dispatch: diff --git a/.gitmodules b/.gitmodules index efb13d4..a679f03 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ [submodule "cloudflare-worker"] path = cloudflare-worker url = https://github.com/betterandbetterii/cf-kv.git +[submodule "excalidraw"] + path = excalidraw + url = git@github.com:BetterAndBetterII/excalidraw.git + branch = multi-canvas diff --git a/excalidraw/.dockerignore b/excalidraw/.dockerignore index d50e12c..6472839 100644 --- a/excalidraw/.dockerignore +++ b/excalidraw/.dockerignore @@ -1,12 +1,19 @@ * -!excalidraw-app/ !.env.development !.env.production !.eslintrc.json !.npmrc !.prettierrc +!excalidraw-app/ !package.json !public/ !packages/ +!scripts/ !tsconfig.json !yarn.lock + +# keep (sub)sub directories at the end to exclude from explicit included +# e.g. ./packages/excalidraw/{dist,node_modules} +**/build +**/dist +**/node_modules diff --git a/excalidraw/.env.development b/excalidraw/.env.development index d6d0edb..bf641c3 100644 --- a/excalidraw/.env.development +++ b/excalidraw/.env.development @@ -1,5 +1,7 @@ -VITE_APP_BACKEND_V2_GET_URL=/api/v2/ -VITE_APP_BACKEND_V2_POST_URL=/api/v2/post/ +MODE="development" + +VITE_APP_BACKEND_V2_GET_URL=https://json-dev.excalidraw.com/api/v2/ +VITE_APP_BACKEND_V2_POST_URL=https://json-dev.excalidraw.com/api/v2/post/ VITE_APP_LIBRARY_URL=https://libraries.excalidraw.com VITE_APP_LIBRARY_BACKEND=https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries @@ -8,7 +10,7 @@ VITE_APP_LIBRARY_BACKEND=https://us-central1-excalidraw-room-persistence.cloudfu VITE_APP_WS_SERVER_URL=http://localhost:3002 VITE_APP_PLUS_LP=https://plus.excalidraw.com -VITE_APP_PLUS_APP=https://app.excalidraw.com +VITE_APP_PLUS_APP=http://localhost:3000 VITE_APP_AI_BACKEND=http://localhost:3015 @@ -17,12 +19,10 @@ VITE_APP_FIREBASE_CONFIG='{"apiKey":"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8","a # put these in your .env.local, or make sure you don't commit! # must be lowercase `true` when turned on # -# whether to enable Service Workers in development -VITE_APP_DEV_ENABLE_SW= # whether to disable live reload / HMR. Usuaully what you want to do when # debugging Service Workers. VITE_APP_DEV_DISABLE_LIVE_RELOAD= -VITE_APP_DISABLE_TRACKING=true +VITE_APP_ENABLE_TRACKING=true FAST_REFRESH=false @@ -39,3 +39,17 @@ VITE_APP_COLLAPSE_OVERLAY=true # Set this flag to false to disable eslint VITE_APP_ENABLE_ESLINT=true + +# Enable PWA in dev server +VITE_APP_ENABLE_PWA=false + +VITE_APP_PLUS_EXPORT_PUBLIC_KEY='MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2g5T+Rub6Kbf1Mf57t0 +7r2zeHuVg4dla3r5ryXMswtzz6x767octl6oLThn33mQsPSy3GKglFZoCTXJR4ij +ba8SxB04sL/N8eRrKja7TFWjCVtRwTTfyy771NYYNFVJclkxHyE5qw4m27crHF1y +UNWEjuqNMi/lwAErS9fFa2oJlWyT8U7zzv/5kQREkxZI6y9v0AF3qcbsy2731FnD +s9ChJvOUW9toIab2gsIdrKW8ZNpu084ZFVKb6LNjvIXI1Se4oMTHeszXzNptzlot +kdxxjOoaQMAyfljFSot1F1FlU6MQlag7UnFGvFjRHN1JI5q4K+n3a67DX+TMyRqS +HQIDAQAB' + +# set to true in .env.development.local to disable the prevent unload dialog +VITE_APP_DISABLE_PREVENT_UNLOAD= diff --git a/excalidraw/.env.production b/excalidraw/.env.production index 26a13ba..72dd24d 100644 --- a/excalidraw/.env.production +++ b/excalidraw/.env.production @@ -1,17 +1,34 @@ -VITE_APP_BACKEND_V2_GET_URL=http://localhost:3002/api/v2/ -VITE_APP_BACKEND_V2_POST_URL=http://localhost:3002/api/v2/post/ +MODE="production" + +VITE_APP_BACKEND_V2_GET_URL=https://json.excalidraw.com/api/v2/ +VITE_APP_BACKEND_V2_POST_URL=https://json.excalidraw.com/api/v2/post/ VITE_APP_LIBRARY_URL=https://libraries.excalidraw.com -VITE_APP_LIBRARY_BACKEND=http://localhost:3002/libraries +VITE_APP_LIBRARY_BACKEND=https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries -VITE_APP_PLUS_LP=http://localhost:3002/plus/ -VITE_APP_PLUS_APP=http://localhost:3002/app/ +VITE_APP_PLUS_LP=https://plus.excalidraw.com +VITE_APP_PLUS_APP=https://app.excalidraw.com -VITE_APP_AI_BACKEND=http://localhost:3002/ai/ +VITE_APP_AI_BACKEND=https://oss-ai.excalidraw.com # socket server URL used for collaboration -VITE_APP_WS_SERVER_URL=http://localhost:3002 +VITE_APP_WS_SERVER_URL=https://oss-collab.excalidraw.com -VITE_APP_FIREBASE_CONFIG='{"apiKey":"AIzaSyAd15pYlMci_xIp9ko6wkEsDzAAA0Dn0RU","authDomain":"","databaseURL":"","projectId":"excalidraw-room-persistence","storageBucket":"","messagingSenderId":"654800341332","appId":"1:654800341332:web:4a692de832b55bd57ce0c1"}' +VITE_APP_FIREBASE_CONFIG='{"apiKey":"AIzaSyAd15pYlMci_xIp9ko6wkEsDzAAA0Dn0RU","authDomain":"excalidraw-room-persistence.firebaseapp.com","databaseURL":"https://excalidraw-room-persistence.firebaseio.com","projectId":"excalidraw-room-persistence","storageBucket":"excalidraw-room-persistence.appspot.com","messagingSenderId":"654800341332","appId":"1:654800341332:web:4a692de832b55bd57ce0c1"}' + +VITE_APP_ENABLE_TRACKING=false + +VITE_APP_PLUS_EXPORT_PUBLIC_KEY='MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApQ0jM9Qz8TdFLzcuAZZX +/WvuKSOJxiw6AR/ZcE3eFQWM/mbFdhQgyK8eHGkKQifKzH1xUZjCxyXcxW6ZO02t +kPOPxhz+nxUrIoWCD/V4NGmUA1lxwHuO21HN1gzKrN3xHg5EGjyouR9vibT9VDGF +gq6+4Ic/kJX+AD2MM7Yre2+FsOdysrmuW2Fu3ahuC1uQE7pOe1j0k7auNP0y1q53 +PrB8Ts2LUpepWC1l7zIXFm4ViDULuyWXTEpUcHSsEH8vpd1tckjypxCwkipfZsXx +iPszy0o0Dx2iArPfWMXlFAI9mvyFCyFC3+nSvfyAUb2C4uZgCwAuyFh/ydPF4DEE +PQIDAQAB' + +# Set the below flags explicitly to false in production mode since vite loads and merges .env.local vars when running the build command +VITE_APP_DEBUG_ENABLE_TEXT_CONTAINER_BOUNDING_BOX=false +VITE_APP_COLLAPSE_OVERLAY=false +# Enable eslint in dev server +VITE_APP_ENABLE_ESLINT=false -VITE_APP_DISABLE_TRACKING=yes diff --git a/excalidraw/.eslintignore b/excalidraw/.eslintignore index ab3aa6c..8b4f458 100644 --- a/excalidraw/.eslintignore +++ b/excalidraw/.eslintignore @@ -6,3 +6,6 @@ firebase/ dist/ public/workbox packages/excalidraw/types +examples/**/public +dev-dist +coverage diff --git a/excalidraw/.eslintrc.json b/excalidraw/.eslintrc.json index fbb12f5..89f8227 100644 --- a/excalidraw/.eslintrc.json +++ b/excalidraw/.eslintrc.json @@ -1,7 +1,43 @@ { "extends": ["@excalidraw/eslint-config", "react-app"], "rules": { + "import/order": [ + "warn", + { + "groups": ["builtin", "external", "internal", "parent", "sibling", "index", "object", "type"], + "pathGroups": [ + { + "pattern": "@excalidraw/**", + "group": "external", + "position": "after" + } + ], + "newlines-between": "always-and-inside-groups", + "warnOnUnassignedImports": true + } + ], "import/no-anonymous-default-export": "off", - "no-restricted-globals": "off" + "no-restricted-globals": "off", + "@typescript-eslint/consistent-type-imports": [ + "error", + { + "prefer": "type-imports", + "disallowTypeAnnotations": false, + "fixStyle": "separate-type-imports" + } + ], + "no-restricted-imports": [ + "error", + { + "name": "jotai", + "message": "Do not import from \"jotai\" directly. Use our app-specific modules (\"editor-jotai\" or \"app-jotai\")." + } + ], + "react/jsx-no-target-blank": [ + "error", + { + "allowReferrer": true + } + ] } } diff --git a/excalidraw/.gitattributes b/excalidraw/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/excalidraw/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/excalidraw/.github/copilot-instructions.md b/excalidraw/.github/copilot-instructions.md new file mode 100644 index 0000000..aebac52 --- /dev/null +++ b/excalidraw/.github/copilot-instructions.md @@ -0,0 +1,45 @@ +# Project coding standards + +## Generic Communication Guidelines + +- Be succint and be aware that expansive generative AI answers are costly and slow +- Avoid providing explanations, trying to teach unless asked for, your chat partner is an expert +- Stop apologising if corrected, just provide the correct information or code +- Prefer code unless asked for explanation +- Stop summarizing what you've changed after modifications unless asked for + +## TypeScript Guidelines + +- Use TypeScript for all new code +- Where possible, prefer implementations without allocation +- When there is an option, opt for more performant solutions and trade RAM usage for less CPU cycles +- Prefer immutable data (const, readonly) +- Use optional chaining (?.) and nullish coalescing (??) operators + +## React Guidelines + +- Use functional components with hooks +- Follow the React hooks rules (no conditional hooks) +- Keep components small and focused +- Use CSS modules for component styling + +## Naming Conventions + +- Use PascalCase for component names, interfaces, and type aliases +- Use camelCase for variables, functions, and methods +- Use ALL_CAPS for constants + +## Error Handling + +- Use try/catch blocks for async operations +- Implement proper error boundaries in React components +- Always log errors with contextual information + +## Testing + +- Always attempt to fix #problems +- Always offer to run `yarn test:app` in the project root after modifications are complete and attempt fixing the issues reported + +## Types + +- Always include `packages/math/src/types.ts` in the context when your write math related code and always use the Point type instead of { x, y} diff --git a/excalidraw/.github/workflows/autorelease-excalidraw.yml b/excalidraw/.github/workflows/autorelease-excalidraw.yml index 5ff5690..6e2c0d0 100644 --- a/excalidraw/.github/workflows/autorelease-excalidraw.yml +++ b/excalidraw/.github/workflows/autorelease-excalidraw.yml @@ -24,4 +24,4 @@ jobs: - name: Auto release run: | yarn add @actions/core -W - yarn autorelease + yarn release --tag=next --non-interactive diff --git a/excalidraw/.github/workflows/autorelease-preview.yml b/excalidraw/.github/workflows/autorelease-preview.yml deleted file mode 100644 index a40ed3c..0000000 --- a/excalidraw/.github/workflows/autorelease-preview.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: Auto release excalidraw preview -on: - issue_comment: - types: [created, edited] - -jobs: - Auto-release-excalidraw-preview: - name: Auto release preview - if: github.event.comment.body == '@excalibot trigger release' && github.event.issue.pull_request - runs-on: ubuntu-latest - steps: - - name: React to release comment - uses: peter-evans/create-or-update-comment@v1 - with: - token: ${{ secrets.PUSH_TRANSLATIONS_COVERAGE_PAT }} - comment-id: ${{ github.event.comment.id }} - reactions: "+1" - - name: Get PR SHA - id: sha - uses: actions/github-script@v4 - with: - result-encoding: string - script: | - const { owner, repo, number } = context.issue; - const pr = await github.pulls.get({ - owner, - repo, - pull_number: number, - }); - return pr.data.head.sha - - uses: actions/checkout@v2 - with: - ref: ${{ steps.sha.outputs.result }} - fetch-depth: 2 - - name: Setup Node.js 18.x - uses: actions/setup-node@v2 - with: - node-version: 18.x - - name: Set up publish access - run: | - npm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN} - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - - name: Auto release preview - id: "autorelease" - run: | - yarn add @actions/core -W - yarn autorelease preview ${{ github.event.issue.number }} - - name: Post comment post release - if: always() - uses: peter-evans/create-or-update-comment@v1 - with: - token: ${{ secrets.PUSH_TRANSLATIONS_COVERAGE_PAT }} - issue-number: ${{ github.event.issue.number }} - body: "@${{ github.event.comment.user.login }} ${{ steps.autorelease.outputs.result }}" diff --git a/excalidraw/.github/workflows/locales-coverage.yml b/excalidraw/.github/workflows/locales-coverage.yml index 3cce93e..957e9bc 100644 --- a/excalidraw/.github/workflows/locales-coverage.yml +++ b/excalidraw/.github/workflows/locales-coverage.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: token: ${{ secrets.PUSH_TRANSLATIONS_COVERAGE_PAT }} diff --git a/excalidraw/.github/workflows/publish-docker.yml b/excalidraw/.github/workflows/publish-docker.yml index a4a8a4c..68eee27 100644 --- a/excalidraw/.github/workflows/publish-docker.yml +++ b/excalidraw/.github/workflows/publish-docker.yml @@ -17,9 +17,14 @@ jobs: with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - name: Build and push - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v5 with: context: . push: true tags: excalidraw/excalidraw:latest + platforms: linux/amd64, linux/arm64, linux/arm/v7 diff --git a/excalidraw/.github/workflows/semantic-pr-title.yml b/excalidraw/.github/workflows/semantic-pr-title.yml index 969d236..34a6413 100644 --- a/excalidraw/.github/workflows/semantic-pr-title.yml +++ b/excalidraw/.github/workflows/semantic-pr-title.yml @@ -11,6 +11,6 @@ jobs: semantic: runs-on: ubuntu-latest steps: - - uses: amannn/action-semantic-pull-request@v3.0.0 + - uses: amannn/action-semantic-pull-request@v5 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/excalidraw/.github/workflows/test.yml b/excalidraw/.github/workflows/test.yml index 2c458a8..7d454ec 100644 --- a/excalidraw/.github/workflows/test.yml +++ b/excalidraw/.github/workflows/test.yml @@ -1,14 +1,16 @@ name: Tests -on: pull_request +on: + push: + branches: master jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Setup Node.js 18.x - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 with: node-version: 18.x - name: Install and test diff --git a/excalidraw/.gitignore b/excalidraw/.gitignore new file mode 100644 index 0000000..6f3a62b --- /dev/null +++ b/excalidraw/.gitignore @@ -0,0 +1,29 @@ +.DS_Store +.env.development.local +.env.local +.env.production.local +.env.test.local +.envrc +.eslintcache +.history +.idea +.vercel +.vscode +.yarn +*.log +*.tgz +build +dist +firebase +logs +node_modules +npm-debug.log* +package-lock.json +yarn-debug.log* +yarn-error.log* +packages/excalidraw/types +coverage +dev-dist +html +meta*.json +.claude diff --git a/excalidraw/.husky/pre-commit b/excalidraw/.husky/pre-commit new file mode 100644 index 0000000..ab2a5ac --- /dev/null +++ b/excalidraw/.husky/pre-commit @@ -0,0 +1,2 @@ +#!/bin/sh +# yarn lint-staged diff --git a/excalidraw/.npmrc b/excalidraw/.npmrc index afb89e4..1b78f1c 100644 --- a/excalidraw/.npmrc +++ b/excalidraw/.npmrc @@ -1,3 +1,2 @@ save-exact=true legacy-peer-deps=true -shamefully-hoist=true diff --git a/excalidraw/CLAUDE.md b/excalidraw/CLAUDE.md new file mode 100644 index 0000000..4faf291 --- /dev/null +++ b/excalidraw/CLAUDE.md @@ -0,0 +1,34 @@ +# CLAUDE.md + +## Project Structure + +Excalidraw is a **monorepo** with a clear separation between the core library and the application: + +- **`packages/excalidraw/`** - Main React component library published to npm as `@excalidraw/excalidraw` +- **`excalidraw-app/`** - Full-featured web application (excalidraw.com) that uses the library +- **`packages/`** - Core packages: `@excalidraw/common`, `@excalidraw/element`, `@excalidraw/math`, `@excalidraw/utils` +- **`examples/`** - Integration examples (NextJS, browser script) + +## Development Workflow + +1. **Package Development**: Work in `packages/*` for editor features +2. **App Development**: Work in `excalidraw-app/` for app-specific features +3. **Testing**: Always run `yarn test:update` before committing +4. **Type Safety**: Use `yarn test:typecheck` to verify TypeScript + +## Development Commands + +```bash +yarn test:typecheck # TypeScript type checking +yarn test:update # Run all tests (with snapshot updates) +yarn fix # Auto-fix formatting and linting issues +``` + +## Architecture Notes + +### Package System + +- Uses Yarn workspaces for monorepo management +- Internal packages use path aliases (see `vitest.config.mts`) +- Build system uses esbuild for packages, Vite for the app +- TypeScript throughout with strict configuration diff --git a/excalidraw/Dockerfile b/excalidraw/Dockerfile index 11c88d0..c08385d 100644 --- a/excalidraw/Dockerfile +++ b/excalidraw/Dockerfile @@ -1,14 +1,20 @@ -FROM node:18 AS build +FROM --platform=${BUILDPLATFORM} node:18 AS build -WORKDIR /home/node/app +WORKDIR /opt/node_app COPY . . -RUN npm install -RUN cd excalidraw-app && npm run build:app:docker +# do not ignore optional dependencies: +# Error: Cannot find module @rollup/rollup-linux-x64-gnu +RUN --mount=type=cache,target=/root/.cache/yarn \ + npm_config_target_arch=${TARGETARCH} yarn --network-timeout 600000 -FROM nginx:1.21-alpine +ARG NODE_ENV=production -COPY --from=build /home/node/app/excalidraw-app/build /usr/share/nginx/html +RUN npm_config_target_arch=${TARGETARCH} yarn build:app:docker + +FROM --platform=${TARGETPLATFORM} nginx:1.27-alpine + +COPY --from=build /opt/node_app/excalidraw-app/build /usr/share/nginx/html HEALTHCHECK CMD wget -q -O /dev/null http://localhost || exit 1 diff --git a/excalidraw/README.md b/excalidraw/README.md index e8cd3b0..f1cf030 100644 --- a/excalidraw/README.md +++ b/excalidraw/README.md @@ -7,7 +7,7 @@

Excalidraw Editor | - Blog | + Blog | Documentation | Excalidraw+

@@ -34,6 +34,9 @@ Chat on Discord + + Ask DeepWiki + Follow Excalidraw on Twitter @@ -63,7 +66,7 @@ The Excalidraw editor (npm package) supports: - 🏗️ Customizable. - 📷 Image support. - 😀 Shape libraries support. -- 👅 Localization (i18n) support. +- 🌐 Localization (i18n) support. - 🖼️ Export to PNG, SVG & clipboard. - 💾 Open format - export drawings as an `.excalidraw` json file. - ⚒️ Wide range of tools - rectangle, circle, diamond, arrow, line, free-draw, eraser... @@ -87,13 +90,11 @@ We'll be adding these features as drop-in plugins for the npm package in the fut **Note:** following instructions are for installing the Excalidraw [npm package](https://www.npmjs.com/package/@excalidraw/excalidraw) when integrating Excalidraw into your own app. To run the repository locally for development, please refer to our [Development Guide](https://docs.excalidraw.com/docs/introduction/development). -``` +Use `npm` or `yarn` to install the package. + +```bash npm install react react-dom @excalidraw/excalidraw -``` - -or via yarn - -``` +# or yarn add react react-dom @excalidraw/excalidraw ``` diff --git a/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/children-components/footer.mdx b/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/children-components/footer.mdx index 3831268..e7852ce 100644 --- a/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/children-components/footer.mdx +++ b/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/children-components/footer.mdx @@ -2,7 +2,7 @@ Earlier we were using `renderFooter` prop to render custom footer which was removed in [#5970](https://github.com/excalidraw/excalidraw/pull/5970). Now you can pass a `Footer` component instead to render the custom UI for footer. -You will need to import the `Footer` component from the package and wrap your component with the Footer component. The `Footer` should a valid React Node. +You will need to import the `Footer` component from the package and wrap your component with the Footer component. The `Footer` should be a valid React Node. **Usage** @@ -25,7 +25,7 @@ function App() { } ``` -This will only for `Desktop` devices. +This will only work for `Desktop` devices. For `mobile` you will need to render it inside the [MainMenu](#mainmenu). You can use the [`useDevice`](#useDevice) hook to check the type of device, this will be available only inside the `children` of `Excalidraw` component. @@ -65,4 +65,4 @@ const App = () => ( // Need to render when code is span across multiple components // in Live Code blocks editor render(); -``` \ No newline at end of file +``` diff --git a/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/children-components/main-menu.mdx b/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/children-components/main-menu.mdx index e601a24..b0062d9 100644 --- a/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/children-components/main-menu.mdx +++ b/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/children-components/main-menu.mdx @@ -133,7 +133,7 @@ function App() { } ``` -Here is a [complete list](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/components/mainMenu/DefaultItems.tsx) of the default items. +Here is a [complete list](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/components/main-menu/DefaultItems.tsx) of the default items. ### MainMenu.Group diff --git a/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/children-components/welcome-screen.mdx b/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/children-components/welcome-screen.mdx index 8150508..8834870 100644 --- a/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/children-components/welcome-screen.mdx +++ b/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/children-components/welcome-screen.mdx @@ -31,7 +31,7 @@ The welcome screen consists of two main groups of subcomponents: Excalidraw logo: Sketch handrawn like diagrams. ### Center diff --git a/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/constants.mdx b/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/constants.mdx index 029f5b0..36fbfa7 100644 --- a/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/constants.mdx +++ b/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/constants.mdx @@ -8,15 +8,15 @@ import { FONT_FAMILY } from "@excalidraw/excalidraw"; ``` -`FONT_FAMILY` contains all the font families used in `Excalidraw` as explained below +`FONT_FAMILY` contains all the font families used in `Excalidraw`. The default families are the following: | Font Family | Description | | ----------- | ---------------------- | -| `Virgil` | The `handwritten` font | -| `Helvetica` | The `Normal` Font | -| `Cascadia` | The `Code` Font | +| `Excalifont` | The `Hand-drawn` font | +| `Nunito` | The `Normal` Font | +| `Comic Shanns` | The `Code` Font | -Defaults to `FONT_FAMILY.Virgil` unless passed in `initialData.appState.currentItemFontFamily`. +Pre-selected family is `FONT_FAMILY.Excalifont`, unless it's overriden with `initialData.appState.currentItemFontFamily`. ### THEME diff --git a/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/props/excalidraw-api.mdx b/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/props/excalidraw-api.mdx index ffff19f..c9580b6 100644 --- a/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/props/excalidraw-api.mdx +++ b/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/props/excalidraw-api.mdx @@ -13,7 +13,7 @@ Once the callback is triggered, you will need to store the api in state to acces ```jsx showLineNumbers export default function App() { const [excalidrawAPI, setExcalidrawAPI] = useState(null); - return setExcalidrawAPI(api)}} />; + return setExcalidrawAPI(api)} />; } ``` @@ -22,7 +22,7 @@ You can use this prop when you want to access some [Excalidraw APIs](https://git | API | Signature | Usage | | --- | --- | --- | | [updateScene](#updatescene) | `function` | updates the scene with the sceneData | -| [updateLibrary](#updatelibrary) | `function` | updates the scene with the sceneData | +| [updateLibrary](#updatelibrary) | `function` | updates the library | | [addFiles](#addfiles) | `function` | add files data to the appState | | [resetScene](#resetscene) | `function` | Resets the scene. If `resetLoadingState` is passed as true then it will also force set the loading state to false. | | [getSceneElementsIncludingDeleted](#getsceneelementsincludingdeleted) | `function` | Returns all the elements including the deleted in the scene | @@ -65,7 +65,7 @@ You can use this function to update the scene with the sceneData. It accepts the | `elements` | [`ImportedDataState["elements"]`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/types.ts#L38) | The `elements` to be updated in the scene | | `appState` | [`ImportedDataState["appState"]`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/types.ts#L39) | The `appState` to be updated in the scene. | | `collaborators` | MapCollaborator> | The list of collaborators to be updated in the scene. | -| `commitToHistory` | `boolean` | Implies if the `history (undo/redo)` should be recorded. Defaults to `false`. | +| `captureUpdate` | [`CaptureUpdateAction`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/store.ts#L40) | Controls which updates should be captured by the `Store`. Captured updates are emmitted and listened to by other components, such as `History` for undo / redo purposes. | ```jsx live function App() { @@ -105,6 +105,7 @@ function App() { appState: { viewBackgroundColor: "#edf2ff", }, + captureUpdate: CaptureUpdateAction.IMMEDIATELY, }; excalidrawAPI.updateScene(sceneData); }; @@ -115,12 +116,24 @@ function App() { - setExcalidrawAPI(api)} /> + setExcalidrawAPI(api)} /> ); } ``` +#### captureUpdate + +You can use the `captureUpdate` to influence undo / redo behaviour. + +> **NOTE**: Some updates are not observed by the store / history - i.e. updates to `collaborators` object or parts of `AppState` which are not observed (not `ObservedAppState`). Such updates will never make it to the undo / redo stacks, regardless of the passed `captureUpdate` value. + +| | `captureUpdate` value | Notes | +| --- | --- | --- | +| _Immediately undoable_ | `CaptureUpdateAction.IMMEDIATELY` | Use for updates which should be captured. Should be used for most of the local updates. These updates will _immediately_ make it to the local undo / redo stacks. | +| _Eventually undoable_ | `CaptureUpdateAction.EVENTUALLY` | Use for updates which should not be captured immediately - likely exceptions which are part of some async multi-step process. Otherwise, all such updates would end up being captured with the next `CaptureUpdateAction.IMMEDIATELY` - triggered either by the next `updateScene` or internally by the editor. These updates will _eventually_ make it to the local undo / redo stacks. | +| _Never undoable_ | `CaptureUpdateAction.NEVER` | Use for updates which should never be recorded, such as remote updates or scene initialization. These updates will _never_ make it to the local undo / redo stacks. | + ### updateLibrary
@@ -188,7 +201,7 @@ function App() {
         Update Library
       
        setExcalidrawAPI(api)}
+        excalidrawAPI={(api) => setExcalidrawAPI(api)}
         // initial data retrieved from https://github.com/excalidraw/excalidraw/blob/master/dev-docs/packages/excalidraw/initialData.js
         initialData={{
           libraryItems: initialData.libraryItems,
@@ -350,13 +363,7 @@ This API has the below signature. It sets the `tool` passed in param as the acti
 ```ts
 (
   tool: (
-    | (
-        | { type: Exclude }
-        | {
-            type: Extract;
-            insertOnCanvasDirectly?: boolean;
-          }
-      )
+    | { type: ToolType }
     | { type: "custom"; customType: string }
   ) & { locked?: boolean },
 ) => {};
@@ -364,7 +371,7 @@ This API has the below signature. It sets the `tool` passed in param as the acti
 
 | Name | Type | Default | Description |
 | --- | --- | --- | --- |
-| `type` | [ToolType](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L91) | `selection` | The tool type which should be set as active tool. When setting `image` as active tool, the insertion onto canvas when using image tool is disabled by default, so you can enable it by setting `insertOnCanvasDirectly` to `true` |
+| `type` | [ToolType](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L91) | `selection` | The tool type which should be set as active tool |
 | `locked` | `boolean` | `false` | Indicates whether the the active tool should be locked. It behaves the same way when using the `lock` tool in the editor interface |
 
 ## setCursor
diff --git a/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/props/props.mdx b/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/props/props.mdx
index 766c723..607e971 100644
--- a/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/props/props.mdx
+++ b/excalidraw/dev-docs/docs/@excalidraw/excalidraw/api/props/props.mdx
@@ -5,31 +5,33 @@ All `props` are _optional_.
 | Name | Type | Default | Description |
 | --- | --- | --- | --- |
 | [`initialData`](/docs/@excalidraw/excalidraw/api/props/initialdata) | `object` | `null` | Promise | `null` | The initial data with which app loads. |
-| [`excalidrawAPI`](/docs/@excalidraw/excalidraw/api/props/excalidraw-api) | `function` | _ | Callback triggered with the excalidraw api once rendered |
-| [`isCollaborating`](#iscollaborating) | `boolean` | _ | This indicates if the app is in `collaboration` mode |
-| [`onChange`](#onchange) | `function` | _ | This callback is triggered whenever the component updates due to any change. This callback will receive the excalidraw `elements` and the current `app state`. |
-| [`onPointerUpdate`](#onpointerupdate) | `function` | _ | Callback triggered when mouse pointer is updated. |
-| [`onPointerDown`](#onpointerdown) | `function` | _ | This prop if passed gets triggered on pointer down evenets |
-| [`onScrollChange`](#onscrollchange) | `function` | _ | This prop if passed gets triggered when scrolling the canvas. |
-| [`onPaste`](#onpaste) | `function` | _ | Callback to be triggered if passed when the something is pasted in to the scene |
-| [`onLibraryChange`](#onlibrarychange) | `function` | _ | The callback if supplied is triggered when the library is updated and receives the library items. |
-| [`onLinkOpen`](#onlinkopen) | `function` | _ | The callback if supplied is triggered when any link is opened. |
+| [`excalidrawAPI`](/docs/@excalidraw/excalidraw/api/props/excalidraw-api) | `function` | \_ | Callback triggered with the excalidraw api once rendered |
+| [`isCollaborating`](#iscollaborating) | `boolean` | \_ | This indicates if the app is in `collaboration` mode |
+| [`onChange`](#onchange) | `function` | \_ | This callback is triggered whenever the component updates due to any change. This callback will receive the excalidraw `elements` and the current `app state`. |
+| [`onPointerUpdate`](#onpointerupdate) | `function` | \_ | Callback triggered when mouse pointer is updated. |
+| [`onPointerDown`](#onpointerdown) | `function` | \_ | This prop if passed gets triggered on pointer down events |
+| [`onScrollChange`](#onscrollchange) | `function` | \_ | This prop if passed gets triggered when scrolling the canvas. |
+| [`onPaste`](#onpaste) | `function` | \_ | Callback to be triggered if passed when something is pasted into the scene |
+| [`onLibraryChange`](#onlibrarychange) | `function` | \_ | The callback if supplied is triggered when the library is updated and receives the library items. |
+| [`generateLinkForSelection`](#generatelinkforselection) | `function` | \_ | Allows you to override `url` generation when linking to Excalidraw elements. |
+| [`onLinkOpen`](#onlinkopen) | `function` | \_ | The callback if supplied is triggered when any link is opened. |
 | [`langCode`](#langcode) | `string` | `en` | Language code string to be used in Excalidraw |
-| [`renderTopRightUI`](/docs/@excalidraw/excalidraw/api/props/render-props#rendertoprightui) | `function` | _ | Render function that renders custom UI in top right corner |
-| [`renderCustomStats`](/docs/@excalidraw/excalidraw/api/props/render-props#rendercustomstats) | `function` | _ | Render function that can be used to render custom stats on the stats dialog. |
-| [`viewModeEnabled`](#viewmodeenabled) | `boolean` | _ | This indicates if the app is in `view` mode. |
-| [`zenModeEnabled`](#zenmodeenabled) | `boolean` | _ | This indicates if the `zen` mode is enabled |
-| [`gridModeEnabled`](#gridmodeenabled) | `boolean` | _ | This indicates if the `grid` mode is enabled |
-| [`libraryReturnUrl`](#libraryreturnurl) | `string` | _ | What URL should [libraries.excalidraw.com](https://libraries.excalidraw.com) be installed to |
+| [`renderTopRightUI`](/docs/@excalidraw/excalidraw/api/props/render-props#rendertoprightui) | `function` | \_ | Render function that renders custom UI in top right corner |
+| [`renderCustomStats`](/docs/@excalidraw/excalidraw/api/props/render-props#rendercustomstats) | `function` | \_ | Render function that can be used to render custom stats on the stats dialog. |
+| [`viewModeEnabled`](#viewmodeenabled) | `boolean` | \_ | This indicates if the app is in `view` mode. |
+| [`zenModeEnabled`](#zenmodeenabled) | `boolean` | \_ | This indicates if the `zen` mode is enabled |
+| [`gridModeEnabled`](#gridmodeenabled) | `boolean` | \_ | This indicates if the `grid` mode is enabled |
+| [`libraryReturnUrl`](#libraryreturnurl) | `string` | \_ | What URL should [libraries.excalidraw.com](https://libraries.excalidraw.com) be installed to |
 | [`theme`](#theme) | `"light"` | `"dark"` | `"light"` | The theme of the Excalidraw component |
 | [`name`](#name) | `string` |  | Name of the drawing |
 | [`UIOptions`](/docs/@excalidraw/excalidraw/api/props/ui-options) | `object` | [DEFAULT UI OPTIONS](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/constants.ts#L151) | To customise UI options. Currently we support customising [`canvas actions`](/docs/@excalidraw/excalidraw/api/props/ui-options#canvasactions) |
 | [`detectScroll`](#detectscroll) | `boolean` | `true` | Indicates whether to update the offsets when nearest ancestor is scrolled. |
 | [`handleKeyboardGlobally`](#handlekeyboardglobally) | `boolean` | `false` | Indicates whether to bind the keyboard events to document. |
-| [`autoFocus`](#autofocus) | `boolean` | `false` | indicates whether to focus the Excalidraw component on page load |
-| [`generateIdForFile`](#generateidforfile) | `function` | _ | Allows you to override `id` generation for files added on canvas |
-| [`validateEmbeddable`](#validateEmbeddable) | string[] | `boolean | RegExp | RegExp[] | ((link: string) => boolean | undefined)` | \_ | use for custom src url validation |
+| [`autoFocus`](#autofocus) | `boolean` | `false` | Indicates whether to focus the Excalidraw component on page load |
+| [`generateIdForFile`](#generateidforfile) | `function` | \_ | Allows you to override `id` generation for files added on canvas |
+| [`validateEmbeddable`](#validateembeddable) | `string[]` \| `boolean` \| `RegExp` \| `RegExp[]` \| ((link: string) => boolean | undefined) | \_ | use for custom src url validation |
 | [`renderEmbeddable`](/docs/@excalidraw/excalidraw/api/props/render-props#renderEmbeddable) | `function` | \_ | Render function that can override the built-in `