commit da7d6e8e71818f7feccef406fa51ce85e62785df Author: NikitolProject Date: Fri Dec 27 18:16:21 2024 +0300 Init commit diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..509908e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,3 @@ +# Contributing + +Head over to the [docs](https://docs.excalidraw.com/docs/introduction/contributing) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2716803 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +FROM node:18 AS build + +WORKDIR /opt/node_app + +COPY . . + +# do not ignore optional dependencies: +# Error: Cannot find module @rollup/rollup-linux-x64-gnu +RUN yarn --network-timeout 600000 + +ARG NODE_ENV=production + +RUN yarn build:app:docker + +FROM 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/LICENSE b/LICENSE new file mode 100644 index 0000000..8a844bc --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Excalidraw + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..3c7265a --- /dev/null +++ b/README.md @@ -0,0 +1,129 @@ + + + + Excalidraw + + + +

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

+ +
+

+ An open source virtual hand-drawn style whiteboard.
+ Collaborative and end-to-end encrypted.
+
+

+
+ +
+

+ + Excalidraw is released under the MIT license. + + + npm downloads/month + + + PRs welcome! + + + Chat on Discord + + + Follow Excalidraw on Twitter + +

+ +
+
+ + Product showcase + +
+

+ Create beautiful hand-drawn like diagrams, wireframes, or whatever you like. +

+
+
+
+ +## Features + +The Excalidraw editor (npm package) supports: + +- 💯 Free & open-source. +- 🎨 Infinite, canvas-based whiteboard. +- ✍️ Hand-drawn like style. +- 🌓 Dark mode. +- 🏗️ Customizable. +- 📷 Image support. +- 😀 Shape libraries 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... +- ➡️ Arrow-binding & labeled arrows. +- 🔙 Undo / Redo. +- 🔍 Zoom and panning support. + +## Excalidraw.com + +The app hosted at [excalidraw.com](https://excalidraw.com) is a minimal showcase of what you can build with Excalidraw. Its [source code](https://github.com/excalidraw/excalidraw/tree/master/excalidraw-app) is part of this repository as well, and the app features: + +- 📡 PWA support (works offline). +- 🤼 Real-time collaboration. +- 🔒 End-to-end encryption. +- 💾 Local-first support (autosaves to the browser). +- 🔗 Shareable links (export to a readonly link you can share with others). + +We'll be adding these features as drop-in plugins for the npm package in the future. + +## Quick start + +**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). + +``` +npm install react react-dom @excalidraw/excalidraw +``` + +or via yarn + +``` +yarn add react react-dom @excalidraw/excalidraw +``` + +Check out our [documentation](https://docs.excalidraw.com/docs/@excalidraw/excalidraw/installation) for more details! + +## Contributing + +- Missing something or found a bug? [Report here](https://github.com/excalidraw/excalidraw/issues). +- Want to contribute? Check out our [contribution guide](https://docs.excalidraw.com/docs/introduction/contributing) or let us know on [Discord](https://discord.gg/UexuTaE). +- Want to help with translations? See the [translation guide](https://docs.excalidraw.com/docs/introduction/contributing#translating). + +## Integrations + +- [VScode extension](https://marketplace.visualstudio.com/items?itemName=pomdtr.excalidraw-editor) +- [npm package](https://www.npmjs.com/package/@excalidraw/excalidraw) + +## Who's integrating Excalidraw + +[Google Cloud](https://googlecloudcheatsheet.withgoogle.com/architecture) • [Meta](https://meta.com/) • [CodeSandbox](https://codesandbox.io/) • [Obsidian Excalidraw](https://github.com/zsviczian/obsidian-excalidraw-plugin) • [Replit](https://replit.com/) • [Slite](https://slite.com/) • [Notion](https://notion.so/) • [HackerRank](https://www.hackerrank.com/) • and many others + +## Sponsors & support + +If you like the project, you can become a sponsor at [Open Collective](https://opencollective.com/excalidraw) or use [Excalidraw+](https://plus.excalidraw.com/). + +## Thank you for supporting Excalidraw + +[](https://opencollective.com/excalidraw/tiers/sponsors/0/website) [](https://opencollective.com/excalidraw/tiers/sponsors/1/website) [](https://opencollective.com/excalidraw/tiers/sponsors/2/website) [](https://opencollective.com/excalidraw/tiers/sponsors/3/website) [](https://opencollective.com/excalidraw/tiers/sponsors/4/website) [](https://opencollective.com/excalidraw/tiers/sponsors/5/website) [](https://opencollective.com/excalidraw/tiers/sponsors/6/website) [](https://opencollective.com/excalidraw/tiers/sponsors/7/website) [](https://opencollective.com/excalidraw/tiers/sponsors/8/website) [](https://opencollective.com/excalidraw/tiers/sponsors/9/website) [](https://opencollective.com/excalidraw/tiers/sponsors/10/website) + + + +Last but not least, we're thankful to these companies for offering their services for free: + +[![Vercel](./.github/assets/vercel.svg)](https://vercel.com) [![Sentry](./.github/assets/sentry.svg)](https://sentry.io) [![Crowdin](./.github/assets/crowdin.svg)](https://crowdin.com) diff --git a/crowdin.yml b/crowdin.yml new file mode 100644 index 0000000..ccb8a17 --- /dev/null +++ b/crowdin.yml @@ -0,0 +1,3 @@ +files: + - source: /packages/excalidraw/locales/en.json + translation: /packages/excalidraw/locales/%locale%.json diff --git a/dev-docs/.gitignore b/dev-docs/.gitignore new file mode 100644 index 0000000..b2d6de3 --- /dev/null +++ b/dev-docs/.gitignore @@ -0,0 +1,20 @@ +# Dependencies +/node_modules + +# Production +/build + +# Generated files +.docusaurus +.cache-loader + +# Misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/dev-docs/README.md b/dev-docs/README.md new file mode 100644 index 0000000..aaba2fa --- /dev/null +++ b/dev-docs/README.md @@ -0,0 +1,41 @@ +# Website + +This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. + +### Installation + +``` +$ yarn +``` + +### Local Development + +``` +$ yarn start +``` + +This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. + +### Build + +``` +$ yarn build +``` + +This command generates static content into the `build` directory and can be served using any static contents hosting service. + +### Deployment + +Using SSH: + +``` +$ USE_SSH=true yarn deploy +``` + +Not using SSH: + +``` +$ GIT_USER= yarn deploy +``` + +If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. diff --git a/dev-docs/babel.config.js b/dev-docs/babel.config.js new file mode 100644 index 0000000..bfd75db --- /dev/null +++ b/dev-docs/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: [require.resolve("@docusaurus/core/lib/babel/preset")], +}; diff --git a/dev-docs/docs/@excalidraw/excalidraw/api/api-intro.mdx b/dev-docs/docs/@excalidraw/excalidraw/api/api-intro.mdx new file mode 100644 index 0000000..aee7f3b --- /dev/null +++ b/dev-docs/docs/@excalidraw/excalidraw/api/api-intro.mdx @@ -0,0 +1,11 @@ +--- +slug: /@excalidraw/excalidraw/api +--- + +# API + +Currently the **API** is divided into 3 broad categories 👇 + +- [Props](/docs/@excalidraw/excalidraw/api/props) - The `props` you can pass to the `Excalidraw` component. +- [Children components](/docs/@excalidraw/excalidraw/api/children-components) - Official components you can use to customize the UI. +- [Utils](/docs/@excalidraw/excalidraw/api/utils) - Utilities and helpers you can use to export, restore and more. diff --git a/dev-docs/docs/@excalidraw/excalidraw/api/children-components/children-components-intro.mdx b/dev-docs/docs/@excalidraw/excalidraw/api/children-components/children-components-intro.mdx new file mode 100644 index 0000000..06bb1cb --- /dev/null +++ b/dev-docs/docs/@excalidraw/excalidraw/api/children-components/children-components-intro.mdx @@ -0,0 +1,22 @@ +--- +sidebar_label: Children Components +slug: /@excalidraw/excalidraw/api/children-components +--- + +# `` children + +We expose several components you can render as children of the `` component to customize the UI. + +:::info + +We have only recently started migrating to this type of component API. Some UI components are still using render props, and some UI customization isn't supported yet (such as the toolbar or the element properties panel). Stay tuned for more updates! + +::: + +Below are the currently supported components: + +- [MainMenu](/docs/@excalidraw/excalidraw/api/children-components/main-menu) +- [WelcomeScreen](/docs/@excalidraw/excalidraw/api/children-components/welcome-screen) +- [Sidebar](/docs/@excalidraw/excalidraw/api/children-components/sidebar) +- [Footer](/docs/@excalidraw/excalidraw/api/children-components/footer) +- [LiveCollaborationTrigger](/docs/@excalidraw/excalidraw/api/children-components/live-collaboration-trigger) diff --git a/dev-docs/docs/@excalidraw/excalidraw/api/children-components/footer.mdx b/dev-docs/docs/@excalidraw/excalidraw/api/children-components/footer.mdx new file mode 100644 index 0000000..3831268 --- /dev/null +++ b/dev-docs/docs/@excalidraw/excalidraw/api/children-components/footer.mdx @@ -0,0 +1,68 @@ +# Footer + +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. + +**Usage** + +```jsx live +function App() { + return ( +
+ +
+ +
+
+
+ ); +} +``` + +This will only 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. + +Open the `Menu` in the below playground and you will see the `custom footer` rendered. + +```jsx live noInline +const MobileFooter = ({}) => { + const device = useDevice(); + if (device.editor.isMobile) { + return ( +
+ +
+ ); + } + return null; +}; + +const App = () => ( +
+ + + Item1 + Item 2 + + + +
+); + +// 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/dev-docs/docs/@excalidraw/excalidraw/api/children-components/live-collaboration-trigger.mdx b/dev-docs/docs/@excalidraw/excalidraw/api/children-components/live-collaboration-trigger.mdx new file mode 100644 index 0000000..ef74d0e --- /dev/null +++ b/dev-docs/docs/@excalidraw/excalidraw/api/children-components/live-collaboration-trigger.mdx @@ -0,0 +1,62 @@ +# LiveCollaborationTrigger + +If you implement live collaboration support and want to expose the same UI button as on [excalidraw.com](https://excalidraw.com), you can render the `` component using the [renderTopRightUI](/docs/@excalidraw/excalidraw/api/props#rendertoprightui) prop. + +You'll need to supply `onSelect()` to handle opening of your collaboration dialog, but the button will display `appState.collaborators` count provided you have supplied it. + +| Prop | Type | Required | Default | Description | +| --- | --- | --- | --- | --- | +| `onSelect` | `function` | Yes | | Handler called when the user clicks on the button | +| `isCollaborating` | `boolean` | Yes | false | Whether live collaboration session is in effect. Modifies button style. | + +```tsx live +function App() { + const [excalidrawAPI, setExcalidrawAPI] = useState(null); + const [isCollaborating, setIsCollaborating] = useState(false); + return ( +
+

+ Selecting the checkbox to see the collaborator count +

+ + setExcalidrawAPI(api)} + renderTopRightUI={() => ( + { + window.alert("You clicked on collab button"); + setIsCollaborating(true); + }} + /> + )} + > +
+ ); +} +``` diff --git a/dev-docs/docs/@excalidraw/excalidraw/api/children-components/main-menu.mdx b/dev-docs/docs/@excalidraw/excalidraw/api/children-components/main-menu.mdx new file mode 100644 index 0000000..b0062d9 --- /dev/null +++ b/dev-docs/docs/@excalidraw/excalidraw/api/children-components/main-menu.mdx @@ -0,0 +1,169 @@ +# MainMenu + +By default Excalidraw will render the `MainMenu` with default options. If you want to customise the `MainMenu`, you can pass the `MainMenu` component with the list options. + +**Usage** + +```jsx live +function App() { + return ( +
+ + + window.alert("Item1")}> + Item1 + + window.alert("Item2")}> + Item 2 + + + +
+ ); +} +``` + +### `` + +This is the `MainMenu` component. If you render it, you will need to populate the menu with your own items as we will not render any ourselves at that point. + +| Prop | Type | Required | Default | Description | +| --- | --- | :-: | :-: | --- | +| `onSelect` | `function` | No | - | Triggered when any item is selected (via mouse). Calling `event.preventDefault()` will stop menu from closing. | + +### MainMenu.Item + +To render an item, its recommended to use `MainMenu.Item`. + +| Prop | Type | Required | Default | Description | +| --- | --- | :-: | :-: | --- | +| `onSelect` | `function` | Yes | - | Triggered when selected (via mouse). Calling `event.preventDefault()` will stop menu from closing. | +| `selected` | `boolean` | No | `false` | Whether item is active | +| `children` | `React.ReactNode` | Yes | - | The content of the menu item | +| `icon` | `JSX.Element` | No | - | The icon used in the menu item | +| `shortcut` | `string` | No | - | The shortcut to be shown for the menu item | + +### MainMenu.ItemLink + +To render an item as a link, its recommended to use `MainMenu.ItemLink`. + +**Usage** + +```jsx live +function App() { + return ( +
+ + + + Google + + + Excalidraw + + + +
+ ); +} +``` + +| Prop | Type | Required | Default | Description | +| --- | --- | :-: | :-: | --- | +| `onSelect` | `function` | No | - | Triggered when selected (via mouse). Calling `event.preventDefault()` will stop menu from closing. | +| `selected` | `boolean` | No | `false` | Whether item is active | +| `href` | `string` | Yes | - | The `href` attribute to be added to the `anchor` element. | +| `children` | `React.ReactNode` | Yes | - | The content of the menu item | +| `icon` | `JSX.Element` | No | - | The icon used in the menu item | +| `shortcut` | `string` | No | - | The shortcut to be shown for the menu item | + +### MainMenu.ItemCustom + +To render a custom item, you can use `MainMenu.ItemCustom`. + +**Usage** + +```jsx live +function App() { + return ( +
+ + + + + + + +
+ ); +} +``` + +| Prop | Type | Required | Default | Description | +| --- | --- | :-: | :-: | --- | +| `children` | `React.ReactNode` | Yes | - | The content of the menu item | + +### MainMenu.DefaultItems + +For the items which are shown in the menu in [excalidraw.com](https://excalidraw.com), you can use `MainMenu.DefaultItems` + +```jsx live +function App() { + return ( +
+ + + + + window.alert("Item1")}> + Item1 + + window.alert("Item2")}> + Item 2 + + + +
+ ); +} +``` + +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 + +To Group item in the main menu, you can use `MainMenu.Group` + +```jsx live +function App() { + return ( +
+ + + + + + + + window.alert("Item1")}> + Item1 + + window.alert("Item2")}> + Item 2 + + + + +
+ ); +} +``` + +| Prop | Type | Required | Default | Description | +| --- | --- | :-: | :-: | --- | +| `children ` | `React.ReactNode` | Yes | - | The content of the `Menu Group` | diff --git a/dev-docs/docs/@excalidraw/excalidraw/api/children-components/sidebar.mdx b/dev-docs/docs/@excalidraw/excalidraw/api/children-components/sidebar.mdx new file mode 100644 index 0000000..ed12f64 --- /dev/null +++ b/dev-docs/docs/@excalidraw/excalidraw/api/children-components/sidebar.mdx @@ -0,0 +1,129 @@ +# Sidebar + +The editor comes with a default sidebar on the right in LTR (Left to Right) mode which contains the library. You can also add your own custom sidebar(s) by rendering this component as a child of ``. + +## Props + +| Prop | Type | Required | Description | +| --- | --- | --- | --- | +| `name` | `string` | Yes | Sidebar name that uniquely identifies it. | +| `children` | `React.ReactNode` | Yes | Content you want to render inside the sidebar. | +| `onStateChange` | `(state: AppState["openSidebar"]) => void` | No | Invoked on open/close or tab change. No need to act on this event, as the editor manages the sidebar open state on its own. | +| `onDock` | `(docked: boolean) => void` | No | Invoked when the user toggles the `dock` button. Passed the current docked state. | +| `docked` | `boolean` | No | Indicates whether the sidebar is `docked`. By default, the sidebar is `undocked`. If passed, the docking becomes controlled. | +| `className` | `string` | No | | +| `style` | `React.CSSProperties` | No | | + +At minimum, each sidebar needs to have a unique `name` prop, and render some content inside it, which can be either composed from the exported sidebar sub-components, or custom elements. + +Unless `docked={true}` is passed, the sidebar will close when the user clicks outside of it. It can also be closed using the close button in the header, if you render the `` component. + +Further, if the sidebader doesn't comfortably fit in the editor, it won't be dockable. To decide the breakpoint for docking you can use [UIOptions.dockedSidebarBreakpoint](/docs/@excalidraw/excalidraw/api/props/ui-options#dockedsidebarbreakpoint). + +To make your sidebar user-dockable, you need to supply `props.docked` (current docked state) alongside `props.onDock` callback (to listen for and handle docked state changes). The component doesn't track local state for the `docked` prop, so you need to manage it yourself. + +## Sidebar.Header + +| Prop | Type | Required | Description | +| --- | --- | --- | --- | +| `children` | `React.ReactNode` | No | Content you want to render inside the sidebar header next to the `close` / `dock` buttons. | +| `className` | `string` | No | | + +Renders a sidebar header which contains a close button, and a dock button (when applicable). You can also render custom content in addition. + +Can be nested inside specific tabs, or rendered as direct child of `` for the whole sidebar component. + +## Sidebar.Tabs + +| Prop | Type | Required | Description | +| ---------- | ----------------- | -------- | ------------------------------ | +| `children` | `React.ReactNode` | No | Container for individual tabs. | + +Sidebar may contain inner tabs. Each `` must be rendered inside this `` container component. + +## Sidebar.Tab + +| Prop | Type | Required | Description | +| ---------- | ----------------- | -------- | ---------------- | +| `tab` | `string` | Yes | Unique tab name. | +| `children` | `React.ReactNode` | No | Tab content. | + +Content of a given sidebar tab. It must be rendered inside ``. + +## Sidebar.TabTriggers + +| Prop | Type | Required | Description | +| --- | --- | --- | --- | +| `children` | `React.ReactNode` | No | Container for individual tab triggers. | + +Container component for tab trigger buttons to switch between tabs. + +## Sidebar.TabTrigger + +| Prop | Type | Required | Description | +| --- | --- | --- | --- | +| `tab` | `string` | Yes | Tab name to toggle. | +| `children` | `React.ReactNode` | No | Tab trigger content, such as a label. | + +A given tab trigger button that switches to a given sidebar tab. It must be rendered inside ``. + +## Sidebar.Trigger + +| Prop | Type | Required | Description | +| --- | --- | --- | --- | +| `name` | `string` | Yes | Sidebar name the trigger will control. | +| `tab` | `string` | No | Optional tab to open. | +| `onToggle` | `(open: boolean) => void` | No | Callback invoked on toggle. | +| `title` | `string` | No | A11y title. | +| `children` | `React.ReactNode` | No | Content (usually label) you want to render inside the button. | +| `icon` | `JSX.Element` | No | Trigger icon if any. | +| `className` | `string` | No | | +| `style` | `React.CSSProperties` | No | | + +You can use the [`ref.toggleSidebar({ name: "custom" })`](/docs/@excalidraw/excalidraw/api/props/excalidraw-api#toggleSidebar) api to control the sidebar, but we export a trigger button to make UI use cases easier. + +## Example + +```tsx live +function App() { + const [docked, setDocked] = useState(false); + + return ( +
+ + + + + Tab one! + Tab two! + + One + Two + + + + +
+ + Toggle Custom Sidebar + +
+
+
+ ); +} +``` diff --git a/dev-docs/docs/@excalidraw/excalidraw/api/children-components/welcome-screen.mdx b/dev-docs/docs/@excalidraw/excalidraw/api/children-components/welcome-screen.mdx new file mode 100644 index 0000000..8834870 --- /dev/null +++ b/dev-docs/docs/@excalidraw/excalidraw/api/children-components/welcome-screen.mdx @@ -0,0 +1,140 @@ +# WelcomeScreen + +When the canvas is empty, Excalidraw can show a welcome _splash_ screen with a logo, a few quick action items, and hints explaining what some of the UI buttons do. Once the user picks a tool, or has created an element on the canvas, the welcome screen will disappear. + +You can enable this behavior by rendering a `WelcomeScreen` component like this: + +```jsx live +function App() { + return ( +
+ + + +
+ ); +} +``` + +You can also customize the welcome screen by passing children to the `WelcomeScreen` component. See below. + +## + +This is the main component. If you render it without any children, we will render the default welcome screen. + +You can customize which welcome screen subcomponents are rendered by passing them as children. + +The welcome screen consists of two main groups of subcomponents: + +1. [WelcomeScreen.Center](#welcomescreencenterlogo). +2. [WeelcomeScreen.Hints](#welcomescreenhints). + +Excalidraw logo: Sketch hand-drawn like diagrams. + +### Center + +`` subcomponent is the center piece of the welcome screen, containing the `logo`, `heading`, and `menu`. All three subcomponents are optional, and you can render whatever you wish into the center component. + +```jsx live +function App() { + return ( +
+ + + + + + Welcome Screen Heading! + + + + Excalidraw GitHub + + + + + + +
+ ); +} +``` + +#### Logo + +Use the `` to render a logo. By default it renders the Excalidraw logo and name. Supply `children` to customize. + +#### Heading + +Use the `` to render a heading below the logo. Supply `children` to change the default message. + +#### Menu + +`` is a wrapper component for the menu items. You can build your menu using the `` and `` components, render your own, or render one of the default menu items. + +The default menu items are: + +- `` - opens the help dialog. + +- `` - open the load file dialog. + +- `` - intended to open the live collaboration dialog. Works similarly to [``](/docs/@excalidraw/excalidraw/api/children-components/live-collaboration-trigger) and you must supply `onSelect()` handler to integrate with your collaboration implementation. + +#### MenuItem + +The `` component can be used to render a menu item. + +| Prop | Type | Required | Default | Description | +| --- | --- | --- | --- | --- | +| `onSelect` | `function` | Yes | | The handler is triggered when the item is selected. | +| `children` | `React.ReactNode` | Yes | | The content of the menu item | +| `icon` | `JSX.Element` | No | | The icon used in the menu item | +| `shortcut` | `string` | No | | The keyboard shortcut (label-only, does not affect behavior) | + +**WelcomeScreen.Center.MenuItemLink** + +To render an external link in a menu item, you can use this component. + +| Prop | Type | Required | Default | Description | +| --- | --- | --- | --- | --- | +| `href` | `string` | Yes | | The `href` attribute to be added to the `anchor` element. | +| `children` | `React.ReactNode` | Yes | | The content of the menu item | +| `icon` | `JSX.Element` | No | | The icon used in the menu item | +| `shortcut` | `string` | No | | The keyboard shortcut (label-only, does not affect behavior) | + +### Hints + +These `` subcomponents render the UI hints. Text of each hint can be customized by supplying `children`. + +```jsx live +function App() { + return ( +
+ + + +

ToolBar Hints

+
+ + +
+
+
+ ); +} +``` + +#### MenuHint + +`` hint subcomponent for the main menu. Supply `children` to customize the hint text. + +#### ToolbarHint + +`` hint subcomponent for the toolbar. Supply `children` to customize the hint text. + +#### Help + +`` hint subcomponent for the help dialog. Supply `children` to customize the hint text. diff --git a/dev-docs/docs/@excalidraw/excalidraw/api/constants.mdx b/dev-docs/docs/@excalidraw/excalidraw/api/constants.mdx new file mode 100644 index 0000000..411cbb4 --- /dev/null +++ b/dev-docs/docs/@excalidraw/excalidraw/api/constants.mdx @@ -0,0 +1,46 @@ +# Constants + +### FONT_FAMILY + +**How to use** + +```js +import { FONT_FAMILY } from "@excalidraw/excalidraw"; +``` + +`FONT_FAMILY` contains all the font families used in `Excalidraw` as explained below + +| Font Family | Description | +| ----------- | ---------------------- | +| `Virgil` | The `Hand-drawn` font | +| `Helvetica` | The `Normal` Font | +| `Cascadia` | The `Code` Font | + +Defaults to `FONT_FAMILY.Virgil` unless passed in `initialData.appState.currentItemFontFamily`. + +### THEME + +**How to use** + +```js +import { THEME } from "@excalidraw/excalidraw"; +``` + +`THEME` contains all the themes supported by `Excalidraw` as explained below + +| Theme | Description | +| ------- | ----------------- | +| `LIGHT` | The `light` theme | +| `DARK` | The `Dark` theme | + +Defaults to `THEME.LIGHT` unless passed in `initialData.appState.theme` + +### MIME_TYPES + +[`MIME_TYPES`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/constants.ts#L101) contains all the mime types supported by `Excalidraw`. + +**How to use ** + +```js +import { MIME_TYPES } from "@excalidraw/excalidraw"; +``` diff --git a/dev-docs/docs/@excalidraw/excalidraw/api/excalidraw-element-skeleton.mdx b/dev-docs/docs/@excalidraw/excalidraw/api/excalidraw-element-skeleton.mdx new file mode 100644 index 0000000..b633236 --- /dev/null +++ b/dev-docs/docs/@excalidraw/excalidraw/api/excalidraw-element-skeleton.mdx @@ -0,0 +1,475 @@ +# Creating Elements programmatically + +We support a simplified API to make it easier to generate Excalidraw elements programmatically. This API is in beta and subject to change before stable. You can check the [PR](https://github.com/excalidraw/excalidraw/pull/6546) for more details. + +For this purpose we introduced a new type [`ExcalidrawElementSkeleton`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L133). This is the simplified version of [`ExcalidrawElement`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L134) type with the minimum possible attributes so that creating elements programmatically is much easier (especially for cases like binding arrows or creating text containers). + +The [`ExcalidrawElementSkeleton`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L133) can be converted to fully qualified Excalidraw elements by using [`convertToExcalidrawElements`](/docs/@excalidraw/excalidraw/api/excalidraw-element-skeleton#converttoexcalidrawelements). + +## convertToExcalidrawElements + +**_Signature_** + +```ts +convertToExcalidrawElements( + elements: ExcalidrawElementSkeleton, + opts?: { regenerateIds: boolean } +): ExcalidrawElement[] +``` + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `elements` | [ExcalidrawElementSkeleton](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L137) | | The Excalidraw element Skeleton which needs to be converted to Excalidraw elements. | +| `opts` | `{ regenerateIds: boolean }` | ` {regenerateIds: true}` | By default `id` will be regenerated for all the elements irrespective of whether you pass the `id` so if you don't want the ids to regenerated, you can set this attribute to `false`. | + +**_How to use_** + +```js +import { convertToExcalidrawElements } from "@excalidraw/excalidraw"; +``` + +This function converts the Excalidraw Element Skeleton to excalidraw elements which could be then rendered on the canvas. Hence calling this function is necessary before passing it to APIs like [`initialData`](https://docs.excalidraw.com/docs/@excalidraw/excalidraw/api/props/initialdata), [`updateScene`](https://docs.excalidraw.com/docs/@excalidraw/excalidraw/api/props/excalidraw-api#updatescene) if you are using the Skeleton API + +## Supported Features + +### Rectangle, Ellipse, and Diamond + +To create these shapes you need to pass its `type` and `x` and `y` coordinates for position. The rest of the attributes are optional\_. + +For the Skeleton API to work, `convertToExcalidrawElements` needs to be called before passing it to Excalidraw Component via initialData, updateScene or any such API. + +```jsx live +function App() { + const elements = convertToExcalidrawElements([ + { + type: "rectangle", + x: 100, + y: 250, + }, + { + type: "ellipse", + x: 250, + y: 250, + }, + { + type: "diamond", + x: 380, + y: 250, + }, + ]); + return ( +
+ +
+ ); +} +``` + +You can pass additional [`properties`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L27) as well to decorate the shapes. + +:::info + +You can copy the below test examples and replace the elements in the live editor above to test it out. + +::: + +```js +convertToExcalidrawElements([ + { + type: "rectangle", + x: 50, + y: 250, + width: 200, + height: 100, + backgroundColor: "#c0eb75", + strokeWidth: 2, + }, + { + type: "ellipse", + x: 300, + y: 250, + width: 200, + height: 100, + backgroundColor: "#ffc9c9", + strokeStyle: "dotted", + fillStyle: "solid", + strokeWidth: 2, + }, + { + type: "diamond", + x: 550, + y: 250, + width: 200, + height: 100, + backgroundColor: "#a5d8ff", + strokeColor: "#1971c2", + strokeStyle: "dashed", + fillStyle: "cross-hatch", + strokeWidth: 2, + }, +]); +``` + +![image](https://github.com/excalidraw/excalidraw/assets/11256141/70ca7063-88fb-434c-838a-cd466e1bc3c2) + +### Text Element + +The `type`, `x`, `y` and `text` properties are required to create a text element, rest of the attributes are optional + +```js +convertToExcalidrawElements([ + { + type: "text", + x: 100, + y: 100, + text: "HELLO WORLD!", + }, + { + type: "text", + x: 100, + y: 150, + text: "STYLED HELLO WORLD!", + fontSize: 20, + strokeColor: "#5f3dc4", + }, +]); +``` + +![image](https://github.com/excalidraw/excalidraw/assets/11256141/085c7ac3-7952-4f22-b9c3-6beb51438526) + +### Lines and Arrows + +The `type`, `x`, and `y` properties are required, rest of the attributes are optional + +```js +convertToExcalidrawElements([ + { + type: "arrow", + x: 100, + y: 20, + }, + { + type: "line", + x: 100, + y: 60, + }, +]); +``` + +![image](https://github.com/excalidraw/excalidraw/assets/11256141/0c22a06b-b568-4ab5-9848-a5f0160f66a6) + +#### With Addtional properties + +```js +convertToExcalidrawElements([ + { + type: "arrow", + x: 450, + y: 20, + startArrowhead: "dot", + endArrowhead: "triangle", + strokeColor: "#1971c2", + strokeWidth: 2, + }, + { + type: "line", + x: 450, + y: 60, + strokeColor: "#2f9e44", + strokeWidth: 2, + strokeStyle: "dotted", + }, +]); +``` + +![image](https://github.com/excalidraw/excalidraw/assets/11256141/14f1bf3f-ad81-4096-8c1c-f35235084ec5) + +### Text Containers + +In addition to `type`, `x` and `y` properties, [`label`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L124C7-L130C59) property is required for text containers. The `text` property in `label` is required, rest of the attributes are optional. + +If you don't provide the dimensions of container, we calculate it based of the label dimensions. + +```js +convertToExcalidrawElements([ + { + type: "rectangle", + x: 300, + y: 290, + label: { + text: "RECTANGLE TEXT CONTAINER", + }, + }, + { + type: "ellipse", + x: 500, + y: 100, + label: { + text: "ELLIPSE\n TEXT CONTAINER", + }, + }, + { + type: "diamond", + x: 100, + y: 100, + label: { + text: "DIAMOND\nTEXT CONTAINER", + }, + }, +]); +``` + +![image](https://github.com/excalidraw/excalidraw/assets/11256141/1e2c7b5d-fcb4-4f86-946d-0bfb0e97d532) + +#### With Additional properties + +```js +convertToExcalidrawElements([ + { + type: "diamond", + x: -120, + y: 100, + width: 270, + backgroundColor: "#fff3bf", + strokeWidth: 2, + label: { + text: "STYLED DIAMOND TEXT CONTAINER", + strokeColor: "#099268", + fontSize: 20, + }, + }, + { + type: "rectangle", + x: 180, + y: 150, + width: 200, + strokeColor: "#c2255c", + label: { + text: "TOP LEFT ALIGNED RECTANGLE TEXT CONTAINER", + textAlign: "left", + verticalAlign: "top", + fontSize: 20, + }, + }, + { + type: "ellipse", + x: 400, + y: 130, + strokeColor: "#f08c00", + backgroundColor: "#ffec99", + width: 200, + label: { + text: "STYLED ELLIPSE TEXT CONTAINER", + strokeColor: "#c2255c", + }, + }, +]); +``` + +![image](https://github.com/excalidraw/excalidraw/assets/11256141/f8123cd1-c9aa-452d-b96b-05c846c5030d) + +### Labelled Arrows + +Similar to Text Containers, you can create labelled arrows as well. + +```js +convertToExcalidrawElements([ + { + type: "arrow", + x: 100, + y: 100, + label: { + text: "LABELED ARROW", + }, + }, + { + type: "arrow", + x: 100, + y: 200, + label: { + text: "STYLED LABELED ARROW", + strokeColor: "#099268", + fontSize: 20, + }, + }, + { + type: "arrow", + x: 100, + y: 300, + strokeColor: "#1098ad", + strokeWidth: 2, + label: { + text: "ANOTHER STYLED LABELLED ARROW", + }, + }, + { + type: "arrow", + x: 100, + y: 400, + strokeColor: "#1098ad", + strokeWidth: 2, + label: { + text: "ANOTHER STYLED LABELLED ARROW", + strokeColor: "#099268", + }, + }, +]); +``` + +![image](https://github.com/excalidraw/excalidraw/assets/11256141/70635e9b-f1c8-4839-89e1-73b813abeb93) + +### Arrow bindings + +To bind arrow to a shape you need to specify its [`start`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L86) and [`end`](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/data/transform.ts#L54) properties. You need to pass either `type` or `id` property in `start` and `end` properties, rest of the attributes are optional + +```js +convertToExcalidrawElements([ + { + type: "arrow", + x: 255, + y: 239, + label: { + text: "HELLO WORLD!!", + }, + start: { + type: "rectangle", + }, + end: { + type: "ellipse", + }, + }, +]); +``` + +When position for `start` and `end ` properties are not specified, we compute it according to arrow position. + +![image](https://github.com/excalidraw/excalidraw/assets/11256141/5aff09fd-b7e8-4c63-98be-da40b0698704) + +```js +convertToExcalidrawElements([ + { + type: "arrow", + x: 255, + y: 239, + label: { + text: "HELLO WORLD!!", + }, + start: { + type: "text", + text: "HEYYYYY", + }, + end: { + type: "text", + text: "WHATS UP ?", + }, + }, +]); +``` + +![image](https://github.com/excalidraw/excalidraw/assets/11256141/2a9f03ac-e45c-4fbd-9be0-5d9f8c8e0343) + +#### When passing `id` + +Useful when you want to bind multiple arrows to one diagram / use some existing diagram + +```js +convertToExcalidrawElements([ + { + type: "ellipse", + id: "ellipse-1", + strokeColor: "#66a80f", + x: 390, + y: 356, + width: 150, + height: 150, + backgroundColor: "#d8f5a2", + }, + { + type: "diamond", + id: "diamond-1", + strokeColor: "#9c36b5", + width: 100, + x: -30, + y: 380, + }, + { + type: "arrow", + x: 100, + y: 440, + width: 295, + height: 35, + strokeColor: "#1864ab", + start: { + type: "rectangle", + width: 150, + height: 150, + }, + end: { + id: "ellipse-1", + }, + }, + { + type: "arrow", + x: 60, + y: 420, + width: 330, + strokeColor: "#e67700", + start: { + id: "diamond-1", + }, + end: { + id: "ellipse-1", + }, + }, +]); +``` + +![image](https://github.com/excalidraw/excalidraw/assets/11256141/a8b047c8-2eed-4aea-82a2-e1e6bbddb8d4) + +### Frames + +To create a frame, you need to pass `type`, `children` (list of Excalidraw element ids). The rest of the attributes are optional. + +```ts +{ + type: "frame"; + children: readonly ExcalidrawElement["id"][]; + name?: string; + } & Partial); +``` + +```ts +convertToExcalidrawElements([ + { + "type": "rectangle", + "x": 10, + "y": 10, + "strokeWidth": 2, + "id": "1" + }, + { + "type": "diamond", + "x": 120, + "y": 20, + "backgroundColor": "#fff3bf", + "strokeWidth": 2, + "label": { + "text": "HELLO EXCALIDRAW", + "strokeColor": "#099268", + "fontSize": 30 + }, + "id": "2" + }, + { + "type": "frame", + "children": ["1", "2"], + "name": "My frame" + }] +} +``` diff --git a/dev-docs/docs/@excalidraw/excalidraw/api/props/excalidraw-api.mdx b/dev-docs/docs/@excalidraw/excalidraw/api/props/excalidraw-api.mdx new file mode 100644 index 0000000..f68b4bd --- /dev/null +++ b/dev-docs/docs/@excalidraw/excalidraw/api/props/excalidraw-api.mdx @@ -0,0 +1,442 @@ +# excalidrawAPI + +
+  (api:{" "}
+  
+    ExcalidrawAPI
+  
+  ) => void;
+
+ +Once the callback is triggered, you will need to store the api in state to access it later. + +```jsx showLineNumbers +export default function App() { + const [excalidrawAPI, setExcalidrawAPI] = useState(null); + return setExcalidrawAPI(api)} />; +} +``` + +You can use this prop when you want to access some [Excalidraw APIs](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L616). We expose the below APIs :point_down: + +| API | Signature | Usage | +| --- | --- | --- | +| [updateScene](#updatescene) | `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 | +| [getSceneElements](#getsceneelements) | `function` | Returns all the elements excluding the deleted in the scene | +| [getAppState](#getappstate) | `function` | Returns current appState | +| [history](#history) | `object` | This is the history API. `history.clear()` will clear the history | +| [scrollToContent](#scrolltocontent) | `function` | Scroll the nearest element out of the elements supplied to the center. Defaults to the elements on the scene. | +| [refresh](#refresh) | `function` | Updates the offsets for the Excalidraw component so that the coordinates are computed correctly (for example the cursor position). | +| [setToast](#settoast) | `function` | This API can be used to show the toast with custom message. | +| [id](#id) | `string` | Unique ID for the excalidraw component. | +| [getFiles](#getfiles) | `function` | This API can be used to get the files present in the scene. | +| [setActiveTool](#setactivetool) | `function` | This API can be used to set the active tool | +| [setCursor](#setcursor) | `function` | This API can be used to set customise the mouse cursor on the canvas | +| [resetCursor](#resetcursor) | `function` | This API can be used to reset to default mouse cursor on the canvas | +| [toggleSidebar](#toggleSidebar) | `function` | Toggles specific sidebar on/off | +| [onChange](#onChange) | `function` | Subscribes to change events | +| [onPointerDown](#onPointerDown) | `function` | Subscribes to `pointerdown` events | +| [onPointerUp](#onPointerUp) | `function` | Subscribes to `pointerup` events | + +:::info The `Ref` support has been removed in v0.17.0 so if you are using refs, please update the integration to use the `excalidrawAPI`. + +Additionally `ready` and `readyPromise` from the API have been discontinued. These APIs were found to be superfluous, and as part of the effort to streamline the APIs and maintain simplicity, they were removed in version v0.17.0. + +::: + +## updateScene + +
+  (scene:{" "}
+  
+    sceneData
+  
+  ) => void
+
+ +You can use this function to update the scene with the sceneData. It accepts the below attributes. + +| Name | Type | Description | +| --- | --- | --- | +| `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. | +| `commitToStore` | `boolean` | Implies if the change should be captured and commited to the `store`. Commited changes are emmitted and listened to by other components, such as `History` for undo / redo purposes. Defaults to `false`. | + +```jsx live +function App() { + const updateScene = () => { + const sceneData = { + elements: [ + { + type: "rectangle", + version: 141, + versionNonce: 361174001, + isDeleted: false, + id: "oDVXy8D6rom3H1-LLH2-f", + fillStyle: "hachure", + strokeWidth: 1, + strokeStyle: "solid", + roughness: 1, + opacity: 100, + angle: 0, + x: 100.50390625, + y: 93.67578125, + strokeColor: "#c92a2a", + backgroundColor: "transparent", + width: 186.47265625, + height: 141.9765625, + seed: 1968410350, + groupIds: [], + boundElements: null, + locked: false, + link: null, + updated: 1, + roundness: { + type: 3, + value: 32, + }, + }, + ], + appState: { + viewBackgroundColor: "#edf2ff", + }, + }; + excalidrawAPI.updateScene(sceneData); + }; + const [excalidrawAPI, setExcalidrawAPI] = useState(null); + return ( +
+

Click to update the scene

+ + setExcalidrawAPI(api)} /> +
+ ); +} +``` + +### updateLibrary + +
+  (opts: { 
libraryItems:{" "} + + LibraryItemsSource + + ;
merge?: boolean;
prompt?: boolean; +
openLibraryMenu?: boolean; +
defaultStatus?: "unpublished" | "published";
}) => Promise< + + LibraryItems + + > +
+ +You can use this function to update the library. It accepts the below attributes. + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `libraryItems` | [LibraryItemsSource](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L249) | \_ | The `libraryItems` to be replaced/merged with current library | +| `merge` | boolean | `false` | Whether to merge with existing library items. | +| `prompt` | boolean | `false` | Whether to prompt user for confirmation. | +| `openLibraryMenu` | boolean | `false` | Keep the library menu open after library is updated. | +| `defaultStatus` | "unpublished" | "published" | `"unpublished"` | Default library item's `status` if not present. | + +```tsx live +function App() { + const [excalidrawAPI, setExcalidrawAPI] = useState(null); + + useEffect(() => { + if (!excalidrawAPI) { + return; + } + // to open the library sidebar + excalidrawAPI.updateScene({ appState: { openSidebar: "library" } }); + }, [excalidrawAPI]); + + return ( +
+

Click to update the library items

+ + setExcalidrawAPI(api)} + // initial data retrieved from https://github.com/excalidraw/excalidraw/blob/master/dev-docs/packages/excalidraw/initialData.js + initialData={{ + libraryItems: initialData.libraryItems, + appState: { openSidebar: "library" }, + }} + /> +
+ ); +} +``` + +### addFiles + +
+  (files:{" "}
+  
+    BinaryFileData
+  
+  ) => void
+
+ +Adds supplied files data to the `appState.files` cache on top of existing files present in the cache. + +## resetScene + +```tsx +(opts?: { resetLoadingState: boolean }) => void +``` + +Resets the scene. If `resetLoadingState` is passed as true then it will also force set the loading state to false. + +## getSceneElementsIncludingDeleted + +
+  () =>{" "}
+  
+    ExcalidrawElement[]
+  
+
+ +Returns all the elements including the deleted in the scene. + +## getSceneElements + +
+  () => NonDeleted<
+  
+    ExcalidrawElement
+  
+  []>
+
+ +Returns all the elements excluding the deleted in the scene + +## getAppState + +
+  () =>{" "}
+  
+    AppState
+  
+
+ +Returns current appState. + +## history + +```tsx +{ + clear: () => void +} +``` + +This is the history API. history.clear() will clear the history. + +## scrollToContent + +```tsx +( + target?: ExcalidrawElement | ExcalidrawElement[], + opts?: + | { + fitToContent?: boolean; + animate?: boolean; + duration?: number; + } + | { + fitToViewport?: boolean; + viewportZoomFactor?: number; + animate?: boolean; + duration?: number; + } +) => void +``` + +Scroll the nearest element out of the elements supplied to the center of the viewport. Defaults to the elements on the scene. + +| Attribute | type | default | Description | +| --- | --- | --- | --- | +| target | [ExcalidrawElement](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L115) | [ExcalidrawElement[]](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L115) | All scene elements | The element(s) to scroll to. | +| opts.fitToContent | boolean | false | Whether to fit the elements to viewport by automatically changing zoom as needed. Note that the zoom range is between 10%-100%. | +| opts.fitToViewport | boolean | false | Similar to fitToContent but the zoom range is not limited. If elements are smaller than the viewport, zoom will go above 100%. | +| opts.viewportZoomFactor | number | 0.7 | when fitToViewport=true, how much screen should the content cover, between 0.1 (10%) and 1 (100%) | +| opts.animate | boolean | false | Whether to animate between starting and ending position. Note that for larger scenes the animation may not be smooth due to performance issues. | +| opts.duration | number | 500 | Duration of the animation if `opts.animate` is `true`. | + +## refresh + +```tsx +() => void +``` + +Updates the `offsets` for the `Excalidraw` component so that the coordinates are computed correctly (for example the cursor position). + +You don't have to call this when the position is changed on page scroll or when the excalidraw container resizes (we handle that ourselves). + +For any other cases if the position of excalidraw is updated (example due to scroll on parent container and not page scroll) you should call this API. + +## setToast + +This API can be used to show the toast with custom message. + +```tsx +({ message: string, closable?:boolean,duration?:number + } | null) => void +``` + +| Attribute | type | Description | +| --- | --- | --- | +| message | string | The message to be shown on the toast. | +| closable | boolean | Indicates whether to show the closable button on toast to dismiss the toast. | +| duration | number | Determines the duration after which the toast should auto dismiss. To prevent autodimiss you can pass `Infinity`. | + +To dismiss an existing toast you can simple pass `null` + +```js +setToast(null); +``` + +## id + +The unique id of the excalidraw component. This can be used to identify the excalidraw component, for example importing the library items to the excalidraw component from where it was initiated when you have multiple excalidraw components rendered on the same page as shown in [multiple excalidraw demo](https://codesandbox.io/s/multiple-excalidraw-k1xx5). + +## getFiles + +
+  () =>{" "}
+  
+    files
+  
+
+ +This API can be used to get the files present in the scene. It may contain files that aren't referenced by any element, so if you're persisting the files to a storage, you should compare them against stored elements. + +## setActiveTool + +This API has the below signature. It sets the `tool` passed in param as the active tool. + +```ts +( + tool: ( + | ( + | { type: Exclude } + | { + type: Extract; + insertOnCanvasDirectly?: boolean; + } + ) + | { type: "custom"; customType: string } + ) & { locked?: boolean }, +) => {}; +``` + +| 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` | +| `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 + +This API can be used to customise the mouse cursor on the canvas and has the below signature. It sets the mouse cursor to the cursor passed in param. + +```tsx +(cursor: string) => void +``` + +## toggleSidebar + +```tsx +(opts: { name: string; tab?: string; force?: boolean }) => boolean; +``` + +This API can be used to toggle sidebar, optionally opening a specific sidebar tab. It returns whether the sidebar was toggled on or off. If the `force` flag passed, it will force the sidebar to be toggled either on/off. + +This API is especially useful when you render a custom [``](/docs/@excalidraw/excalidraw/api/children-components/sidebar), and you want to toggle it from your app based on a user action. + +## resetCursor + +```tsx +() => void +``` + +This API can be used to reset to default mouse cursor. + +## onChange + +```tsx +( + callback: ( + elements: readonly ExcalidrawElement[], + appState: AppState, + files: BinaryFiles, + ) => void +) => () => void +``` + +Subscribes to change events, similar to [`props.onChange`](/docs/@excalidraw/excalidraw/api/props#onchange). + +Returns an unsubscribe function. + +## onPointerDown + +```tsx +( + callback: ( + activeTool: AppState["activeTool"], + pointerDownState: PointerDownState, + event: React.PointerEvent, + ) => void, +) => () => void +``` + +Subscribes to canvas `pointerdown` events. + +Returns an unsubscribe function. + +## onPointerUp + +```tsx +( + callback: ( + activeTool: AppState["activeTool"], + pointerDownState: PointerDownState, + event: PointerEvent, + ) => void, +) => () => void +``` + +Subscribes to canvas `pointerup` events. + +Returns an unsubscribe function. diff --git a/dev-docs/docs/@excalidraw/excalidraw/api/props/initialdata.mdx b/dev-docs/docs/@excalidraw/excalidraw/api/props/initialdata.mdx new file mode 100644 index 0000000..0fec6ea --- /dev/null +++ b/dev-docs/docs/@excalidraw/excalidraw/api/props/initialdata.mdx @@ -0,0 +1,55 @@ +# initialData + +
+{ elements?: ExcalidrawElement[], appState?: AppState }
+
+ +This helps to load Excalidraw with `initialData`. It must be an object or a [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise) which resolves to an object containing the below optional fields. + +| Name | Type | Description | +| --- | --- | --- | +| `elements` | [ExcalidrawElement[]](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/element/types.ts#L114) | The `elements` with which `Excalidraw` should be mounted. | +| `appState` | [AppState](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95) | The `AppState` with which `Excalidraw` should be mounted. | +| `scrollToContent` | `boolean` | This attribute indicates whether to `scroll` to the nearest element to center once `Excalidraw` is mounted. By default, it will not scroll the nearest element to the center. Make sure you pass `initialData.appState.scrollX` and `initialData.appState.scrollY` when `scrollToContent` is false so that scroll positions are retained | +| `libraryItems` | [LibraryItems](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L247) | Promise<[LibraryItems](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L200)> | This library items with which `Excalidraw` should be mounted. | +| `files` | [BinaryFiles](https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L82) | The `files` added to the scene. | + +You might want to use this when you want to load excalidraw with some initial elements and app state. + +```jsx live +function App() { + return ( +
+ +
+ ); +} +``` diff --git a/dev-docs/docs/@excalidraw/excalidraw/api/props/props.mdx b/dev-docs/docs/@excalidraw/excalidraw/api/props/props.mdx new file mode 100644 index 0000000..e25aedc --- /dev/null +++ b/dev-docs/docs/@excalidraw/excalidraw/api/props/props.mdx @@ -0,0 +1,260 @@ +# Props + +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 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 | +| [`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 | +| [`renderEmbeddable`](/docs/@excalidraw/excalidraw/api/props/render-props#renderEmbeddable) | `function` | \_ | Render function that can override the built-in `