diff --git a/apps/examples/src/examples/custom-styles/CustomStylesExample.tsx b/apps/examples/src/examples/custom-styles/CustomStylesExample.tsx index 74fb91ee6..99135e264 100644 --- a/apps/examples/src/examples/custom-styles/CustomStylesExample.tsx +++ b/apps/examples/src/examples/custom-styles/CustomStylesExample.tsx @@ -34,7 +34,7 @@ create a custom style for a card shape that lets the user apply a filter to blur invert or grayscale the card. [1] -We define an array to hold the custom shape util and cusom tool. It's important to +We define an array to hold the custom shape util and custom tool. It's important to do this outside of any React component so that this array doesn't get redefined on every render. We'll pass this into the Tldraw component's `shapeUtils` and `tools` props. diff --git a/apps/examples/src/examples/persistence/PersistenceExample.tsx b/apps/examples/src/examples/persistence/PersistenceExample.tsx index 23e6b2d5a..1e8356452 100644 --- a/apps/examples/src/examples/persistence/PersistenceExample.tsx +++ b/apps/examples/src/examples/persistence/PersistenceExample.tsx @@ -2,16 +2,20 @@ import { Tldraw, createTLStore, defaultShapeUtils, throttle } from '@tldraw/tldr import '@tldraw/tldraw/tldraw.css' import { useLayoutEffect, useState } from 'react' +// There's a guide at the bottom of this file! + const PERSISTENCE_KEY = 'example-3' export default function PersistenceExample() { + //[1] const [store] = useState(() => createTLStore({ shapeUtils: defaultShapeUtils })) + //[2] const [loadingState, setLoadingState] = useState< { status: 'loading' } | { status: 'ready' } | { status: 'error'; error: string } >({ status: 'loading', }) - + //[3] useLayoutEffect(() => { setLoadingState({ status: 'loading' }) @@ -43,6 +47,7 @@ export default function PersistenceExample() { } }, [store]) + // [4] if (loadingState.status === 'loading') { return (
@@ -66,3 +71,38 @@ export default function PersistenceExample() {
) } + +/* +This example shows how to implement persistence in the Tldraw component. We do +this by saving the editor's state to local storage each time it changes. You +should replace this in your app with some sort of backend storage solution. If +you just want to save to local storage, you can use the `persistenceKey` prop +instead. Simply pass any string to this prop and the editor will automatically +save to local storage. + +[1] +We create a new store using the `createTLStore` helper function. We pass in the +default shape utils so that the store knows how to handle the built-in shapes. +We also wrap this in a `useState` hook so that the store is only created once. + +[2] +This is a cool pattern that uses Typescript to help keep track of our app's +loading state. + +[3] +We use the `useLayoutEffect` hook to run our persistence code after the first +render. First we grab the persisted snapshot from local storage. If there is +one, we load it into the store and set the loading state to ready. If there +isn't one, we just set the loading state to ready. + +Then we setup a listener on the store that will run our persistence code each +time the store changes. We use the `throttle` helper function to debounce the +listener so that it doesn't run too often. We also return a cleanup function +that will remove the listener when the component unmounts. + +[4] +This is where we render our application depending on the loading state. If the +loading state is `loading`, we render a loading message. If the loading state +is `error`, we render an error message. If the loading state is `ready`, we +render the Tldraw component. +*/