diff --git a/apps/examples/src/examples/external-ui-context/ExternalUiContextExample.tsx b/apps/examples/src/examples/external-ui-context/ExternalUiContextExample.tsx new file mode 100644 index 000000000..37815f35d --- /dev/null +++ b/apps/examples/src/examples/external-ui-context/ExternalUiContextExample.tsx @@ -0,0 +1,74 @@ +import { Editor, Tldraw, useValue } from '@tldraw/tldraw' +import '@tldraw/tldraw/tldraw.css' +import { createContext, useContext, useState } from 'react' +import './external-ui.css' + +// There's a guide at the bottom of this file! + +// [1] +const editorContext = createContext({} as { editor: Editor }) + +export default function ExternalUiExample2() { + const [editor, setEditor] = useState(null) + + return ( +
+
+ setEditor(editor)} + components={{ Toolbar: null }} + /> +
+ {/* [3] */} + {editor && ( + + + + )} +
+ ) +} + +// [4] +const ExternalToolbar = () => { + const { editor } = useContext(editorContext) + + const currentToolId = useValue('current tool id', () => editor?.getCurrentToolId(), [editor]) + + return ( +
+
+ + +
+
+ ) +} + +/* + +[1] +Use React context to store the editor at a higher place in the React component tree. + +[2] +Use the `onMount` prop to get the editor instance and store it in state. + +[3] +When we have an editor in state, render the context provider and its descendants. + +[4] +You can access the editor from any of the provider's descendants. +*/ diff --git a/apps/examples/src/examples/external-ui-context/README.md b/apps/examples/src/examples/external-ui-context/README.md new file mode 100644 index 000000000..b1f825e45 --- /dev/null +++ b/apps/examples/src/examples/external-ui-context/README.md @@ -0,0 +1,15 @@ +--- +title: External UI (Context) +component: ./ExternalUiContextExample.tsx +category: ui +--- + +This example shows how to control the tldraw editor from an external UI, outside of the `Tldraw` component. This example shows how to pass a reference +to the editor around using React Context. + +--- + +This example shows how to control the tldraw editor from an external UI, outside +of the `Tldraw` component. There are a few ways of doing this—for example, by putting the editor on the window object, passing it around via props, or using React context. + +In this example, we use React context to distribute a reference to the editor to child components. diff --git a/apps/examples/src/examples/external-ui-context/external-ui.css b/apps/examples/src/examples/external-ui-context/external-ui.css new file mode 100644 index 000000000..78a18ae9b --- /dev/null +++ b/apps/examples/src/examples/external-ui-context/external-ui.css @@ -0,0 +1,20 @@ +.external-toolbar { + display: flex; + align-items: center; + justify-content: center; + padding: 8px; + gap: 8px; +} + +.external-button { + pointer-events: all; + padding: 4px 12px; + background: white; + border: 1px solid black; + border-radius: 16px; +} + +.external-button[data-isactive='true'] { + background-color: black; + color: white; +} diff --git a/apps/examples/src/examples/external-ui/ExternalUiExample.tsx b/apps/examples/src/examples/external-ui/ExternalUiExample.tsx new file mode 100644 index 000000000..e04834fd2 --- /dev/null +++ b/apps/examples/src/examples/external-ui/ExternalUiExample.tsx @@ -0,0 +1,56 @@ +import { Editor, Tldraw, useValue } from '@tldraw/tldraw' +import '@tldraw/tldraw/tldraw.css' +import { useState } from 'react' +import './external-ui.css' + +// There's a guide at the bottom of this file! + +export default function ExternalUiExample() { + // [1] + const [editor, setEditor] = useState(null) + + const currentToolId = useValue('current tool id', () => editor?.getCurrentToolId(), [editor]) + + return ( +
+
+ setEditor(editor)} + components={{ Toolbar: null }} + /> +
+ {/* [3] */} +
+
+ + +
+
+
+ ) +} + +/* +[1] +Use React state to store the editor instance. + +[2] +Use the `onMount` prop to get the editor instance and store it in state. + +[3] +Use data from the editor instance or use the editor's methods to control the editor. +Note that these callbacks also need to work if the editor isn't mounted yet. +*/ diff --git a/apps/examples/src/examples/external-ui/README.md b/apps/examples/src/examples/external-ui/README.md new file mode 100644 index 000000000..96971c238 --- /dev/null +++ b/apps/examples/src/examples/external-ui/README.md @@ -0,0 +1,14 @@ +--- +title: External UI +component: ./ExternalUiExample.tsx +category: ui +--- + +This example shows how to control the tldraw editor from an external UI, outside of the `Tldraw` component. + +--- + +This example shows how to control the tldraw editor from an external UI, outside +of the `Tldraw` component. There are a few ways of doing this—for example, by putting the editor on the window object, passing it around via props, or using React context. + +In this example, we'll just put the editor instance in state and use it in the same component. See the External UI Example 2 for an alternative (and more realistic) solution using React context. diff --git a/apps/examples/src/examples/external-ui/external-ui.css b/apps/examples/src/examples/external-ui/external-ui.css new file mode 100644 index 000000000..78a18ae9b --- /dev/null +++ b/apps/examples/src/examples/external-ui/external-ui.css @@ -0,0 +1,20 @@ +.external-toolbar { + display: flex; + align-items: center; + justify-content: center; + padding: 8px; + gap: 8px; +} + +.external-button { + pointer-events: all; + padding: 4px 12px; + background: white; + border: 1px solid black; + border-radius: 16px; +} + +.external-button[data-isactive='true'] { + background-color: black; + color: white; +} diff --git a/apps/examples/src/examples/image-component/TldrawImageExample.tsx b/apps/examples/src/examples/image-component/TldrawImageExample.tsx index 5c82eac8b..98576c63a 100644 --- a/apps/examples/src/examples/image-component/TldrawImageExample.tsx +++ b/apps/examples/src/examples/image-component/TldrawImageExample.tsx @@ -100,8 +100,8 @@ and viewing it. [2] You can specify which page to display by using the `pageId` prop. By default, the first page is shown. - + [3] You can customize the appearance of the image by passing other props to the - `TldrawImage` component. For example, you can toggle the background, set the - dark mode, and specify the viewport bounds. + `TldrawImage` component. For example, you can toggle the background, set + the dark mode, and specify the viewport bounds. */