diff --git a/.env.development b/.env.development index d67b137d1d..bee5d8944b 100644 --- a/.env.development +++ b/.env.development @@ -10,6 +10,9 @@ VITE_APP_WS_SERVER_URL=http://localhost:3002 # set this only if using the collaboration workflow we use on excalidraw.com VITE_APP_PORTAL_URL= +VITE_APP_PLUS_LP=https://plus.excalidraw.com +VITE_APP_PLUS_APP=https://app.excalidraw.com + VITE_APP_FIREBASE_CONFIG='{"apiKey":"AIzaSyCMkxA60XIW8KbqMYL7edC4qT5l4qHX2h8","authDomain":"excalidraw-oss-dev.firebaseapp.com","projectId":"excalidraw-oss-dev","storageBucket":"excalidraw-oss-dev.appspot.com","messagingSenderId":"664559512677","appId":"1:664559512677:web:a385181f2928d328a7aa8c"}' # put these in your .env.local, or make sure you don't commit! diff --git a/.env.production b/.env.production index b0570f2a03..19df4b96e5 100644 --- a/.env.production +++ b/.env.production @@ -5,11 +5,14 @@ VITE_APP_LIBRARY_URL=https://libraries.excalidraw.com VITE_APP_LIBRARY_BACKEND=https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries VITE_APP_PORTAL_URL=https://portal.excalidraw.com + +VITE_APP_PLUS_LP=https://plus.excalidraw.com +VITE_APP_PLUS_APP=https://app.excalidraw.com + # Fill to set socket server URL used for collaboration. # Meant for forks only: excalidraw.com uses custom VITE_APP_PORTAL_URL flow VITE_APP_WS_SERVER_URL= 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_PLUS_APP=https://app.excalidraw.com VITE_APP_DISABLE_TRACKING= diff --git a/.github/assets/logo.png b/.github/assets/logo.png deleted file mode 100644 index d9b8953ebd..0000000000 Binary files a/.github/assets/logo.png and /dev/null differ diff --git a/README.md b/README.md index 48529165e6..3a3d1c4d61 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ - - Excalidraw + + Excalidraw 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 index 706adb594c..06bb1cbaf6 100644 --- 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 @@ -17,5 +17,6 @@ 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/sidebar.mdx b/dev-docs/docs/@excalidraw/excalidraw/api/children-components/sidebar.mdx new file mode 100644 index 0000000000..08445a1c34 --- /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/ref#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/excalidraw-element-skeleton.mdx b/dev-docs/docs/@excalidraw/excalidraw/api/excalidraw-element-skeleton.mdx new file mode 100644 index 0000000000..3c1baeeaf2 --- /dev/null +++ b/dev-docs/docs/@excalidraw/excalidraw/api/excalidraw-element-skeleton.mdx @@ -0,0 +1,429 @@ +# 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/src/data/transform.ts#L133). This is the simplified version of [`ExcalidrawElement`](https://github.com/excalidraw/excalidraw/blob/master/src/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/src/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_** + +
+  convertToExcalidrawElements(elements:{" "}
+  
+    ExcalidrawElementSkeleton
+  
+  )
+
+ +**_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/ref#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/src/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/src/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/src/data/transform.ts#L86) and [`end`](https://github.com/excalidraw/excalidraw/blob/master/src/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) diff --git a/dev-docs/docs/@excalidraw/excalidraw/api/props/props.mdx b/dev-docs/docs/@excalidraw/excalidraw/api/props/props.mdx index 104d9dccd4..5764528b61 100644 --- a/dev-docs/docs/@excalidraw/excalidraw/api/props/props.mdx +++ b/dev-docs/docs/@excalidraw/excalidraw/api/props/props.mdx @@ -17,7 +17,6 @@ All `props` are *optional*. | [`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. | -| [`renderSidebar`](/docs/@excalidraw/excalidraw/api/props/render-props#rendersidebar) | `function` | _ | Render function that renders custom sidebar. | | [`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 | diff --git a/dev-docs/docs/@excalidraw/excalidraw/api/props/ref.mdx b/dev-docs/docs/@excalidraw/excalidraw/api/props/ref.mdx index eaf58f758e..6edcc9b9e9 100644 --- a/dev-docs/docs/@excalidraw/excalidraw/api/props/ref.mdx +++ b/dev-docs/docs/@excalidraw/excalidraw/api/props/ref.mdx @@ -404,15 +404,15 @@ This API can be used to customise the mouse cursor on the canvas and has the bel (cursor: string) => void ``` -## toggleMenu +## toggleSidebar ```tsx -(type: "library" | "customSidebar", force?: boolean) => boolean; +(opts: { name: string; tab?: string; force?: boolean }) => boolean; ``` -This API can be used to toggle a specific menu (currently only the sidebars), and returns whether the menu was toggled on or off. If the `force` flag passed, it will force the menu to be toggled either on/off based on the `boolean` passed. +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 sidebar using [`renderSidebar`](#rendersidebar) prop, and you want to toggle it from your app based on a user action. +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 diff --git a/dev-docs/docs/@excalidraw/excalidraw/api/props/render-props.mdx b/dev-docs/docs/@excalidraw/excalidraw/api/props/render-props.mdx index 2cec0daefd..f0f4adc449 100644 --- a/dev-docs/docs/@excalidraw/excalidraw/api/props/render-props.mdx +++ b/dev-docs/docs/@excalidraw/excalidraw/api/props/render-props.mdx @@ -6,8 +6,7 @@ (isMobile: boolean, appState: AppState - - ) => JSX | null + ) => JSX | null A function returning `JSX` to render `custom` UI in the top right corner of the app. @@ -63,69 +62,14 @@ function App() { } ``` -## renderSidebar - -```tsx -() => JSX | null; -``` - -You can render `custom sidebar` using this prop. This sidebar is the same that the library menu sidebar is using, and can be used for any purposes your app needs. - -You need to import the `Sidebar` component from `excalidraw` package and pass your content as its `children`. The function `renderSidebar` should return the `Sidebar` instance. - -### Sidebar -The `` component takes these props (all are optional except `children`): - -| Prop | Type | Description | -| --- | --- | --- | -| `children` | `React.ReactNode` | Content you want to render inside the `sidebar`. | -| `onClose` | `function` | Invoked when the component is closed (by user, or the editor). No need to act on this event, as the editor manages the sidebar open state on its own. | -| `onDock` | `function` | Invoked when the user toggles the `dock` button. The callback recieves a `boolean` parameter `isDocked` which indicates whether the sidebar is `docked` | -| `docked` | `boolean` | Indicates whether the sidebar is`docked`. By default, the sidebar is `undocked`. If passed, the docking becomes controlled, and you are responsible for updating the `docked` state by listening on `onDock` callback. To decide the breakpoint for docking you can use [UIOptions.dockedSidebarBreakpoint](/docs/@excalidraw/excalidraw/api/props/ui-options#dockedsidebarbreakpoint) for more info on docking. | -| `dockable` | `boolean` | Indicates whether to show the `dock` button so that user can `dock` the sidebar. If `false`, you can still dock programmatically by passing `docked` as `true`. | - -The sidebar will always include a header with `close / dock` buttons (when applicable). -You can also add custom content to the header, by rendering `` as a child of the `` component. Note that the custom header will still include the default buttons. - - -### Sidebar.Header - -| name | type | description | -| --- | --- | --- | -| children | `React.ReactNode` | Content you want to render inside the sidebar header as a sibling of `close` / `dock` buttons. | - -To control the visibility of the sidebar you can use [`toggleMenu("customSidebar")`](/docs/@excalidraw/excalidraw/api/props/ref#togglemenu) api available via `ref`. - -```tsx live -function App() { - const [excalidrawAPI, setExcalidrawAPI] = useState(null); - - return ( -
- - setExcalidrawAPI(api)} - renderSidebar={() => { - return ( - - Custom Sidebar Header -

custom Sidebar Content

-
- ); - }} - /> -
- ); -} -``` - ## renderEmbeddable
-  (element: NonDeleted<ExcalidrawEmbeddableElement>, appState: AppState) => JSX.Element | null
+  (element: NonDeleted<ExcalidrawEmbeddableElement>, appState:{" "}
+  
+    AppState
+  
+  ) => JSX.Element | null
 
Allows you to replace the renderer for embeddable elements (which renders `