Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Annotate/refactor store events example #2400

Merged
merged 3 commits into from
Jan 3, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
64 changes: 41 additions & 23 deletions apps/examples/src/examples/store-events/StoreEventsExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Editor, TLEventMapHandler, Tldraw } from '@tldraw/tldraw'
import '@tldraw/tldraw/tldraw.css'
import { useCallback, useEffect, useState } from 'react'

// There's a guide at the bottom of this file!

export default function StoreEventsExample() {
const [editor, setEditor] = useState<Editor>()

Expand All @@ -18,40 +20,39 @@ export default function StoreEventsExample() {
setStoreEvents((events) => [eventName, ...events])
}

// This is the fire hose, it will be called at the end of every transaction
//[1]
const handleChangeEvent: TLEventMapHandler<'change'> = (change) => {
if (change.source === 'user') {
// Added
for (const record of Object.values(change.changes.added)) {
if (record.typeName === 'shape') {
logChangeEvent(`created shape (${record.type})`)
}
// Added
for (const record of Object.values(change.changes.added)) {
if (record.typeName === 'shape') {
logChangeEvent(`created shape (${record.type})`)
}
}

// Updated
for (const [from, to] of Object.values(change.changes.updated)) {
if (
from.typeName === 'instance' &&
to.typeName === 'instance' &&
from.currentPageId !== to.currentPageId
) {
logChangeEvent(`changed page (${from.currentPageId}, ${to.currentPageId})`)
}
// Updated
for (const [from, to] of Object.values(change.changes.updated)) {
if (
from.typeName === 'instance' &&
to.typeName === 'instance' &&
from.currentPageId !== to.currentPageId
) {
logChangeEvent(`changed page (${from.currentPageId}, ${to.currentPageId})`)
}
}

// Removed
for (const record of Object.values(change.changes.removed)) {
if (record.typeName === 'shape') {
logChangeEvent(`deleted shape (${record.type})`)
}
// Removed
for (const record of Object.values(change.changes.removed)) {
if (record.typeName === 'shape') {
logChangeEvent(`deleted shape (${record.type})`)
}
}
}

editor.on('change', handleChangeEvent)
// [2]
const cleanupFunction = editor.store.listen(handleChangeEvent, { source: 'user', scope: 'all' })

return () => {
editor.off('change', handleChangeEvent)
cleanupFunction()
}
}, [editor])

Expand Down Expand Up @@ -82,3 +83,20 @@ export default function StoreEventsExample() {
</div>
)
}

/*
This example shows how to listen to store events. This includes things creating/deleting shapes,
or moving between pages, but not things such as pointer and keyboard events. Those are canvas events.
To listen to changes to the canvas, check out the canvas events example.

[1]
This is the fire hose, it will be called at the end of every transaction. We're checking to see what
kind of changes were made and logging a more readable message to the to our panel.

[2]
This is the function that subscribes to changes to the store. You pass in the callback function that
you want to execute along with a handy filter object. In this case, we're only listening to changes
that were made by the user. It also returns a cleanup function that you can shove into the return of
a useeffect hook.

*/